#![doc = include_str!("../README.md")] mod document; mod format; pub mod syntax; pub use document::{Document, PathSegment}; pub use syntax::{Error, ErrorKind, Span}; #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[non_exhaustive] pub struct Options { pub max_depth: usize, } impl Options { pub const DEFAULT_MAX_DEPTH: usize = 128; pub fn new() -> Self { Self::default() } pub fn with_max_depth(mut self, max_depth: usize) -> Self { self.max_depth = max_depth; self } } impl Default for Options { fn default() -> Self { Self { max_depth: Self::DEFAULT_MAX_DEPTH, } } } pub fn parse(source: &str) -> Result { parse_with(source, &Options::default()) } pub fn parse_with(source: &str, options: &Options) -> Result { syntax::parse_with(source, options)?.to_value() } pub fn stringify(value: &serde_json::Value) -> Result { stringify_with(value, &Options::default()) } pub fn stringify_with(value: &serde_json::Value, options: &Options) -> Result { format::print(value, true, options) } impl syntax::Value { pub fn to_value(&self) -> Result { use serde_json::Value; use syntax::ValueKind; Ok(match &self.kind { ValueKind::Null => Value::Null, ValueKind::Bool(value) => Value::Bool(*value), // Rebuilt from primitives so `serde_json/arbitrary_precision`, which the // bundler enables, neither keeps the source spelling nor admits out-of-range numbers. ValueKind::Number(value) => Value::Number( value .parse() .ok() .and_then(|number: serde_json::Number| { number .as_u64() .map(Into::into) .or_else(|| number.as_i64().map(Into::into)) .or_else(|| serde_json::Number::from_f64(number.as_f64()?)) }) .ok_or_else(|| Error { kind: ErrorKind::Number, span: self.span.clone(), message: "Invalid or out-of-range JSON number".into(), previous: None, })?, ), ValueKind::String(value) => Value::String(value.clone()), ValueKind::Array(values) => Value::Array( values .iter() .map(Self::to_value) .collect::>()?, ), ValueKind::Object(members) => Value::Object( members .iter() .map(|member| Ok((member.key.clone(), member.value.to_value()?))) .collect::>()?, ), }) } }