Skip to content

Commit

Permalink
Remove derivative dependency
Browse files Browse the repository at this point in the history
  • Loading branch information
DragonDev1906 committed Dec 3, 2024
1 parent 9e59ff9 commit 6455633
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 10 deletions.
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ ethereum_ssz = "0.7.0"
serde = "1.0.0"
serde_derive = "1.0.0"
typenum = "1.12.0"
derivative = "2.1.1"
smallvec = "1.8.0"
arbitrary = { version = "1.0", features = ["derive"], optional = true }
itertools = "0.13.0"
Expand Down
33 changes: 30 additions & 3 deletions src/bitfield.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use crate::tree_hash::bitfield_bytes_tree_hash_root;
use crate::Error;
use core::marker::PhantomData;
use derivative::Derivative;
use serde::de::{Deserialize, Deserializer};
use serde::ser::{Serialize, Serializer};
use serde_utils::hex::{encode as hex_encode, PrefixedHexVisitor};
Expand Down Expand Up @@ -95,14 +94,29 @@ pub type BitVector<N> = Bitfield<Fixed<N>>;
/// The internal representation of the bitfield is the same as that required by SSZ. The lowest
/// byte (by `Vec` index) stores the lowest bit-indices and the right-most bit stores the lowest
/// bit-index. E.g., `smallvec![0b0000_0001, 0b0000_0010]` has bits `0, 9` set.
#[derive(Clone, Debug, Derivative)]
#[derivative(PartialEq, Eq, Hash(bound = ""))]
#[derive(Clone, Debug)]
pub struct Bitfield<T> {
bytes: SmallVec<[u8; SMALLVEC_LEN]>,
len: usize,
_phantom: PhantomData<T>,
}

// Implement comparison functions even if T doesn't implement them (since we don't sotre T)
impl<T> PartialEq for Bitfield<T> {
fn eq(&self, other: &Self) -> bool {
// T is already compared because other must have the same T
// We don't store values of T, so we don't have to compare it either.
self.len == other.len && self.bytes == other.bytes
}
}
impl<T> Eq for Bitfield<T> {}
impl<T> std::hash::Hash for Bitfield<T> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.bytes.hash(state);
self.len.hash(state);

Check warning on line 116 in src/bitfield.rs

View check run for this annotation

Codecov / codecov/patch

src/bitfield.rs#L114-L116

Added lines #L114 - L116 were not covered by tests
}
}

impl<N: Unsigned + Clone> Bitfield<Variable<N>> {
/// Instantiate with capacity for `num_bits` boolean values. The length cannot be grown or
/// shrunk after instantiation.
Expand Down Expand Up @@ -1438,4 +1452,17 @@ mod bitlist {
// Can't extend a BitList to a smaller BitList
resized_bit_list.resize::<typenum::U16>().unwrap_err();
}

/// Test if Eq and Hash are implemented regardless of whether T does
/// (backwards compatibility).
#[test]
fn can_use_in_hashmaps() {
let mut map: std::collections::HashSet<Bitfield<u8>> = std::collections::HashSet::new();
map.reserve(5);

struct NoDerives {}
let mut map: std::collections::HashSet<Bitfield<NoDerives>> =
std::collections::HashSet::new();
map.reserve(5);
}
}
19 changes: 16 additions & 3 deletions src/fixed_vector.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::tree_hash::vec_tree_hash_root;
use crate::Error;
use derivative::Derivative;
use serde_derive::{Deserialize, Serialize};
use std::marker::PhantomData;
use std::ops::{Deref, DerefMut, Index, IndexMut};
Expand Down Expand Up @@ -45,14 +44,28 @@ pub use typenum;
/// let long: FixedVector<_, typenum::U5> = FixedVector::from(base);
/// assert_eq!(&long[..], &[1, 2, 3, 4, 0]);
/// ```
#[derive(Debug, Clone, Serialize, Deserialize, Derivative)]
#[derivative(PartialEq, Eq, Hash(bound = "T: std::hash::Hash"))]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(transparent)]
pub struct FixedVector<T, N> {
vec: Vec<T>,
_phantom: PhantomData<N>,
}

// Implement comparison functions even if T doesn't implement them (since we don't sotre T)
impl<T: PartialEq, N> PartialEq for FixedVector<T, N> {
fn eq(&self, other: &Self) -> bool {
// T and N are already compared because other must have the same T/N
// We don't store values of T or N, so we don't have to compare them either.
self.vec == other.vec
}
}
impl<T: Eq, N> Eq for FixedVector<T, N> {}
impl<T: std::hash::Hash, N> std::hash::Hash for FixedVector<T, N> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.vec.hash(state);
}
}

Check warning on line 67 in src/fixed_vector.rs

View check run for this annotation

Codecov / codecov/patch

src/fixed_vector.rs#L64-L67

Added lines #L64 - L67 were not covered by tests

impl<T, N: Unsigned> FixedVector<T, N> {
/// Returns `Ok` if the given `vec` equals the fixed length of `Self`. Otherwise returns
/// `Err`.
Expand Down
19 changes: 16 additions & 3 deletions src/variable_list.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::tree_hash::vec_tree_hash_root;
use crate::Error;
use derivative::Derivative;
use serde_derive::{Deserialize, Serialize};
use std::marker::PhantomData;
use std::ops::{Deref, DerefMut, Index, IndexMut};
Expand Down Expand Up @@ -47,14 +46,28 @@ pub use typenum;
/// // Push a value to if it _does_ exceed the maximum.
/// assert!(long.push(6).is_err());
/// ```
#[derive(Debug, Clone, Serialize, Deserialize, Derivative)]
#[derivative(PartialEq, Eq, Hash(bound = "T: std::hash::Hash"))]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(transparent)]
pub struct VariableList<T, N> {
vec: Vec<T>,
_phantom: PhantomData<N>,
}

// Implement comparison functions even if T doesn't implement them (since we don't sotre T)
impl<T: PartialEq, N> PartialEq for VariableList<T, N> {
fn eq(&self, other: &Self) -> bool {
// T and N are already compared because other must have the same T/N
// We don't store values of T or N, so we don't have to compare them either.
self.vec == other.vec
}
}
impl<T: Eq, N> Eq for VariableList<T, N> {}
impl<T: std::hash::Hash, N> std::hash::Hash for VariableList<T, N> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.vec.hash(state);
}
}

/// Maximum number of elements to pre-allocate in `try_from_iter`.
///
/// Some variable lists have *very long* maximum lengths such that we can't actually fit them
Expand Down

0 comments on commit 6455633

Please sign in to comment.