11use log:: kv:: value:: Error as ValueError ;
2- use slog:: { Record , Serializer } ;
2+ use slog:: { Record , Serializer , KV } ;
3+
4+ use std:: fmt:: Arguments ;
35
46struct Visitor < ' s > {
57 serializer : & ' s mut dyn Serializer ,
@@ -60,7 +62,7 @@ impl<'s> log::kv::value::Visit<'s> for KeyVisit<'s> {
6062 visit_to_emit ! ( & ( dyn std:: error:: Error + ' static ) : visit_error -> emit_error) ;
6163}
6264
63- impl slog :: KV for SourceKV < ' _ > {
65+ impl KV for SourceKV < ' _ > {
6466 fn serialize ( & self , _record : & Record , serializer : & mut dyn Serializer ) -> slog:: Result {
6567 // Unfortunately, there isn't a way for use to pass the original error through.
6668 self . 0
@@ -79,4 +81,96 @@ fn to_value_err(err: slog::Error) -> ValueError {
7981 }
8082}
8183
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