1use crate::map::{Map, MapKey};
2use crate::value::{Kind, Value};
3
4mod sealed {
5 pub trait Sealed {}
6}
7
8pub trait ValueIndex: sealed::Sealed {
23 #[doc(hidden)]
24 fn index_into<'v>(&self, value: &'v Kind) -> Option<&'v Value>;
25
26 #[doc(hidden)]
27 fn index_into_mut<'v>(&self, value: &'v mut Kind) -> Option<&'v mut Value>;
28
29 #[doc(hidden)]
30 fn index_or_insert<'v>(&self, value: &'v mut Value) -> &'v mut Value;
31}
32
33impl sealed::Sealed for usize {}
34
35impl ValueIndex for usize {
36 fn index_into<'v>(&self, value: &'v Kind) -> Option<&'v Value> {
37 match value {
38 Kind::Seq(seq) => seq.get(*self),
39 _ => None,
40 }
41 }
42
43 fn index_into_mut<'v>(&self, value: &'v mut Kind) -> Option<&'v mut Value> {
44 match value {
45 Kind::Seq(seq) => seq.get_mut(*self),
46 _ => None,
47 }
48 }
49
50 fn index_or_insert<'v>(&self, value: &'v mut Value) -> &'v mut Value {
51 match &mut value.kind {
52 Kind::Seq(seq) => {
53 let len = seq.len();
54 seq.get_mut(*self).unwrap_or_else(|| {
55 panic!(
56 "index {} out of bounds for sequence of length {}",
57 self, len
58 )
59 })
60 }
61 other => panic!("cannot index into {} with an integer", other.name()),
62 }
63 }
64}
65
66fn index_or_insert_key<'v, K: MapKey + ?Sized>(
68 key: &K,
69 make_key: impl FnOnce() -> Value,
70 value: &'v mut Value,
71) -> &'v mut Value {
72 if let Kind::Null = value.kind {
73 value.kind = Kind::Map(Map::new());
74 }
75 match &mut value.kind {
76 Kind::Map(map) => {
77 if let Some(index) = map.get_index_of(key) {
78 map.get_index_mut(index).unwrap().1
79 } else {
80 map.get_or_insert_with(make_key(), Value::null)
81 }
82 }
83 other => panic!("cannot index into {} with a key", other.name()),
84 }
85}
86
87impl sealed::Sealed for str {}
88
89impl ValueIndex for str {
90 fn index_into<'v>(&self, value: &'v Kind) -> Option<&'v Value> {
91 value.as_map().and_then(|map| map.get(self))
92 }
93
94 fn index_into_mut<'v>(&self, value: &'v mut Kind) -> Option<&'v mut Value> {
95 value.as_map_mut().and_then(|map| map.get_mut(self))
96 }
97
98 fn index_or_insert<'v>(&self, value: &'v mut Value) -> &'v mut Value {
99 index_or_insert_key(self, || Value::from(self), value)
100 }
101}
102
103impl sealed::Sealed for String {}
104
105impl ValueIndex for String {
106 fn index_into<'v>(&self, value: &'v Kind) -> Option<&'v Value> {
107 self.as_str().index_into(value)
108 }
109
110 fn index_into_mut<'v>(&self, value: &'v mut Kind) -> Option<&'v mut Value> {
111 self.as_str().index_into_mut(value)
112 }
113
114 fn index_or_insert<'v>(&self, value: &'v mut Value) -> &'v mut Value {
115 self.as_str().index_or_insert(value)
116 }
117}
118
119impl sealed::Sealed for Value {}
120
121impl ValueIndex for Value {
122 fn index_into<'v>(&self, value: &'v Kind) -> Option<&'v Value> {
123 value.as_map().and_then(|map| map.get(self))
124 }
125
126 fn index_into_mut<'v>(&self, value: &'v mut Kind) -> Option<&'v mut Value> {
127 value.as_map_mut().and_then(|map| map.get_mut(self))
128 }
129
130 fn index_or_insert<'v>(&self, value: &'v mut Value) -> &'v mut Value {
131 index_or_insert_key(self, || self.clone(), value)
132 }
133}
134
135impl<T: ValueIndex + ?Sized> sealed::Sealed for &T {}
136
137impl<T: ValueIndex + ?Sized> ValueIndex for &T {
138 fn index_into<'v>(&self, value: &'v Kind) -> Option<&'v Value> {
139 (**self).index_into(value)
140 }
141
142 fn index_into_mut<'v>(&self, value: &'v mut Kind) -> Option<&'v mut Value> {
143 (**self).index_into_mut(value)
144 }
145
146 fn index_or_insert<'v>(&self, value: &'v mut Value) -> &'v mut Value {
147 (**self).index_or_insert(value)
148 }
149}