1use crate::{
2 util::{private::Sealed, reborrow::DormantMutRef},
3 JsonValueMutTrait, JsonValueTrait, PointerNode, Value,
4};
5
6impl<I> std::ops::Index<I> for Value
7where
8 I: Index,
9{
10 type Output = Value;
11
12 #[inline]
41 fn index(&self, index: I) -> &Value {
42 static NULL: Value = Value::new();
43 index.value_index_into(self).unwrap_or(&NULL)
44 }
45}
46
47impl<I: Index> std::ops::IndexMut<I> for Value {
48 #[inline]
93 fn index_mut(&mut self, index: I) -> &mut Value {
94 index.index_or_insert(self)
95 }
96}
97
98pub trait Index: Sealed {
100 #[doc(hidden)]
102 fn value_index_into<'v>(&self, v: &'v Value) -> Option<&'v Value>;
103
104 #[doc(hidden)]
106 fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value>;
107
108 #[doc(hidden)]
113 fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value;
114
115 #[doc(hidden)]
116 fn as_key(&self) -> Option<&str> {
117 None
118 }
119
120 #[doc(hidden)]
121 fn as_index(&self) -> Option<usize> {
122 None
123 }
124}
125
126impl Index for usize {
127 fn value_index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
128 if !v.is_array() {
129 return None;
130 }
131 v.get_index(*self)
132 }
133
134 fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
135 if !v.is_array() {
136 return None;
137 }
138 v.get_index_mut(*self)
139 }
140
141 fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value {
142 let typ = v.get_type();
143 let len = v.len();
144 v.as_array_mut()
145 .unwrap_or_else(|| panic!("cannot access index in non-array value type {typ:?}"))
146 .0
147 .get_index_mut(*self)
148 .unwrap_or_else(|| panic!("index {} out of bounds (len: {})", *self, len))
149 }
150
151 fn as_index(&self) -> Option<usize> {
152 Some(*self)
153 }
154}
155
156macro_rules! impl_str_index {
157 ($($t: ty),*) => {
158 $(
159 impl Index for &$t {
160 #[inline]
161 fn value_index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
162 if !v.is_object() {
163 return None;
164 }
165 v.get_key(*self)
166 }
167
168 #[inline]
169 fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
170 if !v.is_object() {
171 return None;
172 }
173 v.get_key_mut(*self)
174 }
175
176 #[inline]
177 fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value {
178 if v.is_null() {
179 *v = Value::new_object_with(8);
180 }
181
182 let typ = v.get_type();
183 let (obj, mut dormant_obj) = DormantMutRef::new(v);
184 obj.as_object_mut()
185 .expect(&format!("cannot access key in non-object value {:?}", typ))
186 .0
187 .get_key_mut(*self).unwrap_or_else(|| {
188 let o = unsafe { dormant_obj.reborrow() };
189 let inserted = o.insert(&self, Value::new_null());
190 inserted
191 })
192 }
193
194 #[inline]
195 fn as_key(&self) -> Option<&str> {
196 Some(self.as_ref())
197 }
198 }
199 )*
200 };
201}
202
203impl_str_index!(str, String, faststr::FastStr);
204
205impl Index for PointerNode {
206 #[inline]
207 fn value_index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
208 match self {
209 PointerNode::Index(i) => i.value_index_into(v),
210 PointerNode::Key(k) => k.value_index_into(v),
211 }
212 }
213
214 #[inline]
215 fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
216 match self {
217 PointerNode::Index(i) => i.index_into_mut(v),
218 PointerNode::Key(k) => k.index_into_mut(v),
219 }
220 }
221
222 #[inline]
223 fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value {
224 match self {
225 PointerNode::Index(i) => i.index_or_insert(v),
226 PointerNode::Key(k) => k.index_or_insert(v),
227 }
228 }
229
230 #[inline]
231 fn as_index(&self) -> Option<usize> {
232 match self {
233 PointerNode::Index(i) => Some(*i),
234 PointerNode::Key(_) => None,
235 }
236 }
237
238 #[inline]
239 fn as_key(&self) -> Option<&str> {
240 match self {
241 PointerNode::Index(_) => None,
242 PointerNode::Key(k) => Some(k.as_ref()),
243 }
244 }
245}
246
247impl<T> Index for &T
248where
249 T: ?Sized + Index,
250{
251 #[inline]
252 fn value_index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
253 (**self).value_index_into(v)
254 }
255
256 #[inline]
257 fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
258 (**self).index_into_mut(v)
259 }
260
261 #[inline]
262 fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value {
263 (**self).index_or_insert(v)
264 }
265
266 #[inline]
267 fn as_index(&self) -> Option<usize> {
268 (**self).as_index()
269 }
270
271 #[inline]
272 fn as_key(&self) -> Option<&str> {
273 (**self).as_key()
274 }
275}