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