1use alloc::borrow::Cow;
2use alloc::format;
3use alloc::string::String;
4use half::f16;
5use num_bigint::{BigInt, BigUint};
6use esexpr::ESExprEncodedEq;
7use crate::cowstr::CowStr;
8use crate::{DecodeError, DecodeErrorPath, DecodeErrorType, ESExpr, ESExprCodec, ESExprTag, ESExprTagSet};
9
10macro_rules! encoded_as_partial_eq {
11 ($t: ty) => {
12 impl ESExprEncodedEq for $t {
13 fn is_encoded_eq(&self, other: &Self) -> bool {
14 *self == *other
15 }
16 }
17 };
18}
19
20encoded_as_partial_eq!(bool);
21
22impl<'a> ESExprCodec<'a> for bool {
23 const TAGS: ESExprTagSet = ESExprTagSet::Tags(&[ESExprTag::Bool]);
24
25 fn encode_esexpr(&'a self) -> ESExpr<'a> {
26 ESExpr::Bool(*self)
27 }
28
29 fn decode_esexpr(expr: ESExpr<'a>) -> Result<Self, DecodeError> {
30 match expr {
31 ESExpr::Bool(b) => Ok(b),
32 _ => Err(DecodeError::new(
33 DecodeErrorType::UnexpectedExpr {
34 expected_tags: Self::TAGS,
35 actual_tag: expr.tag().into_owned(),
36 },
37 DecodeErrorPath::Current,
38 )),
39 }
40 }
41}
42
43encoded_as_partial_eq!(BigInt);
44
45impl<'a> ESExprCodec<'a> for BigInt {
46 const TAGS: ESExprTagSet = ESExprTagSet::Tags(&[ESExprTag::Int]);
47
48 fn encode_esexpr(&'a self) -> ESExpr<'a> {
49 ESExpr::Int(Cow::Borrowed(self))
50 }
51
52 fn decode_esexpr(expr: ESExpr<'a>) -> Result<Self, DecodeError> {
53 match expr {
54 ESExpr::Int(i) => Ok(i.into_owned()),
55 _ => Err(DecodeError::new(
56 DecodeErrorType::UnexpectedExpr {
57 expected_tags: Self::TAGS,
58 actual_tag: expr.tag().into_owned(),
59 },
60 DecodeErrorPath::Current,
61 )),
62 }
63 }
64}
65
66encoded_as_partial_eq!(BigUint);
67
68impl<'a> ESExprCodec<'a> for BigUint {
69 const TAGS: ESExprTagSet = ESExprTagSet::Tags(&[ESExprTag::Int]);
70
71 fn encode_esexpr(&'a self) -> ESExpr<'a> {
72 ESExpr::Int(Cow::Owned(BigInt::from(self.clone())))
73 }
74
75 fn decode_esexpr(expr: ESExpr<'a>) -> Result<Self, DecodeError> {
76 match expr {
77 ESExpr::Int(i) => match BigUint::try_from(i.into_owned()) {
78 Ok(i) => Ok(i),
79 Err(_) => Err(DecodeError::new(
80 DecodeErrorType::OutOfRange(format!("Unexpected integer value for {}", stringify!($T))),
81 DecodeErrorPath::Current,
82 )),
83 },
84 _ => Err(DecodeError::new(
85 DecodeErrorType::UnexpectedExpr {
86 expected_tags: Self::TAGS,
87 actual_tag: expr.tag().into_owned(),
88 },
89 DecodeErrorPath::Current,
90 )),
91 }
92 }
93}
94
95macro_rules! int_codec {
96 ($T: ty) => {
97 encoded_as_partial_eq!($T);
98 impl<'a> ESExprCodec<'a> for $T {
99 const TAGS: ESExprTagSet = ESExprTagSet::Tags(&[ESExprTag::Int]);
100
101 fn encode_esexpr(&self) -> ESExpr<'a> {
102 ESExpr::Int(Cow::Owned(BigInt::from(*self)))
103 }
104
105 fn decode_esexpr(expr: ESExpr<'a>) -> Result<Self, DecodeError> {
106 match expr {
107 ESExpr::Int(i) => match <$T>::try_from(i.into_owned()) {
108 Ok(i) => Ok(i),
109 Err(_) => Err(DecodeError::new(
110 DecodeErrorType::OutOfRange(format!("Unexpected integer value for {}", stringify!($T))),
111 DecodeErrorPath::Current,
112 )),
113 },
114 _ => Err(DecodeError::new(
115 DecodeErrorType::UnexpectedExpr {
116 expected_tags: Self::TAGS,
117 actual_tag: expr.tag().into_owned(),
118 },
119 DecodeErrorPath::Current,
120 )),
121 }
122 }
123 }
124 };
125}
126
127int_codec!(isize);
128int_codec!(usize);
129int_codec!(i128);
130int_codec!(u128);
131int_codec!(i64);
132int_codec!(u64);
133int_codec!(i32);
134int_codec!(u32);
135int_codec!(i16);
136int_codec!(u16);
137int_codec!(i8);
138int_codec!(u8);
139
140
141
142encoded_as_partial_eq!(String);
143
144impl<'a> ESExprCodec<'a> for String {
145 const TAGS: ESExprTagSet = ESExprTagSet::Tags(&[ESExprTag::Str]);
146
147 fn encode_esexpr(&'a self) -> ESExpr<'a> {
148 ESExpr::Str(CowStr::Borrowed(self))
149 }
150
151 fn decode_esexpr(expr: ESExpr<'a>) -> Result<Self, DecodeError> {
152 match expr {
153 ESExpr::Str(s) => Ok(s.into_string()),
154 _ => Err(DecodeError::new(
155 DecodeErrorType::UnexpectedExpr {
156 expected_tags: Self::TAGS,
157 actual_tag: expr.tag().into_owned(),
158 },
159 DecodeErrorPath::Current,
160 )),
161 }
162 }
163}
164
165
166impl <'a> ESExprEncodedEq for Cow<'a, str> {
167 fn is_encoded_eq(&self, other: &Self) -> bool {
168 self == other
169 }
170}
171
172impl<'a> ESExprCodec<'a> for Cow<'a, str> {
173 const TAGS: ESExprTagSet = ESExprTagSet::Tags(&[ESExprTag::Str]);
174
175 fn encode_esexpr(&'a self) -> ESExpr<'a> {
176 ESExpr::Str(CowStr::Borrowed(self.as_ref()))
177 }
178
179 fn decode_esexpr(expr: ESExpr<'a>) -> Result<Self, DecodeError> {
180 match expr {
181 ESExpr::Str(s) => Ok(Cow::from(s)),
182 _ => Err(DecodeError::new(
183 DecodeErrorType::UnexpectedExpr {
184 expected_tags: Self::TAGS,
185 actual_tag: expr.tag().into_owned(),
186 },
187 DecodeErrorPath::Current,
188 )),
189 }
190 }
191}
192
193
194impl <'a> ESExprEncodedEq for CowStr<'a> {
195 fn is_encoded_eq(&self, other: &Self) -> bool {
196 self == other
197 }
198}
199
200impl<'a> ESExprCodec<'a> for CowStr<'a> {
201 const TAGS: ESExprTagSet = ESExprTagSet::Tags(&[ESExprTag::Str]);
202
203 fn encode_esexpr(&'a self) -> ESExpr<'a> {
204 ESExpr::Str(self.as_borrowed())
205 }
206
207 fn decode_esexpr(expr: ESExpr<'a>) -> Result<Self, DecodeError> {
208 match expr {
209 ESExpr::Str(s) => Ok(s),
210 _ => Err(DecodeError::new(
211 DecodeErrorType::UnexpectedExpr {
212 expected_tags: Self::TAGS,
213 actual_tag: expr.tag().into_owned(),
214 },
215 DecodeErrorPath::Current,
216 )),
217 }
218 }
219}
220
221
222
223impl <'a> ESExprEncodedEq for f16 {
224 fn is_encoded_eq(&self, other: &Self) -> bool {
225 self.to_bits() == other.to_bits()
226 }
227}
228
229impl<'a> ESExprCodec<'a> for f16 {
230 const TAGS: ESExprTagSet = ESExprTagSet::Tags(&[ESExprTag::Float16]);
231
232 fn encode_esexpr(&self) -> ESExpr<'a> {
233 ESExpr::Float16(*self)
234 }
235
236 fn decode_esexpr(expr: ESExpr<'a>) -> Result<Self, DecodeError> {
237 match expr {
238 ESExpr::Float16(f) => Ok(f),
239 _ => Err(DecodeError::new(
240 DecodeErrorType::UnexpectedExpr {
241 expected_tags: Self::TAGS,
242 actual_tag: expr.tag().into_owned(),
243 },
244 DecodeErrorPath::Current,
245 )),
246 }
247 }
248}
249
250impl <'a> ESExprEncodedEq for f32 {
251 fn is_encoded_eq(&self, other: &Self) -> bool {
252 self.to_bits() == other.to_bits()
253 }
254}
255
256impl<'a> ESExprCodec<'a> for f32 {
257 const TAGS: ESExprTagSet = ESExprTagSet::Tags(&[ESExprTag::Float32]);
258
259 fn encode_esexpr(&self) -> ESExpr<'a> {
260 ESExpr::Float32(*self)
261 }
262
263 fn decode_esexpr(expr: ESExpr<'a>) -> Result<Self, DecodeError> {
264 match expr {
265 ESExpr::Float32(f) => Ok(f),
266 _ => Err(DecodeError::new(
267 DecodeErrorType::UnexpectedExpr {
268 expected_tags: Self::TAGS,
269 actual_tag: expr.tag().into_owned(),
270 },
271 DecodeErrorPath::Current,
272 )),
273 }
274 }
275}
276
277impl <'a> ESExprEncodedEq for f64 {
278 fn is_encoded_eq(&self, other: &Self) -> bool {
279 self.to_bits() == other.to_bits()
280 }
281}
282
283impl<'a> ESExprCodec<'a> for f64 {
284 const TAGS: ESExprTagSet = ESExprTagSet::Tags(&[ESExprTag::Float64]);
285
286 fn encode_esexpr(&'a self) -> ESExpr<'a> {
287 ESExpr::Float64(*self)
288 }
289
290 fn decode_esexpr(expr: ESExpr<'a>) -> Result<Self, DecodeError> {
291 match expr {
292 ESExpr::Float64(f) => Ok(f),
293 _ => Err(DecodeError::new(
294 DecodeErrorType::UnexpectedExpr {
295 expected_tags: Self::TAGS,
296 actual_tag: expr.tag().into_owned(),
297 },
298 DecodeErrorPath::Current,
299 )),
300 }
301 }
302}
303
304
305encoded_as_partial_eq!(());
306
307impl<'a> ESExprCodec<'a> for () {
308 const TAGS: ESExprTagSet = ESExprTagSet::Tags(&[ESExprTag::Null]);
309
310 fn encode_esexpr<'b>(&'b self) -> ESExpr<'b> {
311 ESExpr::Null(Cow::Owned(BigUint::ZERO))
312 }
313
314 fn decode_esexpr(expr: ESExpr<'a>) -> Result<Self, DecodeError> {
315 match expr {
316 ESExpr::Null(level) if *level == BigUint::ZERO => Ok(()),
317 _ => Err(DecodeError::new(
318 DecodeErrorType::UnexpectedExpr {
319 expected_tags: Self::TAGS,
320 actual_tag: expr.tag().into_owned(),
321 },
322 DecodeErrorPath::Current,
323 )),
324 }
325 }
326}