1use alloc::boxed::Box;
2use alloc::collections::BTreeMap;
3#[cfg(feature = "sets")]
4use alloc::collections::BTreeSet;
5use alloc::string::{String, ToString};
6use alloc::vec::Vec;
7use alloc::{fmt, format};
8#[cfg(feature = "sets")]
9use core::cmp::{Ord, PartialOrd};
10use core::convert::{Infallible, TryFrom};
11use core::num;
12
13use crate::deserialize::parse::{self};
14use utils::index::Index;
15
16#[cfg(feature = "sets")]
17use ordered_float::OrderedFloat;
18
19#[doc(hidden)]
20pub mod utils;
21
22#[derive(Debug, Clone, PartialEq)]
26#[cfg_attr(feature = "sets", derive(Eq, PartialOrd, Ord))]
27#[non_exhaustive]
28pub enum Edn {
29 Tagged(String, Box<Self>),
30 Vector(Vector),
31 #[cfg(feature = "sets")]
32 Set(Set),
33 Map(Map),
34 List(List),
35 Key(String),
36 Symbol(String),
37 Str(String),
38 Int(i64),
39 UInt(u64),
40 Double(Double),
41 Rational(String),
42 Char(char),
43 Bool(bool),
44 Nil,
45 Empty,
46}
47
48#[derive(Clone, Ord, Debug, Eq, PartialEq, PartialOrd, Hash)]
49#[cfg(feature = "sets")]
50pub struct Double(pub(crate) OrderedFloat<f64>);
51
52#[derive(Clone, Debug, PartialEq)]
53#[cfg(not(feature = "sets"))]
54pub struct Double(f64);
55
56impl fmt::Display for Double {
57 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
58 write!(f, "{}", self.0)
59 }
60}
61
62#[cfg(feature = "sets")]
63impl Double {
64 fn to_float(&self) -> f64 {
65 self.0.into_inner()
66 }
67}
68
69#[cfg(not(feature = "sets"))]
70impl Double {
71 const fn to_float(&self) -> f64 {
72 self.0
73 }
74}
75
76#[cfg(feature = "sets")]
77impl From<f64> for Double {
78 fn from(f: f64) -> Self {
79 Self(OrderedFloat(f))
80 }
81}
82
83#[cfg(not(feature = "sets"))]
84impl From<f64> for Double {
85 fn from(f: f64) -> Self {
86 Self(f)
87 }
88}
89
90#[derive(Debug, Clone, PartialEq)]
91#[cfg_attr(feature = "sets", derive(Eq, PartialOrd, Ord))]
92pub struct Vector(Vec<Edn>);
93impl Vector {
94 #[must_use]
95 pub const fn new(v: Vec<Edn>) -> Self {
96 Self(v)
97 }
98
99 #[must_use]
100 pub const fn empty() -> Self {
101 Self(Vec::new())
102 }
103
104 #[must_use]
105 pub fn to_vec(self) -> Vec<Edn> {
106 self.0
107 }
108}
109
110#[derive(Debug, Clone, PartialEq)]
111#[cfg_attr(feature = "sets", derive(Eq, PartialOrd, Ord))]
112pub struct List(Vec<Edn>);
113impl List {
114 #[must_use]
115 pub const fn new(v: Vec<Edn>) -> Self {
116 Self(v)
117 }
118
119 #[must_use]
120 pub const fn empty() -> Self {
121 Self(Vec::new())
122 }
123
124 #[must_use]
125 pub fn to_vec(self) -> Vec<Edn> {
126 self.0
127 }
128}
129
130#[cfg(feature = "sets")]
131#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
132pub struct Set(BTreeSet<Edn>);
133
134#[cfg(feature = "sets")]
135impl Set {
136 #[must_use]
137 pub const fn new(v: BTreeSet<Edn>) -> Self {
138 Self(v)
139 }
140
141 #[must_use]
142 pub const fn empty() -> Self {
143 Self(BTreeSet::new())
144 }
145
146 #[must_use]
147 pub fn to_set(self) -> BTreeSet<Edn> {
148 self.0
149 }
150}
151
152#[derive(Debug, Clone, PartialEq)]
153#[cfg_attr(feature = "sets", derive(Eq, PartialOrd, Ord))]
154pub struct Map(BTreeMap<String, Edn>);
155impl Map {
156 #[must_use]
157 pub const fn new(m: BTreeMap<String, Edn>) -> Self {
158 Self(m)
159 }
160
161 #[must_use]
162 pub const fn empty() -> Self {
163 Self(BTreeMap::new())
164 }
165
166 #[must_use]
167 pub fn to_map(self) -> BTreeMap<String, Edn> {
168 self.0
169 }
170}
171
172impl core::fmt::Display for Vector {
173 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
174 write!(f, "[")?;
175 let mut it = self.0.iter().peekable();
176 while let Some(i) = it.next() {
177 if it.peek().is_some() {
178 write!(f, "{i} ")?;
179 } else {
180 write!(f, "{i}")?;
181 }
182 }
183 write!(f, "]")
184 }
185}
186
187impl core::fmt::Display for List {
188 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
189 write!(f, "(")?;
190 let mut it = self.0.iter().peekable();
191 while let Some(i) = it.next() {
192 if it.peek().is_some() {
193 write!(f, "{i} ")?;
194 } else {
195 write!(f, "{i}")?;
196 }
197 }
198 write!(f, ")")
199 }
200}
201
202#[cfg(feature = "sets")]
203impl core::fmt::Display for Set {
204 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
205 write!(f, "#{{")?;
206 let mut it = self.0.iter().peekable();
207 while let Some(i) = it.next() {
208 if it.peek().is_some() {
209 write!(f, "{i} ")?;
210 } else {
211 write!(f, "{i}")?;
212 }
213 }
214 write!(f, "}}")
215 }
216}
217
218impl core::fmt::Display for Map {
219 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
220 write!(f, "{{")?;
221 let mut it = self.0.iter().peekable();
222 while let Some(kv) = it.next() {
223 if it.peek().is_some() {
224 write!(f, "{} {}, ", kv.0, kv.1)?;
225 } else {
226 write!(f, "{} {}", kv.0, kv.1)?;
227 }
228 }
229 write!(f, "}}")
230 }
231}
232
233fn char_to_edn(c: char) -> String {
234 match c {
235 '\n' => "\\newline".to_string(),
236 '\r' => "\\return".to_string(),
237 ' ' => "\\space".to_string(),
238 '\t' => "\\tab".to_string(),
239 _ => format!("\\{c}"),
240 }
241}
242
243impl core::fmt::Display for Edn {
244 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
245 let text = match self {
246 Self::Vector(v) => format!("{v}"),
247 #[cfg(feature = "sets")]
248 Self::Set(s) => format!("{s}"),
249 Self::Map(m) => format!("{m}"),
250 Self::List(l) => format!("{l}"),
251 Self::Symbol(sy) => sy.clone(),
252 Self::Key(k) => k.clone(),
253 Self::Str(s) => format!("{s:?}"),
254 Self::Int(i) => format!("{i}"),
255 Self::UInt(u) => format!("{u}"),
256 Self::Double(d) => format!("{d}"),
257 Self::Rational(r) => r.clone(),
258 Self::Bool(b) => format!("{b}"),
259 Self::Char(c) => char_to_edn(*c),
260 Self::Nil => String::from("nil"),
261 Self::Empty => String::new(),
262 Self::Tagged(tag, edn) => format!("#{tag} {edn}"),
263 };
264 write!(f, "{text}")
265 }
266}
267
268impl Edn {
269 #[must_use]
283 pub fn to_float(&self) -> Option<f64> {
284 match self {
285 Self::Key(k) => k.replace(':', "").parse::<f64>().ok(),
286 Self::Str(s) => s.parse::<f64>().ok(),
287 Self::Int(i) => to_double(i).ok(),
288 Self::UInt(u) => to_double(u).ok(),
289 Self::Double(d) => Some(d.to_float()),
290 Self::Rational(r) => rational_to_double(r),
291 _ => None,
292 }
293 }
294
295 #[must_use]
309 pub fn to_int(&self) -> Option<i64> {
310 match self {
311 Self::Key(k) => k.replace(':', "").parse::<i64>().ok(),
312 Self::Str(s) => s.parse::<i64>().ok(),
313 Self::Int(i) => Some(*i),
314 #[allow(clippy::cast_possible_wrap)]
315 Self::UInt(u) if i64::try_from(*u).is_ok() => Some(*u as i64),
316 #[allow(clippy::cast_possible_truncation)]
317 #[cfg(feature = "std")]
318 Self::Double(d) => Some((*d).to_float().round() as i64),
319 #[allow(clippy::cast_possible_truncation)]
320 #[cfg(feature = "std")]
321 Self::Rational(r) => Some(rational_to_double(r).unwrap_or(0f64).round() as i64),
322 _ => None,
323 }
324 }
325
326 #[must_use]
328 pub fn to_uint(&self) -> Option<u64> {
329 match self {
330 Self::Str(s) => s.parse::<u64>().ok(),
331 #[allow(clippy::cast_sign_loss)]
332 Self::Int(i) if i > &0 => Some(*i as u64),
333 Self::UInt(i) => Some(*i),
334 #[cfg(feature = "std")]
335 Self::Double(d) if d.to_float() > 0f64 =>
336 {
337 #[allow(clippy::cast_sign_loss)]
338 #[allow(clippy::cast_possible_truncation)]
339 Some((*d).to_float().round() as u64)
340 }
341 #[cfg(feature = "std")]
342 Self::Rational(r) if !r.contains('-') =>
343 {
344 #[allow(clippy::cast_sign_loss)]
345 #[allow(clippy::cast_possible_truncation)]
346 Some(rational_to_double(r)?.round() as u64)
347 }
348 _ => None,
349 }
350 }
351
352 #[must_use]
365 pub fn to_bool(&self) -> Option<bool> {
366 match self {
367 Self::Bool(b) => Some(*b),
368 Self::Str(s) | Self::Symbol(s) => s.parse::<bool>().ok(),
369 _ => None,
370 }
371 }
372
373 #[must_use]
384 pub const fn to_char(&self) -> Option<char> {
385 match self {
386 Self::Char(c) => Some(*c),
387 _ => None,
388 }
389 }
390
391 #[must_use]
394 pub fn to_vec(&self) -> Option<Vec<String>> {
395 match self {
396 Self::Vector(_) => Some(
397 self.iter_some()?
398 .map(|e| match e {
399 Self::Str(s) => s.clone(),
400 _ => e.to_string(),
401 })
402 .collect::<Vec<String>>(),
403 ),
404 Self::List(_) => Some(
405 self.iter_some()?
406 .map(|e| match e {
407 Self::Str(s) => s.clone(),
408 _ => e.to_string(),
409 })
410 .collect::<Vec<String>>(),
411 ),
412 #[cfg(feature = "sets")]
413 Self::Set(_) => Some(
414 self.iter_some()?
415 .map(|e| match e {
416 Self::Str(s) => s.clone(),
417 _ => e.to_string(),
418 })
419 .collect::<Vec<String>>(),
420 ),
421 _ => None,
422 }
423 }
424
425 #[must_use]
428 pub fn to_int_vec(&self) -> Option<Vec<i64>> {
429 match self {
430 Self::Vector(_) if !self.iter_some()?.any(|e| e.to_int().is_none()) => Some(
431 self.iter_some()?
432 .map(Self::to_int)
433 .collect::<Option<Vec<i64>>>()?,
434 ),
435 Self::List(_) if !self.iter_some()?.any(|e| e.to_int().is_none()) => Some(
436 self.iter_some()?
437 .map(Self::to_int)
438 .collect::<Option<Vec<i64>>>()?,
439 ),
440 #[cfg(feature = "sets")]
441 Self::Set(_) if !self.iter_some()?.any(|e| e.to_int().is_none()) => Some(
442 self.iter_some()?
443 .map(Self::to_int)
444 .collect::<Option<Vec<i64>>>()?,
445 ),
446 _ => None,
447 }
448 }
449
450 #[must_use]
453 pub fn to_uint_vec(&self) -> Option<Vec<u64>> {
454 match self {
455 Self::Vector(_) if !self.iter_some()?.any(|e| e.to_uint().is_none()) => Some(
456 self.iter_some()?
457 .map(Self::to_uint)
458 .collect::<Option<Vec<u64>>>()?,
459 ),
460 Self::List(_) if !self.iter_some()?.any(|e| e.to_uint().is_none()) => Some(
461 self.iter_some()?
462 .map(Self::to_uint)
463 .collect::<Option<Vec<u64>>>()?,
464 ),
465 #[cfg(feature = "sets")]
466 Self::Set(_) if !self.iter_some()?.any(|e| e.to_uint().is_none()) => Some(
467 self.iter_some()?
468 .map(Self::to_uint)
469 .collect::<Option<Vec<u64>>>()?,
470 ),
471 _ => None,
472 }
473 }
474
475 #[must_use]
478 pub fn to_float_vec(&self) -> Option<Vec<f64>> {
479 match self {
480 Self::Vector(_) if !self.iter_some()?.any(|e| e.to_float().is_none()) => Some(
481 self.iter_some()?
482 .map(Self::to_float)
483 .collect::<Option<Vec<f64>>>()?,
484 ),
485 Self::List(_) if !self.iter_some()?.any(|e| e.to_float().is_none()) => Some(
486 self.iter_some()?
487 .map(Self::to_float)
488 .collect::<Option<Vec<f64>>>()?,
489 ),
490 #[cfg(feature = "sets")]
491 Self::Set(_) if !self.iter_some()?.any(|e| e.to_float().is_none()) => Some(
492 self.iter_some()?
493 .map(Self::to_float)
494 .collect::<Option<Vec<f64>>>()?,
495 ),
496 _ => None,
497 }
498 }
499
500 #[must_use]
503 pub fn to_bool_vec(&self) -> Option<Vec<bool>> {
504 match self {
505 Self::Vector(_) if !self.iter_some()?.any(|e| e.to_bool().is_none()) => Some(
506 self.iter_some()?
507 .map(Self::to_bool)
508 .collect::<Option<Vec<bool>>>()?,
509 ),
510 Self::List(_) if !self.iter_some()?.any(|e| e.to_bool().is_none()) => Some(
511 self.iter_some()?
512 .map(Self::to_bool)
513 .collect::<Option<Vec<bool>>>()?,
514 ),
515 #[cfg(feature = "sets")]
516 Self::Set(_) if !self.iter_some()?.any(|e| e.to_bool().is_none()) => Some(
517 self.iter_some()?
518 .map(Self::to_bool)
519 .collect::<Option<Vec<bool>>>()?,
520 ),
521 _ => None,
522 }
523 }
524
525 #[allow(clippy::must_use_candidate)]
548 pub fn to_debug(&self) -> String {
549 format!("{self:?}")
550 }
551
552 #[must_use]
576 pub fn get<I: Index>(&self, index: I) -> Option<&Self> {
577 index.index_into(self)
578 }
579
580 #[must_use]
604 pub fn get_mut<I: Index>(&mut self, index: I) -> Option<&mut Self> {
605 index.index_into_mut(self)
606 }
607
608 #[allow(clippy::needless_doctest_main)]
621 #[must_use]
622 pub fn iter_some(&self) -> Option<core::slice::Iter<'_, Self>> {
623 match self {
624 Self::Vector(v) => Some(v.0.iter()),
625 Self::List(l) => Some(l.0.iter()),
626 _ => None,
627 }
628 }
629
630 #[cfg(feature = "sets")]
633 #[must_use]
634 pub fn set_iter(&self) -> Option<alloc::collections::btree_set::Iter<'_, Self>> {
635 match self {
636 Self::Set(s) => Some(s.0.iter()),
637 _ => None,
638 }
639 }
640
641 #[must_use]
644 pub fn map_iter(&self) -> Option<alloc::collections::btree_map::Iter<'_, String, Self>> {
645 match self {
646 Self::Map(m) => Some(m.0.iter()),
647 _ => None,
648 }
649 }
650
651 #[cfg(feature = "json")]
688 #[must_use]
689 pub fn to_json(&self) -> String {
690 crate::json::display_as_json(self)
691 }
692}
693
694impl core::str::FromStr for Edn {
695 type Err = Error;
696
697 fn from_str(s: &str) -> Result<Self, Self::Err> {
699 parse::parse(s)
700 }
701}
702
703fn to_double<T>(i: T) -> Result<f64, num::ParseFloatError>
704where
705 T: fmt::Debug,
706{
707 format!("{i:?}").parse::<f64>()
708}
709
710pub(crate) fn rational_to_double(r: &str) -> Option<f64> {
711 if r.split('/').count() == 2 {
712 let vals = r
713 .split('/')
714 .map(ToString::to_string)
715 .map(|v| v.parse::<f64>())
716 .map(Result::ok)
717 .collect::<Option<Vec<f64>>>()?;
718 return Some(vals[0] / vals[1]);
719 }
720 None
721}
722
723#[derive(Debug, PartialEq, Eq)]
724#[non_exhaustive]
725pub enum Error {
726 ParseEdn(String),
727 Deserialize(String),
728 Iter(String),
729 TryFromInt(num::TryFromIntError),
730 #[doc(hidden)]
731 Infallable(), }
733
734impl From<String> for Error {
735 fn from(s: String) -> Self {
736 Self::ParseEdn(s)
737 }
738}
739
740impl From<num::ParseIntError> for Error {
741 fn from(s: num::ParseIntError) -> Self {
742 Self::ParseEdn(s.to_string())
743 }
744}
745
746impl From<num::ParseFloatError> for Error {
747 fn from(s: num::ParseFloatError) -> Self {
748 Self::ParseEdn(s.to_string())
749 }
750}
751
752impl From<core::str::ParseBoolError> for Error {
753 fn from(s: core::str::ParseBoolError) -> Self {
754 Self::ParseEdn(s.to_string())
755 }
756}
757
758impl From<num::TryFromIntError> for Error {
759 fn from(e: num::TryFromIntError) -> Self {
760 Self::TryFromInt(e)
761 }
762}
763
764impl From<Infallible> for Error {
765 fn from(_: Infallible) -> Self {
766 Self::Infallable()
767 }
768}
769
770impl fmt::Display for Error {
771 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
772 match self {
773 Self::ParseEdn(s) | Self::Deserialize(s) | Self::Iter(s) => write!(f, "{}", &s),
774 Self::TryFromInt(e) => write!(f, "{e}"),
775 Self::Infallable() => panic!("Infallable conversion"),
776 }
777 }
778}
779
780#[cfg(test)]
781mod test {
782 use alloc::borrow::ToOwned;
783 use alloc::vec;
784
785 use super::*;
786 #[test]
787 #[expect(clippy::float_cmp)]
788 fn parses_rationals() {
789 assert_eq!(rational_to_double("3/4").unwrap(), 0.75f64);
790 assert_eq!(rational_to_double("25/5").unwrap(), 5f64);
791 assert_eq!(rational_to_double("15/4").unwrap(), 3.75f64);
792 assert_eq!(rational_to_double("3 4"), None);
793 assert_eq!(rational_to_double("3/4/5"), None);
794 assert_eq!(rational_to_double("text/moretext"), None);
795 }
796
797 #[test]
798 fn iterator() {
799 let v = Edn::Vector(Vector::new(vec![Edn::Int(5), Edn::Int(6), Edn::Int(7)]));
800 let sum: i64 = v.iter_some().unwrap().filter_map(super::Edn::to_int).sum();
801
802 assert_eq!(18i64, sum);
803 }
804
805 #[test]
806 fn to_vec() {
807 let edn = Edn::Vector(Vector::new(vec![Edn::Int(5), Edn::Int(6), Edn::Int(7)]));
808 let v = vec![String::from("5"), String::from("6"), String::from("7")];
809
810 assert_eq!(edn.to_vec().unwrap(), v);
811 }
812
813 #[test]
814 fn to_char() {
815 let c = Edn::Char('c');
816 let symbol = Edn::Symbol("d".to_string());
817
818 assert_eq!(c.to_char().unwrap(), 'c');
819 assert_eq!(symbol.to_char(), None);
820 }
821
822 #[test]
823 fn to_int_vec() {
824 let edn = Edn::Vector(Vector::new(vec![Edn::Int(5), Edn::Int(6), Edn::Int(7)]));
825 let v = vec![5i64, 6i64, 7i64];
826
827 assert_eq!(edn.to_int_vec().unwrap(), v);
828 }
829
830 #[test]
831 fn to_uint_vec() {
832 let edn = Edn::Vector(Vector::new(vec![Edn::UInt(5), Edn::UInt(6), Edn::UInt(7)]));
833 let v = vec![5u64, 6u64, 7u64];
834
835 assert_eq!(edn.to_uint_vec().unwrap(), v);
836 }
837
838 #[test]
839 fn to_float_vec() {
840 let edn = Edn::Vector(Vector::new(vec![
841 Edn::Double(5.5.into()),
842 Edn::Double(6.6.into()),
843 Edn::Double(7.7.into()),
844 ]));
845 let v = vec![5.5f64, 6.6f64, 7.7f64];
846
847 assert_eq!(edn.to_float_vec().unwrap(), v);
848 }
849
850 #[test]
851 fn to_bool_vec() {
852 let edn = Edn::Vector(Vector::new(vec![
853 Edn::Bool(true),
854 Edn::Bool(true),
855 Edn::Bool(false),
856 ]));
857 let v = vec![true, true, false];
858
859 assert_eq!(edn.to_bool_vec().unwrap(), v);
860 }
861
862 #[test]
863 fn to_bool_vec_with_non_bool_is_none() {
864 let edn = Edn::Vector(Vector::new(vec![
865 Edn::Bool(true),
866 Edn::Int(5),
867 Edn::Bool(false),
868 ]));
869
870 assert_eq!(edn.to_bool_vec(), None);
871 }
872
873 #[test]
874 fn edn_to_string() {
875 let edn = Edn::Map(Map::new(
876 map! {":a".to_string() => Edn::Key(":something".to_string()),
877 ":b".to_string() => Edn::Bool(false), ":c".to_string() => Edn::Nil},
878 ));
879 assert_eq!(edn.to_string(), "{:a :something, :b false, :c nil}");
880 }
881
882 #[test]
883 fn edn_to_debug() {
884 let edn = Edn::Map(Map::new(
885 map! {":a".to_string() => Edn::Key(":something".to_string()),
886 ":b".to_string() => Edn::Bool(false), ":c".to_string() => Edn::Nil},
887 ));
888 let expected = "Map(Map({\":a\": Key(\":something\"), \":b\": Bool(false), \":c\": Nil}))";
889 assert_eq!(edn.to_debug(), expected);
890 }
891
892 #[test]
893 fn negative_i64_to_u64() {
894 let neg_i = Edn::Int(-10);
895
896 assert_eq!(neg_i.to_uint(), None);
897 }
898
899 #[test]
900 fn max_u64_to_uint() {
901 let max_u = Edn::UInt(u64::MAX);
902
903 assert_eq!(max_u.to_int(), None);
904 }
905
906 #[test]
907 fn positive_i64_to_u64() {
908 let max_i = Edn::Int(i64::MAX);
909
910 assert_eq!(max_i.to_uint(), Some(i64::MAX as u64));
911 }
912
913 #[test]
914 fn small_u64_to_i64() {
915 let small_u = Edn::UInt(10);
916
917 assert_eq!(small_u.to_int(), Some(10));
918 }
919
920 #[test]
921 fn regression_to_vec() {
922 let expected = vec!["true", ":b", "test"];
923 let edn = Edn::Vector(Vector(vec![
924 Edn::Bool(true),
925 Edn::Key(":b".to_string()),
926 Edn::Str("test".to_string()),
927 ]));
928 let edn_vec = edn.to_vec().unwrap();
929
930 assert_eq!(edn_vec, expected);
931 }
932
933 #[test]
934 fn get_vec_at() {
935 let expected = &Edn::Key(":b".to_string());
936 let edn = Edn::Vector(Vector(vec![
937 Edn::Bool(true),
938 Edn::Key(":b".to_string()),
939 Edn::Str("test".to_string()),
940 ]));
941 let val = &edn[Edn::UInt(1)];
942
943 assert_eq!(val, expected);
944 }
945
946 #[test]
947 fn get_list_at() {
948 let expected = &Edn::Str("test".to_string());
949 let edn = Edn::Vector(Vector(vec![
950 Edn::Bool(true),
951 Edn::Key(":b".to_string()),
952 Edn::Str("test".to_string()),
953 ]));
954 let val = &edn[Edn::Int(2)];
955
956 assert_eq!(val, expected);
957 }
958
959 #[test]
960 fn get_map() {
961 let expected = &Edn::Key(":val".to_string());
962 let map = Edn::Map(Map::new(map! {
963 ":key".to_string() => Edn::Key(":val".to_string()),
964 "1".to_string() => Edn::Key(":value".to_string())
965 }));
966
967 let val = &map[Edn::Key(":key".to_owned())];
968 assert_eq!(expected, val);
969 }
970}