serde_yaml/value/
index.rs1use crate::mapping::Entry;
2use crate::{
3 mapping,
4 private,
5 Mapping,
6 Value,
7};
8use std::fmt::{
9 self,
10 Debug,
11};
12use std::ops;
13
14pub trait Index: private::Sealed {
20 #[doc(hidden)]
22 fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value>;
23
24 #[doc(hidden)]
26 fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value>;
27
28 #[doc(hidden)]
33 fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value;
34}
35
36impl Index for usize {
37 fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
38 match v.untag_ref() {
39 Value::Sequence(vec) => vec.get(*self),
40 Value::Mapping(vec) => vec.get(Value::Number((*self).into())),
41 _ => None,
42 }
43 }
44 fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
45 match v.untag_mut() {
46 Value::Sequence(vec) => vec.get_mut(*self),
47 Value::Mapping(vec) => vec.get_mut(Value::Number((*self).into())),
48 _ => None,
49 }
50 }
51 fn index_or_insert<'v>(&self, mut v: &'v mut Value) -> &'v mut Value {
52 loop {
53 match v {
54 Value::Sequence(vec) => {
55 let len = vec.len();
56 return vec
57 .get_mut(*self)
58 .unwrap_or_else(|| panic!("cannot access index {} of YAML sequence of length {}", self, len));
59 },
60 Value::Mapping(map) => {
61 let n = Value::Number((*self).into());
62 return map.entry(n).or_insert(Value::Null);
63 },
64 Value::Tagged(tagged) => v = &mut tagged.value,
65 _ => panic!("cannot access index {} of YAML {}", self, Type(v)),
66 }
67 }
68 }
69}
70
71fn index_into_mapping<'v, I>(index: &I, v: &'v Value) -> Option<&'v Value>
72where
73 I: ?Sized + mapping::Index,
74{
75 match v.untag_ref() {
76 Value::Mapping(map) => map.get(index),
77 _ => None,
78 }
79}
80
81fn index_into_mut_mapping<'v, I>(index: &I, v: &'v mut Value) -> Option<&'v mut Value>
82where
83 I: ?Sized + mapping::Index,
84{
85 match v.untag_mut() {
86 Value::Mapping(map) => map.get_mut(index),
87 _ => None,
88 }
89}
90
91fn index_or_insert_mapping<'v, I>(index: &I, mut v: &'v mut Value) -> &'v mut Value
92where
93 I: ?Sized + mapping::Index + ToOwned + Debug,
94 Value: From<I::Owned>,
95{
96 if let Value::Null = *v {
97 *v = Value::Mapping(Mapping::new());
98 return match v {
99 Value::Mapping(map) => match map.entry(index.to_owned().into()) {
100 Entry::Vacant(entry) => entry.insert(Value::Null),
101 Entry::Occupied(_) => unreachable!(),
102 },
103 _ => unreachable!(),
104 };
105 }
106 loop {
107 match v {
108 Value::Mapping(map) => {
109 return map.entry(index.to_owned().into()).or_insert(Value::Null);
110 },
111 Value::Tagged(tagged) => v = &mut tagged.value,
112 _ => panic!("cannot access key {:?} in YAML {}", index, Type(v)),
113 }
114 }
115}
116
117impl Index for Value {
118 fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
119 index_into_mapping(self, v)
120 }
121 fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
122 index_into_mut_mapping(self, v)
123 }
124 fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value {
125 index_or_insert_mapping(self, v)
126 }
127}
128
129impl Index for str {
130 fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
131 index_into_mapping(self, v)
132 }
133 fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
134 index_into_mut_mapping(self, v)
135 }
136 fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value {
137 index_or_insert_mapping(self, v)
138 }
139}
140
141impl Index for String {
142 fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
143 self.as_str().index_into(v)
144 }
145 fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
146 self.as_str().index_into_mut(v)
147 }
148 fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value {
149 self.as_str().index_or_insert(v)
150 }
151}
152
153impl<T> Index for &T
154where
155 T: ?Sized + Index,
156{
157 fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
158 (**self).index_into(v)
159 }
160 fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
161 (**self).index_into_mut(v)
162 }
163 fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value {
164 (**self).index_or_insert(v)
165 }
166}
167
168struct Type<'a>(&'a Value);
170
171impl fmt::Display for Type<'_> {
172 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
173 match self.0 {
174 Value::Null => formatter.write_str("null"),
175 Value::Bool(_) => formatter.write_str("boolean"),
176 Value::Number(_) => formatter.write_str("number"),
177 Value::String(_) => formatter.write_str("string"),
178 Value::Sequence(_) => formatter.write_str("sequence"),
179 Value::Mapping(_) => formatter.write_str("mapping"),
180 Value::Tagged(_) => unreachable!(),
181 }
182 }
183}
184
185impl<I> ops::Index<I> for Value
205where
206 I: Index,
207{
208 type Output = Value;
209
210 fn index(&self, index: I) -> &Value {
238 static NULL: Value = Value::Null;
239 index.index_into(self).unwrap_or(&NULL)
240 }
241}
242
243impl<I> ops::IndexMut<I> for Value
244where
245 I: Index,
246{
247 fn index_mut(&mut self, index: I) -> &mut Value {
282 index.index_or_insert(self)
283 }
284}