1
1
use log:: kv:: value:: Error as ValueError ;
2
- use slog:: { Record , Serializer } ;
2
+ use slog:: { Record , Serializer , KV } ;
3
+
4
+ use std:: fmt:: Arguments ;
3
5
4
6
struct Visitor < ' s > {
5
7
serializer : & ' s mut dyn Serializer ,
@@ -60,7 +62,7 @@ impl<'s> log::kv::value::Visit<'s> for KeyVisit<'s> {
60
62
visit_to_emit ! ( & ( dyn std:: error:: Error + ' static ) : visit_error -> emit_error) ;
61
63
}
62
64
63
- impl slog :: KV for SourceKV < ' _ > {
65
+ impl KV for SourceKV < ' _ > {
64
66
fn serialize ( & self , _record : & Record , serializer : & mut dyn Serializer ) -> slog:: Result {
65
67
// Unfortunately, there isn't a way for use to pass the original error through.
66
68
self . 0
@@ -79,4 +81,96 @@ fn to_value_err(err: slog::Error) -> ValueError {
79
81
}
80
82
}
81
83
82
- // TODO: support going the other way
84
+ /// Create a [`log::kv::Source`] for the key-value pairs for a slog record.
85
+ pub ( crate ) fn get_kv_source < ' a > (
86
+ record : & ' a slog:: Record < ' a > ,
87
+ logger_kv : & ' a slog:: OwnedKVList ,
88
+ ) -> std:: io:: Result < Vec < ( String , OwnedValue ) > > {
89
+ let mut serialized_source = LogSerializer ( vec ! [ ] ) ;
90
+
91
+ record. kv ( ) . serialize ( record, & mut serialized_source) ?;
92
+ logger_kv. serialize ( record, & mut serialized_source) ?;
93
+ Ok ( serialized_source. 0 )
94
+ }
95
+
96
+ /// A wrapper around [`log::kv::Value`], that owns the data included.
97
+ ///
98
+ /// In particular this is necessary for strings, and large integers (u128, and i128), because the
99
+ /// `Value` type itself only supports references, which must survive for the lifetime of the
100
+ /// visitor.
101
+ pub ( crate ) enum OwnedValue {
102
+ Value ( log:: kv:: Value < ' static > ) ,
103
+ Str ( String ) ,
104
+ U128 ( Box < u128 > ) ,
105
+ I128 ( Box < i128 > ) ,
106
+ }
107
+
108
+ impl log:: kv:: value:: ToValue for OwnedValue {
109
+ fn to_value ( & self ) -> log:: kv:: Value < ' _ > {
110
+ use OwnedValue :: * ;
111
+
112
+ match self {
113
+ Value ( v) => v. to_value ( ) ,
114
+ Str ( s) => s. to_value ( ) ,
115
+ U128 ( v) => v. to_value ( ) ,
116
+ I128 ( v) => v. to_value ( ) ,
117
+ }
118
+ }
119
+ }
120
+
121
+ struct LogSerializer ( Vec < ( String , OwnedValue ) > ) ;
122
+
123
+ impl LogSerializer {
124
+ fn add ( & mut self , key : slog:: Key , val : OwnedValue ) -> slog:: Result {
125
+ self . 0 . push ( ( key. into ( ) , val) ) ;
126
+ Ok ( ( ) )
127
+ }
128
+ }
129
+
130
+ macro_rules! emit_to_value {
131
+ ( $f: ident : $t: ty) => {
132
+ fn $f( & mut self , key: slog:: Key , val: $t) -> slog:: Result {
133
+ self . add( key, OwnedValue :: Value ( val. into( ) ) )
134
+ }
135
+ } ;
136
+ }
137
+
138
+ impl Serializer for LogSerializer {
139
+ fn emit_arguments ( & mut self , key : slog:: Key , val : & Arguments < ' _ > ) -> slog:: Result {
140
+ self . add ( key, OwnedValue :: Str ( val. to_string ( ) ) )
141
+ }
142
+
143
+ emit_to_value ! ( emit_usize: usize ) ;
144
+ emit_to_value ! ( emit_isize: isize ) ;
145
+ emit_to_value ! ( emit_bool: bool ) ;
146
+ emit_to_value ! ( emit_char: char ) ;
147
+ emit_to_value ! ( emit_u8: u8 ) ;
148
+ emit_to_value ! ( emit_i8: i8 ) ;
149
+ emit_to_value ! ( emit_u16: u16 ) ;
150
+ emit_to_value ! ( emit_i16: i16 ) ;
151
+ emit_to_value ! ( emit_u32: u32 ) ;
152
+ emit_to_value ! ( emit_i32: i32 ) ;
153
+ emit_to_value ! ( emit_f32: f32 ) ;
154
+ emit_to_value ! ( emit_f64: f64 ) ;
155
+
156
+ fn emit_u128 ( & mut self , key : slog:: Key , val : u128 ) -> slog:: Result {
157
+ self . add ( key, OwnedValue :: U128 ( Box :: new ( val) ) )
158
+ }
159
+
160
+ fn emit_i128 ( & mut self , key : slog:: Key , val : i128 ) -> slog:: Result {
161
+ self . add ( key, OwnedValue :: I128 ( Box :: new ( val) ) )
162
+ }
163
+
164
+ fn emit_str ( & mut self , key : slog:: Key , val : & str ) -> slog:: Result {
165
+ self . add ( key, OwnedValue :: Str ( val. to_string ( ) ) )
166
+ }
167
+
168
+ fn emit_unit ( & mut self , key : slog:: Key ) -> slog:: Result {
169
+ use log:: kv:: ToValue ;
170
+ self . add ( key, OwnedValue :: Value ( ( ) . to_value ( ) ) )
171
+ }
172
+
173
+ fn emit_none ( & mut self , key : slog:: Key ) -> slog:: Result {
174
+ self . emit_unit ( key)
175
+ }
176
+ }
0 commit comments