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 = 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; // 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}