1use alloc::boxed::Box;
10use alloc::collections::{BTreeMap, BTreeSet};
11use alloc::vec::Vec;
12use core::fmt;
13
14#[cfg(feature = "arbitrary-nums")]
15use bigdecimal::BigDecimal;
16#[cfg(feature = "arbitrary-nums")]
17use num_bigint::BigInt;
18#[cfg(feature = "floats")]
19use ordered_float::OrderedFloat;
20
21use crate::{error, parse};
22
23#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord)]
24#[non_exhaustive]
25pub enum Edn<'e> {
26 Vector(Vec<Edn<'e>>),
27 Set(BTreeSet<Edn<'e>>),
28 Map(BTreeMap<Edn<'e>, Edn<'e>>),
29 List(Vec<Edn<'e>>),
30 Key(&'e str),
31 Symbol(&'e str),
32 Str(&'e str),
33 Int(i64),
34 Tagged(&'e str, Box<Edn<'e>>),
35 #[cfg(feature = "floats")]
36 Double(OrderedFloat<f64>),
37 Rational((i64, i64)),
38 #[cfg(feature = "arbitrary-nums")]
39 BigInt(BigInt),
40 #[cfg(feature = "arbitrary-nums")]
41 BigDec(BigDecimal),
42 Char(char),
43 Bool(bool),
44 Nil,
45}
46
47pub fn read_string(edn: &str) -> Result<Edn<'_>, error::Error> {
53 Ok(parse::parse(edn)?.0)
54}
55
56pub fn read(edn: &str) -> Result<(Edn<'_>, &str), error::Error> {
65 let r = parse::parse(edn)?;
66 if r.0 == Edn::Nil && r.1.is_empty() {
67 return Err(error::Error {
68 code: error::Code::UnexpectedEOF,
69 line: None,
70 column: None,
71 ptr: None,
72 });
73 }
74 Ok((r.0, r.1))
75}
76
77impl Edn<'_> {
78 pub fn get(&self, e: &Self) -> Option<&Self> {
79 if let Edn::Map(m) = self {
80 if let Some(l) = m.get(e) {
81 return Some(l);
82 };
83 }
84 None
85 }
86 pub fn nth(&self, i: usize) -> Option<&Self> {
87 let vec = match self {
88 Edn::Vector(v) => v,
89 Edn::List(l) => l,
90 _ => return None,
91 };
92
93 vec.get(i)
94 }
95}
96
97pub(crate) const fn char_to_edn(c: char) -> Option<&'static str> {
98 match c {
99 '\n' => Some("newline"),
100 '\r' => Some("return"),
101 ' ' => Some("space"),
102 '\t' => Some("tab"),
103 _ => None,
104 }
105}
106
107impl fmt::Display for Edn<'_> {
108 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
109 match self {
110 Self::Vector(v) => {
111 write!(f, "[")?;
112 let mut it = v.iter().peekable();
113 while let Some(i) = it.next() {
114 if it.peek().is_some() {
115 write!(f, "{i} ")?;
116 } else {
117 write!(f, "{i}")?;
118 }
119 }
120 write!(f, "]")
121 }
122 Self::Set(s) => {
123 write!(f, "#{{")?;
124 let mut it = s.iter().peekable();
125 while let Some(i) = it.next() {
126 if it.peek().is_some() {
127 write!(f, "{i} ")?;
128 } else {
129 write!(f, "{i}")?;
130 }
131 }
132 write!(f, "}}")
133 }
134 Self::Map(m) => {
135 write!(f, "{{")?;
136 let mut it = m.iter().peekable();
137 while let Some(kv) = it.next() {
138 if it.peek().is_some() {
139 write!(f, "{} {}, ", kv.0, kv.1)?;
140 } else {
141 write!(f, "{} {}", kv.0, kv.1)?;
142 }
143 }
144 write!(f, "}}")
145 }
146 Self::List(l) => {
147 write!(f, "(")?;
148 let mut it = l.iter().peekable();
149 while let Some(i) = it.next() {
150 if it.peek().is_some() {
151 write!(f, "{i} ")?;
152 } else {
153 write!(f, "{i}")?;
154 }
155 }
156 write!(f, ")")
157 }
158 Self::Symbol(sy) => write!(f, "{sy}"),
159 Self::Tagged(t, s) => write!(f, "#{t} {s}"),
160 Self::Key(k) => write!(f, ":{k}"),
161 Self::Str(s) => write!(f, "\"{s}\""),
162 Self::Int(i) => write!(f, "{i}"),
163 #[cfg(feature = "floats")]
164 Self::Double(d) => write!(f, "{d}"),
165 #[cfg(feature = "arbitrary-nums")]
166 Self::BigInt(bi) => write!(f, "{bi}N"),
167 #[cfg(feature = "arbitrary-nums")]
168 Self::BigDec(bd) => write!(f, "{bd}M"),
169 Self::Rational((n, d)) => write!(f, "{n}/{d}"),
170 Self::Bool(b) => write!(f, "{b}"),
171 Self::Char(c) => {
172 write!(f, "\\")?;
173 if let Some(c) = char_to_edn(*c) {
174 return write!(f, "{c}");
175 }
176 write!(f, "{c}")
177 }
178 Self::Nil => write!(f, "nil"),
179 }
180 }
181}