1use alloc::collections::BTreeMap;
2use alloc::format;
3use alloc::string::ToString;
4use alloc::vec::Vec;
5use core::fmt::Display;
6
7use crate::edn::Edn;
8use crate::parse;
9
10use serde::de::{
11 self, DeserializeSeed, EnumAccess, IntoDeserializer, MapAccess, SeqAccess, VariantAccess, Visitor,
12};
13use serde::{Deserialize, forward_to_deserialize_any};
14
15use crate::error::{Code, Error, Result};
16
17pub fn from_str<'a, T>(s: &'a str) -> Result<T>
24where
25 T: Deserialize<'a>,
26{
27 let (edn, remaining) = parse::parse_as_edn(s)?;
28 let t = T::deserialize(edn)?;
29
30 let mut remaining = remaining;
31 loop {
32 remaining = remaining.trim_start_matches(|c: char| c == ',' || c.is_whitespace());
33
34 let Some(comment) = remaining.strip_prefix(';') else {
35 break;
36 };
37
38 let Some(comment_end) = comment.find(['\n', '\r']) else {
39 return Ok(t);
40 };
41 remaining = &comment[comment_end..];
42 }
43 if !remaining.is_empty() {
44 return Err(de::Error::custom("trailing input"));
45 }
46 Ok(t)
47}
48
49impl de::Error for Error {
50 #[cold]
51 fn custom<T: Display>(msg: T) -> Self {
52 Self { code: Code::Serde(msg.to_string()), line: None, column: None, ptr: None }
53 }
54}
55
56fn get_int_from_edn(edn: &Edn<'_>) -> Result<i64> {
57 if let Edn::Int(i) = edn {
58 return Ok(*i);
59 }
60 Err(de::Error::custom(format!("cannot convert {edn:?} to i64")))
61}
62
63fn get_bytes_from_edn(edn: &Edn<'_>) -> Result<Vec<u8>> {
64 match edn {
65 Edn::Vector(list) | Edn::List(list) => list
66 .iter()
67 .map(|item| {
68 let int = get_int_from_edn(item)?;
69 u8::try_from(int).map_err(|_| de::Error::custom(format!("can't convert {int} into u8")))
70 })
71 .collect(),
72 _ => Err(de::Error::custom(format!("can't convert {edn:?} into bytes"))),
73 }
74}
75
76impl<'de> de::Deserializer<'de> for Edn<'de> {
77 type Error = Error;
78
79 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
80 where
81 V: Visitor<'de>,
82 {
83 match self {
84 Edn::Key(k) => visitor.visit_borrowed_str(k),
85 Edn::Str(s) | Edn::Symbol(s) => visitor.visit_borrowed_str(s),
86 Edn::Int(i) => visitor.visit_i64(i),
87 #[cfg(feature = "floats")]
88 Edn::Double(d) => visitor.visit_f64(*d),
89 Edn::Char(c) => visitor.visit_char(c),
90 Edn::Bool(b) => visitor.visit_bool(b),
91 Edn::Nil => visitor.visit_unit(),
92 Edn::Vector(mut list) | Edn::List(mut list) => {
93 list.reverse();
94 Ok(visitor.visit_seq(SeqEdn::new(list))?)
95 }
96 Edn::Map(map) => visitor.visit_map(MapEdn::new(map)),
97 Edn::Set(set) => {
98 let mut s: Vec<Edn<'_>> = set.into_iter().collect();
99 s.reverse();
100 Ok(visitor.visit_seq(SeqEdn::new(s))?)
101 }
102 _ => Err(de::Error::custom(format!("Don't know how to convert {self:?} into any"))),
104 }
105 }
106
107 forward_to_deserialize_any! {
108 bool i64 f64 char str map seq tuple_struct
109 }
110
111 fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
112 where
113 V: Visitor<'de>,
114 {
115 let _ = self;
116 visitor.visit_unit()
117 }
118
119 fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value>
120 where
121 V: Visitor<'de>,
122 {
123 let int = get_int_from_edn(&self)?;
124 i8::try_from(int).map_or_else(
125 |_| Err(de::Error::custom(format!("can't convert {int} into i8"))),
126 |i| visitor.visit_i8(i),
127 )
128 }
129
130 fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value>
131 where
132 V: Visitor<'de>,
133 {
134 let int = get_int_from_edn(&self)?;
135 i16::try_from(int).map_or_else(
136 |_| Err(de::Error::custom(format!("can't convert {int} into i16"))),
137 |i| visitor.visit_i16(i),
138 )
139 }
140
141 fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value>
142 where
143 V: Visitor<'de>,
144 {
145 let int = get_int_from_edn(&self)?;
146 i32::try_from(int).map_or_else(
147 |_| Err(de::Error::custom(format!("can't convert {int} into i32"))),
148 |i| visitor.visit_i32(i),
149 )
150 }
151
152 fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
153 where
154 V: Visitor<'de>,
155 {
156 let int = get_int_from_edn(&self)?;
157 u8::try_from(int).map_or_else(
158 |_| Err(de::Error::custom(format!("can't convert {int} into u8"))),
159 |i| visitor.visit_u8(i),
160 )
161 }
162
163 fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value>
164 where
165 V: Visitor<'de>,
166 {
167 let int = get_int_from_edn(&self)?;
168 u16::try_from(int).map_or_else(
169 |_| Err(de::Error::custom(format!("can't convert {int} into u16"))),
170 |i| visitor.visit_u16(i),
171 )
172 }
173
174 fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value>
175 where
176 V: Visitor<'de>,
177 {
178 let int = get_int_from_edn(&self)?;
179 u32::try_from(int).map_or_else(
180 |_| Err(de::Error::custom(format!("can't convert {int} into u32"))),
181 |i| visitor.visit_u32(i),
182 )
183 }
184
185 fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value>
186 where
187 V: Visitor<'de>,
188 {
189 #[cfg(feature = "arbitrary-nums")]
190 if let Edn::BigInt(i) = &self {
191 return u64::try_from(i).map_or_else(
192 |_| Err(de::Error::custom(format!("can't convert {i} into u64"))),
193 |i| visitor.visit_u64(i),
194 );
195 }
196
197 let int = get_int_from_edn(&self)?;
198 u64::try_from(int).map_or_else(
199 |_| Err(de::Error::custom(format!("can't convert {int} into u64"))),
200 |i| visitor.visit_u64(i),
201 )
202 }
203
204 fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value>
205 where
206 V: Visitor<'de>,
207 {
208 let _ = visitor; #[cfg(feature = "floats")]
210 if let Edn::Double(f) = self {
211 #[expect(clippy::cast_possible_truncation)]
212 return visitor.visit_f32(*f as f32);
213 }
214 Err(de::Error::custom(format!("can't convert {self:?} into f32")))
215 }
216
217 fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
218 where
219 V: Visitor<'de>,
220 {
221 self.deserialize_str(visitor)
222 }
223
224 fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
225 where
226 V: Visitor<'de>,
227 {
228 struct BytesFromBuf<V>(V);
229 impl<'de, V: Visitor<'de>> Visitor<'de> for BytesFromBuf<V> {
230 type Value = V::Value;
231 fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
232 self.0.expecting(f)
233 }
234 fn visit_byte_buf<E: de::Error>(self, v: Vec<u8>) -> core::result::Result<Self::Value, E> {
235 self.0.visit_bytes(&v)
236 }
237 }
238 self.deserialize_byte_buf(BytesFromBuf(visitor))
239 }
240
241 fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
242 where
243 V: Visitor<'de>,
244 {
245 let buf = get_bytes_from_edn(&self)?;
246 visitor.visit_byte_buf(buf)
247 }
248
249 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
250 where
251 V: Visitor<'de>,
252 {
253 if self == Edn::Nil { visitor.visit_none() } else { visitor.visit_some(self) }
254 }
255
256 fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
257 where
258 V: Visitor<'de>,
259 {
260 match self {
261 Edn::Nil => visitor.visit_unit(),
262 Edn::Map(map) if map.is_empty() => visitor.visit_unit(),
263 other => Err(de::Error::custom(format!("can't convert {other:?} into unit"))),
264 }
265 }
266
267 fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
268 where
269 V: Visitor<'de>,
270 {
271 self.deserialize_unit(visitor)
272 }
273
274 fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
275 where
276 V: Visitor<'de>,
277 {
278 visitor.visit_newtype_struct(self)
279 }
280
281 fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value>
282 where
283 V: Visitor<'de>,
284 {
285 self.deserialize_seq(visitor)
286 }
287
288 fn deserialize_struct<V>(
289 self,
290 _name: &'static str,
291 _fields: &'static [&'static str],
292 visitor: V,
293 ) -> Result<V::Value>
294 where
295 V: Visitor<'de>,
296 {
297 self.deserialize_map(visitor)
298 }
299
300 fn deserialize_enum<V>(
301 self,
302 name: &'static str,
303 _variants: &'static [&'static str],
304 visitor: V,
305 ) -> Result<V::Value>
306 where
307 V: Visitor<'de>,
308 {
309 let Edn::Tagged(tag, edn) = self else {
310 return Err(de::Error::custom(format!("can't convert {self:?} into Tagged for enum")));
311 };
312
313 let mut split = tag.split('/');
314 let (Some(tag_first), Some(tag_second)) = (split.next(), split.next()) else {
315 return Err(de::Error::custom(format!("Expected namespace in {tag} for Tagged for enum")));
316 };
317
318 if name != tag_first {
319 return Err(de::Error::custom(format!("namespace in {tag} can't be matched to {name}")));
320 }
321
322 visitor.visit_enum(EnumEdn::new(*edn, tag_second))
323 }
324
325 fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
326 where
327 V: Visitor<'de>,
328 {
329 match self {
330 Edn::Key(k) | Edn::Str(k) | Edn::Symbol(k) => visitor.visit_borrowed_str(k),
331 other => visitor.visit_string(other.to_string()),
332 }
333 }
334}
335
336struct SeqEdn<'de> {
337 de: Vec<Edn<'de>>,
338}
339
340impl<'de> SeqEdn<'de> {
341 const fn new(de: Vec<Edn<'de>>) -> Self {
342 SeqEdn { de }
343 }
344}
345
346impl<'de> SeqAccess<'de> for SeqEdn<'de> {
347 type Error = Error;
348
349 fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
350 where
351 T: DeserializeSeed<'de>,
352 {
353 let s = self.de.pop();
354 match s {
355 Some(e) => Ok(Some(seed.deserialize(e)?)),
356 None => Ok(None),
357 }
358 }
359}
360
361struct MapEdn<'de> {
362 de: BTreeMap<Edn<'de>, Edn<'de>>,
363 pending_value: Option<Edn<'de>>,
364}
365
366impl<'de> MapEdn<'de> {
367 const fn new(de: BTreeMap<Edn<'de>, Edn<'de>>) -> Self {
368 MapEdn { de, pending_value: None }
369 }
370}
371
372impl<'de> MapAccess<'de> for MapEdn<'de> {
373 type Error = Error;
374
375 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
376 where
377 K: DeserializeSeed<'de>,
378 {
379 if let Some((k, v)) = self.de.pop_first() {
380 self.pending_value = Some(v);
381 return Ok(Some(seed.deserialize(k)?));
382 }
383 Ok(None)
384 }
385
386 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
387 where
388 V: DeserializeSeed<'de>,
389 {
390 let v = self.pending_value.take().ok_or_else(|| {
392 de::Error::custom("value missing: next_value_seed called without next_key_seed")
393 })?;
394 seed.deserialize(v)
395 }
396}
397
398#[derive(Debug)]
399struct EnumEdn<'de> {
400 de: Edn<'de>,
401 variant: &'de str,
402}
403
404impl<'de> EnumEdn<'de> {
405 const fn new(de: Edn<'de>, variant: &'de str) -> Self {
406 EnumEdn { de, variant }
407 }
408}
409
410impl<'de> EnumAccess<'de> for EnumEdn<'de> {
411 type Error = Error;
412 type Variant = Self;
413
414 fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
415 where
416 V: DeserializeSeed<'de>,
417 {
418 let val = seed.deserialize(self.variant.into_deserializer())?;
419 Ok((val, self))
420 }
421}
422
423impl<'de> VariantAccess<'de> for EnumEdn<'de> {
424 type Error = Error;
425
426 fn unit_variant(self) -> Result<()> {
427 Ok(())
428 }
429
430 fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
431 where
432 T: DeserializeSeed<'de>,
433 {
434 seed.deserialize(self.de)
435 }
436
437 fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
438 where
439 V: Visitor<'de>,
440 {
441 de::Deserializer::deserialize_seq(self.de, visitor)
442 }
443
444 fn struct_variant<V>(
445 self,
446 _fields: &'static [&'static str],
447 visitor: V,
448 ) -> core::result::Result<V::Value, Self::Error>
449 where
450 V: Visitor<'de>,
451 {
452 de::Deserializer::deserialize_map(self.de, visitor)
453 }
454}