Skip to main content

clojure_reader/
de.rs

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
17/// Deserializer for a EDN formatted &str.
18///
19/// # Errors
20///
21/// See [`crate::error::Error`].
22/// Always returns `Code::Serde`.
23pub 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      // Things like rational numbers and custom tags can't be represented in rust types
103      _ => 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 = i8::try_from(get_int_from_edn(&self)?);
124    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 = i16::try_from(get_int_from_edn(&self)?);
135    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 = i32::try_from(get_int_from_edn(&self)?);
146    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 = u8::try_from(get_int_from_edn(&self)?);
157    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 = u16::try_from(get_int_from_edn(&self)?);
168    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 = u32::try_from(get_int_from_edn(&self)?);
179    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 match u64::try_from(i.clone()) {
192        Ok(i) => visitor.visit_u64(i),
193        Err(err) => Err(de::Error::custom(format!("can't convert {err:?} into u64"))),
194      };
195    }
196
197    let int = u64::try_from(get_int_from_edn(&self)?);
198    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; // hush clippy
209    #[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    // Infallible: serde always calls next_key_seed before next_value_seed.
391    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}