edn_rs/edn/utils/
index.rs1use alloc::borrow::ToOwned;
2use alloc::string::{String, ToString};
3use core::convert::TryFrom;
4use core::{fmt, ops};
5
6use crate::edn::{Edn, Map};
7
8pub trait Index: private::Sealed {
10 fn index_into<'v>(&self, v: &'v Edn) -> Option<&'v Edn>;
11
12 fn index_into_mut<'v>(&self, v: &'v mut Edn) -> Option<&'v mut Edn>;
13
14 fn index_or_insert<'v>(&self, v: &'v mut Edn) -> &'v mut Edn;
15}
16
17impl Index for usize {
18 fn index_into<'v>(&self, v: &'v Edn) -> Option<&'v Edn> {
19 return match *v {
20 Edn::Vector(ref vec) => vec.0.get(*self),
21 Edn::List(ref vec) => vec.0.get(*self),
22 Edn::Map(ref map) => map.0.get(&self.to_string()),
23 _ => None,
24 };
25 }
26 fn index_into_mut<'v>(&self, v: &'v mut Edn) -> Option<&'v mut Edn> {
27 return match *v {
28 Edn::Vector(ref mut vec) => vec.0.get_mut(*self),
29 Edn::List(ref mut vec) => vec.0.get_mut(*self),
30 Edn::Map(ref mut map) => map.0.get_mut(&self.to_string()),
31 _ => None,
32 };
33 }
34 fn index_or_insert<'v>(&self, v: &'v mut Edn) -> &'v mut Edn {
35 match *v {
36 Edn::Vector(ref mut vec) => {
37 let len = vec.0.len();
38 vec.0.get_mut(*self).unwrap_or_else(|| {
39 panic!("cannot access index {self} of EDN array of length {len}")
40 })
41 }
42 _ => panic!("cannot access index {} of EDN {}", self, Type(v)),
43 }
44 }
45}
46
47impl Index for str {
48 fn index_into<'v>(&self, v: &'v Edn) -> Option<&'v Edn> {
49 match *v {
50 Edn::Map(ref map) => map.0.get(self),
51 _ => None,
52 }
53 }
54 fn index_into_mut<'v>(&self, v: &'v mut Edn) -> Option<&'v mut Edn> {
55 match *v {
56 Edn::Map(ref mut map) => map.0.get_mut(self),
57 _ => None,
58 }
59 }
60 fn index_or_insert<'v>(&self, v: &'v mut Edn) -> &'v mut Edn {
61 if *v == Edn::Nil {
62 *v = Edn::Map(Map::new(alloc::collections::BTreeMap::new()));
63 }
64 match *v {
65 Edn::Map(ref mut map) => map.0.entry(self.to_owned()).or_insert(Edn::Nil),
66 _ => panic!("cannot access key {:?} in EDN {}", self, Type(v)),
67 }
68 }
69}
70
71impl Index for String {
72 fn index_into<'v>(&self, v: &'v Edn) -> Option<&'v Edn> {
73 self[..].index_into(v)
74 }
75 fn index_into_mut<'v>(&self, v: &'v mut Edn) -> Option<&'v mut Edn> {
76 self[..].index_into_mut(v)
77 }
78 fn index_or_insert<'v>(&self, v: &'v mut Edn) -> &'v mut Edn {
79 self[..].index_or_insert(v)
80 }
81}
82
83impl Index for Edn {
84 fn index_into<'v>(&self, v: &'v Edn) -> Option<&'v Edn> {
85 let key = self.to_string();
86 let index = self.to_uint();
87
88 match (v, index) {
89 (Self::Map(ref map), _) => map.0.get(&key),
90 (Self::List(_) | Self::Vector(_), Some(idx)) => {
91 let idx = usize::try_from(idx).unwrap();
93 idx.index_into(v)
94 }
95 _ => None,
96 }
97 }
98 fn index_into_mut<'v>(&self, _: &'v mut Edn) -> Option<&'v mut Edn> {
99 panic!("index_into_mut not implemented for edn")
100 }
101 fn index_or_insert<'v>(&self, _: &'v mut Edn) -> &'v mut Edn {
102 panic!("index_or_insert not implemented for edn")
103 }
104}
105
106impl<'a, T> Index for &'a T
107where
108 T: ?Sized + Index,
109{
110 fn index_into<'v>(&self, v: &'v Edn) -> Option<&'v Edn> {
111 (**self).index_into(v)
112 }
113 fn index_into_mut<'v>(&self, v: &'v mut Edn) -> Option<&'v mut Edn> {
114 (**self).index_into_mut(v)
115 }
116 fn index_or_insert<'v>(&self, v: &'v mut Edn) -> &'v mut Edn {
117 (**self).index_or_insert(v)
118 }
119}
120
121mod private {
123 use alloc::string::String;
124
125 use crate::Edn;
126
127 pub trait Sealed {}
128 impl Sealed for usize {}
129 impl Sealed for str {}
130 impl Sealed for String {}
131 impl Sealed for Edn {}
132 impl<'a, T> Sealed for &'a T where T: ?Sized + Sealed {}
133}
134struct Type<'a>(&'a Edn);
135
136impl<'a> fmt::Display for Type<'a> {
137 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
138 match *self.0 {
139 Edn::Empty => formatter.write_str("empty"),
140 Edn::Nil => formatter.write_str("null"),
141 Edn::Bool(_) => formatter.write_str("boolean"),
142 Edn::Int(_) | Edn::UInt(_) => formatter.write_str("integer"),
143 Edn::Str(_) => formatter.write_str("string"),
144 Edn::Vector(_) => formatter.write_str("vector"),
145 #[cfg(feature = "sets")]
146 Edn::Set(_) => formatter.write_str("set"),
147 Edn::List(_) => formatter.write_str("list"),
148 Edn::Map(_) => formatter.write_str("map"),
149 Edn::Key(_) => formatter.write_str("key"),
150 Edn::Char(_) => formatter.write_str("char"),
151 Edn::Symbol(_) => formatter.write_str("symbol"),
152 Edn::Double(_) => formatter.write_str("double"),
153 Edn::Rational(_) => formatter.write_str("rational"),
154 Edn::Tagged(_, _) => formatter.write_str("tagged-element"),
155 }
156 }
157}
158
159impl<I> ops::Index<I> for Edn
160where
161 I: Index,
162{
163 type Output = Self;
164 fn index(&self, index: I) -> &Self {
165 static NULL: Edn = Edn::Nil;
166 index.index_into(self).unwrap_or(&NULL)
167 }
168}
169
170impl<I> ops::IndexMut<I> for Edn
171where
172 I: Index,
173{
174 fn index_mut(&mut self, index: I) -> &mut Self {
175 index.index_or_insert(self)
176 }
177}