1
- use slog:: { Record , Serializer } ;
1
+ use slog:: { Record , Serializer , KV } ;
2
+
3
+ use std:: fmt:: Arguments ;
2
4
3
5
pub ( crate ) struct Visitor {
4
6
kvs : Vec < ( String , String ) > ,
@@ -25,11 +27,105 @@ impl<'kvs, 'a> log::kv::Visitor<'kvs> for Visitor {
25
27
}
26
28
}
27
29
28
- impl slog :: KV for Visitor {
30
+ impl KV for Visitor {
29
31
fn serialize ( & self , _record : & Record , serializer : & mut dyn Serializer ) -> slog:: Result {
30
32
for ( key, val) in & self . kvs {
31
33
serializer. emit_str ( key. to_owned ( ) . into ( ) , val. as_str ( ) ) ?;
32
34
}
33
35
Ok ( ( ) )
34
36
}
35
37
}
38
+
39
+ /// Create a [`log::kv::Source`] for the key-value pairs for a slog record.
40
+ pub ( crate ) fn get_kv_source < ' a > (
41
+ record : & ' a slog:: Record < ' a > ,
42
+ logger_kv : & ' a slog:: OwnedKVList ,
43
+ ) -> std:: io:: Result < Vec < ( String , OwnedValue ) > > {
44
+ let mut serialized_source = LogSerializer ( vec ! [ ] ) ;
45
+
46
+ record. kv ( ) . serialize ( record, & mut serialized_source) ?;
47
+ logger_kv. serialize ( record, & mut serialized_source) ?;
48
+ Ok ( serialized_source. 0 )
49
+ }
50
+
51
+ /// A wrapper around [`log::kv::Value`], that owns the data included.
52
+ ///
53
+ /// In particular this is necessary for strings, and large integers (u128, and i128), because the
54
+ /// `Value` type itself only supports references, which must survive for the lifetime of the
55
+ /// visitor.
56
+ pub ( crate ) enum OwnedValue {
57
+ Value ( log:: kv:: Value < ' static > ) ,
58
+ Str ( String ) ,
59
+ U128 ( Box < u128 > ) ,
60
+ I128 ( Box < i128 > ) ,
61
+ }
62
+
63
+ impl log:: kv:: value:: ToValue for OwnedValue {
64
+ fn to_value ( & self ) -> log:: kv:: Value < ' _ > {
65
+ use OwnedValue :: * ;
66
+
67
+ match self {
68
+ Value ( v) => v. to_value ( ) ,
69
+ Str ( s) => s. to_value ( ) ,
70
+ U128 ( v) => v. to_value ( ) ,
71
+ I128 ( v) => v. to_value ( ) ,
72
+ }
73
+ }
74
+ }
75
+
76
+ struct LogSerializer ( Vec < ( String , OwnedValue ) > ) ;
77
+
78
+ impl LogSerializer {
79
+ fn add ( & mut self , key : slog:: Key , val : OwnedValue ) -> slog:: Result {
80
+ self . 0 . push ( ( key. into ( ) , val) ) ;
81
+ Ok ( ( ) )
82
+ }
83
+ }
84
+
85
+ macro_rules! emit_to_value {
86
+ ( $f: ident : $t: ty) => {
87
+ fn $f( & mut self , key: slog:: Key , val: $t) -> slog:: Result {
88
+ self . add( key, OwnedValue :: Value ( val. into( ) ) )
89
+ }
90
+ } ;
91
+ }
92
+
93
+ impl Serializer for LogSerializer {
94
+ fn emit_arguments ( & mut self , key : slog:: Key , val : & Arguments < ' _ > ) -> slog:: Result {
95
+ self . add ( key, OwnedValue :: Str ( val. to_string ( ) ) )
96
+ }
97
+
98
+ emit_to_value ! ( emit_usize: usize ) ;
99
+ emit_to_value ! ( emit_isize: isize ) ;
100
+ emit_to_value ! ( emit_bool: bool ) ;
101
+ emit_to_value ! ( emit_char: char ) ;
102
+ emit_to_value ! ( emit_u8: u8 ) ;
103
+ emit_to_value ! ( emit_i8: i8 ) ;
104
+ emit_to_value ! ( emit_u16: u16 ) ;
105
+ emit_to_value ! ( emit_i16: i16 ) ;
106
+ emit_to_value ! ( emit_u32: u32 ) ;
107
+ emit_to_value ! ( emit_i32: i32 ) ;
108
+ emit_to_value ! ( emit_f32: f32 ) ;
109
+ emit_to_value ! ( emit_f64: f64 ) ;
110
+
111
+ fn emit_u128 ( & mut self , key : slog:: Key , val : u128 ) -> slog:: Result {
112
+ self . add ( key, OwnedValue :: U128 ( Box :: new ( val) ) )
113
+ }
114
+
115
+ fn emit_i128 ( & mut self , key : slog:: Key , val : i128 ) -> slog:: Result {
116
+ self . add ( key, OwnedValue :: I128 ( Box :: new ( val) ) )
117
+ }
118
+
119
+ fn emit_str ( & mut self , key : slog:: Key , val : & str ) -> slog:: Result {
120
+ self . add ( key, OwnedValue :: Str ( val. to_string ( ) ) )
121
+ }
122
+
123
+ fn emit_unit ( & mut self , key : slog:: Key ) -> slog:: Result {
124
+ use log:: kv:: ToValue ;
125
+ self . add ( key, OwnedValue :: Value ( ( ) . to_value ( ) ) )
126
+ }
127
+
128
+ fn emit_none ( & mut self , key : slog:: Key ) -> slog:: Result {
129
+ self . emit_unit ( key)
130
+ }
131
+ }
0 commit comments