Skip to content

Commit 3348de6

Browse files
committed
IMPL EVERYWHERE
1 parent 513b37f commit 3348de6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+478
-158
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

consensus/context_deserialize/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,6 @@ version = "0.1.0"
44
edition = "2021"
55

66
[dependencies]
7+
milhouse = { workspace = true }
78
serde = { workspace = true }
9+
ssz_types = { workspace = true }
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
use crate::ContextDeserialize;
2+
use serde::de::{Deserialize, DeserializeSeed, Deserializer, SeqAccess, Visitor};
3+
use std::marker::PhantomData;
4+
use std::sync::Arc;
5+
impl<'de, C, T> ContextDeserialize<'de, T> for Arc<C>
6+
where
7+
C: ContextDeserialize<'de, T>,
8+
{
9+
fn context_deserialize<D>(deserializer: D, context: T) -> Result<Self, D::Error>
10+
where
11+
D: Deserializer<'de>,
12+
{
13+
Ok(Arc::new(C::context_deserialize(deserializer, context)?))
14+
}
15+
}
16+
17+
impl<'de, C, T> ContextDeserialize<'de, T> for Vec<C>
18+
where
19+
C: ContextDeserialize<'de, T>,
20+
T: Clone,
21+
{
22+
fn context_deserialize<D>(deserializer: D, context: T) -> Result<Self, D::Error>
23+
where
24+
D: Deserializer<'de>,
25+
{
26+
// Our Visitor, which owns one copy of the context T
27+
struct ContextVisitor<C, T> {
28+
context: T,
29+
_marker: PhantomData<C>,
30+
}
31+
32+
impl<'de, C, T> Visitor<'de> for ContextVisitor<C, T>
33+
where
34+
C: ContextDeserialize<'de, T>,
35+
T: Clone,
36+
{
37+
type Value = Vec<C>;
38+
39+
fn expecting(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
40+
fmt.write_str("a sequence of context‐deserialized elements")
41+
}
42+
43+
fn visit_seq<A>(self, mut seq: A) -> Result<Vec<C>, A::Error>
44+
where
45+
A: SeqAccess<'de>,
46+
{
47+
let mut out = Vec::with_capacity(seq.size_hint().unwrap_or(0));
48+
// for each element, we clone the context and hand it to the seed
49+
while let Some(elem) = seq.next_element_seed(ContextSeed {
50+
context: self.context.clone(),
51+
_marker: PhantomData,
52+
})? {
53+
out.push(elem);
54+
}
55+
Ok(out)
56+
}
57+
}
58+
59+
// A little seed that hands the deserializer + context into C::context_deserialize
60+
struct ContextSeed<C, T> {
61+
context: T,
62+
_marker: PhantomData<C>,
63+
}
64+
65+
impl<'de, C, T> DeserializeSeed<'de> for ContextSeed<C, T>
66+
where
67+
C: ContextDeserialize<'de, T>,
68+
T: Clone,
69+
{
70+
type Value = C;
71+
72+
fn deserialize<D>(self, deserializer: D) -> Result<C, D::Error>
73+
where
74+
D: Deserializer<'de>,
75+
{
76+
C::context_deserialize(deserializer, self.context)
77+
}
78+
}
79+
80+
deserializer.deserialize_seq(ContextVisitor {
81+
context,
82+
_marker: PhantomData,
83+
})
84+
}
85+
}
86+
87+
macro_rules! trivial_deserialize {
88+
($($t:ty),* $(,)?) => {
89+
$(
90+
impl<'de, T> ContextDeserialize<'de, T> for $t {
91+
fn context_deserialize<D>(deserializer: D, _context: T) -> Result<Self, D::Error>
92+
where
93+
D: Deserializer<'de>,
94+
{
95+
<$t>::deserialize(deserializer)
96+
}
97+
}
98+
)*
99+
};
100+
}
101+
102+
trivial_deserialize!(bool, u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, f32, f64);
Lines changed: 5 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,93 +1,13 @@
1+
pub mod impls;
2+
pub mod milhouse;
3+
pub mod ssz_impls;
4+
15
extern crate serde;
6+
use serde::de::Deserializer;
27

3-
use serde::de::{DeserializeSeed, Deserializer, SeqAccess, Visitor};
4-
use std::marker::PhantomData;
5-
use std::sync::Arc;
68
/// General-purpose deserialization trait that accepts extra context `C`.
79
pub trait ContextDeserialize<'de, C>: Sized {
810
fn context_deserialize<D>(deserializer: D, context: C) -> Result<Self, D::Error>
911
where
1012
D: Deserializer<'de>;
1113
}
12-
13-
impl<'de, C, T> ContextDeserialize<'de, T> for Arc<C>
14-
where
15-
C: ContextDeserialize<'de, T>,
16-
{
17-
fn context_deserialize<D>(deserializer: D, context: T) -> Result<Self, D::Error>
18-
where
19-
D: Deserializer<'de>,
20-
{
21-
Ok(Arc::new(C::context_deserialize(deserializer, context)?))
22-
}
23-
}
24-
25-
impl<'de, C, T> ContextDeserialize<'de, T> for Vec<C>
26-
where
27-
C: ContextDeserialize<'de, T>,
28-
T: Clone,
29-
{
30-
fn context_deserialize<D>(deserializer: D, context: T) -> Result<Self, D::Error>
31-
where
32-
D: Deserializer<'de>,
33-
{
34-
// Our Visitor, which owns one copy of the context T
35-
struct ContextVisitor<C, T> {
36-
context: T,
37-
_marker: PhantomData<C>,
38-
}
39-
40-
impl<'de, C, T> Visitor<'de> for ContextVisitor<C, T>
41-
where
42-
C: ContextDeserialize<'de, T>,
43-
T: Clone,
44-
{
45-
type Value = Vec<C>;
46-
47-
fn expecting(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
48-
fmt.write_str("a sequence of context‐deserialized elements")
49-
}
50-
51-
fn visit_seq<A>(self, mut seq: A) -> Result<Vec<C>, A::Error>
52-
where
53-
A: SeqAccess<'de>,
54-
{
55-
let mut out = Vec::with_capacity(seq.size_hint().unwrap_or(0));
56-
// for each element, we clone the context and hand it to the seed
57-
while let Some(elem) = seq.next_element_seed(ContextSeed {
58-
context: self.context.clone(),
59-
_marker: PhantomData,
60-
})? {
61-
out.push(elem);
62-
}
63-
Ok(out)
64-
}
65-
}
66-
67-
// A little seed that hands the deserializer + context into C::context_deserialize
68-
struct ContextSeed<C, T> {
69-
context: T,
70-
_marker: PhantomData<C>,
71-
}
72-
73-
impl<'de, C, T> DeserializeSeed<'de> for ContextSeed<C, T>
74-
where
75-
C: ContextDeserialize<'de, T>,
76-
T: Clone,
77-
{
78-
type Value = C;
79-
80-
fn deserialize<D>(self, deserializer: D) -> Result<C, D::Error>
81-
where
82-
D: Deserializer<'de>,
83-
{
84-
C::context_deserialize(deserializer, self.context)
85-
}
86-
}
87-
88-
deserializer.deserialize_seq(ContextVisitor {
89-
context,
90-
_marker: PhantomData,
91-
})
92-
}
93-
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
use crate::ContextDeserialize;
2+
use milhouse::{List, Value, Vector};
3+
use serde::de::{DeserializeSeed, Deserializer, SeqAccess, Visitor};
4+
use ssz_types::typenum::Unsigned;
5+
use std::marker::PhantomData;
6+
7+
impl<'de, C, T, N> ContextDeserialize<'de, C> for List<T, N>
8+
where
9+
T: ContextDeserialize<'de, C> + Value,
10+
N: Unsigned,
11+
C: Clone,
12+
{
13+
fn context_deserialize<D>(deserializer: D, context: C) -> Result<Self, D::Error>
14+
where
15+
D: Deserializer<'de>,
16+
{
17+
// Our Visitor, which owns one copy of the context C
18+
struct ListVisitor<C, T, N> {
19+
context: C,
20+
_marker: PhantomData<(T, N)>,
21+
}
22+
23+
impl<'de, C, T, N> Visitor<'de> for ListVisitor<C, T, N>
24+
where
25+
C: Clone,
26+
T: ContextDeserialize<'de, C> + Value,
27+
N: Unsigned,
28+
{
29+
type Value = List<T, N>;
30+
31+
fn expecting(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
32+
fmt.write_str("a sequence of context‐deserialized elements")
33+
}
34+
35+
fn visit_seq<A>(self, mut seq: A) -> Result<List<T, N>, A::Error>
36+
where
37+
A: SeqAccess<'de>,
38+
{
39+
let mut out = Vec::with_capacity(seq.size_hint().unwrap_or(0));
40+
41+
// for each element, we clone the context and hand it to the seed
42+
while let Some(elem) = seq.next_element_seed(ContextSeed {
43+
context: self.context.clone(),
44+
_marker: PhantomData,
45+
})? {
46+
out.push(elem);
47+
}
48+
49+
List::new(out).map_err(|e| {
50+
serde::de::Error::custom(format!("Failed to create List: {:?}", e))
51+
})
52+
}
53+
}
54+
55+
// A little seed that hands the deserializer + context into T::context_deserialize
56+
struct ContextSeed<C, T> {
57+
context: C,
58+
_marker: PhantomData<T>,
59+
}
60+
61+
impl<'de, C, T> DeserializeSeed<'de> for ContextSeed<C, T>
62+
where
63+
C: Clone,
64+
T: ContextDeserialize<'de, C>,
65+
{
66+
type Value = T;
67+
68+
fn deserialize<D>(self, deserializer: D) -> Result<T, D::Error>
69+
where
70+
D: Deserializer<'de>,
71+
{
72+
T::context_deserialize(deserializer, self.context)
73+
}
74+
}
75+
76+
deserializer.deserialize_seq(ListVisitor {
77+
context,
78+
_marker: PhantomData,
79+
})
80+
}
81+
}
82+
83+
impl<'de, C, T, N> ContextDeserialize<'de, C> for Vector<T, N>
84+
where
85+
T: ContextDeserialize<'de, C> + Value,
86+
N: Unsigned,
87+
C: Clone,
88+
{
89+
fn context_deserialize<D>(deserializer: D, context: C) -> Result<Self, D::Error>
90+
where
91+
D: Deserializer<'de>,
92+
{
93+
// First deserialize as a List
94+
let list = List::<T, N>::context_deserialize(deserializer, context)?;
95+
96+
// Then convert to Vector, which will check the length
97+
Vector::try_from(list).map_err(|e| {
98+
serde::de::Error::custom(format!("Failed to convert List to Vector: {:?}", e))
99+
})
100+
}
101+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
use crate::serde::de::Error;
2+
use crate::ContextDeserialize;
3+
use serde::de::Deserializer;
4+
use serde::Deserialize;
5+
use ssz_types::length::{Fixed, Variable};
6+
use ssz_types::typenum::Unsigned;
7+
use ssz_types::{Bitfield, FixedVector};
8+
9+
impl<'de, C, T, N> ContextDeserialize<'de, C> for FixedVector<T, N>
10+
where
11+
T: ContextDeserialize<'de, C>,
12+
N: Unsigned,
13+
C: Clone,
14+
{
15+
fn context_deserialize<D>(deserializer: D, context: C) -> Result<Self, D::Error>
16+
where
17+
D: Deserializer<'de>,
18+
{
19+
let vec = Vec::<T>::context_deserialize(deserializer, context)?;
20+
FixedVector::new(vec).map_err(|e| D::Error::custom(format!("{:?}", e)))
21+
}
22+
}
23+
24+
impl<'de, C, N> ContextDeserialize<'de, C> for Bitfield<Variable<N>>
25+
where
26+
N: Unsigned + Clone,
27+
{
28+
fn context_deserialize<D>(deserializer: D, _context: C) -> Result<Self, D::Error>
29+
where
30+
D: Deserializer<'de>,
31+
{
32+
Bitfield::<Variable<N>>::deserialize(deserializer)
33+
.map_err(|e| D::Error::custom(format!("{:?}", e)))
34+
}
35+
}
36+
37+
impl<'de, C, N> ContextDeserialize<'de, C> for Bitfield<Fixed<N>>
38+
where
39+
N: Unsigned + Clone,
40+
{
41+
fn context_deserialize<D>(deserializer: D, _context: C) -> Result<Self, D::Error>
42+
where
43+
D: Deserializer<'de>,
44+
{
45+
Bitfield::<Fixed<N>>::deserialize(deserializer)
46+
.map_err(|e| D::Error::custom(format!("{:?}", e)))
47+
}
48+
}

0 commit comments

Comments
 (0)