generic_json/
value.rs

1use crate::{Json, JsonNew, ValueMut, ValueRef};
2use std::{
3	borrow::Cow,
4	cmp::Ordering,
5	fmt,
6	hash::{Hash, Hasher},
7	iter::{FromIterator, IntoIterator},
8};
9
10/// Any JSON value.
11pub enum Value<T: Json> {
12	/// JSON `null` value.
13	Null,
14
15	/// JSON boolean value (`true` or `false`).
16	Boolean(bool),
17
18	/// JSON number, wether integer of floating point.
19	Number(T::Number),
20
21	/// JSON string value.
22	String(T::String),
23
24	/// JSON array of values.
25	Array(T::Array),
26
27	/// JSON object.
28	Object(T::Object),
29}
30
31impl<T: Json> Value<T> {
32	/// Returns `true` if the value is a `Null`. Returns `false` otherwise.
33	pub fn is_null(&self) -> bool {
34		matches!(self, Self::Null)
35	}
36
37	/// Returns `true` if the value is a boolean. Returns `false` otherwise.
38	///
39	/// For any value on which `is_bool` returns `true`,
40	/// [`as_bool`](Self::as_bool()) is guaranteed to return the boolean value.
41	pub fn is_bool(&self) -> bool {
42		matches!(self, Self::Boolean(_))
43	}
44
45	/// Returns `true` if the value is a number. Returns `false` otherwise.
46	///
47	/// For any value on which `is_number` returns `true`,
48	/// [`as_number`](Self::as_number()) is guaranteed to return the number value.
49	pub fn is_number(&self) -> bool {
50		matches!(self, Self::Number(_))
51	}
52
53	/// Returns `true` if the value is a string.
54	/// Returns `false` otherwise.
55	///
56	/// For any value on which `is_string` returns `true`,
57	/// [`as_str`](Self::as_str()) is guaranteed to return the string value.
58	pub fn is_string(&self) -> bool {
59		matches!(self, Self::String(_))
60	}
61
62	/// Returns `true` if the value is an array.
63	/// Returns `false` otherwise.
64	///
65	/// For any value on which `is_array` returns `true`,
66	/// [`as_array`](Self::as_array()) is guaranteed to return the array value.
67	pub fn is_array(&self) -> bool {
68		matches!(self, Self::Array(_))
69	}
70
71	/// Returns `true` if the value is an object.
72	/// Returns `false` otherwise.
73	///
74	/// For any value on which `is_object` returns `true`,
75	/// [`as_object`](Self::as_object()) is guaranteed to return the object value.
76	pub fn is_object(&self) -> bool {
77		matches!(self, Self::Object(_))
78	}
79
80	/// If the value is a boolean, returns the associated `bool`.
81	/// Returns `None` otherwise.
82	pub fn as_bool(&self) -> Option<bool> {
83		match self {
84			Self::Boolean(b) => Some(*b),
85			_ => None,
86		}
87	}
88
89	/// If the value is a number, returns a reference to it.
90	/// Returns `None` otherwise.
91	pub fn as_number(&self) -> Option<&T::Number> {
92		match self {
93			Self::Number(n) => Some(n),
94			_ => None,
95		}
96	}
97
98	/// If the value is a string, returns its associated [`str`].
99	/// Returns `None` otherwise.
100	pub fn as_str(&self) -> Option<&str> {
101		match self {
102			Self::String(s) => Some(s.as_ref()),
103			_ => None,
104		}
105	}
106
107	/// If the value is an array, returns a reference to it.
108	/// Returns `None` otherwise.
109	pub fn as_array(&self) -> Option<&T::Array> {
110		match self {
111			Self::Array(a) => Some(a),
112			_ => None,
113		}
114	}
115
116	/// If the value is an array, returns a mutable reference to it.
117	/// Returns `None` otherwise.
118	pub fn as_array_mut(&mut self) -> Option<&mut T::Array> {
119		match self {
120			Self::Array(a) => Some(a),
121			_ => None,
122		}
123	}
124
125	/// If the value is an object, returns a reference to it.
126	/// Returns `None` otherwise.
127	pub fn as_object(&self) -> Option<&T::Object> {
128		match self {
129			Self::Object(o) => Some(o),
130			_ => None,
131		}
132	}
133
134	/// If the value is an object, returns a mutable reference to it.
135	/// Returns `None` otherwise.
136	pub fn as_object_mut(&mut self) -> Option<&mut T::Object> {
137		match self {
138			Self::Object(o) => Some(o),
139			_ => None,
140		}
141	}
142
143	pub fn as_value_ref(&self) -> ValueRef<T> {
144		match self {
145			Self::Null => ValueRef::Null,
146			Self::Boolean(b) => ValueRef::Boolean(*b),
147			Self::Number(n) => ValueRef::Number(n),
148			Self::String(s) => ValueRef::String(s),
149			Self::Array(a) => ValueRef::Array(a),
150			Self::Object(o) => ValueRef::Object(o),
151		}
152	}
153
154	pub fn as_value_mut(&mut self) -> ValueMut<T> {
155		match self {
156			Self::Null => ValueMut::Null,
157			Self::Boolean(b) => ValueMut::Boolean(*b),
158			Self::Number(n) => ValueMut::Number(n),
159			Self::String(s) => ValueMut::String(s),
160			Self::Array(a) => ValueMut::Array(a),
161			Self::Object(o) => ValueMut::Object(o),
162		}
163	}
164
165	/// Takes the value out of the Value, leaving a Null in its place.
166	pub fn take(&mut self) -> Self {
167		let mut value = Self::Null;
168		std::mem::swap(&mut value, self);
169		value
170	}
171}
172
173impl<T: JsonNew> Value<T>
174where
175	// the where bound is necessary until https://github.com/rust-lang/rust/issues/20671 is fixed.
176	T::String: for<'a> From<&'a str>,
177{
178	pub fn with(self, meta: T::MetaData) -> T {
179		T::new(self, meta)
180	}
181
182	pub fn with_default(self) -> T
183	where
184		T::MetaData: Default,
185	{
186		T::new(self, T::MetaData::default())
187	}
188}
189
190impl<T: Json> fmt::Debug for Value<T>
191where
192	T::Number: fmt::Debug,
193	T::String: fmt::Debug,
194	T::Array: fmt::Debug,
195	T::Object: fmt::Debug,
196{
197	fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
198		match *self {
199			Value::Null => formatter.debug_tuple("Null").finish(),
200			Value::Boolean(v) => formatter.debug_tuple("Boolean").field(&v).finish(),
201			Value::Number(ref v) => fmt::Debug::fmt(v, formatter),
202			Value::String(ref v) => formatter.debug_tuple("String").field(v).finish(),
203			Value::Array(ref v) => {
204				formatter.write_str("Array(")?;
205				fmt::Debug::fmt(v, formatter)?;
206				formatter.write_str(")")
207			}
208			Value::Object(ref v) => {
209				formatter.write_str("Object(")?;
210				fmt::Debug::fmt(v, formatter)?;
211				formatter.write_str(")")
212			}
213		}
214	}
215}
216
217impl<T: Json> Default for Value<T> {
218	/// The default value is [`Value::Null`].
219	fn default() -> Self {
220		Self::Null
221	}
222}
223
224impl<T: Json> Clone for Value<T>
225where
226	T::Number: Clone,
227	T::String: Clone,
228	T::Array: Clone,
229	T::Object: Clone,
230{
231	fn clone(&self) -> Self {
232		match self {
233			Self::Null => Self::Null,
234			Self::Boolean(b) => Self::Boolean(*b),
235			Self::Number(n) => Self::Number(n.clone()),
236			Self::String(s) => Self::String(s.clone()),
237			Self::Array(a) => Self::Array(a.clone()),
238			Self::Object(o) => Self::Object(o.clone()),
239		}
240	}
241}
242
243impl<T: Json, U: Json> PartialEq<Value<U>> for Value<T>
244where
245	T::Number: PartialEq<U::Number>,
246	T::String: PartialEq<U::String>,
247	T::Array: PartialEq<U::Array>,
248	T::Object: PartialEq<U::Object>,
249{
250	fn eq(&self, other: &Value<U>) -> bool {
251		match (self, other) {
252			(Self::Null, Value::Null) => true,
253			(Self::Boolean(a), Value::Boolean(b)) => a == b,
254			(Self::Number(a), Value::Number(b)) => a == b,
255			(Self::String(a), Value::String(b)) => a == b,
256			(Self::Array(a), Value::Array(b)) => a == b,
257			(Self::Object(a), Value::Object(b)) => a == b,
258			_ => false,
259		}
260	}
261}
262
263impl<T: Json> Eq for Value<T>
264where
265	T::Number: Eq,
266	T::String: Eq,
267	T::Array: Eq,
268	T::Object: Eq,
269{
270}
271
272impl<'a, T: Json> PartialEq<&'a str> for Value<T> {
273	fn eq(&self, other: &&'a str) -> bool {
274		match self {
275			Self::String(s) => &**s == *other,
276			_ => false,
277		}
278	}
279}
280
281impl<'a, T: Json> PartialEq<String> for Value<T> {
282	fn eq(&self, other: &String) -> bool {
283		match self {
284			Self::String(s) => s.as_ref() == *other,
285			_ => false,
286		}
287	}
288}
289
290impl<T: Json> PartialEq<bool> for Value<T> {
291	fn eq(&self, other: &bool) -> bool {
292		match self {
293			Self::Boolean(b) => b == other,
294			_ => false,
295		}
296	}
297}
298
299impl<T: Json> Hash for Value<T>
300where
301	T::Number: Hash,
302	T::String: Hash,
303	T::Array: Hash,
304	T::Object: Hash,
305{
306	fn hash<H: Hasher>(&self, h: &mut H) {
307		match self {
308			Self::Null => (),
309			Self::Boolean(b) => b.hash(h),
310			Self::Number(n) => n.hash(h),
311			Self::String(s) => s.hash(h),
312			Self::Array(a) => a.hash(h),
313			Self::Object(o) => o.hash(h),
314		}
315	}
316}
317
318impl<T: Json, U: Json> PartialOrd<Value<U>> for Value<T>
319where
320	T::Number: PartialOrd<U::Number>,
321	T::String: PartialOrd<U::String>,
322	T::Array: PartialOrd<U::Array>,
323	T::Object: PartialOrd<U::Object>,
324{
325	fn partial_cmp(&self, other: &Value<U>) -> Option<Ordering> {
326		match (self, other) {
327			(Self::Null, Value::Null) => Some(Ordering::Equal),
328			(Self::Null, _) => Some(Ordering::Less),
329			(Self::Boolean(_), Value::Null) => Some(Ordering::Greater),
330			(Self::Boolean(a), Value::Boolean(b)) => a.partial_cmp(b),
331			(Self::Boolean(_), _) => Some(Ordering::Less),
332			(Self::Number(_), Value::Null | Value::Boolean(_)) => Some(Ordering::Greater),
333			(Self::Number(a), Value::Number(b)) => a.partial_cmp(b),
334			(Self::Number(_), _) => Some(Ordering::Less),
335			(Self::String(_), Value::Null | Value::Boolean(_) | Value::Number(_)) => {
336				Some(Ordering::Greater)
337			}
338			(Self::String(a), Value::String(b)) => a.partial_cmp(b),
339			(Self::String(_), _) => Some(Ordering::Less),
340			(
341				Self::Array(_),
342				Value::Null | Value::Boolean(_) | Value::Number(_) | Value::String(_),
343			) => Some(Ordering::Greater),
344			(Self::Array(a), Value::Array(b)) => a.partial_cmp(b),
345			(Self::Array(_), _) => Some(Ordering::Less),
346			(Self::Object(a), Value::Object(b)) => a.partial_cmp(b),
347			(Self::Object(_), _) => Some(Ordering::Greater),
348		}
349	}
350}
351
352impl<T: Json> From<()> for Value<T> {
353	fn from(_: ()) -> Self {
354		Self::Null
355	}
356}
357
358impl<T: Json> From<bool> for Value<T> {
359	fn from(b: bool) -> Self {
360		Self::Boolean(b)
361	}
362}
363
364macro_rules! number_impls {
365	($($ty:ty),*) => {
366		$(
367			impl<T: Json> From<$ty> for Value<T> where T::Number: From<$ty> {
368				fn from(n: $ty) -> Self {
369					Self::Number(n.into())
370				}
371			}
372
373			impl<T: Json> PartialEq<$ty> for Value<T> where T::Number: PartialEq<$ty> {
374				fn eq(&self, other: &$ty) -> bool {
375					match self {
376						Self::Number(n) => n == other,
377						_ => false
378					}
379				}
380			}
381
382			impl<'a, T: Json> PartialEq<$ty> for &'a Value<T> where T::Number: PartialEq<$ty> {
383				fn eq(&self, other: &$ty) -> bool {
384					match self {
385						Value::Number(n) => n == other,
386						_ => false
387					}
388				}
389			}
390
391			impl<'a, T: Json> PartialEq<$ty> for &'a mut Value<T> where T::Number: PartialEq<$ty> {
392				fn eq(&self, other: &$ty) -> bool {
393					match self {
394						Value::Number(n) => n == other,
395						_ => false
396					}
397				}
398			}
399
400			impl<T: Json> PartialEq<Value<T>> for $ty where $ty: PartialEq<T::Number> {
401				fn eq(&self, other: &Value<T>) -> bool {
402					match other {
403						Value::Number(n) => self == n,
404						_ => false
405					}
406				}
407			}
408		)*
409	};
410}
411
412number_impls!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize, f32, f64);
413
414impl<'a, T: Json> From<&'a str> for Value<T>
415where
416	T::String: From<&'a str>,
417{
418	fn from(s: &'a str) -> Self {
419		Self::String(s.into())
420	}
421}
422
423impl<T: Json> From<String> for Value<T>
424where
425	T::String: From<String>,
426{
427	fn from(s: String) -> Self {
428		Self::String(s.into())
429	}
430}
431
432impl<'a, T: Json> From<Cow<'a, str>> for Value<T>
433where
434	T::String: From<Cow<'a, str>>,
435{
436	fn from(s: Cow<'a, str>) -> Self {
437		Self::String(s.into())
438	}
439}
440
441impl<'a, T: Json> From<&'a [Value<T>]> for Value<T>
442where
443	T::Array: From<&'a [Value<T>]>,
444{
445	fn from(a: &'a [Value<T>]) -> Self {
446		Self::Array(a.into())
447	}
448}
449
450impl<T: Json> From<Vec<Value<T>>> for Value<T>
451where
452	T::Array: From<Vec<Value<T>>>,
453{
454	fn from(a: Vec<Value<T>>) -> Self {
455		Self::Array(a.into())
456	}
457}
458
459impl<T: Json, V: Into<Self>> FromIterator<V> for Value<T>
460where
461	T::Array: FromIterator<Self>,
462{
463	fn from_iter<I: IntoIterator<Item = V>>(iter: I) -> Self {
464		Self::Array(T::Array::from_iter(iter.into_iter().map(Into::into)))
465	}
466}