3939
4040use std:: ops:: Bound ;
4141
42+ use itertools:: Either ;
4243use serde:: de:: {
4344 Deserialize , DeserializeSeed , EnumAccess , IntoDeserializer as _, SeqAccess , VariantAccess ,
4445 Visitor ,
@@ -127,7 +128,7 @@ impl serde::ser::Serializer for &mut Serializer {
127128 unimplemented ! ( )
128129 }
129130
130- /// i64 uses the big-endian two's completement encoding, but flips the
131+ /// i64 uses the big-endian two's complement encoding, but flips the
131132 /// left-most sign bit such that negative numbers are ordered before
132133 /// positive numbers.
133134 ///
@@ -163,16 +164,15 @@ impl serde::ser::Serializer for &mut Serializer {
163164 unimplemented ! ( )
164165 }
165166
166- /// f64 is encoded in big-endian form, but it flips the sign bit to order
167- /// positive numbers after negative numbers, and also flips all other bits
168- /// for negative numbers to order them from smallest to greatest . NaN is
167+ /// f64 is encoded in big-endian IEEE 754 form, but it flips the sign bit to
168+ /// order positive numbers after negative numbers, and also flips all other
169+ /// bits for negative numbers to order them from smallest to largest . NaN is
169170 /// ordered at the end.
170171 fn serialize_f64 ( self , v : f64 ) -> Result < ( ) > {
171172 let mut bytes = v. to_be_bytes ( ) ;
172- if bytes[ 0 ] & 1 << 7 == 0 {
173- bytes[ 0 ] ^= 1 << 7 ; // positive, flip sign bit
174- } else {
175- bytes. iter_mut ( ) . for_each ( |b| * b = !* b) ; // negative, flip all bits
173+ match v. is_sign_negative ( ) {
174+ false => bytes[ 0 ] ^= 1 << 7 , // positive, flip sign bit
175+ true => bytes. iter_mut ( ) . for_each ( |b| * b = !* b) , // negative, flip all bits
176176 }
177177 self . output . extend ( bytes) ;
178178 Ok ( ( ) )
@@ -187,14 +187,20 @@ impl serde::ser::Serializer for &mut Serializer {
187187 self . serialize_bytes ( v. as_bytes ( ) )
188188 }
189189
190- // Byte slices are terminated by 0x0000, escaping 0x00 as 0x00ff.
191- // Prefix-length encoding can't be used, since it violates ordering.
190+ // Byte slices are terminated by 0x0000, escaping 0x00 as 0x00ff. This
191+ // ensures that we can detect the end, and that for two overlapping slices,
192+ // the shorter one orders before the longer one.
193+ //
194+ // We can't use e.g. length prefix encoding, since it doesn't sort correctly.
192195 fn serialize_bytes ( self , v : & [ u8 ] ) -> Result < ( ) > {
193- let b = v
196+ let bytes = v
194197 . iter ( )
195- . flat_map ( |& b| if b == 0x00 { vec ! [ 0x00 , 0xff ] } else { vec ! [ b] } )
198+ . flat_map ( |& byte| match byte {
199+ 0x00 => Either :: Left ( [ 0x00 , 0xff ] . into_iter ( ) ) ,
200+ byte => Either :: Right ( [ byte] . into_iter ( ) ) ,
201+ } )
196202 . chain ( [ 0x00 , 0x00 ] ) ;
197- self . output . extend ( b ) ;
203+ self . output . extend ( bytes ) ;
198204 Ok ( ( ) )
199205 }
200206
@@ -354,9 +360,6 @@ impl<'de> Deserializer<'de> {
354360
355361 /// Decodes and chops off the next encoded byte slice.
356362 fn decode_next_bytes ( & mut self ) -> Result < Vec < u8 > > {
357- // We can't easily share state between Iterator.scan() and
358- // Iterator.filter() when processing escape sequences, so use a
359- // straightforward loop.
360363 let mut decoded = Vec :: new ( ) ;
361364 let mut iter = self . input . iter ( ) . enumerate ( ) ;
362365 let taken = loop {
@@ -387,7 +390,7 @@ impl<'de> serde::de::Deserializer<'de> for &mut Deserializer<'de> {
387390 visitor. visit_bool ( match self . take_bytes ( 1 ) ?[ 0 ] {
388391 0x00 => false ,
389392 0x01 => true ,
390- b => return errdata ! ( "Invalid boolean value {b:? }" ) ,
393+ b => return errdata ! ( "invalid boolean value {b}" ) ,
391394 } )
392395 }
393396
@@ -431,10 +434,10 @@ impl<'de> serde::de::Deserializer<'de> for &mut Deserializer<'de> {
431434
432435 fn deserialize_f64 < V : Visitor < ' de > > ( self , visitor : V ) -> Result < V :: Value > {
433436 let mut bytes = self . take_bytes ( 8 ) ?. to_vec ( ) ;
434- if bytes[ 0 ] >> 7 & 1 == 1 {
435- bytes [ 0 ] ^= 1 << 7 ; // positive , flip sign bit
436- } else {
437- bytes . iter_mut ( ) . for_each ( |b| * b = ! * b ) ; // negative, flip all bits
437+ match bytes[ 0 ] >> 7 {
438+ 0 => bytes . iter_mut ( ) . for_each ( |b| * b = ! * b ) , // negative , flip all bits
439+ 1 => bytes [ 0 ] ^= 1 << 7 , // positive, flip sign bit
440+ _ => panic ! ( "bits can only be 0 or 1" ) ,
438441 }
439442 visitor. visit_f64 ( f64:: from_be_bytes ( bytes. as_slice ( ) . try_into ( ) ?) )
440443 }
0 commit comments