11use std:: convert:: TryInto ;
22use std:: mem:: size_of;
33
4- /// `FixedInt` provides encoding/decoding to and from fixed int representations.
4+ /// `FixedInt` provides encoding/decoding to and from fixed int representations. Note that current
5+ /// Rust versions already provide this functionality via the `to_le_bytes()` and `to_be_bytes()`
6+ /// methods.
57///
68/// The emitted bytestring contains the bytes of the integer in machine endianness.
79pub trait FixedInt : Sized + Copy {
810 type Bytes : AsRef < [ u8 ] > ;
11+ const ENCODED_SIZE : usize = size_of :: < Self > ( ) ;
912
10- /// Encode a value into the given slice. `dst` must be exactly `REQUIRED_SPACE` bytes.
11- fn encode_fixed ( self , dst : & mut [ u8 ] ) ;
12- /// Decode a value from the given slice. `src` must be exactly `REQUIRED_SPACE` bytes.
13- fn decode_fixed ( src : & [ u8 ] ) -> Self ;
13+ /// Encode a value into the given slice using machine endianness. Returns `None` if `dst`
14+ /// doesn't provide enough space to encode this integer.
15+ fn encode_fixed ( self , dst : & mut [ u8 ] ) -> Option < ( ) > ;
1416 /// Returns the representation of [`FixedInt`] as [`Bytes`], the little-endian representation
1517 /// of self in the stack.
1618 fn encode_fixed_light ( self ) -> Self :: Bytes ;
1719
20+ /// Decode a value from the given slice assuming little-endian.
21+ fn decode_le_fixed ( src : & [ u8 ] ) -> Option < Self > ;
22+ /// Decode a value from the given slice assuming big-endian.
23+ fn decode_be_fixed ( src : & [ u8 ] ) -> Option < Self > ;
24+
1825 /// Helper: Encode the value and return a Vec.
1926 fn encode_fixed_vec ( self ) -> Vec < u8 > {
2027 self . encode_fixed_light ( ) . as_ref ( ) . to_vec ( )
2128 }
2229
23- /// Helper: Decode the value from the Vec.
24- fn decode_fixed_vec ( v : & Vec < u8 > ) -> Self {
25- Self :: decode_fixed ( & v[ ..] )
26- }
27-
2830 /// integer-encoding-rs always emits and receives little-endian integers (converting implicitly
2931 /// on big-endian machines). If you receive a big-endian integer, and would like it to be
3032 /// treated correctly, use this helper method to convert between endiannesses.
@@ -36,23 +38,33 @@ macro_rules! impl_fixedint {
3638 impl FixedInt for $t {
3739 type Bytes = [ u8 ; size_of:: <$t>( ) ] ;
3840
39- fn encode_fixed_light( self ) -> Self :: Bytes {
40- self . to_le_bytes( )
41+ fn encode_fixed( self , dst: & mut [ u8 ] ) -> Option <( ) > {
42+ if dst. len( ) == size_of:: <Self >( ) {
43+ dst. clone_from_slice( & self . to_le_bytes( ) ) ;
44+ Some ( ( ) )
45+ } else {
46+ None
47+ }
4148 }
4249
43- fn encode_fixed( self , dst: & mut [ u8 ] ) {
44- assert_eq!( dst. len( ) , size_of:: <Self >( ) ) ;
45- dst. clone_from_slice( & self . to_le_bytes( ) ) ;
50+ fn encode_fixed_light( self ) -> Self :: Bytes {
51+ self . to_le_bytes( )
4652 }
4753
48- #[ cfg( target_endian = "little" ) ]
49- fn decode_fixed( src: & [ u8 ] ) -> Self {
50- Self :: from_le_bytes( src. try_into( ) . unwrap( ) )
54+ fn decode_le_fixed( src: & [ u8 ] ) -> Option <Self > {
55+ if src. len( ) == size_of:: <Self >( ) {
56+ Some ( Self :: from_le_bytes( src. try_into( ) . unwrap( ) ) )
57+ } else {
58+ None
59+ }
5160 }
5261
53- #[ cfg( target_endian = "big" ) ]
54- fn decode_fixed( src: & [ u8 ] ) -> $t {
55- Self :: from_be_bytes( src. try_into( ) . unwrap( ) )
62+ fn decode_be_fixed( src: & [ u8 ] ) -> Option <Self > {
63+ if src. len( ) == size_of:: <Self >( ) {
64+ Some ( Self :: from_be_bytes( src. try_into( ) . unwrap( ) ) )
65+ } else {
66+ None
67+ }
5668 }
5769
5870 fn switch_endianness( self ) -> Self {
0 commit comments