Enum json_syntax::Value
source · pub enum Value<M = ()> {
Null,
Boolean(bool),
Number(NumberBuf),
String(String),
Array(Array<M>),
Object(Object<M>),
}
Expand description
Value.
The type parameter M
is the type of metadata attached to each syntax node
(values, sub values and object keys).
The metadata is derived from the locspan::Span
of the node in the source
document using the metadata builder function passed to the parsing function
(see the Parse
trait for more details).
Parsing
You can parse a Value
by importing the Parse
trait providing a
collection of parsing functions.
Example
use json_syntax::{Value, Parse};
use locspan::{Meta, Span};
let value: Meta<Value<Span>, Span> = Value::parse_str("{ \"key\": \"value\" }", |span| span).unwrap();
You don’t need to specify the return type, here only shown to make it clear.
Furthermore the MetaValue<Span>
type alias can be used instead of
Meta<Value<Span>, Span>
to avoid repetition of the metadata type.
Comparison
This type implements the usual comparison traits PartialEq
, Eq
,
PartialOrd
and Ord
. However these implementations will also compare the
metadata.
If you want to do comparisons while ignoring ths metadata, you can use
the locspan::Stripped
type
(combined with the locspan::BorrowStripped
trait).
Example
use json_syntax::{Value, Parse};
use locspan::BorrowStripped;
let a = Value::parse_str("null", |_| 0).unwrap();
let b = Value::parse_str("null", |_| 1).unwrap();
assert_ne!(a, b); // not equals because the metadata is different.
assert_eq!(a.stripped(), b.stripped()); // equals because the metadata is ignored.
Printing
The Print
trait provide a highly configurable printing method.
Example
use json_syntax::{Value, Parse, Print};
let value = Value::parse_str("[ 0, 1, { \"key\": \"value\" }, null ]", |span| span).unwrap();
println!("{}", value.pretty_print()); // multi line, indent with 2 spaces
println!("{}", value.inline_print()); // single line, spaces
println!("{}", value.compact_print()); // single line, no spaces
let mut options = json_syntax::print::Options::pretty();
options.indent = json_syntax::print::Indent::Tabs(1);
println!("{}", value.print_with(options)); // multi line, indent with tabs
Variants§
Null
null
.
Boolean(bool)
Boolean true
or false
.
Number(NumberBuf)
Number.
String(String)
String.
Array(Array<M>)
Array.
Object(Object<M>)
Object.
Implementations§
source§impl<M> Value<M>
impl<M> Value<M>
sourcepub fn from_serde_json(
value: Value,
f: impl Clone + Fn(SerdeJsonFragment<'_>) -> M
) -> Meta<Self, M>
pub fn from_serde_json(
value: Value,
f: impl Clone + Fn(SerdeJsonFragment<'_>) -> M
) -> Meta<Self, M>
Converts a serde_json::Value
into a Value
.
The function f
is used to annotate the output each sub value
(passed as parameter).
Examples found in repository?
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
pub fn from_serde_json(
value: serde_json::Value,
f: impl Clone + Fn(SerdeJsonFragment) -> M,
) -> Meta<Self, M> {
let meta = f(SerdeJsonFragment::Value(&value));
let v = match value {
serde_json::Value::Null => Self::Null,
serde_json::Value::Bool(b) => Self::Boolean(b),
serde_json::Value::Number(n) => Self::Number(n.into()),
serde_json::Value::String(s) => Self::String(s.into()),
serde_json::Value::Array(a) => Self::Array(
a.into_iter()
.map(|i| Self::from_serde_json(i, f.clone()))
.collect(),
),
serde_json::Value::Object(o) => Self::Object(
o.into_iter()
.map(|(k, v)| {
let k_meta = f(SerdeJsonFragment::Key(&k));
Entry::new(Meta(k.into(), k_meta), Self::from_serde_json(v, f.clone()))
})
.collect(),
),
};
Meta(v, meta)
}
/// Converts a `Value` into a [`serde_json::Value`], stripping the metadata.
pub fn into_serde_json(Meta(this, _): Meta<Self, M>) -> serde_json::Value {
this.into()
}
}
impl<M: Default> From<serde_json::Value> for Value<M> {
#[inline(always)]
fn from(value: serde_json::Value) -> Self {
Value::from_serde_json(value, |_| M::default()).into_value()
}
sourcepub fn into_serde_json(Meta: Meta<Self, M>) -> Value
pub fn into_serde_json(Meta: Meta<Self, M>) -> Value
Converts a Value
into a serde_json::Value
, stripping the metadata.
Examples found in repository?
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
fn from(value: Value<M>) -> Self {
match value {
Value::Null => Self::Null,
Value::Boolean(b) => Self::Bool(b),
Value::Number(n) => Self::Number(n.into()),
Value::String(s) => Self::String(s.into_string()),
Value::Array(a) => Self::Array(a.into_iter().map(Value::into_serde_json).collect()),
Value::Object(o) => Self::Object(
o.into_iter()
.map(
|Entry {
key: Meta(key, _),
value,
}| { (key.into_string(), Value::into_serde_json(value)) },
)
.collect(),
),
}
}
source§impl<M> Value<M>
impl<M> Value<M>
pub fn is_kind(&self, kind: Kind) -> bool
pub fn is_null(&self) -> bool
pub fn is_boolean(&self) -> bool
pub fn is_number(&self) -> bool
pub fn is_string(&self) -> bool
pub fn is_array(&self) -> bool
pub fn is_object(&self) -> bool
sourcepub fn is_empty_array_or_object(&self) -> bool
pub fn is_empty_array_or_object(&self) -> bool
Checks if the value is either an empty array or an empty object.
pub fn as_boolean(&self) -> Option<bool>
pub fn as_boolean_mut(&mut self) -> Option<&mut bool>
pub fn as_number(&self) -> Option<&Number>
pub fn as_number_mut(&mut self) -> Option<&mut NumberBuf>
pub fn as_string_mut(&mut self) -> Option<&mut String>
pub fn as_array(&self) -> Option<&[Meta<Self, M>]>
pub fn as_array_mut(&mut self) -> Option<&mut Array<M>>
sourcepub fn force_as_array(value: &Meta<Self, M>) -> Meta<&[Meta<Self, M>], &M>
pub fn force_as_array(value: &Meta<Self, M>) -> Meta<&[Meta<Self, M>], &M>
Return the given value as an array, even if it is not an array.
Returns the input value as is if it is already an array, or puts it in a slice with a single element if it is not.
pub fn as_object(&self) -> Option<&Object<M>>
pub fn as_object_mut(&mut self) -> Option<&mut Object<M>>
pub fn into_boolean(self) -> Option<bool>
pub fn into_number(self) -> Option<NumberBuf>
pub fn into_string(self) -> Option<String>
pub fn into_array(self) -> Option<Array<M>>
pub fn into_object(self) -> Option<Object<M>>
sourcepub fn traverse(&self) -> TraverseStripped<'_, M> ⓘ
pub fn traverse(&self) -> TraverseStripped<'_, M> ⓘ
Examples found in repository?
421 422 423 424 425 426 427 428 429 430 431 432 433 434 435
pub fn count(&self, mut f: impl FnMut(StrippedFragmentRef<M>) -> bool) -> usize {
self.traverse().filter(|i| f(*i)).count()
}
/// Returns the volume of the value.
///
/// The volume is the sum of all values and recursively nested values
/// included in `self`, including `self` (the volume is at least `1`).
///
/// This is equivalent to `value.traverse().filter(StrippedFragmentRef::is_value).count()`.
pub fn volume(&self) -> usize {
self.traverse()
.filter(StrippedFragmentRef::is_value)
.count()
}
sourcepub fn count(&self, f: impl FnMut(StrippedFragmentRef<'_, M>) -> bool) -> usize
pub fn count(&self, f: impl FnMut(StrippedFragmentRef<'_, M>) -> bool) -> usize
Recursively count the number of values for which f
returns true
.
Examples found in repository?
792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811
fn fmt_with(&self, f: &mut fmt::Formatter, options: &Options, indent: usize) -> fmt::Result {
match self {
Self::Null => f.write_str("null"),
Self::Boolean(b) => b.fmt_with(f, options, indent),
Self::Number(n) => n.fmt_with(f, options, indent),
Self::String(s) => s.fmt_with(f, options, indent),
Self::Array(a) => {
let mut sizes = Vec::with_capacity(self.count(|v| v.is_array() || v.is_object()));
self.pre_compute_size(options, &mut sizes);
let mut index = 0;
a.fmt_with_size(f, options, indent, &sizes, &mut index)
}
Self::Object(o) => {
let mut sizes = Vec::with_capacity(self.count(|v| v.is_array() || v.is_object()));
self.pre_compute_size(options, &mut sizes);
let mut index = 0;
o.fmt_with_size(f, options, indent, &sizes, &mut index)
}
}
}
sourcepub fn volume(&self) -> usize
pub fn volume(&self) -> usize
Returns the volume of the value.
The volume is the sum of all values and recursively nested values
included in self
, including self
(the volume is at least 1
).
This is equivalent to value.traverse().filter(StrippedFragmentRef::is_value).count()
.
sourcepub fn map_metadata<N>(self, f: impl FnMut(M) -> N) -> Value<N>
pub fn map_metadata<N>(self, f: impl FnMut(M) -> N) -> Value<N>
Recursively maps the metadata inside the value.
Examples found in repository?
438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532
pub fn map_metadata<N>(self, mut f: impl FnMut(M) -> N) -> Value<N> {
match self {
Self::Null => Value::Null,
Self::Boolean(b) => Value::Boolean(b),
Self::Number(n) => Value::Number(n),
Self::String(s) => Value::String(s),
Self::Array(a) => Value::Array(
a.into_iter()
.map(|Meta(item, meta)| Meta(item.map_metadata(&mut f), f(meta)))
.collect(),
),
Self::Object(o) => Value::Object(o.map_metadata(f)),
}
}
/// Tries to recursively maps the metadata inside the value.
pub fn try_map_metadata<N, E>(
self,
mut f: impl FnMut(M) -> Result<N, E>,
) -> Result<Value<N>, E> {
match self {
Self::Null => Ok(Value::Null),
Self::Boolean(b) => Ok(Value::Boolean(b)),
Self::Number(n) => Ok(Value::Number(n)),
Self::String(s) => Ok(Value::String(s)),
Self::Array(a) => {
let mut items = Vec::with_capacity(a.len());
for item in a {
items.push(item.try_map_metadata_recursively(&mut f)?)
}
Ok(Value::Array(items))
}
Self::Object(o) => Ok(Value::Object(o.try_map_metadata(f)?)),
}
}
/// Move and return the value, leaves `null` in its place.
#[inline(always)]
pub fn take(&mut self) -> Self {
let mut result = Self::Null;
std::mem::swap(&mut result, self);
result
}
/// Puts this JSON value in canonical form according to
/// [RFC 8785](https://www.rfc-editor.org/rfc/rfc8785).
///
/// The given `buffer` is used to canonicalize the number values.
#[cfg(feature = "canonicalize")]
pub fn canonicalize_with(&mut self, buffer: &mut ryu_js::Buffer) {
match self {
Self::Number(n) => *n = NumberBuf::from_number(n.canonical_with(buffer)),
Self::Array(a) => {
for item in a {
item.canonicalize_with(buffer)
}
}
Self::Object(o) => o.canonicalize_with(buffer),
_ => (),
}
}
/// Puts this JSON value in canonical form according to
/// [RFC 8785](https://www.rfc-editor.org/rfc/rfc8785).
#[cfg(feature = "canonicalize")]
pub fn canonicalize(&mut self) {
let mut buffer = ryu_js::Buffer::new();
self.canonicalize_with(&mut buffer)
}
}
pub trait Traversal<'a> {
type Fragment;
type Traverse: Iterator<Item = Self::Fragment>;
fn traverse(&'a self) -> Self::Traverse;
}
impl<'a, M: 'a> Traversal<'a> for Meta<Value<M>, M> {
type Fragment = FragmentRef<'a, M>;
type Traverse = Traverse<'a, M>;
fn traverse(&'a self) -> Self::Traverse {
let mut stack = SmallVec::new();
stack.push(FragmentRef::Value(self));
Traverse { stack }
}
}
impl<M, N> locspan::MapMetadataRecursively<M, N> for Value<M> {
type Output = Value<N>;
fn map_metadata_recursively<F: FnMut(M) -> N>(self, f: F) -> Value<N> {
self.map_metadata(f)
}
Trait Implementations§
source§impl<M, N> MapMetadataRecursively<M, N> for Value<M>
impl<M, N> MapMetadataRecursively<M, N> for Value<M>
source§impl<M: Ord> Ord for Value<M>
impl<M: Ord> Ord for Value<M>
source§impl<M> Parse<M> for Value<M>
impl<M> Parse<M> for Value<M>
fn parse_spanned<C, F, E>(
parser: &mut Parser<C, F, E>,
context: Context
) -> Result<Meta<Self, Span>, Meta<Error<M, E>, M>>where
C: Iterator<Item = Result<DecodedChar, E>>,
F: FnMut(Span) -> M,
fn parse_str<F>(
content: &str,
metadata_builder: F
) -> Result<Meta<Self, M>, Meta<Error<M>, M>>where
F: FnMut(Span) -> M,
fn parse_str_with<F>(
content: &str,
options: Options,
metadata_builder: F
) -> Result<Meta<Self, M>, Meta<Error<M>, M>>where
F: FnMut(Span) -> M,
fn parse_infallible_utf8<C, F>(
chars: C,
metadata_builder: F
) -> Result<Meta<Self, M>, Meta<Error<M>, M>>where
C: Iterator<Item = char>,
F: FnMut(Span) -> M,
fn parse_utf8_infallible_with<C, F>(
chars: C,
options: Options,
metadata_builder: F
) -> Result<Meta<Self, M>, Meta<Error<M>, M>>where
C: Iterator<Item = char>,
F: FnMut(Span) -> M,
fn parse_utf8<C, F, E>(
chars: C,
metadata_builder: F
) -> Result<Meta<Self, M>, Meta<Error<M, E>, M>>where
C: Iterator<Item = Result<char, E>>,
F: FnMut(Span) -> M,
fn parse_utf8_with<C, F, E>(
chars: C,
options: Options,
metadata_builder: F
) -> Result<Meta<Self, M>, Meta<Error<M, E>, M>>where
C: Iterator<Item = Result<char, E>>,
F: FnMut(Span) -> M,
fn parse_infallible<C, F>(
chars: C,
metadata_builder: F
) -> Result<Meta<Self, M>, Meta<Error<M>, M>>where
C: Iterator<Item = DecodedChar>,
F: FnMut(Span) -> M,
fn parse_infallible_with<C, F>(
chars: C,
options: Options,
metadata_builder: F
) -> Result<Meta<Self, M>, Meta<Error<M>, M>>where
C: Iterator<Item = DecodedChar>,
F: FnMut(Span) -> M,
fn parse<C, F, E>(
chars: C,
metadata_builder: F
) -> Result<Meta<Self, M>, Meta<Error<M, E>, M>>where
C: Iterator<Item = Result<DecodedChar, E>>,
F: FnMut(Span) -> M,
fn parse_with<C, F, E>(
chars: C,
options: Options,
metadata_builder: F
) -> Result<Meta<Self, M>, Meta<Error<M, E>, M>>where
C: Iterator<Item = Result<DecodedChar, E>>,
F: FnMut(Span) -> M,
fn parse_in<C, F, E>(
parser: &mut Parser<C, F, E>,
context: Context
) -> Result<Meta<Self, M>, Meta<Error<M, E>, M>>where
C: Iterator<Item = Result<DecodedChar, E>>,
F: FnMut(Span) -> M,
source§impl<M: PartialEq> PartialEq<Value<M>> for Value<M>
impl<M: PartialEq> PartialEq<Value<M>> for Value<M>
source§impl<M: PartialOrd> PartialOrd<Value<M>> for Value<M>
impl<M: PartialOrd> PartialOrd<Value<M>> for Value<M>
1.0.0 · source§fn le(&self, other: &Rhs) -> bool
fn le(&self, other: &Rhs) -> bool
self
and other
) and is used by the <=
operator. Read moresource§impl<M> PrecomputeSize for Value<M>
impl<M> PrecomputeSize for Value<M>
source§impl<M> Print for Value<M>
impl<M> Print for Value<M>
fn fmt_with(
&self,
f: &mut Formatter<'_>,
options: &Options,
indent: usize
) -> Result
source§fn pretty_print(&self) -> Printed<'_, Self>
fn pretty_print(&self) -> Printed<'_, Self>
Options::pretty
options.source§fn compact_print(&self) -> Printed<'_, Self>
fn compact_print(&self) -> Printed<'_, Self>
Options::compact
options.source§fn inline_print(&self) -> Printed<'_, Self>
fn inline_print(&self) -> Printed<'_, Self>
Options::inline
options.source§fn print_with(&self, options: Options) -> Printed<'_, Self>
fn print_with(&self, options: Options) -> Printed<'_, Self>
source§impl<M> PrintWithSize for Value<M>
impl<M> PrintWithSize for Value<M>
source§impl<M> StrippedHash for Value<M>
impl<M> StrippedHash for Value<M>
fn stripped_hash<H: Hasher>(&self, state: &mut H)
source§impl<M> StrippedOrd for Value<M>
impl<M> StrippedOrd for Value<M>
fn stripped_cmp(&self, other: &Self) -> Ordering
source§impl<M, __M> StrippedPartialEq<Value<__M>> for Value<M>
impl<M, __M> StrippedPartialEq<Value<__M>> for Value<M>
fn stripped_eq(&self, other: &Value<__M>) -> bool
source§impl<M, __M> StrippedPartialOrd<Value<__M>> for Value<M>
impl<M, __M> StrippedPartialOrd<Value<__M>> for Value<M>
source§impl<M, N, E> TryMapMetadataRecursively<M, N, E> for Value<M>
impl<M, N, E> TryMapMetadataRecursively<M, N, E> for Value<M>
impl<M: Eq> Eq for Value<M>
impl<M> StrippedEq for Value<M>
impl<M> StructuralEq for Value<M>
impl<M> StructuralPartialEq for Value<M>
Auto Trait Implementations§
impl<M> RefUnwindSafe for Value<M>where
M: RefUnwindSafe,
impl<M> Send for Value<M>where
M: Send,
impl<M> Sync for Value<M>where
M: Sync,
impl<M> Unpin for Value<M>where
M: Unpin,
impl<M> UnwindSafe for Value<M>where
M: UnwindSafe,
Blanket Implementations§
source§impl<Q, K> Equivalent<K> for Qwhere
Q: Eq + ?Sized,
K: Borrow<Q> + ?Sized,
impl<Q, K> Equivalent<K> for Qwhere
Q: Eq + ?Sized,
K: Borrow<Q> + ?Sized,
source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key
and return true
if they are equal.