1use crate::circuits::lookup::lookups::{JointLookup, JointLookupValue};
2use alloc::vec::Vec;
3use core::{fmt::Formatter, marker::PhantomData};
4use serde::{
5 de::{Error, IgnoredAny, MapAccess, SeqAccess},
6 ser::SerializeStruct,
7 Deserialize, Deserializer, Serializer,
8};
9use serde_with::{de::DeserializeAsWrap, ser::SerializeAsWrap, DeserializeAs, SerializeAs};
10
11impl<F, G> SerializeAs<JointLookupValue<F>> for JointLookupValue<G>
12where
13 G: SerializeAs<F>,
14{
15 fn serialize_as<S>(source: &JointLookupValue<F>, serializer: S) -> Result<S::Ok, S::Error>
16 where
17 S: Serializer,
18 {
19 let mut s = serializer.serialize_struct("JointLookup", 2)?;
20 s.serialize_field("table_id", &SerializeAsWrap::<F, G>::new(&source.table_id))?;
21 s.serialize_field(
22 "entry",
23 &SerializeAsWrap::<Vec<F>, Vec<G>>::new(&source.entry),
24 )?;
25 s.end()
26 }
27}
28
29impl<'de, F, G: DeserializeAs<'de, F>> DeserializeAs<'de, JointLookupValue<F>>
30 for JointLookupValue<G>
31{
32 fn deserialize_as<D>(deserializer: D) -> Result<JointLookupValue<F>, D::Error>
33 where
34 D: Deserializer<'de>,
35 {
36 #[allow(non_camel_case_types)]
37 enum Field {
38 field0,
39 field1,
40 ignore,
41 }
42 struct FieldVisitor;
43 impl<'de> serde::de::Visitor<'de> for FieldVisitor {
44 type Value = Field;
45 fn expecting(&self, formatter: &mut Formatter) -> core::fmt::Result {
46 Formatter::write_str(formatter, "field identifier")
47 }
48 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
49 where
50 E: Error,
51 {
52 match value {
53 0u64 => Ok(Field::field0),
54 1u64 => Ok(Field::field1),
55 _ => Ok(Field::ignore),
56 }
57 }
58 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
59 where
60 E: Error,
61 {
62 match value {
63 "table_id" => Ok(Field::field0),
64 "entry" => Ok(Field::field1),
65 _ => Ok(Field::ignore),
66 }
67 }
68 fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
69 where
70 E: Error,
71 {
72 match value {
73 b"table_id" => Ok(Field::field0),
74 b"entry" => Ok(Field::field1),
75 _ => Ok(Field::ignore),
76 }
77 }
78 }
79 impl<'de> Deserialize<'de> for Field {
80 #[inline]
81 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
82 where
83 D: Deserializer<'de>,
84 {
85 Deserializer::deserialize_identifier(deserializer, FieldVisitor)
86 }
87 }
88 struct Visitor<'de, F, G>
89 where
90 G: DeserializeAs<'de, F>,
91 {
92 marker: PhantomData<JointLookupValue<F>>,
93 marker2: PhantomData<JointLookupValue<G>>,
94 lifetime: PhantomData<&'de ()>,
95 }
96 impl<'de, F, G> serde::de::Visitor<'de> for Visitor<'de, F, G>
97 where
98 G: DeserializeAs<'de, F>,
99 {
100 type Value = JointLookupValue<F>;
101 fn expecting(&self, formatter: &mut Formatter) -> core::fmt::Result {
102 Formatter::write_str(formatter, "struct JointLookup")
103 }
104 #[inline]
105 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
106 where
107 A: SeqAccess<'de>,
108 {
109 let field0 = match SeqAccess::next_element::<DeserializeAsWrap<F, G>>(&mut seq)? {
110 Some(value) => value.into_inner(),
111 None => {
112 return Err(Error::invalid_length(
113 0usize,
114 &"struct JointLookup with 2 elements",
115 ));
116 }
117 };
118 let field1 =
119 match SeqAccess::next_element::<DeserializeAsWrap<Vec<F>, Vec<G>>>(&mut seq)? {
120 Some(value) => value.into_inner(),
121 None => {
122 return Err(Error::invalid_length(
123 1usize,
124 &"struct JointLookup with 2 elements",
125 ));
126 }
127 };
128 Ok(JointLookup {
129 table_id: field0,
130 entry: field1,
131 })
132 }
133 #[inline]
134 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
135 where
136 A: MapAccess<'de>,
137 {
138 let mut field0: Option<F> = None;
139 let mut field1: Option<Vec<F>> = None;
140 while let Some(key) = MapAccess::next_key::<Field>(&mut map)? {
141 match key {
142 Field::field0 => {
143 if Option::is_some(&field0) {
144 return Err(A::Error::duplicate_field("table_id"));
145 }
146 field0 = Some(
147 MapAccess::next_value::<DeserializeAsWrap<F, G>>(&mut map)?
148 .into_inner(),
149 );
150 }
151 Field::field1 => {
152 if Option::is_some(&field1) {
153 return Err(A::Error::duplicate_field("entry"));
154 }
155 field1 = Some(
156 MapAccess::next_value::<DeserializeAsWrap<Vec<F>, Vec<G>>>(
157 &mut map,
158 )?
159 .into_inner(),
160 );
161 }
162 Field::ignore => {
163 let _ = MapAccess::next_value::<IgnoredAny>(&mut map)?;
164 }
165 }
166 }
167 let field0 = match field0 {
168 Some(field0) => field0,
169 None => return Err(A::Error::missing_field("table_id")),
170 };
171 let field1 = match field1 {
172 Some(field1) => field1,
173 None => return Err(A::Error::missing_field("entry")),
174 };
175 Ok(JointLookup {
176 table_id: field0,
177 entry: field1,
178 })
179 }
180 }
181 const FIELDS: &[&str] = &["table_id", "entry"];
182 Deserializer::deserialize_struct(
183 deserializer,
184 "JointLookup",
185 FIELDS,
186 Visitor {
187 marker: PhantomData::<JointLookupValue<F>>,
188 marker2: PhantomData::<JointLookupValue<G>>,
189 lifetime: PhantomData,
190 },
191 )
192 }
193}