generic_json/lib.rs
1//! JSON is an ubiquitous format used in many applications.
2//! There is no single way of storing JSON values depending on the context,
3//! sometimes leading some applications to use multiples representations of JSON values in the same place.
4//! This can cause a problem for JSON processing libraries that should not care about the actual internal representation of JSON values,
5//! but are forced to stick to a particular format,
6//! leading to unwanted and costly conversions between the different formats.
7//!
8//! This crate abstracts the JSON data structures defined in different library dealing with JSON such as `json`, `serde_json`, etc.
9//! The goal is to remove hard dependencies to these libraries when possible,
10//! and allow downstream users to choose its preferred library.
11//! It basically defines a trait `Json` and a `ValueRef` type abstracting away the implementation details.
12//!
13//! The `Json` trait must be implemented by the JSON value type
14//! and defines what opaque types are used to represent each component of a JSON value.
15//! It also provides a function returning the value as a `ValueRef` enum type.
16//! Its simplified definition is as follows:
17//! ```rust
18//! # pub struct ValueRef<'a, T>(std::marker::PhantomData<&'a T>);
19//! /// JSON model.
20//! pub trait Json: Sized + 'static {
21//! /// Literal number type.
22//! type Number;
23//!
24//! /// String type.
25//! type String;
26//!
27//! /// Array type.
28//! type Array;
29//!
30//! /// Object key type.
31//! type Key;
32//!
33//! /// Object type.
34//! type Object;
35//!
36//! /// Returns a reference to this value as a `ValueRef`.
37//! fn value(&self) -> ValueRef<'_, Self>;
38//!
39//! /// Metadata type attached to each value.
40//! type MetaData;
41//!
42//! fn metadata(&self) -> &Self::MetaData;
43//! }
44//! ```
45//!
46//! The `ValueRef` exposes the structure of a reference to a JSON value:
47//! ```rust
48//! # use generic_json::Json;
49//! pub enum ValueRef<'v, T: Json> {
50//! Null,
51//! Bool(bool),
52//! Number(&'v T::Number),
53//! String(&'v T::String),
54//! Array(&'v T::Array),
55//! Object(&'v T::Object)
56//! }
57//! ```
58//!
59//! In the same way, this crate also defines a `ValueMut` type for mutable references.
60//! This allows each implementor to have their own inner representation of values while allowing interoperability.
61//!
62//! ## Foreign implementations
63//!
64//! This library optionally provides implementations of the `Json` trait for
65//! the following foreign types, enabled by their associated feature.
66//!
67//! | Type | Feature gate |
68//! |-------------------------------------------------------------------------------|-------------------|
69//! | [`serde_json::Value`](https://docs.serde.rs/serde_json/value/enum.Value.html) | `serde_json-impl` |
70//! | [`ijson::IValue`](https://docs.rs/ijson/latest/ijson/struct.IValue.html) | `ijson-impl` |
71//!
72//! ## Trait aliases
73//!
74//! When the `nightly` feature is enabled,
75//! this crate also defines some trait aliases that define common
76//! requirements for JSON data types.
77//! For instance the `JsonClone` trait alias ensures that every component
78//! of the JSON value implements `Clone`.
79#![cfg_attr(feature = "nightly", feature(trait_alias))]
80#![feature(generic_associated_types)]
81use cc_traits::{Get, GetKeyValue, Iter, Keyed, Len, MapIter};
82use std::{hash::Hash, ops::Deref};
83
84mod impls;
85pub mod number;
86mod reference;
87mod value;
88
89#[cfg(feature = "nightly")]
90mod aliases;
91
92pub use number::Number;
93pub use reference::*;
94pub use value::*;
95
96#[cfg(feature = "nightly")]
97pub use aliases::*;
98
99/// JSON object key.
100pub trait Key<M>: Eq + Hash + Deref<Target = str> {
101 fn metadata(&self) -> &M;
102}
103
104impl Key<()> for String {
105 fn metadata(&self) -> &() {
106 &()
107 }
108}
109
110#[cfg(feature = "smallkey")]
111impl<A: smallvec::Array<Item = u8>> Key<()> for smallstr::SmallString<A> {
112 fn metadata(&self) -> &() {
113 &()
114 }
115}
116
117/// JSON value attached to some metadata.
118pub trait Json: Sized + Eq {
119 /// Metadata type attached to each value.
120 ///
121 /// The metadata should be ignored during comparison/ordering/hashing of JSON values.
122 type MetaData: Clone + Sync + Send;
123
124 /// Literal number type.
125 type Number: Number;
126
127 /// String type.
128 type String: Eq + Deref<Target = str> + for<'a> From<&'a str>;
129
130 /// Array type.
131 type Array: Get<usize, Item = Self> + Len + Iter + IntoIterator<Item = Self>;
132
133 /// Object key type.
134 type Key: Key<Self::MetaData>;
135
136 /// Object type.
137 type Object: Keyed<Key = Self::Key, Item = Self>
138 + Len
139 + for<'a> Get<&'a str>
140 + for<'a> GetKeyValue<&'a str>
141 + MapIter
142 + IntoIterator<Item = (Self::Key, Self)>;
143
144 /// Returns a reference to the actual JSON value (without the metadata).
145 fn as_value_ref(&self) -> ValueRef<'_, Self>;
146
147 /// Returns a mutable reference to the actual JSON value (without the metadata).
148 fn as_value_mut(&mut self) -> ValueMut<'_, Self>;
149
150 /// Transforms this JSON value into a `Value` and `MetaData`.
151 fn into_parts(self) -> (Value<Self>, Self::MetaData);
152
153 /// Transforms this JSON value into a `Value`.
154 fn into_value(self) -> Value<Self> {
155 self.into_parts().0
156 }
157
158 /// Returns a reference to the metadata associated to the JSON value.
159 fn metadata(&self) -> &Self::MetaData;
160
161 /// Returns a pair containing a reference to the JSON value and a reference to its metadata.
162 fn as_pair(&self) -> (ValueRef<'_, Self>, &Self::MetaData) {
163 (self.as_value_ref(), self.metadata())
164 }
165
166 /// Returns a pair containing a mutable reference to the JSON value and a reference to its metadata.
167 fn as_pair_mut(&mut self) -> (ValueMut<'_, Self>, &Self::MetaData);
168
169 /// Returns `true` if the value is a `Null`. Returns `false` otherwise.
170 fn is_null(&self) -> bool {
171 self.as_value_ref().is_null()
172 }
173
174 /// Checks if the value is an empty array.
175 #[inline]
176 fn is_empty_array(&self) -> bool {
177 match self.as_value_ref() {
178 ValueRef::Array(a) => a.is_empty(),
179 _ => false,
180 }
181 }
182
183 /// Checks if the value is an empty object.
184 #[inline]
185 fn is_empty_object(&self) -> bool {
186 match self.as_value_ref() {
187 ValueRef::Array(a) => a.is_empty(),
188 _ => false,
189 }
190 }
191
192 /// Checks if the value is an empty array or empty object.
193 #[inline]
194 fn is_empty_array_or_object(&self) -> bool {
195 match self.as_value_ref() {
196 ValueRef::Array(a) => a.is_empty(),
197 ValueRef::Object(o) => o.is_empty(),
198 _ => false,
199 }
200 }
201
202 /// Returns `true` if the value is a boolean. Returns `false` otherwise.
203 ///
204 /// For any value on which `is_bool` returns `true`,
205 /// [`as_bool`](Self::as_bool()) is guaranteed to return the boolean value.
206 fn is_bool(&self) -> bool {
207 self.as_value_ref().is_bool()
208 }
209
210 /// Returns `true` if the value is a number. Returns `false` otherwise.
211 ///
212 /// For any value on which `is_number` returns `true`,
213 /// [`as_number`](Self::as_number()) is guaranteed to return the number value.
214 fn is_number(&self) -> bool {
215 self.as_value_ref().is_number()
216 }
217
218 /// Returns `true` if the value is a string.
219 /// Returns `false` otherwise.
220 ///
221 /// For any value on which `is_string` returns `true`,
222 /// [`as_str`](Self::as_str()) is guaranteed to return the string value.
223 fn is_string(&self) -> bool {
224 self.as_value_ref().is_string()
225 }
226
227 /// Returns `true` if the value is an array.
228 /// Returns `false` otherwise.
229 ///
230 /// For any value on which `is_array` returns `true`,
231 /// [`as_array`](Self::as_array()) is guaranteed to return the array value.
232 fn is_array(&self) -> bool {
233 self.as_value_ref().is_array()
234 }
235
236 /// Returns `true` if the value is an object.
237 /// Returns `false` otherwise.
238 ///
239 /// For any value on which `is_object` returns `true`,
240 /// [`as_object`](Self::as_object()) is guaranteed to return the object value.
241 fn is_object(&self) -> bool {
242 self.as_value_ref().is_object()
243 }
244
245 /// If the value is a boolean, returns the associated `bool`.
246 /// Returns `None` otherwise.
247 fn as_bool(&self) -> Option<bool> {
248 self.as_value_ref().as_bool()
249 }
250
251 /// If the value is a number, returns a reference to it.
252 /// Returns `None` otherwise.
253 fn as_number(&self) -> Option<&Self::Number> {
254 self.as_value_ref().as_number()
255 }
256
257 /// Returns this number as an `u32` if it can be exactly represented as such.
258 fn as_u32(&self) -> Option<u32> {
259 self.as_value_ref().as_u32()
260 }
261
262 /// Returns this number as an `u64` if it can be exactly represented as such.
263 fn as_u64(&self) -> Option<u64> {
264 self.as_value_ref().as_u64()
265 }
266
267 /// Returns this number as an `i32` if it can be exactly represented as such.
268 fn as_i32(&self) -> Option<i32> {
269 self.as_value_ref().as_i32()
270 }
271
272 /// Returns this number as an `i64` if it can be exactly represented as such.
273 fn as_i64(&self) -> Option<i64> {
274 self.as_value_ref().as_i64()
275 }
276
277 /// Returns this number as an `f32` if it can be exactly represented as such.
278 fn as_f32(&self) -> Option<f32> {
279 self.as_value_ref().as_f32()
280 }
281
282 /// Returns this number as an `f32` if it is a number, potentially losing precision in the process.
283 fn as_f32_lossy(&self) -> Option<f32> {
284 self.as_value_ref().as_f32_lossy()
285 }
286
287 /// Returns this number as an `f64` if it can be exactly represented as such.
288 fn as_f64(&self) -> Option<f64> {
289 self.as_value_ref().as_f64()
290 }
291
292 /// Returns this number as an `f64` if it is a number, potentially losing precision in the process.
293 fn as_f64_lossy(&self) -> Option<f64> {
294 self.as_value_ref().as_f64_lossy()
295 }
296
297 /// If the value is a string, returns its associated [`str`].
298 /// Returns `None` otherwise.
299 fn as_str(&self) -> Option<&str> {
300 self.as_value_ref().into_str()
301 }
302
303 /// If the value is an array, returns a reference to it.
304 /// Returns `None` otherwise.
305 fn as_array(&self) -> Option<&Self::Array> {
306 self.as_value_ref().as_array()
307 }
308
309 /// If the value is an array, returns a mutable reference to it.
310 /// Returns `None` otherwise.
311 fn as_array_mut(&mut self) -> Option<&mut Self::Array> {
312 self.as_value_mut().into_array_mut()
313 }
314
315 /// If the value is an object, returns a reference to it.
316 /// Returns `None` otherwise.
317 fn as_object(&self) -> Option<&Self::Object> {
318 self.as_value_ref().as_object()
319 }
320
321 /// If the value is an object, returns a mutable reference to it.
322 /// Returns `None` otherwise.
323 fn as_object_mut(&mut self) -> Option<&mut Self::Object> {
324 self.as_value_mut().into_object_mut()
325 }
326}
327
328impl<J: Json> From<J> for Value<J> {
329 fn from(j: J) -> Value<J> {
330 j.into_value()
331 }
332}
333
334/// Constructible JSON type.
335pub trait JsonNew: Json {
336 /// Creates a new "meta value" from a `Value` and its associated metadata.
337 fn new(value: Value<Self>, metadata: Self::MetaData) -> Self;
338
339 /// Creates a new object key.
340 fn new_key(key: &str, metadata: Self::MetaData) -> Self::Key;
341
342 /// Creates a new `null` value.
343 fn null(metadata: Self::MetaData) -> Self {
344 Self::new(Value::Null, metadata)
345 }
346
347 /// Creates a new boolean value.
348 fn boolean(b: bool, metadata: Self::MetaData) -> Self {
349 Self::new(Value::Boolean(b), metadata)
350 }
351
352 /// Creates a new number value.
353 fn number(n: Self::Number, metadata: Self::MetaData) -> Self {
354 Self::new(Value::Number(n), metadata)
355 }
356
357 /// Creates a new string value.
358 fn string(s: Self::String, metadata: Self::MetaData) -> Self {
359 Self::new(Value::String(s), metadata)
360 }
361
362 /// Creates a new array value.
363 fn array(a: Self::Array, metadata: Self::MetaData) -> Self {
364 Self::new(Value::Array(a), metadata)
365 }
366
367 /// Creates a new empty object value.
368 fn empty_array(metadata: Self::MetaData) -> Self
369 where
370 Self::Array: Default,
371 {
372 Self::array(Self::Array::default(), metadata)
373 }
374
375 /// Creates a new object value.
376 fn object(o: Self::Object, metadata: Self::MetaData) -> Self {
377 Self::new(Value::Object(o), metadata)
378 }
379
380 /// Creates a new empty object value.
381 fn empty_object(metadata: Self::MetaData) -> Self
382 where
383 Self::Object: Default,
384 {
385 Self::object(Self::Object::default(), metadata)
386 }
387}
388
389/// Null JSON type.
390///
391/// This is a dummy type that can only represent the `null` JSON value.
392#[derive(PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
393pub struct Null;
394
395impl Json for Null {
396 type MetaData = ();
397
398 type Number = number::Zero;
399
400 type String = String;
401
402 /// Array type.
403 type Array = Vec<Self>;
404
405 /// Object key type.
406 type Key = String;
407
408 /// Object type.
409 type Object = std::collections::BTreeMap<String, Self>;
410
411 fn as_value_ref(&self) -> ValueRef<'_, Self> {
412 ValueRef::Null
413 }
414
415 fn as_value_mut(&mut self) -> ValueMut<'_, Self> {
416 ValueMut::Null
417 }
418
419 fn into_parts(self) -> (Value<Self>, Self::MetaData) {
420 (Value::Null, ())
421 }
422
423 fn metadata(&self) -> &Self::MetaData {
424 &()
425 }
426
427 fn as_pair_mut(&mut self) -> (ValueMut<'_, Self>, &Self::MetaData) {
428 (ValueMut::Null, &())
429 }
430}