1- use slog:: { Record , Serializer } ;
1+ use slog:: { Record , Serializer , KV } ;
2+
3+ use std:: fmt:: Arguments ;
24
35pub ( crate ) struct Visitor {
46 kvs : Vec < ( String , String ) > ,
@@ -25,11 +27,105 @@ impl<'kvs, 'a> log::kv::Visitor<'kvs> for Visitor {
2527 }
2628}
2729
28- impl slog :: KV for Visitor {
30+ impl KV for Visitor {
2931 fn serialize ( & self , _record : & Record , serializer : & mut dyn Serializer ) -> slog:: Result {
3032 for ( key, val) in & self . kvs {
3133 serializer. emit_str ( key. to_owned ( ) . into ( ) , val. as_str ( ) ) ?;
3234 }
3335 Ok ( ( ) )
3436 }
3537}
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