shape/from_json.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
use serde_json::Value as JSON;
use serde_json_bytes::Value as JSONBytes;
use super::Shape;
use super::ShapeCase;
impl Shape {
/// Derive a [`Shape`] from a JSON value, which is almost a lossless
/// conversion except that floating point literals get the general
/// [`ShapeCase::Float`] shape, ignoring their particular values.
///
/// Note that all locations will be empty, because [`serde_json`] doesn't track locations.
///
/// # Panics
///
/// If the JSON value can't be converted into a [`serde_json_bytes::Value`]
#[must_use]
pub fn from_json(json: &JSON) -> Self {
Shape::new(ShapeCase::from_json(json), [])
}
/// Derive a [`Shape`] from a JSON value using the [`serde_json_bytes`] crate.
///
/// Note that all locations will be empty, because [`serde_json_bytes`] doesn't track locations.
pub fn from_json_bytes(json: &JSONBytes) -> Self {
Shape::new(ShapeCase::from_json_bytes(json), [])
}
}
impl ShapeCase {
/// Derive a [`ShapeCase`] from a [`serde_json::Value`].
///
/// # Panics
///
/// If the [`serde_json::Value`] can't be converted into a [`serde_json_bytes::Value`]
#[must_use]
pub fn from_json(json: &JSON) -> Self {
Self::from_json_bytes(
&json
.to_string()
.parse()
.expect("serde_json_bytes doesn't match serde_json"),
)
}
pub fn from_json_bytes(json: &JSONBytes) -> Self {
match json {
JSONBytes::Bool(b) => Self::Bool(Some(*b)),
JSONBytes::String(s) => Self::String(Some(s.as_str().to_string())),
JSONBytes::Number(n) => {
if let Some(i) = n.as_i64() {
Self::Int(Some(i))
} else {
Self::Float
}
}
JSONBytes::Null => Self::Null,
JSONBytes::Array(arr) => {
let mut prefix = Vec::with_capacity(arr.len());
for item in arr {
prefix.push(Shape::from_json_bytes(item));
}
Self::Array {
prefix,
tail: Shape::none(),
}
}
JSONBytes::Object(obj) => {
let mut fields = Shape::empty_map();
for (key, value) in obj {
fields.insert(key.as_str().to_string(), Shape::from_json_bytes(value));
}
Self::Object {
fields,
rest: Shape::none(),
}
}
}
}
}