Skip to content

Commit

Permalink
Remove derivative dependency (#37)
Browse files Browse the repository at this point in the history
* Remove derivative dependency

* Tweak doc comments

* Test hash impl

* Test variable list Hash impl

---------

Co-authored-by: Michael Sproul <michael@sigmaprime.io>
  • Loading branch information
DragonDev1906 and michaelsproul authored Dec 5, 2024
1 parent 2b01793 commit c52c5f4
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 7 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.8.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
32 changes: 29 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,26 @@ 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 N doesn't implement PartialEq
impl<T: PartialEq, N> PartialEq for FixedVector<T, N> {
fn eq(&self, other: &Self) -> bool {
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);
}
}

impl<T, N: Unsigned> FixedVector<T, N> {
/// Returns `Ok` if the given `vec` equals the fixed length of `Self`. Otherwise returns
/// `Err`.
Expand Down Expand Up @@ -347,6 +358,7 @@ impl<'a, T: arbitrary::Arbitrary<'a>, N: 'static + Unsigned> arbitrary::Arbitrar
mod test {
use super::*;
use ssz::*;
use std::collections::HashSet;
use tree_hash::{merkle_root, TreeHash};
use tree_hash_derive::TreeHash;
use typenum::*;
Expand Down Expand Up @@ -502,4 +514,18 @@ mod test {
merkle_root(&repeat(a.tree_hash_root().as_slice(), 16), 0)
);
}

#[test]
fn std_hash() {
let x: FixedVector<u32, U16> = FixedVector::from(vec![3; 16]);
let y: FixedVector<u32, U16> = FixedVector::from(vec![4; 16]);
let mut hashset = HashSet::new();

for value in [x.clone(), y.clone()] {
assert!(hashset.insert(value.clone()));
assert!(!hashset.insert(value.clone()));
assert!(hashset.contains(&value));
}
assert_eq!(hashset.len(), 2);
}
}
32 changes: 29 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,26 @@ 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 N doesn't implement PartialEq
impl<T: PartialEq, N> PartialEq for VariableList<T, N> {
fn eq(&self, other: &Self) -> bool {
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 Expand Up @@ -321,6 +332,7 @@ impl<'a, T: arbitrary::Arbitrary<'a>, N: 'static + Unsigned> arbitrary::Arbitrar
mod test {
use super::*;
use ssz::*;
use std::collections::HashSet;
use tree_hash::{merkle_root, TreeHash};
use tree_hash_derive::TreeHash;
use typenum::*;
Expand Down Expand Up @@ -548,4 +560,18 @@ mod test {
List::try_from_iter(wonky_iter).unwrap()
);
}

#[test]
fn std_hash() {
let x: VariableList<u32, U16> = VariableList::from(vec![3; 16]);
let y: VariableList<u32, U16> = VariableList::from(vec![4; 16]);
let mut hashset = HashSet::new();

for value in [x.clone(), y.clone()] {
assert!(hashset.insert(value.clone()));
assert!(!hashset.insert(value.clone()));
assert!(hashset.contains(&value));
}
assert_eq!(hashset.len(), 2);
}
}

0 comments on commit c52c5f4

Please sign in to comment.