@@ -6,10 +6,11 @@ mod span_link;
66
77use  self :: span:: decode_span; 
88use  super :: error:: DecodeError ; 
9- use  super :: number:: read_number_bytes; 
10- use  crate :: span_v04:: Span ; 
9+ use  super :: number:: { read_nullable_number_ref ,   read_number_bytes,  read_number_ref } ; 
10+ use  crate :: span_v04:: { Span ,   SpanSlice } ; 
1111use  rmp:: decode:: DecodeStringError ; 
1212use  rmp:: { decode,  decode:: RmpRead ,  Marker } ; 
13+ use  span:: decode_span_ref; 
1314use  std:: { collections:: HashMap ,  f64} ; 
1415use  tinybytes:: { Bytes ,  BytesString } ; 
1516
@@ -58,11 +59,26 @@ const NULL_MARKER: &u8 = &0xc0;
5859/// let decoded_span = &decoded_traces[0][0]; 
5960/// assert_eq!("test-span", decoded_span.name.as_str()); 
6061/// ``` 
61- pub  fn  from_slice ( mut  data :  tinybytes:: Bytes )  -> Result < ( Vec < Vec < Span > > ,  usize ) ,  DecodeError >  { 
62-     let  trace_count =
63-         rmp:: decode:: read_array_len ( unsafe  {  data. as_mut_slice ( )  } ) . map_err ( |_| { 
64-             DecodeError :: InvalidFormat ( "Unable to read array len for trace count" . to_owned ( ) ) 
65-         } ) ?; 
62+ pub  fn  from_slice ( data :  tinybytes:: Bytes )  -> Result < ( Vec < Vec < Span > > ,  usize ) ,  DecodeError >  { 
63+     let  mut  parsed_data = data. clone ( ) ; 
64+     let  ( traces_ref,  size)  = from_slice_ref ( unsafe  {  parsed_data. as_mut_slice ( )  } ) ?; 
65+     let  traces_owned = traces_ref
66+         . iter ( ) 
67+         . map ( |trace| { 
68+             trace
69+                 . iter ( ) 
70+                 // Safe to unwrap since the spans uses subslices of the `data` slice 
71+                 . map ( |span| span. try_to_bytes ( & data) . unwrap ( ) ) 
72+                 . collect ( ) 
73+         } ) 
74+         . collect ( ) ; 
75+     Ok ( ( traces_owned,  size) ) 
76+ } 
77+ 
78+ pub  fn  from_slice_ref ( mut  data :  & [ u8 ] )  -> Result < ( Vec < Vec < SpanSlice > > ,  usize ) ,  DecodeError >  { 
79+     let  trace_count = rmp:: decode:: read_array_len ( & mut  data) . map_err ( |_| { 
80+         DecodeError :: InvalidFormat ( "Unable to read array len for trace count" . to_owned ( ) ) 
81+     } ) ?; 
6682
6783    let  start_len = data. len ( ) ; 
6884
@@ -74,12 +90,9 @@ pub fn from_slice(mut data: tinybytes::Bytes) -> Result<(Vec<Vec<Span>>, usize),
7490                    . expect ( "Unable to cast trace_count to usize" ) , 
7591            ) , 
7692            |mut  traces,  _| { 
77-                 let  span_count = rmp:: decode:: read_array_len ( unsafe  {  data. as_mut_slice ( )  } ) 
78-                     . map_err ( |_| { 
79-                         DecodeError :: InvalidFormat ( 
80-                             "Unable to read array len for span count" . to_owned ( ) , 
81-                         ) 
82-                     } ) ?; 
93+                 let  span_count = rmp:: decode:: read_array_len ( & mut  data) . map_err ( |_| { 
94+                     DecodeError :: InvalidFormat ( "Unable to read array len for span count" . to_owned ( ) ) 
95+                 } ) ?; 
8396
8497                let  trace = ( 0 ..span_count) . try_fold ( 
8598                    Vec :: with_capacity ( 
@@ -88,7 +101,7 @@ pub fn from_slice(mut data: tinybytes::Bytes) -> Result<(Vec<Vec<Span>>, usize),
88101                            . expect ( "Unable to cast span_count to usize" ) , 
89102                    ) , 
90103                    |mut  trace,  _| { 
91-                         let  span = decode_span ( & mut  data) ?; 
104+                         let  span = decode_span_ref ( & mut  data) ?; 
92105                        trace. push ( span) ; 
93106                        Ok ( trace) 
94107                    } , 
@@ -143,6 +156,15 @@ fn read_nullable_string_bytes(buf: &mut Bytes) -> Result<BytesString, DecodeErro
143156    } 
144157} 
145158
159+ #[ inline]  
160+ fn  read_nullable_string_ref < ' a > ( buf :  & mut  & ' a  [ u8 ] )  -> Result < & ' a  str ,  DecodeError >  { 
161+     if  is_null_marker ( buf)  { 
162+         Ok ( "" ) 
163+     }  else  { 
164+         read_string_ref ( buf) 
165+     } 
166+ } 
167+ 
146168#[ inline]  
147169// Safety: read_string_ref checks utf8 validity, so we don't do it again when creating the 
148170// BytesStrings. 
@@ -172,6 +194,35 @@ fn read_nullable_str_map_to_bytes_strings(
172194    read_str_map_to_bytes_strings ( buf) 
173195} 
174196
197+ #[ inline]  
198+ // Safety: read_string_ref checks utf8 validity, so we don't do it again when creating the 
199+ // BytesStrings. 
200+ fn  read_str_map_to_str_ref < ' a > ( 
201+     buf :  & mut  & ' a  [ u8 ] , 
202+ )  -> Result < HashMap < & ' a  str ,  & ' a  str > ,  DecodeError >  { 
203+     let  len = decode:: read_map_len ( buf) 
204+         . map_err ( |_| DecodeError :: InvalidFormat ( "Unable to get map len for str map" . to_owned ( ) ) ) ?; 
205+ 
206+     let  mut  map = HashMap :: with_capacity ( len. try_into ( ) . expect ( "Unable to cast map len to usize" ) ) ; 
207+     for  _ in  0 ..len { 
208+         let  key = read_string_ref ( buf) ?; 
209+         let  value = read_string_ref ( buf) ?; 
210+         map. insert ( key,  value) ; 
211+     } 
212+     Ok ( map) 
213+ } 
214+ 
215+ #[ inline]  
216+ fn  read_nullable_str_map_to_str_ref < ' a > ( 
217+     buf :  & mut  & ' a  [ u8 ] , 
218+ )  -> Result < HashMap < & ' a  str ,  & ' a  str > ,  DecodeError >  { 
219+     if  is_null_marker ( buf)  { 
220+         return  Ok ( HashMap :: default ( ) ) ; 
221+     } 
222+ 
223+     read_str_map_to_str_ref ( buf) 
224+ } 
225+ 
175226#[ inline]  
176227fn  read_metric_pair ( buf :  & mut  Bytes )  -> Result < ( BytesString ,  f64 ) ,  DecodeError >  { 
177228    let  key = read_string_bytes ( buf) ?; 
@@ -215,6 +266,52 @@ fn read_meta_struct(buf: &mut Bytes) -> Result<HashMap<BytesString, Vec<u8>>, De
215266    read_map ( len,  buf,  read_meta_struct_pair) 
216267} 
217268
269+ #[ inline]  
270+ fn  read_metric_pair_ref < ' a > ( buf :  & mut  & ' a  [ u8 ] )  -> Result < ( & ' a  str ,  f64 ) ,  DecodeError >  { 
271+     let  key = read_string_ref ( buf) ?; 
272+     let  v = read_number_ref ( buf) ?; 
273+ 
274+     Ok ( ( key,  v) ) 
275+ } 
276+ 
277+ #[ inline]  
278+ fn  read_metrics_ref < ' a > ( buf :  & mut  & ' a  [ u8 ] )  -> Result < HashMap < & ' a  str ,  f64 > ,  DecodeError >  { 
279+     if  is_null_marker ( buf)  { 
280+         return  Ok ( HashMap :: default ( ) ) ; 
281+     } 
282+ 
283+     let  len = read_map_len ( buf) ?; 
284+ 
285+     read_map ( len,  buf,  read_metric_pair_ref) 
286+ } 
287+ 
288+ #[ inline]  
289+ fn  read_meta_struct_ref < ' a > ( buf :  & mut  & ' a  [ u8 ] )  -> Result < HashMap < & ' a  str ,  Vec < u8 > > ,  DecodeError >  { 
290+     if  is_null_marker ( buf)  { 
291+         return  Ok ( HashMap :: default ( ) ) ; 
292+     } 
293+ 
294+     fn  read_meta_struct_pair_ref < ' a > ( 
295+         buf :  & mut  & ' a  [ u8 ] , 
296+     )  -> Result < ( & ' a  str ,  Vec < u8 > ) ,  DecodeError >  { 
297+         let  key = read_string_ref ( buf) ?; 
298+         let  array_len = decode:: read_array_len ( buf) . map_err ( |_| { 
299+             DecodeError :: InvalidFormat ( "Unable to read array len for meta_struct" . to_owned ( ) ) 
300+         } ) ?; 
301+ 
302+         let  mut  v = Vec :: with_capacity ( array_len as  usize ) ; 
303+ 
304+         for  _ in  0 ..array_len { 
305+             let  value = read_number_ref ( buf) ?; 
306+             v. push ( value) ; 
307+         } 
308+         Ok ( ( key,  v) ) 
309+     } 
310+ 
311+     let  len = read_map_len ( buf) ?; 
312+     read_map ( len,  buf,  read_meta_struct_pair_ref) 
313+ } 
314+ 
218315/// Reads a map from the buffer and returns it as a `HashMap`. 
219316/// 
220317/// This function is generic over the key and value types of the map, and it uses a provided 
@@ -243,14 +340,10 @@ fn read_meta_struct(buf: &mut Bytes) -> Result<HashMap<BytesString, Vec<u8>>, De
243340/// * `V` - The type of the values in the map. 
244341/// * `F` - The type of the function used to read key-value pairs from the buffer. 
245342#[ inline]  
246- fn  read_map < K ,  V ,  F > ( 
247-     len :  usize , 
248-     buf :  & mut  Bytes , 
249-     read_pair :  F , 
250- )  -> Result < HashMap < K ,  V > ,  DecodeError > 
343+ fn  read_map < K ,  B ,  V ,  F > ( len :  usize ,  buf :  & mut  B ,  read_pair :  F )  -> Result < HashMap < K ,  V > ,  DecodeError > 
251344where 
252345    K :  std:: hash:: Hash  + Eq , 
253-     F :  Fn ( & mut  Bytes )  -> Result < ( K ,  V ) ,  DecodeError > , 
346+     F :  Fn ( & mut  B )  -> Result < ( K ,  V ) ,  DecodeError > , 
254347{ 
255348    let  mut  map = HashMap :: with_capacity ( len) ; 
256349    for  _ in  0 ..len { 
@@ -297,6 +390,18 @@ where
297390    } 
298391} 
299392
393+ /// When you want to "peek" if the next value is a null marker, and only advance the buffer if it is 
394+ /// null and return the default value. If it is not null, you can continue to decode as expected. 
395+ #[ inline]  
396+ fn  is_null_marker ( buf :  & mut  & [ u8 ] )  -> bool  { 
397+     if  buf. first ( )  == Some ( NULL_MARKER )  { 
398+         * buf = & buf[ 1 ..] ; 
399+         true 
400+     }  else  { 
401+         false 
402+     } 
403+ } 
404+ 
300405#[ cfg( test) ]  
301406mod  tests { 
302407    use  super :: * ; 
0 commit comments