generic_json/
reference.rs

1use crate::{Json, Number, Value};
2
3/// JSON value reference.
4pub enum ValueRef<'a, T: Json> {
5	Null,
6	Boolean(bool),
7	Number(&'a T::Number),
8	String(&'a T::String),
9	Array(&'a T::Array),
10	Object(&'a T::Object),
11}
12
13/// Mutable JSON value reference.
14pub enum ValueMut<'a, T: Json> {
15	Null,
16	Boolean(bool),
17	Number(&'a mut T::Number),
18	String(&'a mut T::String),
19	Array(&'a mut T::Array),
20	Object(&'a mut T::Object),
21}
22
23macro_rules! common_impls {
24	($($ty:ident),*) => {
25		$(
26			impl<'a, T: Json> $ty<'a, T> {
27				/// Returns `true` if the value is a `Null`. Returns `false` otherwise.
28				pub fn is_null(&self) -> bool {
29					matches!(self, Self::Null)
30				}
31
32				/// Returns `true` if the value is a boolean. Returns `false` otherwise.
33				///
34				/// For any value on which `is_boolean` returns `true`,
35				/// [`as_bool`](Self::as_bool()) is guaranteed to return the boolean value.
36				pub fn is_bool(&self) -> bool {
37					matches!(self, Self::Boolean(_))
38				}
39
40				/// Returns `true` if the value is a number. Returns `false` otherwise.
41				///
42				/// For any value on which `is_number` returns `true`,
43				/// [`as_number`](Self::as_number()) is guaranteed to return the number value.
44				pub fn is_number(&self) -> bool {
45					matches!(self, Self::Number(_))
46				}
47
48                /// Returns this number as an `u32` if it can be exactly represented as such.
49                pub fn as_u32(&self) -> Option<u32> {
50                    self.as_number().map(Number::as_u32).flatten()
51                }
52
53                /// Returns this number as an `u64` if it can be exactly represented as such.
54                pub fn as_u64(&self) -> Option<u64> {
55                    self.as_number().map(Number::as_u64).flatten()
56                }
57
58                /// Returns this number as an `i32` if it can be exactly represented as such.
59                pub fn as_i32(&self) -> Option<i32> {
60                    self.as_number().map(Number::as_i32).flatten()
61                }
62
63                /// Returns this number as an `i64` if it can be exactly represented as such.
64                pub fn as_i64(&self) -> Option<i64> {
65                    self.as_number().map(Number::as_i64).flatten()
66                }
67
68                /// Returns this number as an `f32` if it can be exactly represented as such.
69                pub fn as_f32(&self) -> Option<f32> {
70                    self.as_number().map(Number::as_f32).flatten()
71                }
72
73                /// Returns this number as an `f32` if it is a number, potentially losing precision in the process.
74                pub fn as_f32_lossy(&self) -> Option<f32> {
75                    self.as_number().map(Number::as_f32_lossy)
76                }
77
78                /// Returns this number as an `f64` if it can be exactly represented as such.
79                pub fn as_f64(&self) -> Option<f64> {
80                    self.as_number().map(Number::as_f64).flatten()
81                }
82
83                /// Returns this number as an `f64` if it is a number, potentially losing precision in the process.
84                pub fn as_f64_lossy(&self) -> Option<f64> {
85                    self.as_number().map(Number::as_f64_lossy)
86                }
87
88				/// Returns `true` if the value is a string.
89				/// Returns `false` otherwise.
90				///
91				/// For any value on which `is_string` returns `true`,
92				/// [`as_str`](Self::as_str()) is guaranteed to return the string value.
93				pub fn is_string(&self) -> bool {
94					matches!(self, Self::String(_))
95				}
96
97				/// Returns `true` if the value is an array.
98				/// Returns `false` otherwise.
99				///
100				/// For any value on which `is_array` returns `true`,
101				/// [`as_array`](Self::as_array()) is guaranteed to return the array value.
102				pub fn is_array(&self) -> bool {
103					matches!(self, Self::Array(_))
104				}
105
106				/// Returns `true` if the value is an object.
107				/// Returns `false` otherwise.
108				///
109				/// For any value on which `is_object` returns `true`,
110				/// [`as_object`](Self::as_object()) is guaranteed to return the object value.
111				pub fn is_object(&self) -> bool {
112					matches!(self, Self::Object(_))
113				}
114			}
115		)*
116	};
117}
118
119common_impls!(ValueRef, ValueMut);
120
121impl<'a, T: Json> ValueRef<'a, T> {
122	/// If the value is a boolean, returns the associated `bool`.
123	/// Returns `None` otherwise.
124	pub fn as_bool(&self) -> Option<bool> {
125		match self {
126			Self::Boolean(b) => Some(*b),
127			_ => None,
128		}
129	}
130
131	/// If the value is a number, returns a reference to it.
132	/// Returns `None` otherwise.
133	pub fn as_number(&self) -> Option<&'a T::Number> {
134		match self {
135			Self::Number(n) => Some(n),
136			_ => None,
137		}
138	}
139
140	/// If the value is a string, returns a reference to it.
141	/// Returns `None` otherwise.
142	pub fn as_string(&self) -> Option<&'a T::String> {
143		match self {
144			Self::String(s) => Some(s),
145			_ => None,
146		}
147	}
148
149	/// If the value is a string, returns its associated [`str`].
150	/// Returns `None` otherwise.
151	pub fn as_str(&self) -> Option<&str> {
152		match self {
153			Self::String(s) => Some(s.as_ref()),
154			_ => None,
155		}
156	}
157
158	/// If the value is a string, returns its associated [`str`].
159	/// Returns `None` otherwise.
160	pub fn into_str(self) -> Option<&'a str> {
161		match self {
162			Self::String(s) => Some(s.as_ref()),
163			_ => None,
164		}
165	}
166
167	/// If the value is an array, returns a reference to it.
168	/// Returns `None` otherwise.
169	pub fn as_array(&self) -> Option<&'a T::Array> {
170		match self {
171			Self::Array(a) => Some(a),
172			_ => None,
173		}
174	}
175
176	/// If the value is an object, returns a reference to it.
177	/// Returns `None` otherwise.
178	pub fn as_object(&self) -> Option<&'a T::Object> {
179		match self {
180			Self::Object(o) => Some(o),
181			_ => None,
182		}
183	}
184
185	/// Creates a new value by cloning the referenced value.
186	pub fn cloned(&self) -> Value<T>
187	where
188		T::Number: Clone,
189		T::String: Clone,
190		T::Array: Clone,
191		T::Object: Clone,
192	{
193		match self {
194			Self::Null => Value::Null,
195			Self::Boolean(b) => Value::Boolean(*b),
196			Self::Number(n) => Value::Number((*n).clone()),
197			Self::String(s) => Value::String((*s).clone()),
198			Self::Array(a) => Value::Array((*a).clone()),
199			Self::Object(o) => Value::Object((*o).clone()),
200		}
201	}
202}
203
204impl<'a, T: Json> ValueMut<'a, T> {
205	/// If the value is a boolean, returns the associated `bool`.
206	/// Returns `None` otherwise.
207	pub fn as_bool(&self) -> Option<bool> {
208		match self {
209			Self::Boolean(b) => Some(*b),
210			_ => None,
211		}
212	}
213
214	/// If the value is a number, returns a reference to it.
215	/// Returns `None` otherwise.
216	pub fn as_number(&self) -> Option<&T::Number> {
217		match self {
218			Self::Number(n) => Some(n),
219			_ => None,
220		}
221	}
222
223	/// If the value is a number, returns a reference to it.
224	/// Returns `None` otherwise.
225	pub fn into_number(self) -> Option<&'a T::Number> {
226		match self {
227			Self::Number(n) => Some(n),
228			_ => None,
229		}
230	}
231
232	/// If the value is a string, returns its associated [`str`].
233	/// Returns `None` otherwise.
234	pub fn as_str(&self) -> Option<&str> {
235		match self {
236			Self::String(s) => Some(s.as_ref()),
237			_ => None,
238		}
239	}
240
241	/// If the value is an array, returns a reference to it.
242	/// Returns `None` otherwise.
243	pub fn as_array(&self) -> Option<&T::Array> {
244		match self {
245			Self::Array(a) => Some(a),
246			_ => None,
247		}
248	}
249
250	/// If the value is an array, returns a reference to it.
251	/// Returns `None` otherwise.
252	pub fn into_array(self) -> Option<&'a T::Array> {
253		match self {
254			Self::Array(a) => Some(a),
255			_ => None,
256		}
257	}
258
259	/// If the value is an object, returns a reference to it.
260	/// Returns `None` otherwise.
261	pub fn as_object(&self) -> Option<&T::Object> {
262		match self {
263			Self::Object(o) => Some(o),
264			_ => None,
265		}
266	}
267
268	/// If the value is an object, returns a reference to it.
269	/// Returns `None` otherwise.
270	pub fn into_object(self) -> Option<&'a T::Object> {
271		match self {
272			Self::Object(o) => Some(o),
273			_ => None,
274		}
275	}
276
277	/// If the value is an array, returns a mutable reference to it.
278	/// Returns `None` otherwise.
279	pub fn as_array_mut(&mut self) -> Option<&mut T::Array> {
280		match self {
281			Self::Array(a) => Some(a),
282			_ => None,
283		}
284	}
285
286	/// If the value is an array, returns a mutable reference to it.
287	/// Returns `None` otherwise.
288	pub fn into_array_mut(self) -> Option<&'a mut T::Array> {
289		match self {
290			Self::Array(a) => Some(a),
291			_ => None,
292		}
293	}
294
295	/// If the value is an object, returns a mutable reference to it.
296	/// Returns `None` otherwise.
297	pub fn as_object_mut(&mut self) -> Option<&mut T::Object> {
298		match self {
299			Self::Object(o) => Some(o),
300			_ => None,
301		}
302	}
303
304	/// If the value is an object, returns a mutable reference to it.
305	/// Returns `None` otherwise.
306	pub fn into_object_mut(self) -> Option<&'a mut T::Object> {
307		match self {
308			Self::Object(o) => Some(o),
309			_ => None,
310		}
311	}
312
313	/// Creates a new value by cloning the referenced value.
314	pub fn cloned(&self) -> Value<T>
315	where
316		T::Number: Clone,
317		T::String: Clone,
318		T::Array: Clone,
319		T::Object: Clone,
320	{
321		match self {
322			Self::Null => Value::Null,
323			Self::Boolean(b) => Value::Boolean(*b),
324			Self::Number(n) => Value::Number((*n).clone()),
325			Self::String(s) => Value::String((*s).clone()),
326			Self::Array(a) => Value::Array((*a).clone()),
327			Self::Object(o) => Value::Object((*o).clone()),
328		}
329	}
330}