Rename marker structs for Bitfield
This commit is contained in:
		
							parent
							
								
									5e1a2ebf25
								
							
						
					
					
						commit
						2c1afcc2d6
					
				| @ -5,43 +5,61 @@ use serde_hex::{encode as hex_encode, PrefixedHexVisitor}; | ||||
| use ssz::{Decode, Encode}; | ||||
| use typenum::Unsigned; | ||||
| 
 | ||||
| /// A marker trait applied to `BitList` and `BitVector` that defines the behaviour of a `Bitfield`.
 | ||||
| /// A marker trait applied to `Variable` and `Fixed` that defines the behaviour of a `Bitfield`.
 | ||||
| pub trait BitfieldBehaviour: Clone {} | ||||
| 
 | ||||
| /// A marker struct used to declare SSZ `BitList` behaviour on a `Bitfield`.
 | ||||
| /// A marker struct used to declare SSZ `Variable` behaviour on a `Bitfield`.
 | ||||
| ///
 | ||||
| /// See the [`Bitfield`](struct.Bitfield.html) docs for usage.
 | ||||
| #[derive(Clone, PartialEq, Debug)] | ||||
| pub struct BitList<N> { | ||||
| pub struct Variable<N> { | ||||
|     _phantom: PhantomData<N>, | ||||
| } | ||||
| 
 | ||||
| /// A marker struct used to declare SSZ `BitVector` behaviour on a `Bitfield`.
 | ||||
| /// A marker struct used to declare SSZ `Fixed` behaviour on a `Bitfield`.
 | ||||
| ///
 | ||||
| /// See the [`Bitfield`](struct.Bitfield.html) docs for usage.
 | ||||
| #[derive(Clone, PartialEq, Debug)] | ||||
| pub struct BitVector<N> { | ||||
| pub struct Fixed<N> { | ||||
|     _phantom: PhantomData<N>, | ||||
| } | ||||
| 
 | ||||
| impl<N: Unsigned + Clone> BitfieldBehaviour for BitList<N> {} | ||||
| impl<N: Unsigned + Clone> BitfieldBehaviour for BitVector<N> {} | ||||
| impl<N: Unsigned + Clone> BitfieldBehaviour for Variable<N> {} | ||||
| impl<N: Unsigned + Clone> BitfieldBehaviour for Fixed<N> {} | ||||
| 
 | ||||
| /// A heap-allocated, ordered, fixed-length, collection of `bool` values. Must be used with the `BitList` or
 | ||||
| /// `BitVector` marker structs.
 | ||||
| /// A heap-allocated, ordered, variable-length collection of `bool` values, limited to `N` bits.
 | ||||
| pub type BitList<N> = Bitfield<Variable<N>>; | ||||
| 
 | ||||
| /// A heap-allocated, ordered, fixed-length collection of `bool` values, with `N` bits.
 | ||||
| ///
 | ||||
| /// See [Bitfield](struct.Bitfield.html) documentation.
 | ||||
| pub type BitVector<N> = Bitfield<Fixed<N>>; | ||||
| 
 | ||||
| /// A heap-allocated, ordered, fixed-length, collection of `bool` values. Use of
 | ||||
| /// [`BitList`](type.BitList.html) or [`BitVector`](type.BitVector.html) type aliases is preferred
 | ||||
| /// over direct use of this struct.
 | ||||
| ///
 | ||||
| /// The `T` type parameter is used to define length behaviour with the `Variable` or `Fixed` marker
 | ||||
| /// structs.
 | ||||
| ///
 | ||||
| /// The length of the Bitfield is set at instantiation (i.e., runtime, not compile time). However,
 | ||||
| /// use with a `BitList` sets a type-level (i.e., compile-time) maximum length and `BitVector`
 | ||||
| /// use with a `Variable` sets a type-level (i.e., compile-time) maximum length and `Fixed`
 | ||||
| /// provides a type-level fixed length.
 | ||||
| ///
 | ||||
| /// ## Example
 | ||||
| ///
 | ||||
| /// The example uses the following crate-level type aliases:
 | ||||
| ///
 | ||||
| /// - `BitList<N>` is an alias for `Bitfield<Variable<N>>`
 | ||||
| /// - `BitVector<N>` is an alias for `Bitfield<Fixed<N>>`
 | ||||
| ///
 | ||||
| /// ```
 | ||||
| /// use ssz_types::{Bitfield, BitVector, BitList, typenum};
 | ||||
| /// use ssz_types::{BitVector, BitList, typenum};
 | ||||
| ///
 | ||||
| /// // `BitList` has a type-level maximum length. The length of the list is specified at runtime
 | ||||
| /// // and it must be less than or equal to `N`. After instantiation, `BitList` cannot grow or
 | ||||
| /// // shrink.
 | ||||
| /// type BitList8 = Bitfield<BitList<typenum::U8>>;
 | ||||
| /// type BitList8 = BitList<typenum::U8>;
 | ||||
| ///
 | ||||
| /// // Creating a `BitList` with a larger-than-`N` capacity returns `None`.
 | ||||
| /// assert!(BitList8::with_capacity(9).is_none());
 | ||||
| @ -52,7 +70,7 @@ impl<N: Unsigned + Clone> BitfieldBehaviour for BitVector<N> {} | ||||
| ///
 | ||||
| /// // `BitVector` has a type-level fixed length. Unlike `BitList`, it cannot be instantiated with a custom length
 | ||||
| /// // or grow/shrink.
 | ||||
| /// type BitVector8 = Bitfield<BitVector<typenum::U8>>;
 | ||||
| /// type BitVector8 = BitVector<typenum::U8>;
 | ||||
| ///
 | ||||
| /// let mut bitvector = BitVector8::new();
 | ||||
| /// assert_eq!(bitvector.len(), 8); // `BitVector` length is fixed at the type-level.
 | ||||
| @ -73,7 +91,7 @@ pub struct Bitfield<T> { | ||||
|     _phantom: PhantomData<T>, | ||||
| } | ||||
| 
 | ||||
| impl<N: Unsigned + Clone> Bitfield<BitList<N>> { | ||||
| impl<N: Unsigned + Clone> Bitfield<Variable<N>> { | ||||
|     /// Instantiate with capacity for `num_bits` boolean values. The length cannot be grown or
 | ||||
|     /// shrunk after instantiation.
 | ||||
|     ///
 | ||||
| @ -104,11 +122,11 @@ impl<N: Unsigned + Clone> Bitfield<BitList<N>> { | ||||
|     ///
 | ||||
|     /// ## Example
 | ||||
|     /// ```
 | ||||
|     /// use ssz_types::{Bitfield, typenum};
 | ||||
|     /// use ssz_types::{BitList, typenum};
 | ||||
|     ///
 | ||||
|     /// type BitList = Bitfield<ssz_types::BitList<typenum::U8>>;
 | ||||
|     /// type BitList8 = BitList<typenum::U8>;
 | ||||
|     ///
 | ||||
|     /// let b = BitList::with_capacity(4).unwrap();
 | ||||
|     /// let b = BitList8::with_capacity(4).unwrap();
 | ||||
|     ///
 | ||||
|     /// assert_eq!(b.into_bytes(), vec![0b0001_0000]);
 | ||||
|     /// ```
 | ||||
| @ -120,7 +138,7 @@ impl<N: Unsigned + Clone> Bitfield<BitList<N>> { | ||||
|             bytes.insert(0, 0); | ||||
|         } | ||||
| 
 | ||||
|         let mut bitfield: Bitfield<BitList<N>> = Bitfield::from_raw_bytes(bytes, len + 1) | ||||
|         let mut bitfield: Bitfield<Variable<N>> = Bitfield::from_raw_bytes(bytes, len + 1) | ||||
|             .expect("Bitfield capacity has been confirmed earlier."); | ||||
|         bitfield.set(len, true).expect("Bitfield index must exist."); | ||||
| 
 | ||||
| @ -132,7 +150,7 @@ impl<N: Unsigned + Clone> Bitfield<BitList<N>> { | ||||
|     ///
 | ||||
|     /// Returns `None` if `bytes` are not a valid encoding.
 | ||||
|     pub fn from_bytes(bytes: Vec<u8>) -> Option<Self> { | ||||
|         let mut initial_bitfield: Bitfield<BitList<N>> = { | ||||
|         let mut initial_bitfield: Bitfield<Variable<N>> = { | ||||
|             let num_bits = bytes.len() * 8; | ||||
|             Bitfield::from_raw_bytes(bytes, num_bits) | ||||
|                 .expect("Must have adequate bytes for bit count.") | ||||
| @ -158,7 +176,7 @@ impl<N: Unsigned + Clone> Bitfield<BitList<N>> { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<N: Unsigned + Clone> Bitfield<BitVector<N>> { | ||||
| impl<N: Unsigned + Clone> Bitfield<Fixed<N>> { | ||||
|     /// Instantiate a new `Bitfield` with a fixed-length of `N` bits.
 | ||||
|     ///
 | ||||
|     /// All bits are initialized to `false`.
 | ||||
| @ -181,11 +199,11 @@ impl<N: Unsigned + Clone> Bitfield<BitVector<N>> { | ||||
|     ///
 | ||||
|     /// ## Example
 | ||||
|     /// ```
 | ||||
|     /// use ssz_types::{Bitfield, typenum};
 | ||||
|     /// use ssz_types::{BitVector, typenum};
 | ||||
|     ///
 | ||||
|     /// type BitVector = Bitfield<ssz_types::BitVector<typenum::U4>>;
 | ||||
|     /// type BitVector4 = BitVector<typenum::U4>;
 | ||||
|     ///
 | ||||
|     /// assert_eq!(BitVector::new().into_bytes(), vec![0b0000_0000]);
 | ||||
|     /// assert_eq!(BitVector4::new().into_bytes(), vec![0b0000_0000]);
 | ||||
|     /// ```
 | ||||
|     pub fn into_bytes(self) -> Vec<u8> { | ||||
|         self.into_raw_bytes() | ||||
| @ -200,7 +218,7 @@ impl<N: Unsigned + Clone> Bitfield<BitVector<N>> { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<N: Unsigned + Clone> Default for Bitfield<BitVector<N>> { | ||||
| impl<N: Unsigned + Clone> Default for Bitfield<Fixed<N>> { | ||||
|     fn default() -> Self { | ||||
|         Self::new() | ||||
|     } | ||||
| @ -437,7 +455,7 @@ impl<'a, T: BitfieldBehaviour> Iterator for BitIter<'a, T> { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<N: Unsigned + Clone> Encode for Bitfield<BitList<N>> { | ||||
| impl<N: Unsigned + Clone> Encode for Bitfield<Variable<N>> { | ||||
|     fn is_ssz_fixed_len() -> bool { | ||||
|         false | ||||
|     } | ||||
| @ -447,18 +465,18 @@ impl<N: Unsigned + Clone> Encode for Bitfield<BitList<N>> { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<N: Unsigned + Clone> Decode for Bitfield<BitList<N>> { | ||||
| impl<N: Unsigned + Clone> Decode for Bitfield<Variable<N>> { | ||||
|     fn is_ssz_fixed_len() -> bool { | ||||
|         false | ||||
|     } | ||||
| 
 | ||||
|     fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, ssz::DecodeError> { | ||||
|         Self::from_bytes(bytes.to_vec()) | ||||
|             .ok_or_else(|| ssz::DecodeError::BytesInvalid("BitList failed to decode".to_string())) | ||||
|             .ok_or_else(|| ssz::DecodeError::BytesInvalid("Variable failed to decode".to_string())) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<N: Unsigned + Clone> Encode for Bitfield<BitVector<N>> { | ||||
| impl<N: Unsigned + Clone> Encode for Bitfield<Fixed<N>> { | ||||
|     fn is_ssz_fixed_len() -> bool { | ||||
|         true | ||||
|     } | ||||
| @ -472,18 +490,18 @@ impl<N: Unsigned + Clone> Encode for Bitfield<BitVector<N>> { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<N: Unsigned + Clone> Decode for Bitfield<BitVector<N>> { | ||||
| impl<N: Unsigned + Clone> Decode for Bitfield<Fixed<N>> { | ||||
|     fn is_ssz_fixed_len() -> bool { | ||||
|         false | ||||
|     } | ||||
| 
 | ||||
|     fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, ssz::DecodeError> { | ||||
|         Self::from_bytes(bytes.to_vec()) | ||||
|             .ok_or_else(|| ssz::DecodeError::BytesInvalid("BitVector failed to decode".to_string())) | ||||
|             .ok_or_else(|| ssz::DecodeError::BytesInvalid("Fixed failed to decode".to_string())) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<N: Unsigned + Clone> Serialize for Bitfield<BitList<N>> { | ||||
| impl<N: Unsigned + Clone> Serialize for Bitfield<Variable<N>> { | ||||
|     /// Serde serialization is compliant with the Ethereum YAML test format.
 | ||||
|     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> | ||||
|     where | ||||
| @ -493,7 +511,7 @@ impl<N: Unsigned + Clone> Serialize for Bitfield<BitList<N>> { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'de, N: Unsigned + Clone> Deserialize<'de> for Bitfield<BitList<N>> { | ||||
| impl<'de, N: Unsigned + Clone> Deserialize<'de> for Bitfield<Variable<N>> { | ||||
|     /// Serde serialization is compliant with the Ethereum YAML test format.
 | ||||
|     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> | ||||
|     where | ||||
| @ -508,7 +526,7 @@ impl<'de, N: Unsigned + Clone> Deserialize<'de> for Bitfield<BitList<N>> { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<N: Unsigned + Clone> Serialize for Bitfield<BitVector<N>> { | ||||
| impl<N: Unsigned + Clone> Serialize for Bitfield<Fixed<N>> { | ||||
|     /// Serde serialization is compliant with the Ethereum YAML test format.
 | ||||
|     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> | ||||
|     where | ||||
| @ -518,7 +536,7 @@ impl<N: Unsigned + Clone> Serialize for Bitfield<BitVector<N>> { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<'de, N: Unsigned + Clone> Deserialize<'de> for Bitfield<BitVector<N>> { | ||||
| impl<'de, N: Unsigned + Clone> Deserialize<'de> for Bitfield<Fixed<N>> { | ||||
|     /// Serde serialization is compliant with the Ethereum YAML test format.
 | ||||
|     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> | ||||
|     where | ||||
| @ -533,7 +551,7 @@ impl<'de, N: Unsigned + Clone> Deserialize<'de> for Bitfield<BitVector<N>> { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<N: Unsigned + Clone> tree_hash::TreeHash for Bitfield<BitList<N>> { | ||||
| impl<N: Unsigned + Clone> tree_hash::TreeHash for Bitfield<Variable<N>> { | ||||
|     fn tree_hash_type() -> tree_hash::TreeHashType { | ||||
|         tree_hash::TreeHashType::List | ||||
|     } | ||||
| @ -552,7 +570,7 @@ impl<N: Unsigned + Clone> tree_hash::TreeHash for Bitfield<BitList<N>> { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<N: Unsigned + Clone> tree_hash::TreeHash for Bitfield<BitVector<N>> { | ||||
| impl<N: Unsigned + Clone> tree_hash::TreeHash for Bitfield<Fixed<N>> { | ||||
|     fn tree_hash_type() -> tree_hash::TreeHashType { | ||||
|         // TODO: move this to be a vector.
 | ||||
|         tree_hash::TreeHashType::List | ||||
| @ -573,7 +591,7 @@ impl<N: Unsigned + Clone> tree_hash::TreeHash for Bitfield<BitVector<N>> { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<N: Unsigned + Clone> cached_tree_hash::CachedTreeHash for Bitfield<BitList<N>> { | ||||
| impl<N: Unsigned + Clone> cached_tree_hash::CachedTreeHash for Bitfield<Variable<N>> { | ||||
|     fn new_tree_hash_cache( | ||||
|         &self, | ||||
|         depth: usize, | ||||
| @ -619,7 +637,7 @@ impl<N: Unsigned + Clone> cached_tree_hash::CachedTreeHash for Bitfield<BitList< | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl<N: Unsigned + Clone> cached_tree_hash::CachedTreeHash for Bitfield<BitVector<N>> { | ||||
| impl<N: Unsigned + Clone> cached_tree_hash::CachedTreeHash for Bitfield<Fixed<N>> { | ||||
|     fn new_tree_hash_cache( | ||||
|         &self, | ||||
|         depth: usize, | ||||
| @ -653,8 +671,8 @@ impl<N: Unsigned + Clone> cached_tree_hash::CachedTreeHash for Bitfield<BitVecto | ||||
| #[cfg(test)] | ||||
| mod bitvector { | ||||
|     use super::*; | ||||
|     use crate::BitVector; | ||||
| 
 | ||||
|     pub type BitVector<N> = crate::Bitfield<crate::BitVector<N>>; | ||||
|     pub type BitVector0 = BitVector<typenum::U0>; | ||||
|     pub type BitVector1 = BitVector<typenum::U1>; | ||||
|     pub type BitVector4 = BitVector<typenum::U4>; | ||||
| @ -753,8 +771,8 @@ mod bitvector { | ||||
| #[cfg(test)] | ||||
| mod bitlist { | ||||
|     use super::*; | ||||
|     use crate::BitList; | ||||
| 
 | ||||
|     pub type BitList<N> = super::Bitfield<crate::BitList<N>>; | ||||
|     pub type BitList0 = BitList<typenum::U0>; | ||||
|     pub type BitList1 = BitList<typenum::U1>; | ||||
|     pub type BitList8 = BitList<typenum::U8>; | ||||
|  | ||||
| @ -2,8 +2,8 @@ | ||||
| //!
 | ||||
| //! - `FixedVector`: A heap-allocated list with a size that is fixed at compile time.
 | ||||
| //! - `VariableList`: A heap-allocated list that cannot grow past a type-level maximum length.
 | ||||
| //! - `Bitfield<BitList>`: A heap-allocated bitfield that with a type-level _maximum_ length.
 | ||||
| //! - `Bitfield<VariableList>`: A heap-allocated bitfield that with a type-level _fixed__ length.
 | ||||
| //! - `BitList`: A heap-allocated bitfield that with a type-level _maximum_ length.
 | ||||
| //! - `BitVector`: A heap-allocated bitfield that with a type-level _fixed__ length.
 | ||||
| //!
 | ||||
| //! These structs are required as SSZ serialization and Merklization rely upon type-level lengths
 | ||||
| //! for padding and verification.
 | ||||
| @ -13,8 +13,8 @@ | ||||
| //! use ssz_types::*;
 | ||||
| //!
 | ||||
| //! pub struct Example {
 | ||||
| //!     bit_vector: Bitfield<BitVector<typenum::U8>>,
 | ||||
| //!     bit_list: Bitfield<BitList<typenum::U8>>,
 | ||||
| //!     bit_vector: BitVector<typenum::U8>,
 | ||||
| //!     bit_list: BitList<typenum::U8>,
 | ||||
| //!     variable_list: VariableList<u64, typenum::U8>,
 | ||||
| //!     fixed_vector: FixedVector<u64, typenum::U8>,
 | ||||
| //! }
 | ||||
| @ -43,6 +43,10 @@ pub use fixed_vector::FixedVector; | ||||
| pub use typenum; | ||||
| pub use variable_list::VariableList; | ||||
| 
 | ||||
| pub mod length { | ||||
|     pub use crate::bitfield::{Fixed, Variable}; | ||||
| } | ||||
| 
 | ||||
| /// Returned when an item encounters an error.
 | ||||
| #[derive(PartialEq, Debug)] | ||||
| pub enum Error { | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user