diff --git a/Cargo.toml b/Cargo.toml index 866c31318..d83176f0a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,7 @@ serde_stacker = "0.1.8" trybuild = { version = "1.0.81", features = ["diff"] } [package.metadata.docs.rs] -features = ["preserve_order", "raw_value", "unbounded_depth"] +features = ["preserve_order", "raw_value", "unbounded_depth", "spanned"] targets = ["x86_64-unknown-linux-gnu"] rustdoc-args = [ "--generate-link-to-definition", @@ -84,8 +84,11 @@ raw_value = [] # structures without any consideration for overflowing the stack. When using # this feature, you will want to provide some other way to protect against stack # overflows, such as by wrapping your Deserializer in the dynamically growing -# stack adapter provided by the serde_stacker crate. Additionally you will need +# stack adapter provided by the serde_stacker crate. Additionally, you will need # to be careful around other recursive operations on the parsed result which may # overflow the stack after deserialization has completed, including, but not # limited to, Display and Debug and Drop impls. unbounded_depth = [] + +# TODO: document +spanned = [] diff --git a/src/de.rs b/src/de.rs index 4080c54ac..2aea15e7f 100644 --- a/src/de.rs +++ b/src/de.rs @@ -24,7 +24,6 @@ pub use crate::read::{Read, SliceRead, StrRead}; #[cfg(feature = "std")] #[cfg_attr(docsrs, doc(cfg(feature = "std")))] pub use crate::read::IoRead; - ////////////////////////////////////////////////////////////////////////////// /// A structure that deserializes JSON into Rust values. @@ -36,6 +35,8 @@ pub struct Deserializer { single_precision: bool, #[cfg(feature = "unbounded_depth")] disable_recursion_limit: bool, + #[cfg(feature = "spanned")] + spanned_enabled: bool, } impl<'de, R> Deserializer @@ -49,7 +50,7 @@ where /// as a [`File`], you will want to apply your own buffering because serde_json /// will not buffer the input. See [`std::io::BufReader`]. /// - /// Typically it is more convenient to use one of these methods instead: + /// Typically, it is more convenient to use one of these methods instead: /// /// - Deserializer::from_str /// - Deserializer::from_slice @@ -65,8 +66,30 @@ where single_precision: false, #[cfg(feature = "unbounded_depth")] disable_recursion_limit: false, + #[cfg(feature = "spanned")] + spanned_enabled: false, } } + + #[cfg(feature = "spanned")] + pub(crate) fn new_spanned(read: R) -> Self { + let mut de = Self::new(read); + de.spanned_enabled = true; + de + } + + #[cfg(feature = "spanned")] + pub(crate) fn position(&self) -> read::Position { + // TODO: consider tracking line-breaks to avoid potentially expensive counting in some + // implementations of `Read::position`. + // TODO: `Read::position().column` tracks byte offset, not character offset. + self.read.position() + } + + #[cfg(feature = "spanned")] + pub(crate) fn byte_offset(&self) -> usize { + self.read.byte_offset() + } } #[cfg(feature = "std")] @@ -82,6 +105,13 @@ where pub fn from_reader(reader: R) -> Self { Deserializer::new(read::IoRead::new(reader)) } + + /// TODO: document + #[cfg(feature = "spanned")] + #[cfg_attr(docsrs, doc(cfg(feature = "spanned")))] + pub fn from_reader_spanned(reader: R) -> Self { + Deserializer::new_spanned(read::IoRead::new(reader)) + } } impl<'a> Deserializer> { @@ -89,6 +119,13 @@ impl<'a> Deserializer> { pub fn from_slice(bytes: &'a [u8]) -> Self { Deserializer::new(read::SliceRead::new(bytes)) } + + /// TODO: document + #[cfg(feature = "spanned")] + #[cfg_attr(docsrs, doc(cfg(feature = "spanned")))] + pub fn from_slice_spanned(bytes: &'a [u8]) -> Self { + Deserializer::new_spanned(read::SliceRead::new(bytes)) + } } impl<'a> Deserializer> { @@ -96,6 +133,13 @@ impl<'a> Deserializer> { pub fn from_str(s: &'a str) -> Self { Deserializer::new(read::StrRead::new(s)) } + + /// TODO: document + #[cfg(feature = "spanned")] + #[cfg_attr(docsrs, doc(cfg(feature = "spanned")))] + pub fn from_str_spanned(s: &'a str) -> Self { + Deserializer::new_spanned(read::StrRead::new(s)) + } } macro_rules! overflow { @@ -1824,6 +1868,13 @@ impl<'de, R: Read<'de>> de::Deserializer<'de> for &mut Deserializer { where V: de::Visitor<'de>, { + #[cfg(feature = "spanned")] + { + if self.spanned_enabled && crate::spanned::is_spanned(_name, _fields) { + return visitor.visit_map(crate::spanned::SpannedDeserializer::new(self)); + } + } + let peek = match tri!(self.parse_whitespace()) { Some(b) => b, None => { @@ -2146,7 +2197,7 @@ impl<'de, 'a, R: Read<'de> + 'a> de::VariantAccess<'de> for UnitVariantAccess<'a } } -/// Only deserialize from this after peeking a '"' byte! Otherwise it may +/// Only deserialize from this after peeking a '"' byte! Otherwise, it may /// deserialize invalid JSON successfully. struct MapKey<'a, R: 'a> { de: &'a mut Deserializer, @@ -2317,8 +2368,28 @@ where self.de.deserialize_bytes(visitor) } + #[inline] + #[cfg(feature = "spanned")] + fn deserialize_struct( + self, + name: &'static str, + fields: &'static [&'static str], + visitor: V, + ) -> result::Result + where + V: de::Visitor<'de>, + { + if crate::spanned::is_spanned(name, fields) { + return visitor.visit_map(crate::spanned::SpannedDeserializer::new(self.de)); + } + self.deserialize_any(visitor) + } + + #[cfg(not(feature = "spanned"))] + forward_to_deserialize_any! { struct } + forward_to_deserialize_any! { - char str string unit unit_struct seq tuple tuple_struct map struct + char str string unit unit_struct seq tuple tuple_struct map identifier ignored_any } } @@ -2362,7 +2433,7 @@ where /// Create a JSON stream deserializer from one of the possible serde_json /// input sources. /// - /// Typically it is more convenient to use one of these methods instead: + /// Typically, it is more convenient to use one of these methods instead: /// /// - Deserializer::from_str(...).into_iter() /// - Deserializer::from_slice(...).into_iter() @@ -2378,6 +2449,22 @@ where } } + /// Create a JSON span tracking stream deserializer from one of the possible serde_json + /// input sources. + /// + /// Typically, it is more convenient to use one of these methods instead: + /// + /// - Deserializer::from_str_spanned(...).into_iter() + /// - Deserializer::from_slice_spanned(...).into_iter() + /// - Deserializer::from_reader_spanned(...).into_iter() + #[cfg(feature = "spanned")] + #[cfg_attr(docsrs, doc(cfg(feature = "spanned")))] + pub fn new_spanned(read: R) -> Self { + let mut de = Self::new(read); + de.de.spanned_enabled = true; + de + } + /// Returns the number of bytes so far deserialized into a successful `T`. /// /// If a stream deserializer returns an EOF error, new data can be joined to diff --git a/src/lib.rs b/src/lib.rs index a9f82f2b3..037a4fa98 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -50,7 +50,7 @@ //! Number(Number), //! String(String), //! Array(Vec), -//! Object(Map), +//! Object(Map), //! } //! ``` //! @@ -398,6 +398,14 @@ pub use crate::ser::{to_string, to_string_pretty, to_vec, to_vec_pretty}; #[cfg_attr(docsrs, doc(cfg(feature = "std")))] #[doc(inline)] pub use crate::ser::{to_writer, to_writer_pretty, Serializer}; +#[cfg(all(feature = "std", feature = "spanned"))] +#[cfg_attr(docsrs, doc(cfg(all(feature = "std", feature = "spanned"))))] +#[doc(inline)] +pub use crate::spanned::from_reader_spanned; +#[cfg(feature = "spanned")] +#[cfg_attr(docsrs, doc(cfg(feature = "spanned")))] +#[doc(inline)] +pub use crate::spanned::{from_slice_spanned, from_str_spanned}; #[doc(inline)] pub use crate::value::{from_value, to_value, Map, Number, Value}; @@ -423,6 +431,9 @@ pub mod map; pub mod ser; #[cfg(not(feature = "std"))] mod ser; +#[cfg(feature = "spanned")] +#[cfg_attr(docsrs, doc(cfg(feature = "spanned")))] +pub mod spanned; pub mod value; mod io; diff --git a/src/map.rs b/src/map.rs index be60f22db..92c882fd6 100644 --- a/src/map.rs +++ b/src/map.rs @@ -7,6 +7,8 @@ //! [`IndexMap`]: indexmap::IndexMap use crate::error::Error; +#[cfg(feature = "spanned")] +use crate::spanned::{Spanned, SpannedValue}; use crate::value::Value; use alloc::string::String; #[cfg(feature = "preserve_order")] @@ -15,6 +17,7 @@ use core::borrow::Borrow; use core::fmt::{self, Debug}; use core::hash::{Hash, Hasher}; use core::iter::FusedIterator; +use core::marker::PhantomData; #[cfg(feature = "preserve_order")] use core::mem; use core::ops; @@ -26,20 +29,68 @@ use alloc::collections::{btree_map, BTreeMap}; use indexmap::IndexMap; /// Represents a JSON key/value type. -pub struct Map { +pub struct GenericMap { map: MapImpl, } +/// Represents a JSON key/value type without span information. +pub type Map = GenericMap; +#[cfg(feature = "spanned")] +#[cfg_attr(docsrs, doc(cfg(feature = "spanned")))] +/// Represents a JSON key/value type with span information. +pub type SpannedMap = GenericMap, Spanned>; + #[cfg(not(feature = "preserve_order"))] type MapImpl = BTreeMap; #[cfg(feature = "preserve_order")] type MapImpl = IndexMap; -impl Map { +// Prevent users from implementing the MapKey and MapValue traits. +mod private { + use super::*; + + pub trait Sealed {} + + impl Sealed for String {} + #[cfg(feature = "spanned")] + impl Sealed for Spanned {} + impl Sealed for Value {} + #[cfg(feature = "spanned")] + impl Sealed for Spanned {} +} + +/// TODO: document +pub trait MapKey: + private::Sealed + + Eq + + Hash + + Ord + + Clone + + Debug + + serde::ser::Serialize + + for<'de> de::Deserialize<'de> +{ +} + +impl MapKey for String {} +#[cfg(feature = "spanned")] +impl MapKey for Spanned {} + +/// TODO: document +pub trait MapValue: + private::Sealed + Eq + Hash + Clone + Debug + serde::ser::Serialize + for<'de> de::Deserialize<'de> +{ +} + +impl MapValue for Value {} +#[cfg(feature = "spanned")] +impl MapValue for Spanned {} + +impl GenericMap { /// Makes a new empty Map. #[inline] pub fn new() -> Self { - Map { + GenericMap { map: MapImpl::new(), } } @@ -47,7 +98,7 @@ impl Map { /// Makes a new empty Map with the given initial capacity. #[inline] pub fn with_capacity(capacity: usize) -> Self { - Map { + GenericMap { #[cfg(not(feature = "preserve_order"))] map: { // does not support with_capacity @@ -70,9 +121,9 @@ impl Map { /// The key may be any borrowed form of the map's key type, but the ordering /// on the borrowed form *must* match the ordering on the key type. #[inline] - pub fn get(&self, key: &Q) -> Option<&Value> + pub fn get(&self, key: &Q) -> Option<&V> where - String: Borrow, + K: Borrow, Q: ?Sized + Ord + Eq + Hash, { self.map.get(key) @@ -85,7 +136,7 @@ impl Map { #[inline] pub fn contains_key(&self, key: &Q) -> bool where - String: Borrow, + K: Borrow, Q: ?Sized + Ord + Eq + Hash, { self.map.contains_key(key) @@ -96,9 +147,9 @@ impl Map { /// The key may be any borrowed form of the map's key type, but the ordering /// on the borrowed form *must* match the ordering on the key type. #[inline] - pub fn get_mut(&mut self, key: &Q) -> Option<&mut Value> + pub fn get_mut(&mut self, key: &Q) -> Option<&mut V> where - String: Borrow, + K: Borrow, Q: ?Sized + Ord + Eq + Hash, { self.map.get_mut(key) @@ -109,9 +160,9 @@ impl Map { /// The key may be any borrowed form of the map's key type, but the ordering /// on the borrowed form *must* match the ordering on the key type. #[inline] - pub fn get_key_value(&self, key: &Q) -> Option<(&String, &Value)> + pub fn get_key_value(&self, key: &Q) -> Option<(&K, &V)> where - String: Borrow, + K: Borrow, Q: ?Sized + Ord + Eq + Hash, { self.map.get_key_value(key) @@ -124,7 +175,7 @@ impl Map { /// If the map did have this key present, the value is updated, and the old /// value is returned. #[inline] - pub fn insert(&mut self, k: String, v: Value) -> Option { + pub fn insert(&mut self, k: K, v: V) -> Option { self.map.insert(k, v) } @@ -137,7 +188,7 @@ impl Map { #[cfg(feature = "preserve_order")] #[cfg_attr(docsrs, doc(cfg(feature = "preserve_order")))] #[inline] - pub fn shift_insert(&mut self, index: usize, k: String, v: Value) -> Option { + pub fn shift_insert(&mut self, index: usize, k: K, v: V) -> Option { self.map.shift_insert(index, k, v) } @@ -153,9 +204,9 @@ impl Map { /// relative order of the keys in the map, use /// [`.shift_remove(key)`][Self::shift_remove] instead. #[inline] - pub fn remove(&mut self, key: &Q) -> Option + pub fn remove(&mut self, key: &Q) -> Option where - String: Borrow, + K: Borrow, Q: ?Sized + Ord + Eq + Hash, { #[cfg(feature = "preserve_order")] @@ -176,9 +227,9 @@ impl Map { /// preserve the relative order of the keys in the map, use /// [`.shift_remove_entry(key)`][Self::shift_remove_entry] instead. #[inline] - pub fn remove_entry(&mut self, key: &Q) -> Option<(String, Value)> + pub fn remove_entry(&mut self, key: &Q) -> Option<(K, V)> where - String: Borrow, + K: Borrow, Q: ?Sized + Ord + Eq + Hash, { #[cfg(feature = "preserve_order")] @@ -197,9 +248,9 @@ impl Map { #[cfg(feature = "preserve_order")] #[cfg_attr(docsrs, doc(cfg(feature = "preserve_order")))] #[inline] - pub fn swap_remove(&mut self, key: &Q) -> Option + pub fn swap_remove(&mut self, key: &Q) -> Option where - String: Borrow, + K: Borrow, Q: ?Sized + Ord + Eq + Hash, { self.map.swap_remove(key) @@ -215,9 +266,9 @@ impl Map { #[cfg(feature = "preserve_order")] #[cfg_attr(docsrs, doc(cfg(feature = "preserve_order")))] #[inline] - pub fn swap_remove_entry(&mut self, key: &Q) -> Option<(String, Value)> + pub fn swap_remove_entry(&mut self, key: &Q) -> Option<(K, V)> where - String: Borrow, + K: Borrow, Q: ?Sized + Ord + Eq + Hash, { self.map.swap_remove_entry(key) @@ -233,9 +284,9 @@ impl Map { #[cfg(feature = "preserve_order")] #[cfg_attr(docsrs, doc(cfg(feature = "preserve_order")))] #[inline] - pub fn shift_remove(&mut self, key: &Q) -> Option + pub fn shift_remove(&mut self, key: &Q) -> Option where - String: Borrow, + K: Borrow, Q: ?Sized + Ord + Eq + Hash, { self.map.shift_remove(key) @@ -251,9 +302,9 @@ impl Map { #[cfg(feature = "preserve_order")] #[cfg_attr(docsrs, doc(cfg(feature = "preserve_order")))] #[inline] - pub fn shift_remove_entry(&mut self, key: &Q) -> Option<(String, Value)> + pub fn shift_remove_entry(&mut self, key: &Q) -> Option<(K, V)> where - String: Borrow, + K: Borrow, Q: ?Sized + Ord + Eq + Hash, { self.map.shift_remove_entry(key) @@ -271,9 +322,9 @@ impl Map { /// Gets the given key's corresponding entry in the map for in-place /// manipulation. - pub fn entry(&mut self, key: S) -> Entry + pub fn entry(&mut self, key: S) -> Entry where - S: Into, + S: Into, { #[cfg(not(feature = "preserve_order"))] use alloc::collections::btree_map::Entry as EntryImpl; @@ -300,7 +351,7 @@ impl Map { /// Gets an iterator over the entries of the map. #[inline] - pub fn iter(&self) -> Iter { + pub fn iter(&self) -> Iter { Iter { iter: self.map.iter(), } @@ -308,7 +359,7 @@ impl Map { /// Gets a mutable iterator over the entries of the map. #[inline] - pub fn iter_mut(&mut self) -> IterMut { + pub fn iter_mut(&mut self) -> IterMut { IterMut { iter: self.map.iter_mut(), } @@ -316,7 +367,7 @@ impl Map { /// Gets an iterator over the keys of the map. #[inline] - pub fn keys(&self) -> Keys { + pub fn keys(&self) -> Keys { Keys { iter: self.map.keys(), } @@ -324,7 +375,7 @@ impl Map { /// Gets an iterator over the values of the map. #[inline] - pub fn values(&self) -> Values { + pub fn values(&self) -> Values { Values { iter: self.map.values(), } @@ -332,7 +383,7 @@ impl Map { /// Gets an iterator over mutable values of the map. #[inline] - pub fn values_mut(&mut self) -> ValuesMut { + pub fn values_mut(&mut self) -> ValuesMut { ValuesMut { iter: self.map.values_mut(), } @@ -340,7 +391,7 @@ impl Map { /// Gets an iterator over the values of the map. #[inline] - pub fn into_values(self) -> IntoValues { + pub fn into_values(self) -> IntoValues { IntoValues { iter: self.map.into_values(), } @@ -353,7 +404,7 @@ impl Map { #[inline] pub fn retain(&mut self, f: F) where - F: FnMut(&String, &mut Value) -> bool, + F: FnMut(&K, &mut V) -> bool, { self.map.retain(f); } @@ -383,19 +434,19 @@ impl Map { } #[allow(clippy::derivable_impls)] // clippy bug: https://github.com/rust-lang/rust-clippy/issues/7655 -impl Default for Map { +impl Default for GenericMap { #[inline] fn default() -> Self { - Map { + GenericMap { map: MapImpl::new(), } } } -impl Clone for Map { +impl Clone for GenericMap { #[inline] fn clone(&self) -> Self { - Map { + GenericMap { map: self.map.clone(), } } @@ -406,16 +457,16 @@ impl Clone for Map { } } -impl PartialEq for Map { +impl PartialEq for GenericMap { #[inline] fn eq(&self, other: &Self) -> bool { self.map.eq(&other.map) } } -impl Eq for Map {} +impl Eq for GenericMap {} -impl Hash for Map { +impl Hash for GenericMap { fn hash(&self, state: &mut H) { #[cfg(not(feature = "preserve_order"))] { @@ -447,14 +498,14 @@ impl Hash for Map { /// } /// # ; /// ``` -impl ops::Index<&Q> for Map +impl ops::Index<&Q> for GenericMap where - String: Borrow, + K: Borrow, Q: ?Sized + Ord + Eq + Hash, { - type Output = Value; + type Output = V; - fn index(&self, index: &Q) -> &Value { + fn index(&self, index: &Q) -> &V { self.map.index(index) } } @@ -470,17 +521,17 @@ where /// # /// map["key"] = json!("value"); /// ``` -impl ops::IndexMut<&Q> for Map +impl ops::IndexMut<&Q> for GenericMap where - String: Borrow, + K: Borrow, Q: ?Sized + Ord + Eq + Hash, { - fn index_mut(&mut self, index: &Q) -> &mut Value { + fn index_mut(&mut self, index: &Q) -> &mut V { self.map.get_mut(index).expect("no entry found for key") } } -impl Debug for Map { +impl Debug for GenericMap { #[inline] fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { self.map.fmt(formatter) @@ -488,7 +539,7 @@ impl Debug for Map { } #[cfg(any(feature = "std", feature = "alloc"))] -impl serde::ser::Serialize for Map { +impl serde::ser::Serialize for GenericMap { #[inline] fn serialize(&self, serializer: S) -> Result where @@ -503,16 +554,16 @@ impl serde::ser::Serialize for Map { } } -impl<'de> de::Deserialize<'de> for Map { +impl<'de, K: MapKey, V: MapValue> de::Deserialize<'de> for GenericMap { #[inline] fn deserialize(deserializer: D) -> Result where D: de::Deserializer<'de>, { - struct Visitor; + struct Visitor(PhantomData, PhantomData); - impl<'de> de::Visitor<'de> for Visitor { - type Value = Map; + impl<'de, K: MapKey, V: MapValue> de::Visitor<'de> for Visitor { + type Value = GenericMap; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("a map") @@ -523,18 +574,18 @@ impl<'de> de::Deserialize<'de> for Map { where E: de::Error, { - Ok(Map::new()) + Ok(GenericMap::new()) } #[cfg(any(feature = "std", feature = "alloc"))] #[inline] - fn visit_map(self, mut visitor: V) -> Result + fn visit_map(self, mut map: A) -> Result where - V: de::MapAccess<'de>, + A: de::MapAccess<'de>, { - let mut values = Map::new(); + let mut values = GenericMap::new(); - while let Some((key, value)) = tri!(visitor.next_entry()) { + while let Some((key, value)) = tri!(map.next_entry()) { values.insert(key, value); } @@ -542,33 +593,33 @@ impl<'de> de::Deserialize<'de> for Map { } } - deserializer.deserialize_map(Visitor) + deserializer.deserialize_map(Visitor(Default::default(), Default::default())) } } -impl FromIterator<(String, Value)> for Map { +impl FromIterator<(K, V)> for GenericMap { fn from_iter(iter: T) -> Self where - T: IntoIterator, + T: IntoIterator, { - Map { + GenericMap { map: FromIterator::from_iter(iter), } } } -impl Extend<(String, Value)> for Map { +impl Extend<(K, V)> for GenericMap { fn extend(&mut self, iter: T) where - T: IntoIterator, + T: IntoIterator, { self.map.extend(iter); } } macro_rules! delegate_iterator { - (($name:ident $($generics:tt)*) => $item:ty) => { - impl $($generics)* Iterator for $name $($generics)* { + (($name:ident $(<$($generic:tt),*>)? $(where $($bound_ident:tt: $bounds:tt),*)?) => $item:ty) => { + impl $(<$($generic),*>)? Iterator for $name $(<$($generic),*>)? $(where $($bound_ident: $bounds),*)? { type Item = $item; #[inline] fn next(&mut self) -> Option { @@ -580,25 +631,28 @@ macro_rules! delegate_iterator { } } - impl $($generics)* DoubleEndedIterator for $name $($generics)* { + impl $(<$($generic),*>)? DoubleEndedIterator for $name $(<$($generic),*>)? $(where $($bound_ident: $bounds),*)? { #[inline] fn next_back(&mut self) -> Option { self.iter.next_back() } } - impl $($generics)* ExactSizeIterator for $name $($generics)* { + impl $(<$($generic),*>)? ExactSizeIterator for $name $(<$($generic),*>)? $(where $($bound_ident: $bounds),*)? { #[inline] fn len(&self) -> usize { self.iter.len() } } - impl $($generics)* FusedIterator for $name $($generics)* {} + impl $(<$($generic),*>)? FusedIterator for $name $(<$($generic),*>)? $(where $($bound_ident: $bounds),*)? {} } } -impl<'de> de::IntoDeserializer<'de, Error> for Map { +impl<'de, K: MapKey, V: MapValue> de::IntoDeserializer<'de, Error> for GenericMap +where + GenericMap: de::Deserializer<'de, Error = Error>, +{ type Deserializer = Self; fn into_deserializer(self) -> Self::Deserializer { @@ -606,7 +660,10 @@ impl<'de> de::IntoDeserializer<'de, Error> for Map { } } -impl<'de> de::IntoDeserializer<'de, Error> for &'de Map { +impl<'de, K: MapKey, V: MapValue> de::IntoDeserializer<'de, Error> for &'de GenericMap +where + &'de GenericMap: de::Deserializer<'de, Error = Error>, +{ type Deserializer = Self; fn into_deserializer(self) -> Self::Deserializer { @@ -620,34 +677,34 @@ impl<'de> de::IntoDeserializer<'de, Error> for &'de Map { /// This enum is constructed from the [`entry`] method on [`Map`]. /// /// [`entry`]: Map::entry -pub enum Entry<'a> { +pub enum Entry<'a, K: MapKey, V: MapValue> { /// A vacant Entry. - Vacant(VacantEntry<'a>), + Vacant(VacantEntry<'a, K, V>), /// An occupied Entry. - Occupied(OccupiedEntry<'a>), + Occupied(OccupiedEntry<'a, K, V>), } /// A vacant Entry. It is part of the [`Entry`] enum. -pub struct VacantEntry<'a> { - vacant: VacantEntryImpl<'a>, +pub struct VacantEntry<'a, K, V> { + vacant: VacantEntryImpl<'a, K, V>, } /// An occupied Entry. It is part of the [`Entry`] enum. -pub struct OccupiedEntry<'a> { - occupied: OccupiedEntryImpl<'a>, +pub struct OccupiedEntry<'a, K, V> { + occupied: OccupiedEntryImpl<'a, K, V>, } #[cfg(not(feature = "preserve_order"))] -type VacantEntryImpl<'a> = btree_map::VacantEntry<'a, String, Value>; +type VacantEntryImpl<'a, K, V> = btree_map::VacantEntry<'a, K, V>; #[cfg(feature = "preserve_order")] -type VacantEntryImpl<'a> = indexmap::map::VacantEntry<'a, String, Value>; +type VacantEntryImpl<'a, K, V> = indexmap::map::VacantEntry<'a, K, V>; #[cfg(not(feature = "preserve_order"))] -type OccupiedEntryImpl<'a> = btree_map::OccupiedEntry<'a, String, Value>; +type OccupiedEntryImpl<'a, K, V> = btree_map::OccupiedEntry<'a, K, V>; #[cfg(feature = "preserve_order")] -type OccupiedEntryImpl<'a> = indexmap::map::OccupiedEntry<'a, String, Value>; +type OccupiedEntryImpl<'a, K, V> = indexmap::map::OccupiedEntry<'a, K, V>; -impl<'a> Entry<'a> { +impl<'a, K: MapKey, V: MapValue> Entry<'a, K, V> { /// Returns a reference to this entry's key. /// /// # Examples @@ -656,7 +713,7 @@ impl<'a> Entry<'a> { /// let mut map = serde_json::Map::new(); /// assert_eq!(map.entry("serde").key(), &"serde"); /// ``` - pub fn key(&self) -> &String { + pub fn key(&self) -> &K { match self { Entry::Vacant(e) => e.key(), Entry::Occupied(e) => e.key(), @@ -676,7 +733,7 @@ impl<'a> Entry<'a> { /// /// assert_eq!(map["serde"], 12); /// ``` - pub fn or_insert(self, default: Value) -> &'a mut Value { + pub fn or_insert(self, default: V) -> &'a mut V { match self { Entry::Vacant(entry) => entry.insert(default), Entry::Occupied(entry) => entry.into_mut(), @@ -697,9 +754,9 @@ impl<'a> Entry<'a> { /// /// assert_eq!(map["serde"], "hoho".to_owned()); /// ``` - pub fn or_insert_with(self, default: F) -> &'a mut Value + pub fn or_insert_with(self, default: F) -> &'a mut V where - F: FnOnce() -> Value, + F: FnOnce() -> V, { match self { Entry::Vacant(entry) => entry.insert(default()), @@ -730,7 +787,7 @@ impl<'a> Entry<'a> { /// ``` pub fn and_modify(self, f: F) -> Self where - F: FnOnce(&mut Value), + F: FnOnce(&mut V), { match self { Entry::Occupied(mut entry) => { @@ -742,7 +799,7 @@ impl<'a> Entry<'a> { } } -impl<'a> VacantEntry<'a> { +impl<'a, K: MapKey, V: MapValue> VacantEntry<'a, K, V> { /// Gets a reference to the key that would be used when inserting a value /// through the VacantEntry. /// @@ -761,7 +818,7 @@ impl<'a> VacantEntry<'a> { /// } /// ``` #[inline] - pub fn key(&self) -> &String { + pub fn key(&self) -> &K { self.vacant.key() } @@ -785,12 +842,12 @@ impl<'a> VacantEntry<'a> { /// } /// ``` #[inline] - pub fn insert(self, value: Value) -> &'a mut Value { + pub fn insert(self, value: V) -> &'a mut V { self.vacant.insert(value) } } -impl<'a> OccupiedEntry<'a> { +impl<'a, K: MapKey, V: MapValue> OccupiedEntry<'a, K, V> { /// Gets a reference to the key in the entry. /// /// # Examples @@ -811,7 +868,7 @@ impl<'a> OccupiedEntry<'a> { /// } /// ``` #[inline] - pub fn key(&self) -> &String { + pub fn key(&self) -> &K { self.occupied.key() } @@ -835,7 +892,7 @@ impl<'a> OccupiedEntry<'a> { /// } /// ``` #[inline] - pub fn get(&self) -> &Value { + pub fn get(&self) -> &V { self.occupied.get() } @@ -861,7 +918,7 @@ impl<'a> OccupiedEntry<'a> { /// assert_eq!(map["serde"].as_array().unwrap().len(), 4); /// ``` #[inline] - pub fn get_mut(&mut self) -> &mut Value { + pub fn get_mut(&mut self) -> &mut V { self.occupied.get_mut() } @@ -887,7 +944,7 @@ impl<'a> OccupiedEntry<'a> { /// assert_eq!(map["serde"].as_array().unwrap().len(), 4); /// ``` #[inline] - pub fn into_mut(self) -> &'a mut Value { + pub fn into_mut(self) -> &'a mut V { self.occupied.into_mut() } @@ -913,7 +970,7 @@ impl<'a> OccupiedEntry<'a> { /// } /// ``` #[inline] - pub fn insert(&mut self, value: Value) -> Value { + pub fn insert(&mut self, value: V) -> V { self.occupied.insert(value) } @@ -943,7 +1000,7 @@ impl<'a> OccupiedEntry<'a> { /// } /// ``` #[inline] - pub fn remove(self) -> Value { + pub fn remove(self) -> V { #[cfg(feature = "preserve_order")] return self.swap_remove(); #[cfg(not(feature = "preserve_order"))] @@ -960,7 +1017,7 @@ impl<'a> OccupiedEntry<'a> { #[cfg(feature = "preserve_order")] #[cfg_attr(docsrs, doc(cfg(feature = "preserve_order")))] #[inline] - pub fn swap_remove(self) -> Value { + pub fn swap_remove(self) -> V { self.occupied.swap_remove() } @@ -974,7 +1031,7 @@ impl<'a> OccupiedEntry<'a> { #[cfg(feature = "preserve_order")] #[cfg_attr(docsrs, doc(cfg(feature = "preserve_order")))] #[inline] - pub fn shift_remove(self) -> Value { + pub fn shift_remove(self) -> V { self.occupied.shift_remove() } @@ -1006,7 +1063,7 @@ impl<'a> OccupiedEntry<'a> { /// } /// ``` #[inline] - pub fn remove_entry(self) -> (String, Value) { + pub fn remove_entry(self) -> (K, V) { #[cfg(feature = "preserve_order")] return self.swap_remove_entry(); #[cfg(not(feature = "preserve_order"))] @@ -1023,7 +1080,7 @@ impl<'a> OccupiedEntry<'a> { #[cfg(feature = "preserve_order")] #[cfg_attr(docsrs, doc(cfg(feature = "preserve_order")))] #[inline] - pub fn swap_remove_entry(self) -> (String, Value) { + pub fn swap_remove_entry(self) -> (K, V) { self.occupied.swap_remove_entry() } @@ -1037,16 +1094,16 @@ impl<'a> OccupiedEntry<'a> { #[cfg(feature = "preserve_order")] #[cfg_attr(docsrs, doc(cfg(feature = "preserve_order")))] #[inline] - pub fn shift_remove_entry(self) -> (String, Value) { + pub fn shift_remove_entry(self) -> (K, V) { self.occupied.shift_remove_entry() } } ////////////////////////////////////////////////////////////////////////////// -impl<'a> IntoIterator for &'a Map { - type Item = (&'a String, &'a Value); - type IntoIter = Iter<'a>; +impl<'a, K: MapKey, V: MapValue> IntoIterator for &'a GenericMap { + type Item = (&'a K, &'a V); + type IntoIter = Iter<'a, K, V>; #[inline] fn into_iter(self) -> Self::IntoIter { Iter { @@ -1056,22 +1113,22 @@ impl<'a> IntoIterator for &'a Map { } /// An iterator over a serde_json::Map's entries. -pub struct Iter<'a> { - iter: IterImpl<'a>, +pub struct Iter<'a, K: MapKey, V: MapValue> { + iter: IterImpl<'a, K, V>, } #[cfg(not(feature = "preserve_order"))] -type IterImpl<'a> = btree_map::Iter<'a, String, Value>; +type IterImpl<'a, K, V> = btree_map::Iter<'a, K, V>; #[cfg(feature = "preserve_order")] -type IterImpl<'a> = indexmap::map::Iter<'a, String, Value>; +type IterImpl<'a, K, V> = indexmap::map::Iter<'a, K, V>; -delegate_iterator!((Iter<'a>) => (&'a String, &'a Value)); +delegate_iterator!((Iter<'a, K, V> where K: MapKey, V: MapValue) => (&'a K, &'a V)); ////////////////////////////////////////////////////////////////////////////// -impl<'a> IntoIterator for &'a mut Map { - type Item = (&'a String, &'a mut Value); - type IntoIter = IterMut<'a>; +impl<'a, K: MapKey, V: MapValue> IntoIterator for &'a mut GenericMap { + type Item = (&'a K, &'a mut V); + type IntoIter = IterMut<'a, K, V>; #[inline] fn into_iter(self) -> Self::IntoIter { IterMut { @@ -1081,22 +1138,22 @@ impl<'a> IntoIterator for &'a mut Map { } /// A mutable iterator over a serde_json::Map's entries. -pub struct IterMut<'a> { - iter: IterMutImpl<'a>, +pub struct IterMut<'a, K: MapKey, V: MapValue> { + iter: IterMutImpl<'a, K, V>, } #[cfg(not(feature = "preserve_order"))] -type IterMutImpl<'a> = btree_map::IterMut<'a, String, Value>; +type IterMutImpl<'a, K, V> = btree_map::IterMut<'a, K, V>; #[cfg(feature = "preserve_order")] -type IterMutImpl<'a> = indexmap::map::IterMut<'a, String, Value>; +type IterMutImpl<'a, K, V> = indexmap::map::IterMut<'a, K, V>; -delegate_iterator!((IterMut<'a>) => (&'a String, &'a mut Value)); +delegate_iterator!((IterMut<'a, K, V> where K: MapKey, V: MapValue) => (&'a K, &'a mut V)); ////////////////////////////////////////////////////////////////////////////// -impl IntoIterator for Map { - type Item = (String, Value); - type IntoIter = IntoIter; +impl IntoIterator for GenericMap { + type Item = (K, V); + type IntoIter = IntoIter; #[inline] fn into_iter(self) -> Self::IntoIter { IntoIter { @@ -1106,69 +1163,69 @@ impl IntoIterator for Map { } /// An owning iterator over a serde_json::Map's entries. -pub struct IntoIter { - iter: IntoIterImpl, +pub struct IntoIter { + iter: IntoIterImpl, } #[cfg(not(feature = "preserve_order"))] -type IntoIterImpl = btree_map::IntoIter; +type IntoIterImpl = btree_map::IntoIter; #[cfg(feature = "preserve_order")] -type IntoIterImpl = indexmap::map::IntoIter; +type IntoIterImpl = indexmap::map::IntoIter; -delegate_iterator!((IntoIter) => (String, Value)); +delegate_iterator!((IntoIter where K: MapKey, V: MapValue) => (K, V)); ////////////////////////////////////////////////////////////////////////////// /// An iterator over a serde_json::Map's keys. -pub struct Keys<'a> { - iter: KeysImpl<'a>, +pub struct Keys<'a, K: MapKey, V: MapValue> { + iter: KeysImpl<'a, K, V>, } #[cfg(not(feature = "preserve_order"))] -type KeysImpl<'a> = btree_map::Keys<'a, String, Value>; +type KeysImpl<'a, K, V> = btree_map::Keys<'a, K, V>; #[cfg(feature = "preserve_order")] -type KeysImpl<'a> = indexmap::map::Keys<'a, String, Value>; +type KeysImpl<'a, K, V> = indexmap::map::Keys<'a, K, V>; -delegate_iterator!((Keys<'a>) => &'a String); +delegate_iterator!((Keys<'a, K, V> where K: MapKey, V: MapValue) => &'a K); ////////////////////////////////////////////////////////////////////////////// /// An iterator over a serde_json::Map's values. -pub struct Values<'a> { - iter: ValuesImpl<'a>, +pub struct Values<'a, K: MapKey, V: MapValue> { + iter: ValuesImpl<'a, K, V>, } #[cfg(not(feature = "preserve_order"))] -type ValuesImpl<'a> = btree_map::Values<'a, String, Value>; +type ValuesImpl<'a, K, V> = btree_map::Values<'a, K, V>; #[cfg(feature = "preserve_order")] -type ValuesImpl<'a> = indexmap::map::Values<'a, String, Value>; +type ValuesImpl<'a, K, V> = indexmap::map::Values<'a, K, V>; -delegate_iterator!((Values<'a>) => &'a Value); +delegate_iterator!((Values<'a, K, V> where K: MapKey, V: MapValue) => &'a V); ////////////////////////////////////////////////////////////////////////////// /// A mutable iterator over a serde_json::Map's values. -pub struct ValuesMut<'a> { - iter: ValuesMutImpl<'a>, +pub struct ValuesMut<'a, K: MapKey, V: MapValue> { + iter: ValuesMutImpl<'a, K, V>, } #[cfg(not(feature = "preserve_order"))] -type ValuesMutImpl<'a> = btree_map::ValuesMut<'a, String, Value>; +type ValuesMutImpl<'a, K, V> = btree_map::ValuesMut<'a, K, V>; #[cfg(feature = "preserve_order")] -type ValuesMutImpl<'a> = indexmap::map::ValuesMut<'a, String, Value>; +type ValuesMutImpl<'a, K, V> = indexmap::map::ValuesMut<'a, K, V>; -delegate_iterator!((ValuesMut<'a>) => &'a mut Value); +delegate_iterator!((ValuesMut<'a, K, V> where K: MapKey, V: MapValue) => &'a mut V); ////////////////////////////////////////////////////////////////////////////// /// An owning iterator over a serde_json::Map's values. -pub struct IntoValues { - iter: IntoValuesImpl, +pub struct IntoValues { + iter: IntoValuesImpl, } #[cfg(not(feature = "preserve_order"))] -type IntoValuesImpl = btree_map::IntoValues; +type IntoValuesImpl = btree_map::IntoValues; #[cfg(feature = "preserve_order")] -type IntoValuesImpl = indexmap::map::IntoValues; +type IntoValuesImpl = indexmap::map::IntoValues; -delegate_iterator!((IntoValues) => Value); +delegate_iterator!((IntoValues where K: MapKey, V: MapValue) => V); diff --git a/src/spanned/de.rs b/src/spanned/de.rs new file mode 100644 index 000000000..7b221e6b7 --- /dev/null +++ b/src/spanned/de.rs @@ -0,0 +1,178 @@ +use crate::de::Deserializer; +use crate::error::Error; +use crate::read; +use crate::read::Read; +use crate::spanned::SpanPosition; +use serde::de::value::BorrowedStrDeserializer; +use serde::de::IntoDeserializer as _; + +#[derive(Default)] +enum SpannedDeserializerState { + #[default] + StartLine, + StartCol, + StartOffset, + Value, + EndLine, + EndCol, + EndOffset, + Done, +} + +pub(crate) struct SpannedDeserializer<'de, 'p, R: Read<'de>> { + phantom_data: core::marker::PhantomData<&'de ()>, + state: SpannedDeserializerState, + start: SpanPosition, + end: SpanPosition, + value_de: Option<&'p mut Deserializer>, +} + +impl<'de, 'p, R: Read<'de>> SpannedDeserializer<'de, 'p, R> { + pub(crate) fn new(de: &'p mut Deserializer) -> Self { + let read_pos = de.position(); + Self { + phantom_data: Default::default(), + state: Default::default(), + start: SpanPosition { + line: read_pos.line, + column: read_pos.column + 1, + byte_offset: de.byte_offset(), + }, + end: SpanPosition::default(), + value_de: Some(de), + } + } +} + +impl<'de, 'p, R: Read<'de>> serde::de::MapAccess<'de> for SpannedDeserializer<'de, 'p, R> { + type Error = Error; + fn next_key_seed(&mut self, seed: K) -> Result, Error> + where + K: serde::de::DeserializeSeed<'de>, + { + match self.state { + SpannedDeserializerState::StartLine => seed + .deserialize(BorrowedStrDeserializer::new( + crate::spanned::START_LINE_FIELD, + )) + .map(Some), + SpannedDeserializerState::StartCol => seed + .deserialize(BorrowedStrDeserializer::new( + crate::spanned::START_COL_FIELD, + )) + .map(Some), + SpannedDeserializerState::StartOffset => seed + .deserialize(BorrowedStrDeserializer::new( + crate::spanned::START_OFFSET_FIELD, + )) + .map(Some), + SpannedDeserializerState::Value => seed + .deserialize(BorrowedStrDeserializer::new(crate::spanned::VALUE_FIELD)) + .map(Some), + SpannedDeserializerState::EndLine => seed + .deserialize(BorrowedStrDeserializer::new(crate::spanned::END_LINE_FIELD)) + .map(Some), + SpannedDeserializerState::EndCol => seed + .deserialize(BorrowedStrDeserializer::new(crate::spanned::END_COL_FIELD)) + .map(Some), + SpannedDeserializerState::EndOffset => seed + .deserialize(BorrowedStrDeserializer::new( + crate::spanned::END_OFFSET_FIELD, + )) + .map(Some), + SpannedDeserializerState::Done => Ok(None), + } + } + + fn next_value_seed(&mut self, seed: V) -> Result + where + V: serde::de::DeserializeSeed<'de>, + { + match self.state { + SpannedDeserializerState::StartLine => { + self.state = SpannedDeserializerState::StartCol; + seed.deserialize(self.start.line.into_deserializer()) + } + SpannedDeserializerState::StartCol => { + self.state = SpannedDeserializerState::StartOffset; + seed.deserialize(self.start.column.into_deserializer()) + } + SpannedDeserializerState::StartOffset => { + self.state = SpannedDeserializerState::Value; + seed.deserialize(self.start.byte_offset.into_deserializer()) + } + SpannedDeserializerState::Value => { + self.state = SpannedDeserializerState::EndLine; + let de = self.value_de.take().unwrap(); + let res = seed.deserialize(&mut *de); + let read_pos = de.position(); + self.end = SpanPosition { + line: read_pos.line, + column: read_pos.column, + byte_offset: de.byte_offset(), + }; + res + } + SpannedDeserializerState::EndLine => { + self.state = SpannedDeserializerState::EndCol; + seed.deserialize(self.end.line.into_deserializer()) + } + SpannedDeserializerState::EndCol => { + self.state = SpannedDeserializerState::EndOffset; + seed.deserialize(self.end.column.into_deserializer()) + } + SpannedDeserializerState::EndOffset => { + self.state = SpannedDeserializerState::Done; + seed.deserialize(self.end.byte_offset.into_deserializer()) + } + SpannedDeserializerState::Done => { + panic!("next_value_seed called before next_key_seed") + } + } + } +} + +#[cfg(feature = "spanned")] +fn from_trait_spanned<'de, R, T>(read: R) -> crate::Result +where + R: Read<'de>, + T: serde::de::Deserialize<'de>, +{ + let mut de = Deserializer::new_spanned(read); + let value = tri!(serde::de::Deserialize::deserialize(&mut de)); + + // Make sure the whole stream has been consumed. + tri!(de.end()); + Ok(value) +} + +/// TODO: document +#[cfg(all(feature = "std", feature = "spanned"))] +#[cfg_attr(docsrs, doc(cfg(all(feature = "std", feature = "spanned"))))] +pub fn from_reader_spanned(rdr: R) -> crate::Result +where + R: crate::io::Read, + T: serde::de::DeserializeOwned, +{ + from_trait_spanned(read::IoRead::new(rdr)) +} + +/// TODO: document +#[cfg(feature = "spanned")] +#[cfg_attr(docsrs, doc(cfg(feature = "spanned")))] +pub fn from_slice_spanned<'a, T>(v: &'a [u8]) -> crate::Result +where + T: serde::de::Deserialize<'a>, +{ + from_trait_spanned(read::SliceRead::new(v)) +} + +/// TODO: document +#[cfg(feature = "spanned")] +#[cfg_attr(docsrs, doc(cfg(feature = "spanned")))] +pub fn from_str_spanned<'a, T>(s: &'a str) -> crate::Result +where + T: serde::de::Deserialize<'a>, +{ + from_trait_spanned(read::StrRead::new(s)) +} diff --git a/src/spanned/mod.rs b/src/spanned/mod.rs new file mode 100644 index 000000000..d767522ce --- /dev/null +++ b/src/spanned/mod.rs @@ -0,0 +1,93 @@ +#![cfg_attr(docsrs, doc(cfg(feature = "spanned")))] +//! TODO: document + +pub(crate) use de::SpannedDeserializer; +#[doc(inline)] +pub use de::{from_reader_spanned, from_slice_spanned, from_str_spanned}; +pub use spanned::Spanned; +pub(crate) use spanned::{ + is_spanned, END_COL_FIELD, END_LINE_FIELD, END_OFFSET_FIELD, START_COL_FIELD, START_LINE_FIELD, + START_OFFSET_FIELD, VALUE_FIELD, +}; +pub use value::SpannedValue; + +mod de; +mod spanned; +pub mod value; + +/// TODO: document +#[cfg_attr(docsrs, doc(cfg(feature = "spanned")))] +#[derive(Debug, Copy, Clone)] +pub struct Span { + /// TODO: document + pub start: SpanPosition, + /// Non-inclusive end position + pub end: SpanPosition, +} + +impl Span { + /// TODO: document + #[cfg_attr(docsrs, doc(cfg(feature = "spanned")))] + pub const fn new(start: SpanPosition, end: SpanPosition) -> Self { + Self { start, end } + } + + /// TODO: document + pub const fn default() -> Self { + Self { + start: SpanPosition::default(), + end: SpanPosition::default(), + } + } + + /// Byte range + #[cfg_attr(docsrs, doc(cfg(feature = "spanned")))] + pub fn byte_span(&self) -> core::ops::Range { + self.start.byte_offset..self.end.byte_offset + } +} + +impl Default for Span { + fn default() -> Self { + Self::default() + } +} + +/// TODO: document +#[cfg_attr(docsrs, doc(cfg(feature = "spanned")))] +#[derive(Debug, Copy, Clone)] +pub struct SpanPosition { + /// Line number (1-indexed) + pub line: usize, + /// Character number in the line (1-indexed) + pub column: usize, + /// Offset (global) in the document's byte stream + pub byte_offset: usize, +} + +impl SpanPosition { + /// TODO: document + #[cfg_attr(docsrs, doc(cfg(feature = "spanned")))] + pub const fn new(line: usize, col: usize, offset: usize) -> Self { + Self { + line, + column: col, + byte_offset: offset, + } + } + + /// TODO: document + pub const fn default() -> Self { + Self { + line: 1, + column: 1, + byte_offset: 0, + } + } +} + +impl Default for SpanPosition { + fn default() -> Self { + Self::default() + } +} diff --git a/src/spanned/spanned.rs b/src/spanned/spanned.rs new file mode 100644 index 000000000..dd56fb2a3 --- /dev/null +++ b/src/spanned/spanned.rs @@ -0,0 +1,1037 @@ +use crate::spanned::{Span, SpanPosition}; +use core::cmp::Ordering; +use core::marker::Copy; +use serde::de::Visitor; + +pub(crate) const NAME: &str = "$serde_json::private::Spanned"; +pub(crate) const START_LINE_FIELD: &str = "$serde_json::private::Spanned::line_start"; +pub(crate) const START_COL_FIELD: &str = "$serde_json::private::Spanned::col_start"; +pub(crate) const START_OFFSET_FIELD: &str = "$serde_json::private::Spanned::offset_start"; +pub(crate) const VALUE_FIELD: &str = "$serde_json::private::Spanned::value"; +pub(crate) const END_LINE_FIELD: &str = "$serde_json::private::Spanned::line_end"; +pub(crate) const END_COL_FIELD: &str = "$serde_json::private::Spanned::col_end"; +pub(crate) const END_OFFSET_FIELD: &str = "$serde_json::private::Spanned::offset_end"; +const FIELDS: [&str; 7] = [ + START_LINE_FIELD, + START_COL_FIELD, + START_OFFSET_FIELD, + VALUE_FIELD, + END_LINE_FIELD, + END_COL_FIELD, + END_OFFSET_FIELD, +]; +pub(crate) fn is_spanned(name: &'static str, fields: &'static [&'static str]) -> bool { + name == NAME && fields == FIELDS +} + +/// A spanned value, indicating the where it is defined in the source. +/// +/// While this type implements [`serde::Deserialize`], it only works as intended with the +/// deserializers provided by this crate. +/// +/// Traits like `PartialEq`, `Hash`, etc. are all forwarded to the inner value and ignore the span. +/// Likewise, is its [`serde::Serialize`] implementation opaque. +#[cfg_attr(docsrs, doc(cfg(feature = "spanned")))] +pub struct Spanned { + /// TODO: document + pub(crate) span: Span, + /// TODO: document + pub(crate) value: T, +} + +impl Spanned { + /// Creates a new spanned value. + #[cfg_attr(docsrs, doc(cfg(feature = "spanned")))] + pub const fn new(span: Span, value: T) -> Self { + Spanned { span, value } + } + + /// Creates a new value with the default span. + #[cfg_attr(docsrs, doc(cfg(feature = "spanned")))] + pub const fn new_default_span(value: T) -> Self { + let span = Span::default(); + Spanned { span, value } + } + + /// Byte range + #[cfg_attr(docsrs, doc(cfg(feature = "spanned")))] + pub fn byte_span(&self) -> core::ops::Range { + self.span.byte_span() + } + + /// TODO: docoument + #[cfg_attr(docsrs, doc(cfg(feature = "spanned")))] + pub fn span(&self) -> Span { + self.span + } + + /// Consumes the spanned value and returns the contained value. + #[cfg_attr(docsrs, doc(cfg(feature = "spanned")))] + pub fn into_inner(self) -> T { + self.value + } + + /// Returns a reference to the contained value. + #[cfg_attr(docsrs, doc(cfg(feature = "spanned")))] + pub fn get_ref(&self) -> &T { + &self.value + } + + /// Returns a mutable reference to the contained value. + #[cfg_attr(docsrs, doc(cfg(feature = "spanned")))] + pub fn get_mut(&mut self) -> &mut T { + &mut self.value + } +} + +impl core::fmt::Debug for Spanned { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("Spanned") + .field("span", &self.span) + .field("value", &self.value) + .finish() + } +} + +impl Clone for Spanned { + fn clone(&self) -> Self { + Spanned { + span: self.span, + value: self.value.clone(), + } + } +} + +impl Copy for Spanned {} + +impl core::borrow::Borrow for Spanned { + fn borrow(&self) -> &str { + self.get_ref() + } +} + +impl AsRef for Spanned { + fn as_ref(&self) -> &T { + self.get_ref() + } +} + +impl AsMut for Spanned { + fn as_mut(&mut self) -> &mut T { + self.get_mut() + } +} + +impl PartialEq for Spanned { + fn eq(&self, other: &Self) -> bool { + self.value.eq(&other.value) + } +} + +impl Eq for Spanned {} + +impl core::hash::Hash for Spanned { + fn hash(&self, state: &mut H) { + self.value.hash(state); + } +} + +impl PartialOrd for Spanned { + fn partial_cmp(&self, other: &Self) -> Option { + self.value.partial_cmp(&other.value) + } +} + +impl Ord for Spanned { + fn cmp(&self, other: &Self) -> Ordering { + self.value.cmp(&other.value) + } +} +// +// impl<'de, T: serde::de::Deserialize<'de>> FromStr for Spanned { +// type Err = Error; +// fn from_str(s: &'de str) -> Result, Error> { +// crate::spanned::from_str_spanned(s) +// } +// } + +impl From for Spanned { + fn from(value: T) -> Self { + Spanned { + span: Default::default(), + value, + } + } +} + +// impl core::borrow::Borrow for Spanned { +// fn borrow(&self) -> &T { +// >::as_ref(self) +// } +// } +// +// impl core::borrow::BorrowMut for Spanned { +// fn borrow_mut(&mut self) -> &mut T { +// >::as_mut(self) +// } +// } + +// impl core::borrow::Borrow for Spanned +// where +// T: core::borrow::Borrow, +// { +// fn borrow(&self) -> &Borrowed { +// self.as_ref().borrow() +// } +// } +// +// impl core::borrow::BorrowMut for Spanned +// where +// T: core::borrow::BorrowMut, +// { +// fn borrow_mut(&mut self) -> &mut Borrowed { +// self.as_mut().borrow_mut() +// } +// } + +impl<'de, T> serde::de::Deserialize<'de> for Spanned +where + T: serde::de::Deserialize<'de>, +{ + fn deserialize(deserializer: D) -> Result, D::Error> + where + D: serde::de::Deserializer<'de>, + { + pub(crate) struct SpannedVisitor(core::marker::PhantomData); + + impl<'de, T> serde::de::Visitor<'de> for SpannedVisitor + where + T: serde::de::Deserialize<'de>, + { + type Value = Spanned; + + fn expecting(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + formatter.write_str("a spanned value") + } + + fn visit_map(self, mut map: A) -> Result, A::Error> + where + A: serde::de::MapAccess<'de>, + { + let mut start_line: Option = None; + let mut start_col: Option = None; + let mut start_offset: Option = None; + let mut end_line: Option = None; + let mut end_col: Option = None; + let mut end_offset: Option = None; + let mut value: Option = None; + while let Some(key) = map.next_key()? { + match key { + START_LINE_FIELD => { + if start_line.is_some() { + return Err(serde::de::Error::duplicate_field(START_LINE_FIELD)); + } + start_line = Some(map.next_value()?); + } + START_COL_FIELD => { + if start_col.is_some() { + return Err(serde::de::Error::duplicate_field(START_COL_FIELD)); + } + start_col = Some(map.next_value()?); + } + START_OFFSET_FIELD => { + if start_offset.is_some() { + return Err(serde::de::Error::duplicate_field(START_OFFSET_FIELD)); + } + start_offset = Some(map.next_value()?); + } + VALUE_FIELD => { + if value.is_some() { + return Err(serde::de::Error::duplicate_field(VALUE_FIELD)); + } + value = Some(map.next_value()?); + } + END_LINE_FIELD => { + if end_line.is_some() { + return Err(serde::de::Error::duplicate_field(END_LINE_FIELD)); + } + end_line = Some(map.next_value()?); + } + END_COL_FIELD => { + if end_col.is_some() { + return Err(serde::de::Error::duplicate_field(END_COL_FIELD)); + } + end_col = Some(map.next_value()?); + } + END_OFFSET_FIELD => { + if end_offset.is_some() { + return Err(serde::de::Error::duplicate_field(END_OFFSET_FIELD)); + } + end_offset = Some(map.next_value()?); + } + field => { + return Err(serde::de::Error::unknown_field( + field, + &[ + START_LINE_FIELD, + START_COL_FIELD, + START_OFFSET_FIELD, + VALUE_FIELD, + END_LINE_FIELD, + END_COL_FIELD, + END_OFFSET_FIELD, + ], + )); + } + } + } + + let Some(start_line) = start_line else { + return Err(serde::de::Error::missing_field(START_LINE_FIELD)); + }; + let Some(start_col) = start_col else { + return Err(serde::de::Error::missing_field(START_COL_FIELD)); + }; + let Some(start_offset) = start_offset else { + return Err(serde::de::Error::missing_field(START_OFFSET_FIELD)); + }; + let Some(value) = value else { + return Err(serde::de::Error::missing_field(VALUE_FIELD)); + }; + let Some(end_line) = end_line else { + return Err(serde::de::Error::missing_field(END_LINE_FIELD)); + }; + let Some(end_col) = end_col else { + return Err(serde::de::Error::missing_field(END_COL_FIELD)); + }; + let Some(end_offset) = end_offset else { + return Err(serde::de::Error::missing_field(END_OFFSET_FIELD)); + }; + Ok(Spanned { + span: Span::new( + SpanPosition::new(start_line, start_col, start_offset), + SpanPosition::new(end_line, end_col, end_offset), + ), + value, + }) + } + } + + let visitor = SpannedVisitor(core::marker::PhantomData::); + + deserializer.deserialize_struct(NAME, &FIELDS, visitor) + } +} + +impl<'de, T> serde::de::DeserializeSeed<'de> for Spanned +where + T: serde::de::DeserializeSeed<'de>, +{ + type Value = Spanned; + + fn deserialize(self, deserializer: D) -> Result, D::Error> + where + D: serde::de::Deserializer<'de>, + { + pub(crate) struct SpannedVisitor(T); + + impl<'de, T> serde::de::Visitor<'de> for SpannedVisitor> + where + T: serde::de::DeserializeSeed<'de>, + { + type Value = Spanned; + + fn expecting(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + formatter.write_str("a spanned value") + } + + fn visit_map(mut self, mut map: A) -> Result, A::Error> + where + A: serde::de::MapAccess<'de>, + { + let mut start_line: Option = None; + let mut start_col: Option = None; + let mut start_offset: Option = None; + let mut end_line: Option = None; + let mut end_col: Option = None; + let mut end_offset: Option = None; + let mut value: Option = None; + while let Some(key) = map.next_key()? { + match key { + START_LINE_FIELD => { + if start_line.is_some() { + return Err(serde::de::Error::duplicate_field(START_LINE_FIELD)); + } + start_line = Some(map.next_value()?); + } + START_COL_FIELD => { + if start_col.is_some() { + return Err(serde::de::Error::duplicate_field(START_COL_FIELD)); + } + start_col = Some(map.next_value()?); + } + START_OFFSET_FIELD => { + if start_offset.is_some() { + return Err(serde::de::Error::duplicate_field(START_OFFSET_FIELD)); + } + start_offset = Some(map.next_value()?); + } + VALUE_FIELD => { + if value.is_some() { + return Err(serde::de::Error::duplicate_field(VALUE_FIELD)); + } + value = Some(map.next_value_seed(self.0.take().unwrap())?); + } + END_LINE_FIELD => { + if end_line.is_some() { + return Err(serde::de::Error::duplicate_field(END_LINE_FIELD)); + } + end_line = Some(map.next_value()?); + } + END_COL_FIELD => { + if end_col.is_some() { + return Err(serde::de::Error::duplicate_field(END_COL_FIELD)); + } + end_col = Some(map.next_value()?); + } + END_OFFSET_FIELD => { + if end_offset.is_some() { + return Err(serde::de::Error::duplicate_field(END_OFFSET_FIELD)); + } + end_offset = Some(map.next_value()?); + } + field => { + return Err(serde::de::Error::unknown_field( + field, + &[ + START_LINE_FIELD, + START_COL_FIELD, + START_OFFSET_FIELD, + VALUE_FIELD, + END_LINE_FIELD, + END_COL_FIELD, + END_OFFSET_FIELD, + ], + )); + } + } + } + + let Some(start_line) = start_line else { + return Err(serde::de::Error::missing_field(START_LINE_FIELD)); + }; + let Some(start_col) = start_col else { + return Err(serde::de::Error::missing_field(START_COL_FIELD)); + }; + let Some(start_offset) = start_offset else { + return Err(serde::de::Error::missing_field(START_OFFSET_FIELD)); + }; + let Some(value) = value else { + return Err(serde::de::Error::missing_field(VALUE_FIELD)); + }; + let Some(end_line) = end_line else { + return Err(serde::de::Error::missing_field(END_LINE_FIELD)); + }; + let Some(end_col) = end_col else { + return Err(serde::de::Error::missing_field(END_COL_FIELD)); + }; + let Some(end_offset) = end_offset else { + return Err(serde::de::Error::missing_field(END_OFFSET_FIELD)); + }; + Ok(Spanned { + span: Span::new( + SpanPosition::new(start_line, start_col, start_offset), + SpanPosition::new(end_line, end_col, end_offset), + ), + value, + }) + } + } + + let visitor = SpannedVisitor(Some(self.into_inner())); + + deserializer.deserialize_struct(NAME, &FIELDS, visitor) + } +} + +impl<'de, T> serde::Deserializer<'de> for Spanned +where + T: serde::Deserializer<'de>, +{ + type Error = T::Error; + + fn deserialize_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.into_inner().deserialize_any(visitor) + } + + fn deserialize_bool(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.into_inner().deserialize_bool(visitor) + } + + fn deserialize_i8(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.into_inner().deserialize_i8(visitor) + } + + fn deserialize_i16(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.into_inner().deserialize_i16(visitor) + } + + fn deserialize_i32(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.into_inner().deserialize_i32(visitor) + } + + fn deserialize_i64(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.into_inner().deserialize_i64(visitor) + } + + fn deserialize_i128(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.into_inner().deserialize_i128(visitor) + } + + fn deserialize_u8(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.into_inner().deserialize_u8(visitor) + } + + fn deserialize_u16(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.into_inner().deserialize_u16(visitor) + } + + fn deserialize_u32(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.into_inner().deserialize_u32(visitor) + } + + fn deserialize_u64(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.into_inner().deserialize_u64(visitor) + } + + fn deserialize_u128(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.into_inner().deserialize_u128(visitor) + } + + fn deserialize_f32(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.into_inner().deserialize_f32(visitor) + } + + fn deserialize_f64(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.into_inner().deserialize_f64(visitor) + } + + fn deserialize_char(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.into_inner().deserialize_char(visitor) + } + + fn deserialize_str(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.into_inner().deserialize_str(visitor) + } + + fn deserialize_string(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.into_inner().deserialize_string(visitor) + } + + fn deserialize_bytes(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.into_inner().deserialize_bytes(visitor) + } + + fn deserialize_byte_buf(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.into_inner().deserialize_byte_buf(visitor) + } + + fn deserialize_option(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.into_inner().deserialize_option(visitor) + } + + fn deserialize_unit(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.into_inner().deserialize_unit(visitor) + } + + fn deserialize_unit_struct( + self, + name: &'static str, + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + self.into_inner().deserialize_unit_struct(name, visitor) + } + + fn deserialize_newtype_struct( + self, + name: &'static str, + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + self.into_inner().deserialize_newtype_struct(name, visitor) + } + + fn deserialize_seq(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.into_inner().deserialize_seq(visitor) + } + + fn deserialize_tuple(self, len: usize, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.into_inner().deserialize_tuple(len, visitor) + } + + fn deserialize_tuple_struct( + self, + name: &'static str, + len: usize, + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + self.into_inner() + .deserialize_tuple_struct(name, len, visitor) + } + + fn deserialize_map(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.into_inner().deserialize_map(visitor) + } + + fn deserialize_struct( + self, + name: &'static str, + fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + self.into_inner().deserialize_struct(name, fields, visitor) + } + + fn deserialize_enum( + self, + name: &'static str, + variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + self.into_inner().deserialize_enum(name, variants, visitor) + } + + fn deserialize_identifier(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.into_inner().deserialize_identifier(visitor) + } + + fn deserialize_ignored_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.into_inner().deserialize_ignored_any(visitor) + } + + fn is_human_readable(&self) -> bool { + self.get_ref().is_human_readable() + } +} + +impl<'de, T> serde::Deserializer<'de> for &'de Spanned +where + &'de T: serde::Deserializer<'de>, +{ + type Error = <&'de T as serde::de::Deserializer<'de>>::Error; + + fn deserialize_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.get_ref().deserialize_any(visitor) + } + + fn deserialize_bool(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.get_ref().deserialize_bool(visitor) + } + + fn deserialize_i8(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.get_ref().deserialize_i8(visitor) + } + + fn deserialize_i16(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.get_ref().deserialize_i16(visitor) + } + + fn deserialize_i32(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.get_ref().deserialize_i32(visitor) + } + + fn deserialize_i64(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.get_ref().deserialize_i64(visitor) + } + + fn deserialize_i128(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.get_ref().deserialize_i128(visitor) + } + + fn deserialize_u8(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.get_ref().deserialize_u8(visitor) + } + + fn deserialize_u16(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.get_ref().deserialize_u16(visitor) + } + + fn deserialize_u32(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.get_ref().deserialize_u32(visitor) + } + + fn deserialize_u64(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.get_ref().deserialize_u64(visitor) + } + + fn deserialize_u128(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.get_ref().deserialize_u128(visitor) + } + + fn deserialize_f32(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.get_ref().deserialize_f32(visitor) + } + + fn deserialize_f64(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.get_ref().deserialize_f64(visitor) + } + + fn deserialize_char(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.get_ref().deserialize_char(visitor) + } + + fn deserialize_str(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.get_ref().deserialize_str(visitor) + } + + fn deserialize_string(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.get_ref().deserialize_string(visitor) + } + + fn deserialize_bytes(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.get_ref().deserialize_bytes(visitor) + } + + fn deserialize_byte_buf(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.get_ref().deserialize_byte_buf(visitor) + } + + fn deserialize_option(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.get_ref().deserialize_option(visitor) + } + + fn deserialize_unit(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.get_ref().deserialize_unit(visitor) + } + + fn deserialize_unit_struct( + self, + name: &'static str, + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + self.get_ref().deserialize_unit_struct(name, visitor) + } + + fn deserialize_newtype_struct( + self, + name: &'static str, + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + self.get_ref().deserialize_newtype_struct(name, visitor) + } + + fn deserialize_seq(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.get_ref().deserialize_seq(visitor) + } + + fn deserialize_tuple(self, len: usize, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.get_ref().deserialize_tuple(len, visitor) + } + + fn deserialize_tuple_struct( + self, + name: &'static str, + len: usize, + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + self.get_ref().deserialize_tuple_struct(name, len, visitor) + } + + fn deserialize_map(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.get_ref().deserialize_map(visitor) + } + + fn deserialize_struct( + self, + name: &'static str, + fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + self.get_ref().deserialize_struct(name, fields, visitor) + } + + fn deserialize_enum( + self, + name: &'static str, + variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + self.get_ref().deserialize_enum(name, variants, visitor) + } + + fn deserialize_identifier(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.get_ref().deserialize_identifier(visitor) + } + + fn deserialize_ignored_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.get_ref().deserialize_ignored_any(visitor) + } + + fn is_human_readable(&self) -> bool { + self.get_ref().is_human_readable() + } +} + +impl serde::ser::Serialize for Spanned +where + T: serde::ser::Serialize, +{ + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + self.value.serialize(serializer) + } +} + +// TODO: remove - just for testing +#[cfg(test)] +mod test { + use crate::spanned::*; + use crate::*; + + fn show_spanned(s: &Spanned, source: &str) { + use codespan_reporting::diagnostic::{Diagnostic, Label}; + use codespan_reporting::files::SimpleFiles; + use codespan_reporting::term; + use codespan_reporting::term::termcolor::{ColorChoice, StandardStream}; + + let mut files = SimpleFiles::new(); + let file_id = files.add("input", source); + let diagnostic = Diagnostic::note() + .with_message(std::format!("Look, it's a {}", std::any::type_name::())) + .with_notes(std::vec![ + std::format!("{:?}", s.as_ref()), + std::format!( + "From {}:{} ({}) to {}:{} ({})", + s.span().start.line, + s.span().start.column, + s.span().start.byte_offset, + s.span().end.line, + s.span().end.column, + s.span().end.byte_offset, + ) + ]) + .with_labels(std::vec![Label::primary(file_id, s.byte_span())]); + + let writer = StandardStream::stderr(ColorChoice::Always); + let config = codespan_reporting::term::Config::default(); + let mut writer_lock = writer.lock(); + + term::emit(&mut writer_lock, &config, &files, &diagnostic).unwrap() + } + + fn show_recursive(v: &Spanned, source: &str) { + show_spanned(v, source); + match v.get_ref() { + SpannedValue::Array(values) => values.iter().for_each(|v| show_recursive(v, source)), + SpannedValue::Object(map) => map.iter().for_each(|(k, v)| { + show_spanned(k, source); + show_recursive(v, source) + }), + _ => {} + } + } + + #[test] + fn foo() { + // Some JSON input data as a &str. Maybe this comes from the user. + let data = r#" + { + "name🔥": "John Doe", + "age": 42, + "phones": [ + "+44 1234567", + "+44 2345678" + ] + }"#; + + let v: Spanned = from_str_spanned(data).unwrap(); + show_recursive(&v, data); + } +} diff --git a/src/spanned/value/de.rs b/src/spanned/value/de.rs new file mode 100644 index 000000000..9644a470c --- /dev/null +++ b/src/spanned/value/de.rs @@ -0,0 +1,1515 @@ +use crate::error::{Error, ErrorCode}; +use crate::map::SpannedMap; +use crate::number::Number; +use crate::spanned::spanned::Spanned; +use crate::spanned::value::SpannedValue; +use alloc::borrow::{Cow, ToOwned}; +use alloc::string::String; +#[cfg(feature = "raw_value")] +use alloc::string::ToString; +use alloc::vec::{self, Vec}; +use core::fmt; +use core::slice; +use core::str::FromStr; +use serde::de::{ + self, Deserialize, DeserializeSeed, Deserializer as _, EnumAccess, Expected, IntoDeserializer, + MapAccess, SeqAccess, Unexpected, VariantAccess, Visitor, +}; +use serde::forward_to_deserialize_any; + +#[cfg(feature = "arbitrary_precision")] +use crate::number::NumberFromString; + +impl<'de> Deserialize<'de> for SpannedValue { + #[inline] + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + struct SpannedValueVisitor; + + impl<'de> Visitor<'de> for SpannedValueVisitor { + type Value = SpannedValue; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("any valid JSON value") + } + + #[inline] + fn visit_bool(self, value: bool) -> Result { + Ok(SpannedValue::Bool(value)) + } + + #[inline] + fn visit_i64(self, value: i64) -> Result { + Ok(SpannedValue::Number(value.into())) + } + + fn visit_i128(self, value: i128) -> Result + where + E: serde::de::Error, + { + let de = serde::de::value::I128Deserializer::new(value); + Number::deserialize(de).map(SpannedValue::Number) + } + + #[inline] + fn visit_u64(self, value: u64) -> Result { + Ok(SpannedValue::Number(value.into())) + } + + fn visit_u128(self, value: u128) -> Result + where + E: serde::de::Error, + { + let de = serde::de::value::U128Deserializer::new(value); + Number::deserialize(de).map(SpannedValue::Number) + } + + #[inline] + fn visit_f64(self, value: f64) -> Result { + Ok(Number::from_f64(value).map_or(SpannedValue::Null, SpannedValue::Number)) + } + + #[cfg(any(feature = "std", feature = "alloc"))] + #[inline] + fn visit_str(self, value: &str) -> Result + where + E: serde::de::Error, + { + self.visit_string(String::from(value)) + } + + #[cfg(any(feature = "std", feature = "alloc"))] + #[inline] + fn visit_string(self, value: String) -> Result { + Ok(SpannedValue::String(value)) + } + + #[inline] + fn visit_none(self) -> Result { + Ok(SpannedValue::Null) + } + + #[inline] + fn visit_some(self, deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + Deserialize::deserialize(deserializer) + } + + #[inline] + fn visit_unit(self) -> Result { + Ok(SpannedValue::Null) + } + + #[inline] + fn visit_seq(self, mut visitor: V) -> Result + where + V: SeqAccess<'de>, + { + let mut vec = Vec::new(); + + while let Some(elem) = tri!(visitor.next_element()) { + vec.push(elem); + } + + Ok(SpannedValue::Array(vec)) + } + + #[cfg(any(feature = "std", feature = "alloc"))] + fn visit_map(self, mut visitor: V) -> Result + where + V: MapAccess<'de>, + { + match tri!(visitor.next_key_seed(Spanned::new(Default::default(), KeyClassifier))) { + #[cfg(feature = "arbitrary_precision")] + Some(Spanned { + value: KeyClass::Number, + span: _, + }) => { + let number: NumberFromString = tri!(visitor.next_value()); + Ok(SpannedValue::Number(number.value)) + } + #[cfg(feature = "raw_value")] + Some(Spanned { + value: KeyClass::RawValue, + span: _, + }) => { + let value = tri!(visitor.next_value_seed(crate::raw::BoxedFromString)); + // FIXME: this resets the span to line 1, col 1, byte 0 + crate::from_str_spanned(value.get()).map_err(de::Error::custom) + } + Some(Spanned { + value: KeyClass::Map(first_key), + span, + }) => { + let mut values = SpannedMap::new(); + let first_key = Spanned::new(span, first_key.into()); + + values.insert(first_key, tri!(visitor.next_value())); + while let Some((key, value)) = tri!(visitor.next_entry()) { + values.insert(key, value); + } + + Ok(SpannedValue::Object(values)) + } + None => Ok(SpannedValue::Object(SpannedMap::new())), + } + } + } + + deserializer.deserialize_any(SpannedValueVisitor) + } +} + +impl FromStr for SpannedValue { + type Err = Error; + fn from_str(s: &str) -> Result { + super::super::de::from_str_spanned(s) + } +} + +macro_rules! deserialize_number { + ($method:ident) => { + #[cfg(not(feature = "arbitrary_precision"))] + fn $method(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + SpannedValue::Number(n) => n.deserialize_any(visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + #[cfg(feature = "arbitrary_precision")] + fn $method(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + SpannedValue::Number(n) => n.$method(visitor), + _ => self.deserialize_any(visitor), + } + } + }; +} + +fn visit_array<'de, V>(array: Vec>, visitor: V) -> Result +where + V: Visitor<'de>, +{ + let len = array.len(); + let mut deserializer = SeqDeserializer::new(array); + let seq = tri!(visitor.visit_seq(&mut deserializer)); + let remaining = deserializer.iter.len(); + if remaining == 0 { + Ok(seq) + } else { + Err(serde::de::Error::invalid_length( + len, + &"fewer elements in array", + )) + } +} + +impl<'de> serde::Deserializer<'de> for SpannedMap { + type Error = Error; + + fn deserialize_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + let len = self.len(); + let mut deserializer = MapDeserializer::new(self); + let map = tri!(visitor.visit_map(&mut deserializer)); + let remaining = deserializer.iter.len(); + if remaining == 0 { + Ok(map) + } else { + Err(serde::de::Error::invalid_length( + len, + &"fewer elements in map", + )) + } + } + + fn deserialize_enum( + self, + _name: &'static str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + let mut iter = self.into_iter(); + let (variant, value) = match iter.next() { + Some(v) => v, + None => { + return Err(serde::de::Error::invalid_value( + Unexpected::Map, + &"map with a single key", + )); + } + }; + // enums are encoded in json as maps with a single key:value pair + if iter.next().is_some() { + return Err(serde::de::Error::invalid_value( + Unexpected::Map, + &"map with a single key", + )); + } + + visitor.visit_enum(EnumDeserializer { + variant: variant.into_inner(), + value: Some(value.into_inner()), + }) + } + + fn deserialize_ignored_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + drop(self); + visitor.visit_unit() + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct identifier + } +} + +impl<'de> serde::Deserializer<'de> for SpannedValue { + type Error = Error; + + #[inline] + fn deserialize_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + SpannedValue::Null => visitor.visit_unit(), + SpannedValue::Bool(v) => visitor.visit_bool(v), + SpannedValue::Number(n) => n.deserialize_any(visitor), + #[cfg(any(feature = "std", feature = "alloc"))] + SpannedValue::String(v) => visitor.visit_string(v), + #[cfg(not(any(feature = "std", feature = "alloc")))] + SpannedValue::String(_) => unreachable!(), + SpannedValue::Array(v) => visit_array(v, visitor), + SpannedValue::Object(v) => v.deserialize_any(visitor), + } + } + + deserialize_number!(deserialize_i8); + deserialize_number!(deserialize_i16); + deserialize_number!(deserialize_i32); + deserialize_number!(deserialize_i64); + deserialize_number!(deserialize_i128); + deserialize_number!(deserialize_u8); + deserialize_number!(deserialize_u16); + deserialize_number!(deserialize_u32); + deserialize_number!(deserialize_u64); + deserialize_number!(deserialize_u128); + deserialize_number!(deserialize_f32); + deserialize_number!(deserialize_f64); + + #[inline] + fn deserialize_option(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + SpannedValue::Null => visitor.visit_none(), + _ => visitor.visit_some(self), + } + } + + #[inline] + fn deserialize_enum( + self, + name: &'static str, + variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + match self { + SpannedValue::Object(value) => value.deserialize_enum(name, variants, visitor), + SpannedValue::String(variant) => visitor.visit_enum(EnumDeserializer { + variant, + value: None, + }), + other => Err(serde::de::Error::invalid_type( + other.unexpected(), + &"string or map", + )), + } + } + + #[inline] + fn deserialize_newtype_struct( + self, + name: &'static str, + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + #[cfg(feature = "raw_value")] + { + if name == crate::raw::TOKEN { + return visitor.visit_map(crate::raw::OwnedRawDeserializer { + raw_value: Some(self.to_string()), + }); + } + } + + let _ = name; + visitor.visit_newtype_struct(self) + } + + fn deserialize_bool(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + SpannedValue::Bool(v) => visitor.visit_bool(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_char(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_string(visitor) + } + + fn deserialize_str(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_string(visitor) + } + + fn deserialize_string(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + #[cfg(any(feature = "std", feature = "alloc"))] + SpannedValue::String(v) => visitor.visit_string(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_bytes(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_byte_buf(visitor) + } + + fn deserialize_byte_buf(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + #[cfg(any(feature = "std", feature = "alloc"))] + SpannedValue::String(v) => visitor.visit_string(v), + SpannedValue::Array(v) => visit_array(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_unit(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + SpannedValue::Null => visitor.visit_unit(), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_unit_struct(self, _name: &'static str, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_unit(visitor) + } + + fn deserialize_seq(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + SpannedValue::Array(v) => visit_array(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_tuple(self, _len: usize, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_map(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + SpannedValue::Object(v) => v.deserialize_any(visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_struct( + self, + _name: &'static str, + _fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + match self { + SpannedValue::Array(v) => visit_array(v, visitor), + SpannedValue::Object(v) => v.deserialize_any(visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_identifier(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_string(visitor) + } + + fn deserialize_ignored_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + drop(self); + visitor.visit_unit() + } +} + +struct EnumDeserializer { + variant: String, + value: Option, +} + +impl<'de> EnumAccess<'de> for EnumDeserializer { + type Error = Error; + type Variant = VariantDeserializer; + + fn variant_seed(self, seed: V) -> Result<(V::Value, VariantDeserializer), Error> + where + V: DeserializeSeed<'de>, + { + let variant = self.variant.into_deserializer(); + let visitor = VariantDeserializer { value: self.value }; + seed.deserialize(variant).map(|v| (v, visitor)) + } +} + +impl<'de> IntoDeserializer<'de, Error> for SpannedValue { + type Deserializer = Self; + + fn into_deserializer(self) -> Self::Deserializer { + self + } +} + +impl<'de> IntoDeserializer<'de, Error> for &'de SpannedValue { + type Deserializer = Self; + + fn into_deserializer(self) -> Self::Deserializer { + self + } +} + +struct VariantDeserializer { + value: Option, +} + +impl<'de> VariantAccess<'de> for VariantDeserializer { + type Error = Error; + + fn unit_variant(self) -> Result<(), Error> { + match self.value { + Some(value) => Deserialize::deserialize(value), + None => Ok(()), + } + } + + fn newtype_variant_seed(self, seed: T) -> Result + where + T: DeserializeSeed<'de>, + { + match self.value { + Some(value) => seed.deserialize(value), + None => Err(serde::de::Error::invalid_type( + Unexpected::UnitVariant, + &"newtype variant", + )), + } + } + + fn tuple_variant(self, _len: usize, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self.value { + Some(SpannedValue::Array(v)) => { + if v.is_empty() { + visitor.visit_unit() + } else { + visit_array(v, visitor) + } + } + Some(other) => Err(serde::de::Error::invalid_type( + other.unexpected(), + &"tuple variant", + )), + None => Err(serde::de::Error::invalid_type( + Unexpected::UnitVariant, + &"tuple variant", + )), + } + } + + fn struct_variant( + self, + _fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + match self.value { + Some(SpannedValue::Object(v)) => v.deserialize_any(visitor), + Some(other) => Err(serde::de::Error::invalid_type( + other.unexpected(), + &"struct variant", + )), + None => Err(serde::de::Error::invalid_type( + Unexpected::UnitVariant, + &"struct variant", + )), + } + } +} + +struct SeqDeserializer { + iter: vec::IntoIter>, +} + +impl SeqDeserializer { + fn new(vec: Vec>) -> Self { + SeqDeserializer { + iter: vec.into_iter(), + } + } +} + +impl<'de> SeqAccess<'de> for SeqDeserializer { + type Error = Error; + + fn next_element_seed(&mut self, seed: T) -> Result, Error> + where + T: DeserializeSeed<'de>, + { + match self.iter.next() { + Some(value) => seed.deserialize(value).map(Some), + None => Ok(None), + } + } + + fn size_hint(&self) -> Option { + match self.iter.size_hint() { + (lower, Some(upper)) if lower == upper => Some(upper), + _ => None, + } + } +} + +struct MapDeserializer { + iter: ::IntoIter, + value: Option>, +} + +impl MapDeserializer { + fn new(map: SpannedMap) -> Self { + MapDeserializer { + iter: map.into_iter(), + value: None, + } + } +} + +impl<'de> MapAccess<'de> for MapDeserializer { + type Error = Error; + + fn next_key_seed(&mut self, seed: T) -> Result, Error> + where + T: DeserializeSeed<'de>, + { + match self.iter.next() { + Some((key, value)) => { + self.value = Some(value); + let key_de = MapKeyDeserializer { + key: Cow::Owned(key.into_inner()), + }; + seed.deserialize(key_de).map(Some) + } + None => Ok(None), + } + } + + fn next_value_seed(&mut self, seed: T) -> Result + where + T: DeserializeSeed<'de>, + { + match self.value.take() { + Some(value) => seed.deserialize(value), + None => Err(serde::de::Error::custom("value is missing")), + } + } + + fn size_hint(&self) -> Option { + match self.iter.size_hint() { + (lower, Some(upper)) if lower == upper => Some(upper), + _ => None, + } + } +} + +macro_rules! deserialize_value_ref_number { + ($method:ident) => { + #[cfg(not(feature = "arbitrary_precision"))] + fn $method(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + SpannedValue::Number(n) => n.deserialize_any(visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + #[cfg(feature = "arbitrary_precision")] + fn $method(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + SpannedValue::Number(n) => n.$method(visitor), + _ => self.deserialize_any(visitor), + } + } + }; +} + +fn visit_array_ref<'de, V>( + array: &'de [Spanned], + visitor: V, +) -> Result +where + V: Visitor<'de>, +{ + let len = array.len(); + let mut deserializer = SeqRefDeserializer::new(array); + let seq = tri!(visitor.visit_seq(&mut deserializer)); + let remaining = deserializer.iter.len(); + if remaining == 0 { + Ok(seq) + } else { + Err(serde::de::Error::invalid_length( + len, + &"fewer elements in array", + )) + } +} + +impl<'de> serde::Deserializer<'de> for &'de SpannedMap { + type Error = Error; + + fn deserialize_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + let len = self.len(); + let mut deserializer = MapRefDeserializer::new(self); + let map = tri!(visitor.visit_map(&mut deserializer)); + let remaining = deserializer.iter.len(); + if remaining == 0 { + Ok(map) + } else { + Err(serde::de::Error::invalid_length( + len, + &"fewer elements in map", + )) + } + } + + fn deserialize_enum( + self, + _name: &'static str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + let mut iter = self.into_iter(); + let (variant, value) = match iter.next() { + Some(v) => v, + None => { + return Err(serde::de::Error::invalid_value( + Unexpected::Map, + &"map with a single key", + )); + } + }; + // enums are encoded in json as maps with a single key:value pair + if iter.next().is_some() { + return Err(serde::de::Error::invalid_value( + Unexpected::Map, + &"map with a single key", + )); + } + + visitor.visit_enum(EnumRefDeserializer { + variant: variant.as_ref(), + value: Some(value), + }) + } + + fn deserialize_ignored_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + visitor.visit_unit() + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct identifier + } +} + +impl<'de> serde::Deserializer<'de> for &'de SpannedValue { + type Error = Error; + + fn deserialize_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + SpannedValue::Null => visitor.visit_unit(), + SpannedValue::Bool(v) => visitor.visit_bool(*v), + SpannedValue::Number(n) => n.deserialize_any(visitor), + SpannedValue::String(v) => visitor.visit_borrowed_str(v), + SpannedValue::Array(v) => visit_array_ref(v, visitor), + SpannedValue::Object(v) => v.deserialize_any(visitor), + } + } + + deserialize_value_ref_number!(deserialize_i8); + deserialize_value_ref_number!(deserialize_i16); + deserialize_value_ref_number!(deserialize_i32); + deserialize_value_ref_number!(deserialize_i64); + deserialize_number!(deserialize_i128); + deserialize_value_ref_number!(deserialize_u8); + deserialize_value_ref_number!(deserialize_u16); + deserialize_value_ref_number!(deserialize_u32); + deserialize_value_ref_number!(deserialize_u64); + deserialize_number!(deserialize_u128); + deserialize_value_ref_number!(deserialize_f32); + deserialize_value_ref_number!(deserialize_f64); + + fn deserialize_option(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match *self { + SpannedValue::Null => visitor.visit_none(), + _ => visitor.visit_some(self), + } + } + + fn deserialize_enum( + self, + name: &'static str, + variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + match self { + SpannedValue::Object(value) => value.deserialize_enum(name, variants, visitor), + SpannedValue::String(variant) => visitor.visit_enum(EnumRefDeserializer { + variant, + value: None, + }), + other => Err(serde::de::Error::invalid_type( + other.unexpected(), + &"string or map", + )), + } + } + + #[inline] + fn deserialize_newtype_struct( + self, + name: &'static str, + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + #[cfg(feature = "raw_value")] + { + if name == crate::raw::TOKEN { + return visitor.visit_map(crate::raw::OwnedRawDeserializer { + raw_value: Some(self.to_string()), + }); + } + } + + let _ = name; + visitor.visit_newtype_struct(self) + } + + fn deserialize_bool(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match *self { + SpannedValue::Bool(v) => visitor.visit_bool(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_char(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_str(visitor) + } + + fn deserialize_str(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + SpannedValue::String(v) => visitor.visit_borrowed_str(v), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_string(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_str(visitor) + } + + fn deserialize_bytes(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + SpannedValue::String(v) => visitor.visit_borrowed_str(v), + SpannedValue::Array(v) => visit_array_ref(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_byte_buf(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_bytes(visitor) + } + + fn deserialize_unit(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match *self { + SpannedValue::Null => visitor.visit_unit(), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_unit_struct(self, _name: &'static str, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_unit(visitor) + } + + fn deserialize_seq(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + SpannedValue::Array(v) => visit_array_ref(v, visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_tuple(self, _len: usize, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + self.deserialize_seq(visitor) + } + + fn deserialize_map(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self { + SpannedValue::Object(v) => v.deserialize_any(visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_struct( + self, + _name: &'static str, + _fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + match self { + SpannedValue::Array(v) => visit_array_ref(v, visitor), + SpannedValue::Object(v) => v.deserialize_any(visitor), + _ => Err(self.invalid_type(&visitor)), + } + } + + fn deserialize_identifier(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + self.deserialize_str(visitor) + } + + fn deserialize_ignored_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + visitor.visit_unit() + } +} + +struct EnumRefDeserializer<'de> { + variant: &'de str, + value: Option<&'de Spanned>, +} + +impl<'de> EnumAccess<'de> for EnumRefDeserializer<'de> { + type Error = Error; + type Variant = VariantRefDeserializer<'de>; + + fn variant_seed(self, seed: V) -> Result<(V::Value, Self::Variant), Error> + where + V: DeserializeSeed<'de>, + { + let variant = self.variant.into_deserializer(); + let visitor = VariantRefDeserializer { value: self.value }; + seed.deserialize(variant).map(|v| (v, visitor)) + } +} + +struct VariantRefDeserializer<'de> { + value: Option<&'de Spanned>, +} + +impl<'de> VariantAccess<'de> for VariantRefDeserializer<'de> { + type Error = Error; + + fn unit_variant(self) -> Result<(), Error> { + match self.value { + Some(value) => Deserialize::deserialize(value), + None => Ok(()), + } + } + + fn newtype_variant_seed(self, seed: T) -> Result + where + T: DeserializeSeed<'de>, + { + match self.value { + Some(value) => seed.deserialize(value), + None => Err(serde::de::Error::invalid_type( + Unexpected::UnitVariant, + &"newtype variant", + )), + } + } + + fn tuple_variant(self, _len: usize, visitor: V) -> Result + where + V: Visitor<'de>, + { + match self.value.map(Spanned::as_ref) { + Some(SpannedValue::Array(v)) => { + if v.is_empty() { + visitor.visit_unit() + } else { + visit_array_ref(v, visitor) + } + } + Some(other) => Err(serde::de::Error::invalid_type( + other.unexpected(), + &"tuple variant", + )), + None => Err(serde::de::Error::invalid_type( + Unexpected::UnitVariant, + &"tuple variant", + )), + } + } + + fn struct_variant( + self, + _fields: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + match self.value.map(Spanned::as_ref) { + Some(SpannedValue::Object(v)) => v.deserialize_any(visitor), + Some(other) => Err(serde::de::Error::invalid_type( + other.unexpected(), + &"struct variant", + )), + None => Err(serde::de::Error::invalid_type( + Unexpected::UnitVariant, + &"struct variant", + )), + } + } +} + +struct SeqRefDeserializer<'de> { + iter: slice::Iter<'de, Spanned>, +} + +impl<'de> SeqRefDeserializer<'de> { + fn new(slice: &'de [Spanned]) -> Self { + SeqRefDeserializer { iter: slice.iter() } + } +} + +impl<'de> SeqAccess<'de> for SeqRefDeserializer<'de> { + type Error = Error; + + fn next_element_seed(&mut self, seed: T) -> Result, Error> + where + T: DeserializeSeed<'de>, + { + match self.iter.next() { + Some(value) => seed.deserialize(value).map(Some), + None => Ok(None), + } + } + + fn size_hint(&self) -> Option { + match self.iter.size_hint() { + (lower, Some(upper)) if lower == upper => Some(upper), + _ => None, + } + } +} + +struct MapRefDeserializer<'de> { + iter: <&'de SpannedMap as IntoIterator>::IntoIter, + value: Option<&'de Spanned>, +} + +impl<'de> MapRefDeserializer<'de> { + fn new(map: &'de SpannedMap) -> Self { + MapRefDeserializer { + iter: map.into_iter(), + value: None, + } + } +} + +impl<'de> MapAccess<'de> for MapRefDeserializer<'de> { + type Error = Error; + + fn next_key_seed(&mut self, seed: T) -> Result, Error> + where + T: DeserializeSeed<'de>, + { + match self.iter.next() { + Some((key, value)) => { + self.value = Some(value); + let key_de = MapKeyDeserializer { + key: Cow::Borrowed(key.as_ref()), + }; + seed.deserialize(key_de).map(Some) + } + None => Ok(None), + } + } + + fn next_value_seed(&mut self, seed: T) -> Result + where + T: DeserializeSeed<'de>, + { + match self.value.take() { + Some(value) => seed.deserialize(value), + None => Err(serde::de::Error::custom("value is missing")), + } + } + + fn size_hint(&self) -> Option { + match self.iter.size_hint() { + (lower, Some(upper)) if lower == upper => Some(upper), + _ => None, + } + } +} + +struct MapKeyDeserializer<'de> { + key: Cow<'de, str>, +} + +macro_rules! deserialize_numeric_key { + ($method:ident) => { + deserialize_numeric_key!($method, deserialize_number); + }; + + ($method:ident, $using:ident) => { + fn $method(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + let mut de = crate::Deserializer::from_str(&self.key); + + match tri!(de.peek()) { + Some(b'0'..=b'9' | b'-') => {} + _ => return Err(Error::syntax(ErrorCode::ExpectedNumericKey, 0, 0)), + } + + let number = tri!(de.$using(visitor)); + + if tri!(de.peek()).is_some() { + return Err(Error::syntax(ErrorCode::ExpectedNumericKey, 0, 0)); + } + + Ok(number) + } + }; +} + +impl<'de> serde::Deserializer<'de> for MapKeyDeserializer<'de> { + type Error = Error; + + fn deserialize_any(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + BorrowedCowStrDeserializer::new(self.key).deserialize_any(visitor) + } + + deserialize_numeric_key!(deserialize_i8); + deserialize_numeric_key!(deserialize_i16); + deserialize_numeric_key!(deserialize_i32); + deserialize_numeric_key!(deserialize_i64); + deserialize_numeric_key!(deserialize_u8); + deserialize_numeric_key!(deserialize_u16); + deserialize_numeric_key!(deserialize_u32); + deserialize_numeric_key!(deserialize_u64); + #[cfg(not(feature = "float_roundtrip"))] + deserialize_numeric_key!(deserialize_f32); + deserialize_numeric_key!(deserialize_f64); + + #[cfg(feature = "float_roundtrip")] + deserialize_numeric_key!(deserialize_f32, do_deserialize_f32); + deserialize_numeric_key!(deserialize_i128, do_deserialize_i128); + deserialize_numeric_key!(deserialize_u128, do_deserialize_u128); + + fn deserialize_bool(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + if self.key == "true" { + visitor.visit_bool(true) + } else if self.key == "false" { + visitor.visit_bool(false) + } else { + Err(serde::de::Error::invalid_type( + Unexpected::Str(&self.key), + &visitor, + )) + } + } + + #[inline] + fn deserialize_option(self, visitor: V) -> Result + where + V: Visitor<'de>, + { + // Map keys cannot be null. + visitor.visit_some(self) + } + + #[inline] + fn deserialize_newtype_struct( + self, + _name: &'static str, + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + visitor.visit_newtype_struct(self) + } + + fn deserialize_enum( + self, + name: &'static str, + variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: Visitor<'de>, + { + self.key + .into_deserializer() + .deserialize_enum(name, variants, visitor) + } + + forward_to_deserialize_any! { + char str string bytes byte_buf unit unit_struct seq tuple tuple_struct + map struct identifier ignored_any + } +} + +struct KeyClassifier; + +enum KeyClass { + Map(String), + #[cfg(feature = "arbitrary_precision")] + Number, + #[cfg(feature = "raw_value")] + RawValue, +} + +impl<'de> DeserializeSeed<'de> for KeyClassifier { + type Value = KeyClass; + + fn deserialize(self, deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + deserializer.deserialize_str(self) + } +} + +impl<'de> Visitor<'de> for KeyClassifier { + type Value = KeyClass; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a string key") + } + + fn visit_str(self, s: &str) -> Result + where + E: de::Error, + { + match s { + #[cfg(feature = "arbitrary_precision")] + crate::number::TOKEN => Ok(KeyClass::Number), + #[cfg(feature = "raw_value")] + crate::raw::TOKEN => Ok(KeyClass::RawValue), + _ => Ok(KeyClass::Map(s.to_owned())), + } + } + + #[cfg(any(feature = "std", feature = "alloc"))] + fn visit_string(self, s: String) -> Result + where + E: de::Error, + { + match s.as_str() { + #[cfg(feature = "arbitrary_precision")] + crate::number::TOKEN => Ok(KeyClass::Number), + #[cfg(feature = "raw_value")] + crate::raw::TOKEN => Ok(KeyClass::RawValue), + _ => Ok(KeyClass::Map(s)), + } + } +} + +impl SpannedValue { + #[cold] + fn invalid_type(&self, exp: &dyn Expected) -> E + where + E: serde::de::Error, + { + serde::de::Error::invalid_type(self.unexpected(), exp) + } + + #[cold] + fn unexpected(&self) -> Unexpected { + match self { + SpannedValue::Null => Unexpected::Unit, + SpannedValue::Bool(b) => Unexpected::Bool(*b), + SpannedValue::Number(n) => n.unexpected(), + SpannedValue::String(s) => Unexpected::Str(s), + SpannedValue::Array(_) => Unexpected::Seq, + SpannedValue::Object(_) => Unexpected::Map, + } + } +} + +struct BorrowedCowStrDeserializer<'de> { + value: Cow<'de, str>, +} + +impl<'de> BorrowedCowStrDeserializer<'de> { + fn new(value: Cow<'de, str>) -> Self { + BorrowedCowStrDeserializer { value } + } +} + +impl<'de> de::Deserializer<'de> for BorrowedCowStrDeserializer<'de> { + type Error = Error; + + fn deserialize_any(self, visitor: V) -> Result + where + V: de::Visitor<'de>, + { + match self.value { + Cow::Borrowed(string) => visitor.visit_borrowed_str(string), + #[cfg(any(feature = "std", feature = "alloc"))] + Cow::Owned(string) => visitor.visit_string(string), + #[cfg(not(any(feature = "std", feature = "alloc")))] + Cow::Owned(_) => unreachable!(), + } + } + + fn deserialize_enum( + self, + _name: &str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result + where + V: de::Visitor<'de>, + { + visitor.visit_enum(self) + } + + forward_to_deserialize_any! { + bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string + bytes byte_buf option unit unit_struct newtype_struct seq tuple + tuple_struct map struct identifier ignored_any + } +} + +impl<'de> de::EnumAccess<'de> for BorrowedCowStrDeserializer<'de> { + type Error = Error; + type Variant = UnitOnly; + + fn variant_seed(self, seed: T) -> Result<(T::Value, Self::Variant), Error> + where + T: de::DeserializeSeed<'de>, + { + let value = tri!(seed.deserialize(self)); + Ok((value, UnitOnly)) + } +} + +struct UnitOnly; + +impl<'de> de::VariantAccess<'de> for UnitOnly { + type Error = Error; + + fn unit_variant(self) -> Result<(), Error> { + Ok(()) + } + + fn newtype_variant_seed(self, _seed: T) -> Result + where + T: de::DeserializeSeed<'de>, + { + Err(de::Error::invalid_type( + Unexpected::UnitVariant, + &"newtype variant", + )) + } + + fn tuple_variant(self, _len: usize, _visitor: V) -> Result + where + V: de::Visitor<'de>, + { + Err(de::Error::invalid_type( + Unexpected::UnitVariant, + &"tuple variant", + )) + } + + fn struct_variant( + self, + _fields: &'static [&'static str], + _visitor: V, + ) -> Result + where + V: de::Visitor<'de>, + { + Err(de::Error::invalid_type( + Unexpected::UnitVariant, + &"struct variant", + )) + } +} diff --git a/src/spanned/value/from.rs b/src/spanned/value/from.rs new file mode 100644 index 000000000..320d99312 --- /dev/null +++ b/src/spanned/value/from.rs @@ -0,0 +1,287 @@ +use crate::map::SpannedMap; +use crate::number::Number; +use crate::spanned::spanned::Spanned; +use crate::spanned::value::SpannedValue; +use alloc::borrow::{Cow, ToOwned}; +use alloc::string::String; +use alloc::vec::Vec; + +macro_rules! from_integer { + ($($ty:ident)*) => { + $( + impl From<$ty> for SpannedValue { + fn from(n: $ty) -> Self { + SpannedValue::Number(n.into()) + } + } + )* + }; +} + +from_integer! { + i8 i16 i32 i64 isize + u8 u16 u32 u64 usize +} + +#[cfg(feature = "arbitrary_precision")] +from_integer! { + i128 u128 +} + +impl From for SpannedValue { + /// Convert 32-bit floating point number to `Value::Number`, or + /// `Value::Null` if infinite or NaN. + /// + /// # Examples + /// + /// ``` + /// use serde_json::Value; + /// + /// let f: f32 = 13.37; + /// let x: Value = f.into(); + /// ``` + fn from(f: f32) -> Self { + Number::from_f32(f).map_or(SpannedValue::Null, SpannedValue::Number) + } +} + +impl From for SpannedValue { + /// Convert 64-bit floating point number to `Value::Number`, or + /// `Value::Null` if infinite or NaN. + /// + /// # Examples + /// + /// ``` + /// use serde_json::Value; + /// + /// let f: f64 = 13.37; + /// let x: Value = f.into(); + /// ``` + fn from(f: f64) -> Self { + Number::from_f64(f).map_or(SpannedValue::Null, SpannedValue::Number) + } +} + +impl From for SpannedValue { + /// Convert boolean to `Value::Bool`. + /// + /// # Examples + /// + /// ``` + /// use serde_json::Value; + /// + /// let b = false; + /// let x: Value = b.into(); + /// ``` + fn from(f: bool) -> Self { + SpannedValue::Bool(f) + } +} + +impl From for SpannedValue { + /// Convert `String` to `Value::String`. + /// + /// # Examples + /// + /// ``` + /// use serde_json::Value; + /// + /// let s: String = "lorem".to_owned(); + /// let x: Value = s.into(); + /// ``` + fn from(f: String) -> Self { + SpannedValue::String(f) + } +} + +impl From<&str> for SpannedValue { + /// Convert string slice to `Value::String`. + /// + /// # Examples + /// + /// ``` + /// use serde_json::Value; + /// + /// let s: &str = "lorem"; + /// let x: Value = s.into(); + /// ``` + fn from(f: &str) -> Self { + SpannedValue::String(f.to_owned()) + } +} + +impl<'a> From> for SpannedValue { + /// Convert copy-on-write string to `Value::String`. + /// + /// # Examples + /// + /// ``` + /// use serde_json::Value; + /// use std::borrow::Cow; + /// + /// let s: Cow = Cow::Borrowed("lorem"); + /// let x: Value = s.into(); + /// ``` + /// + /// ``` + /// use serde_json::Value; + /// use std::borrow::Cow; + /// + /// let s: Cow = Cow::Owned("lorem".to_owned()); + /// let x: Value = s.into(); + /// ``` + fn from(f: Cow<'a, str>) -> Self { + SpannedValue::String(f.into_owned()) + } +} + +impl From for SpannedValue { + /// Convert `Number` to `Value::Number`. + /// + /// # Examples + /// + /// ``` + /// use serde_json::{Number, Value}; + /// + /// let n = Number::from(7); + /// let x: Value = n.into(); + /// ``` + fn from(f: Number) -> Self { + SpannedValue::Number(f) + } +} + +impl From for SpannedValue { + /// Convert map (with string keys) to `Value::Object`. + /// + /// # Examples + /// + /// ``` + /// use serde_json::{Map, Value}; + /// + /// let mut m = Map::new(); + /// m.insert("Lorem".to_owned(), "ipsum".into()); + /// let x: Value = m.into(); + /// ``` + fn from(f: SpannedMap) -> Self { + SpannedValue::Object(f) + } +} + +impl>> From> for SpannedValue { + /// Convert a `Vec` to `Value::Array`. + /// + /// # Examples + /// + /// ``` + /// use serde_json::Value; + /// + /// let v = vec!["lorem", "ipsum", "dolor"]; + /// let x: Value = v.into(); + /// ``` + fn from(f: Vec) -> Self { + SpannedValue::Array(f.into_iter().map(Into::into).collect()) + } +} + +impl>, const N: usize> From<[T; N]> for SpannedValue { + fn from(array: [T; N]) -> Self { + SpannedValue::Array(array.into_iter().map(Into::into).collect()) + } +} + +impl>> From<&[T]> for SpannedValue { + /// Convert a slice to `Value::Array`. + /// + /// # Examples + /// + /// ``` + /// use serde_json::Value; + /// + /// let v: &[&str] = &["lorem", "ipsum", "dolor"]; + /// let x: Value = v.into(); + /// ``` + fn from(f: &[T]) -> Self { + SpannedValue::Array(f.iter().cloned().map(Into::into).collect()) + } +} + +impl>> FromIterator for SpannedValue { + /// Create a `Value::Array` by collecting an iterator of array elements. + /// + /// # Examples + /// + /// ``` + /// use serde_json::Value; + /// + /// let v = std::iter::repeat(42).take(5); + /// let x: Value = v.collect(); + /// ``` + /// + /// ``` + /// use serde_json::Value; + /// + /// let v: Vec<_> = vec!["lorem", "ipsum", "dolor"]; + /// let x: Value = v.into_iter().collect(); + /// ``` + /// + /// ``` + /// use std::iter::FromIterator; + /// use serde_json::Value; + /// + /// let x: Value = Value::from_iter(vec!["lorem", "ipsum", "dolor"]); + /// ``` + fn from_iter>(iter: I) -> Self { + SpannedValue::Array(iter.into_iter().map(Into::into).collect()) + } +} + +impl>, V: Into>> FromIterator<(K, V)> + for SpannedValue +{ + /// Create a `Value::Object` by collecting an iterator of key-value pairs. + /// + /// # Examples + /// + /// ``` + /// use serde_json::Value; + /// + /// let v: Vec<_> = vec![("lorem", 40), ("ipsum", 2)]; + /// let x: Value = v.into_iter().collect(); + /// ``` + fn from_iter>(iter: I) -> Self { + SpannedValue::Object( + iter.into_iter() + .map(|(k, v)| (k.into(), v.into())) + .collect(), + ) + } +} + +impl From<()> for SpannedValue { + /// Convert `()` to `Value::Null`. + /// + /// # Examples + /// + /// ``` + /// use serde_json::Value; + /// + /// let u = (); + /// let x: Value = u.into(); + /// ``` + fn from((): ()) -> Self { + SpannedValue::Null + } +} + +impl From> for SpannedValue +where + T: Into, +{ + fn from(opt: Option) -> Self { + match opt { + None => SpannedValue::Null, + Some(value) => Into::into(value), + } + } +} diff --git a/src/spanned/value/index.rs b/src/spanned/value/index.rs new file mode 100644 index 000000000..abd1bce4c --- /dev/null +++ b/src/spanned/value/index.rs @@ -0,0 +1,265 @@ +use crate::map::SpannedMap; +use crate::spanned::spanned::Spanned; +use crate::spanned::value::SpannedValue; +use crate::spanned::Span; +use alloc::borrow::ToOwned; +use alloc::string::String; +use core::fmt::{self, Display}; +use core::ops; + +/// A type that can be used to index into a `serde_json::Value`. +/// +/// The [`get`] and [`get_mut`] methods of `Value` accept any type that +/// implements `Index`, as does the [square-bracket indexing operator]. This +/// trait is implemented for strings which are used as the index into a JSON +/// map, and for `usize` which is used as the index into a JSON array. +/// +/// [`get`]: SpannedValue::get +/// [`get_mut`]: SpannedValue::get_mut +/// [square-bracket indexing operator]: SpannedValue#impl-Index%3CI%3E-for-Value +/// +/// This trait is sealed and cannot be implemented for types outside of +/// `serde_json`. +/// +/// # Examples +/// +/// ``` +/// # use serde_json::json; +/// # +/// let data = json!({ "inner": [1, 2, 3] }); +/// +/// // Data is a JSON map so it can be indexed with a string. +/// let inner = &data["inner"]; +/// +/// // Inner is a JSON array so it can be indexed with an integer. +/// let first = &inner[0]; +/// +/// assert_eq!(first, 1); +/// ``` +pub trait Index: private::Sealed { + /// Return None if the key is not already in the array or object. + #[doc(hidden)] + fn index_into<'v>(&self, v: &'v SpannedValue) -> Option<&'v Spanned>; + + /// Return None if the key is not already in the array or object. + #[doc(hidden)] + fn index_into_mut<'v>(&self, v: &'v mut SpannedValue) -> Option<&'v mut Spanned>; + + /// Panic if array index out of bounds. If key is not already in the object, + /// insert it with a value of null. Panic if Value is a type that cannot be + /// indexed into, except if Value is null then it can be treated as an empty + /// object. + #[doc(hidden)] + fn index_or_insert<'v>(&self, v: &'v mut SpannedValue) -> &'v mut Spanned; +} + +impl Index for usize { + fn index_into<'v>(&self, v: &'v SpannedValue) -> Option<&'v Spanned> { + match v { + SpannedValue::Array(vec) => vec.get(*self), + _ => None, + } + } + fn index_into_mut<'v>(&self, v: &'v mut SpannedValue) -> Option<&'v mut Spanned> { + match v { + SpannedValue::Array(vec) => vec.get_mut(*self), + _ => None, + } + } + fn index_or_insert<'v>(&self, v: &'v mut SpannedValue) -> &'v mut Spanned { + match v { + SpannedValue::Array(vec) => { + let len = vec.len(); + vec.get_mut(*self).unwrap_or_else(|| { + panic!( + "cannot access index {} of JSON array of length {}", + self, len + ) + }) + } + _ => panic!("cannot access index {} of JSON {}", self, Type(v)), + } + } +} + +impl Index for str { + fn index_into<'v>(&self, v: &'v SpannedValue) -> Option<&'v Spanned> { + match v { + SpannedValue::Object(map) => map.get(self), + _ => None, + } + } + fn index_into_mut<'v>(&self, v: &'v mut SpannedValue) -> Option<&'v mut Spanned> { + match v { + SpannedValue::Object(map) => map.get_mut(self), + _ => None, + } + } + fn index_or_insert<'v>(&self, v: &'v mut SpannedValue) -> &'v mut Spanned { + if let SpannedValue::Null = v { + *v = SpannedValue::Object(SpannedMap::new()).into(); + } + match v { + SpannedValue::Object(map) => map + .entry(self.to_owned()) + .or_insert(SpannedValue::Null.into()), + _ => panic!("cannot access key {:?} in JSON {}", self, Type(v)), + } + } +} + +impl Index for String { + fn index_into<'v>(&self, v: &'v SpannedValue) -> Option<&'v Spanned> { + self[..].index_into(v) + } + fn index_into_mut<'v>(&self, v: &'v mut SpannedValue) -> Option<&'v mut Spanned> { + self[..].index_into_mut(v) + } + fn index_or_insert<'v>(&self, v: &'v mut SpannedValue) -> &'v mut Spanned { + self[..].index_or_insert(v) + } +} + +impl Index for &T +where + T: ?Sized + Index, +{ + fn index_into<'v>(&self, v: &'v SpannedValue) -> Option<&'v Spanned> { + (**self).index_into(v) + } + fn index_into_mut<'v>(&self, v: &'v mut SpannedValue) -> Option<&'v mut Spanned> { + (**self).index_into_mut(v) + } + fn index_or_insert<'v>(&self, v: &'v mut SpannedValue) -> &'v mut Spanned { + (**self).index_or_insert(v) + } +} + +// Prevent users from implementing the Index trait. +mod private { + pub trait Sealed {} + impl Sealed for usize {} + impl Sealed for str {} + impl Sealed for alloc::string::String {} + impl Sealed for &T where T: ?Sized + Sealed {} +} + +/// Used in panic messages. +struct Type<'a>(&'a SpannedValue); + +impl<'a> Display for Type<'a> { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + match *self.0 { + SpannedValue::Null => formatter.write_str("null"), + SpannedValue::Bool(_) => formatter.write_str("boolean"), + SpannedValue::Number(_) => formatter.write_str("number"), + SpannedValue::String(_) => formatter.write_str("string"), + SpannedValue::Array(_) => formatter.write_str("array"), + SpannedValue::Object(_) => formatter.write_str("object"), + } + } +} + +// The usual semantics of Index is to panic on invalid indexing. +// +// That said, the usual semantics are for things like Vec and BTreeMap which +// have different use cases than Value. If you are working with a Vec, you know +// that you are working with a Vec and you can get the len of the Vec and make +// sure your indices are within bounds. The Value use cases are more +// loosey-goosey. You got some JSON from an endpoint, and you want to pull values +// out of it. Outside of this Index impl, you already have the option of using +// value.as_array() and working with the Vec directly, or matching on +// Value::Array and getting the Vec directly. The Index impl means you can skip +// that and index directly into the thing using a concise syntax. You don't have +// to check the type, you don't have to check the len, it is all about what you +// expect the Value to look like. +// +// Basically the use cases that would be well served by panicking here are +// better served by using one of the other approaches: get and get_mut, +// as_array, or match. The value of this impl is that it adds a way of working +// with Value that is not well served by the existing approaches: concise and +// careless and sometimes that is exactly what you want. +impl ops::Index for SpannedValue +where + I: Index, +{ + type Output = Spanned; + + /// Index into a `serde_json::Value` using the syntax `value[0]` or + /// `value["k"]`. + /// + /// Returns `Value::Null` if the type of `self` does not match the type of + /// the index, for example if the index is a string and `self` is an array + /// or a number. Also returns `Value::Null` if the given key does not exist + /// in the map or the given index is not within the bounds of the array. + /// + /// For retrieving deeply nested values, you should have a look at the + /// `Value::pointer` method. + /// + /// # Examples + /// + /// ``` + /// # use serde_json::json; + /// # + /// let data = json!({ + /// "x": { + /// "y": ["z", "zz"] + /// } + /// }); + /// + /// assert_eq!(data["x"]["y"], json!(["z", "zz"])); + /// assert_eq!(data["x"]["y"][0], json!("z")); + /// + /// assert_eq!(data["a"], json!(null)); // returns null for undefined values + /// assert_eq!(data["a"]["b"], json!(null)); // does not panic + /// ``` + fn index(&self, index: I) -> &Spanned { + static NULL: Spanned = Spanned { + value: SpannedValue::Null, + span: Span::default(), + }; + index.index_into(self).unwrap_or(&NULL) + } +} + +impl ops::IndexMut for SpannedValue +where + I: Index, +{ + /// Write into a `serde_json::Value` using the syntax `value[0] = ...` or + /// `value["k"] = ...`. + /// + /// If the index is a number, the value must be an array of length bigger + /// than the index. Indexing into a value that is not an array or an array + /// that is too small will panic. + /// + /// If the index is a string, the value must be an object or null which is + /// treated like an empty object. If the key is not already present in the + /// object, it will be inserted with a value of null. Indexing into a value + /// that is neither an object nor null will panic. + /// + /// # Examples + /// + /// ``` + /// # use serde_json::json; + /// # + /// let mut data = json!({ "x": 0 }); + /// + /// // replace an existing key + /// data["x"] = json!(1); + /// + /// // insert a new key + /// data["y"] = json!([false, false, false]); + /// + /// // replace an array value + /// data["y"][0] = json!(true); + /// + /// // inserted a deeply nested key + /// data["a"]["b"]["c"]["d"] = json!(true); + /// + /// println!("{}", data); + /// ``` + fn index_mut(&mut self, index: I) -> &mut Spanned { + index.index_or_insert(self) + } +} diff --git a/src/spanned/value/mod.rs b/src/spanned/value/mod.rs new file mode 100644 index 000000000..6bf4ecbc7 --- /dev/null +++ b/src/spanned/value/mod.rs @@ -0,0 +1,919 @@ +//! The `SpannedValue` enum, a loosely typed way of representing any valid JSON value. +//! This is the same as [`Value`][value], but with additional span information. +//! +//! # Constructing JSON +//! +//! ``` +//! use serde_json::json; +//! +//! fn main() { +//! // The type of `john` is `serde_json::Value` +//! let john = json!({ +//! "name": "John Doe", +//! "age": 43, +//! "phones": [ +//! "+44 1234567", +//! "+44 2345678" +//! ] +//! }); +//! +//! println!("first phone number: {}", john["phones"][0]); +//! +//! // Convert to a string of JSON and print it out +//! println!("{}", john.to_string()); +//! } +//! ``` +//! [value]: crate::value::Value + +use crate::error::Error; +use crate::io; +use crate::spanned::spanned::Spanned; +use alloc::string::String; +use alloc::vec::Vec; +use core::fmt::{self, Debug, Display}; +use core::mem; +use core::str; +use serde::de::DeserializeOwned; + +pub use self::index::Index; +pub use self::ser::Serializer; +pub use crate::map::SpannedMap; +pub use crate::number::Number; + +/// Represents any valid JSON value tracking the position of its potential children. +/// +/// TODO: document +/// See the [`serde_json::value` module documentation](self) for usage examples. +#[cfg_attr(docsrs, doc(cfg(feature = "spanned")))] +#[derive(Clone, Eq, PartialEq, Hash)] +pub enum SpannedValue { + /// Represents a JSON null value. + /// + /// ``` + /// use serde_json::spanned::{from_str_spanned, Spanned, SpannedValue}; + /// + /// let v: Spanned= from_str_spanned("null").unwrap(); + /// # + /// # assert_eq!(v.into_inner(), SpannedValue::Null); + /// ``` + Null, + + /// Represents a JSON boolean. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!(true); + /// ``` + Bool(bool), + + /// Represents a JSON number, whether integer or floating point. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!(12.5); + /// ``` + Number(Number), + + /// Represents a JSON string. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!("a string"); + /// ``` + String(String), + + /// Represents a JSON array. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!(["an", "array"]); + /// ``` + Array(Vec>), + + /// Represents a JSON object. + /// + /// By default, the map is backed by a BTreeMap. Enable the `preserve_order` + /// feature of serde_json to use IndexMap instead, which preserves + /// entries in the order they are inserted into the map. In particular, this + /// allows JSON data to be deserialized into a Value and serialized to a + /// string while retaining the order of map keys in the input. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!({ "an": "object" }); + /// ``` + Object(SpannedMap), +} + +impl Debug for SpannedValue { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + match self { + SpannedValue::Null => formatter.write_str("Null"), + SpannedValue::Bool(boolean) => write!(formatter, "Bool({})", boolean), + SpannedValue::Number(number) => Debug::fmt(number, formatter), + SpannedValue::String(string) => write!(formatter, "String({:?})", string), + SpannedValue::Array(vec) => { + tri!(formatter.write_str("Array ")); + Debug::fmt(vec, formatter) + } + SpannedValue::Object(map) => { + tri!(formatter.write_str("Object ")); + Debug::fmt(map, formatter) + } + } + } +} + +impl Display for SpannedValue { + /// Display a JSON value as a string. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let json = json!({ "city": "London", "street": "10 Downing Street" }); + /// + /// // Compact format: + /// // + /// // {"city":"London","street":"10 Downing Street"} + /// let compact = format!("{}", json); + /// assert_eq!(compact, + /// "{\"city\":\"London\",\"street\":\"10 Downing Street\"}"); + /// + /// // Pretty format: + /// // + /// // { + /// // "city": "London", + /// // "street": "10 Downing Street" + /// // } + /// let pretty = format!("{:#}", json); + /// assert_eq!(pretty, + /// "{\n \"city\": \"London\",\n \"street\": \"10 Downing Street\"\n}"); + /// ``` + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + struct WriterFormatter<'a, 'b: 'a> { + inner: &'a mut fmt::Formatter<'b>, + } + + impl<'a, 'b> io::Write for WriterFormatter<'a, 'b> { + fn write(&mut self, buf: &[u8]) -> io::Result { + // Safety: the serializer below only emits valid utf8 when using + // the default formatter. + let s = unsafe { str::from_utf8_unchecked(buf) }; + tri!(self.inner.write_str(s).map_err(io_error)); + Ok(buf.len()) + } + + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } + } + + fn io_error(_: fmt::Error) -> io::Error { + // Error value does not matter because Display impl just maps it + // back to fmt::Error. + io::Error::new(io::ErrorKind::Other, "fmt error") + } + + let alternate = f.alternate(); + let mut wr = WriterFormatter { inner: f }; + if alternate { + // {:#} + crate::ser::to_writer_pretty(&mut wr, self).map_err(|_| fmt::Error) + } else { + // {} + crate::ser::to_writer(&mut wr, self).map_err(|_| fmt::Error) + } + } +} + +fn parse_index(s: &str) -> Option { + if s.starts_with('+') || (s.starts_with('0') && s.len() != 1) { + return None; + } + s.parse().ok() +} + +impl SpannedValue { + /// Index into a JSON array or map. A string index can be used to access a + /// value in a map, and a usize index can be used to access an element of an + /// array. + /// + /// Returns `None` if the type of `self` does not match the type of the + /// index, for example if the index is a string and `self` is an array or a + /// number. Also returns `None` if the given key does not exist in the map + /// or the given index is not within the bounds of the array. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let object = json!({ "A": 65, "B": 66, "C": 67 }); + /// assert_eq!(*object.get("A").unwrap(), json!(65)); + /// + /// let array = json!([ "A", "B", "C" ]); + /// assert_eq!(*array.get(2).unwrap(), json!("C")); + /// + /// assert_eq!(array.get("A"), None); + /// ``` + /// + /// Square brackets can also be used to index into a value in a more concise + /// way. This returns `Value::Null` in cases where `get` would have returned + /// `None`. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let object = json!({ + /// "A": ["a", "á", "à"], + /// "B": ["b", "b́"], + /// "C": ["c", "ć", "ć̣", "ḉ"], + /// }); + /// assert_eq!(object["B"][0], json!("b")); + /// + /// assert_eq!(object["D"], json!(null)); + /// assert_eq!(object[0]["x"]["y"]["z"], json!(null)); + /// ``` + pub fn get(&self, index: I) -> Option<&Spanned> { + index.index_into(self) + } + + /// Mutably index into a JSON array or map. A string index can be used to + /// access a value in a map, and a usize index can be used to access an + /// element of an array. + /// + /// Returns `None` if the type of `self` does not match the type of the + /// index, for example if the index is a string and `self` is an array or a + /// number. Also returns `None` if the given key does not exist in the map + /// or the given index is not within the bounds of the array. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let mut object = json!({ "A": 65, "B": 66, "C": 67 }); + /// *object.get_mut("A").unwrap() = json!(69); + /// + /// let mut array = json!([ "A", "B", "C" ]); + /// *array.get_mut(2).unwrap() = json!("D"); + /// ``` + pub fn get_mut(&mut self, index: I) -> Option<&mut Spanned> { + index.index_into_mut(self) + } + + /// Returns true if the `Value` is an Object. Returns false otherwise. + /// + /// For any Value on which `is_object` returns true, `as_object` and + /// `as_object_mut` are guaranteed to return the map representation of the + /// object. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let obj = json!({ "a": { "nested": true }, "b": ["an", "array"] }); + /// + /// assert!(obj.is_object()); + /// assert!(obj["a"].is_object()); + /// + /// // array, not an object + /// assert!(!obj["b"].is_object()); + /// ``` + pub fn is_object(&self) -> bool { + self.as_object().is_some() + } + + /// If the `Value` is an Object, returns the associated Map. Returns None + /// otherwise. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!({ "a": { "nested": true }, "b": ["an", "array"] }); + /// + /// // The length of `{"nested": true}` is 1 entry. + /// assert_eq!(v["a"].as_object().unwrap().len(), 1); + /// + /// // The array `["an", "array"]` is not an object. + /// assert_eq!(v["b"].as_object(), None); + /// ``` + pub fn as_object(&self) -> Option<&SpannedMap> { + match self { + SpannedValue::Object(map) => Some(map), + _ => None, + } + } + + /// If the `Value` is an Object, returns the associated mutable Map. + /// Returns None otherwise. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let mut v = json!({ "a": { "nested": true } }); + /// + /// v["a"].as_object_mut().unwrap().clear(); + /// assert_eq!(v, json!({ "a": {} })); + /// ``` + pub fn as_object_mut(&mut self) -> Option<&mut SpannedMap> { + match self { + SpannedValue::Object(map) => Some(map), + _ => None, + } + } + + /// Returns true if the `Value` is an Array. Returns false otherwise. + /// + /// For any Value on which `is_array` returns true, `as_array` and + /// `as_array_mut` are guaranteed to return the vector representing the + /// array. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let obj = json!({ "a": ["an", "array"], "b": { "an": "object" } }); + /// + /// assert!(obj["a"].is_array()); + /// + /// // an object, not an array + /// assert!(!obj["b"].is_array()); + /// ``` + pub fn is_array(&self) -> bool { + self.as_array().is_some() + } + + /// If the `Value` is an Array, returns the associated vector. Returns None + /// otherwise. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!({ "a": ["an", "array"], "b": { "an": "object" } }); + /// + /// // The length of `["an", "array"]` is 2 elements. + /// assert_eq!(v["a"].as_array().unwrap().len(), 2); + /// + /// // The object `{"an": "object"}` is not an array. + /// assert_eq!(v["b"].as_array(), None); + /// ``` + pub fn as_array(&self) -> Option<&Vec>> { + match self { + SpannedValue::Array(array) => Some(array), + _ => None, + } + } + + /// If the `Value` is an Array, returns the associated mutable vector. + /// Returns None otherwise. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let mut v = json!({ "a": ["an", "array"] }); + /// + /// v["a"].as_array_mut().unwrap().clear(); + /// assert_eq!(v, json!({ "a": [] })); + /// ``` + pub fn as_array_mut(&mut self) -> Option<&mut Vec>> { + match self { + SpannedValue::Array(list) => Some(list), + _ => None, + } + } + + /// Returns true if the `Value` is a String. Returns false otherwise. + /// + /// For any Value on which `is_string` returns true, `as_str` is guaranteed + /// to return the string slice. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!({ "a": "some string", "b": false }); + /// + /// assert!(v["a"].is_string()); + /// + /// // The boolean `false` is not a string. + /// assert!(!v["b"].is_string()); + /// ``` + pub fn is_string(&self) -> bool { + self.as_str().is_some() + } + + /// If the `Value` is a String, returns the associated str. Returns None + /// otherwise. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!({ "a": "some string", "b": false }); + /// + /// assert_eq!(v["a"].as_str(), Some("some string")); + /// + /// // The boolean `false` is not a string. + /// assert_eq!(v["b"].as_str(), None); + /// + /// // JSON values are printed in JSON representation, so strings are in quotes. + /// // + /// // The value is: "some string" + /// println!("The value is: {}", v["a"]); + /// + /// // Rust strings are printed without quotes. + /// // + /// // The value is: some string + /// println!("The value is: {}", v["a"].as_str().unwrap()); + /// ``` + pub fn as_str(&self) -> Option<&str> { + match self { + SpannedValue::String(s) => Some(s), + _ => None, + } + } + + /// Returns true if the `Value` is a Number. Returns false otherwise. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!({ "a": 1, "b": "2" }); + /// + /// assert!(v["a"].is_number()); + /// + /// // The string `"2"` is a string, not a number. + /// assert!(!v["b"].is_number()); + /// ``` + pub fn is_number(&self) -> bool { + match *self { + SpannedValue::Number(_) => true, + _ => false, + } + } + + /// If the `Value` is a Number, returns the associated [`Number`]. Returns + /// None otherwise. + /// + /// ``` + /// # use serde_json::{json, Number}; + /// # + /// let v = json!({ "a": 1, "b": 2.2, "c": -3, "d": "4" }); + /// + /// assert_eq!(v["a"].as_number(), Some(&Number::from(1u64))); + /// assert_eq!(v["b"].as_number(), Some(&Number::from_f64(2.2).unwrap())); + /// assert_eq!(v["c"].as_number(), Some(&Number::from(-3i64))); + /// + /// // The string `"4"` is not a number. + /// assert_eq!(v["d"].as_number(), None); + /// ``` + pub fn as_number(&self) -> Option<&Number> { + match self { + SpannedValue::Number(number) => Some(number), + _ => None, + } + } + + /// Returns true if the `Value` is an integer between `i64::MIN` and + /// `i64::MAX`. + /// + /// For any Value on which `is_i64` returns true, `as_i64` is guaranteed to + /// return the integer value. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let big = i64::max_value() as u64 + 10; + /// let v = json!({ "a": 64, "b": big, "c": 256.0 }); + /// + /// assert!(v["a"].is_i64()); + /// + /// // Greater than i64::MAX. + /// assert!(!v["b"].is_i64()); + /// + /// // Numbers with a decimal point are not considered integers. + /// assert!(!v["c"].is_i64()); + /// ``` + pub fn is_i64(&self) -> bool { + match self { + SpannedValue::Number(n) => n.is_i64(), + _ => false, + } + } + + /// Returns true if the `Value` is an integer between zero and `u64::MAX`. + /// + /// For any Value on which `is_u64` returns true, `as_u64` is guaranteed to + /// return the integer value. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!({ "a": 64, "b": -64, "c": 256.0 }); + /// + /// assert!(v["a"].is_u64()); + /// + /// // Negative integer. + /// assert!(!v["b"].is_u64()); + /// + /// // Numbers with a decimal point are not considered integers. + /// assert!(!v["c"].is_u64()); + /// ``` + pub fn is_u64(&self) -> bool { + match self { + SpannedValue::Number(n) => n.is_u64(), + _ => false, + } + } + + /// Returns true if the `Value` is a number that can be represented by f64. + /// + /// For any Value on which `is_f64` returns true, `as_f64` is guaranteed to + /// return the floating point value. + /// + /// Currently this function returns true if and only if both `is_i64` and + /// `is_u64` return false but this is not a guarantee in the future. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!({ "a": 256.0, "b": 64, "c": -64 }); + /// + /// assert!(v["a"].is_f64()); + /// + /// // Integers. + /// assert!(!v["b"].is_f64()); + /// assert!(!v["c"].is_f64()); + /// ``` + pub fn is_f64(&self) -> bool { + match self { + SpannedValue::Number(n) => n.is_f64(), + _ => false, + } + } + + /// If the `Value` is an integer, represent it as i64 if possible. Returns + /// None otherwise. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let big = i64::max_value() as u64 + 10; + /// let v = json!({ "a": 64, "b": big, "c": 256.0 }); + /// + /// assert_eq!(v["a"].as_i64(), Some(64)); + /// assert_eq!(v["b"].as_i64(), None); + /// assert_eq!(v["c"].as_i64(), None); + /// ``` + pub fn as_i64(&self) -> Option { + match self { + SpannedValue::Number(n) => n.as_i64(), + _ => None, + } + } + + /// If the `Value` is an integer, represent it as u64 if possible. Returns + /// None otherwise. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!({ "a": 64, "b": -64, "c": 256.0 }); + /// + /// assert_eq!(v["a"].as_u64(), Some(64)); + /// assert_eq!(v["b"].as_u64(), None); + /// assert_eq!(v["c"].as_u64(), None); + /// ``` + pub fn as_u64(&self) -> Option { + match self { + SpannedValue::Number(n) => n.as_u64(), + _ => None, + } + } + + /// If the `Value` is a number, represent it as f64 if possible. Returns + /// None otherwise. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!({ "a": 256.0, "b": 64, "c": -64 }); + /// + /// assert_eq!(v["a"].as_f64(), Some(256.0)); + /// assert_eq!(v["b"].as_f64(), Some(64.0)); + /// assert_eq!(v["c"].as_f64(), Some(-64.0)); + /// ``` + pub fn as_f64(&self) -> Option { + match self { + SpannedValue::Number(n) => n.as_f64(), + _ => None, + } + } + + /// Returns true if the `Value` is a Boolean. Returns false otherwise. + /// + /// For any Value on which `is_boolean` returns true, `as_bool` is + /// guaranteed to return the boolean value. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!({ "a": false, "b": "false" }); + /// + /// assert!(v["a"].is_boolean()); + /// + /// // The string `"false"` is a string, not a boolean. + /// assert!(!v["b"].is_boolean()); + /// ``` + pub fn is_boolean(&self) -> bool { + self.as_bool().is_some() + } + + /// If the `Value` is a Boolean, returns the associated bool. Returns None + /// otherwise. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!({ "a": false, "b": "false" }); + /// + /// assert_eq!(v["a"].as_bool(), Some(false)); + /// + /// // The string `"false"` is a string, not a boolean. + /// assert_eq!(v["b"].as_bool(), None); + /// ``` + pub fn as_bool(&self) -> Option { + match *self { + SpannedValue::Bool(b) => Some(b), + _ => None, + } + } + + /// Returns true if the `Value` is a Null. Returns false otherwise. + /// + /// For any Value on which `is_null` returns true, `as_null` is guaranteed + /// to return `Some(())`. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!({ "a": null, "b": false }); + /// + /// assert!(v["a"].is_null()); + /// + /// // The boolean `false` is not null. + /// assert!(!v["b"].is_null()); + /// ``` + pub fn is_null(&self) -> bool { + self.as_null().is_some() + } + + /// If the `Value` is a Null, returns (). Returns None otherwise. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let v = json!({ "a": null, "b": false }); + /// + /// assert_eq!(v["a"].as_null(), Some(())); + /// + /// // The boolean `false` is not null. + /// assert_eq!(v["b"].as_null(), None); + /// ``` + pub fn as_null(&self) -> Option<()> { + match *self { + SpannedValue::Null => Some(()), + _ => None, + } + } + + /// Looks up a value by a JSON Pointer. + /// + /// JSON Pointer defines a string syntax for identifying a specific value + /// within a JavaScript Object Notation (JSON) document. + /// + /// A Pointer is a Unicode string with the reference tokens separated by `/`. + /// Inside tokens `/` is replaced by `~1` and `~` is replaced by `~0`. The + /// addressed value is returned and if there is no such value `None` is + /// returned. + /// + /// For more information read [RFC6901](https://tools.ietf.org/html/rfc6901). + /// + /// # Examples + /// + /// ``` + /// # use serde_json::json; + /// # use serde_json::spanned::{from_str_spanned, SpannedValue}; + /// # + /// let data: SpannedValue = from_str_spanned(r#"{ + /// "x": { + /// "y": ["z", "zz"] + /// } + /// }"#).unwrap(); + /// + /// assert_eq!(data.pointer("/x/y/1").unwrap(), &SpannedValue::String("zz".into())); + /// assert_eq!(data.pointer("/a/b/c"), None); + /// ``` + pub fn pointer(&self, pointer: &str) -> Option<&SpannedValue> { + if pointer.is_empty() { + return Some(self); + } + if !pointer.starts_with('/') { + return None; + } + pointer + .split('/') + .skip(1) + .map(|x| x.replace("~1", "/").replace("~0", "~")) + .try_fold(self, |target, token| match target { + SpannedValue::Object(map) => map + .get(&Spanned::new_default_span(token)) + .map(Spanned::get_ref), + SpannedValue::Array(list) => parse_index(&token) + .and_then(|x| list.get(x)) + .map(Spanned::get_ref), + _ => None, + }) + } + + /// Looks up a value by a JSON Pointer and returns a mutable reference to + /// that value. + /// + /// JSON Pointer defines a string syntax for identifying a specific value + /// within a JavaScript Object Notation (JSON) document. + /// + /// A Pointer is a Unicode string with the reference tokens separated by `/`. + /// Inside tokens `/` is replaced by `~1` and `~` is replaced by `~0`. The + /// addressed value is returned and if there is no such value `None` is + /// returned. + /// + /// For more information read [RFC6901](https://tools.ietf.org/html/rfc6901). + /// + /// # Example of Use + /// + /// ``` + /// use serde_json::Value; + /// + /// fn main() { + /// let s = r#"{"x": 1.0, "y": 2.0}"#; + /// let mut value: Value = serde_json::from_str(s).unwrap(); + /// + /// // Check value using read-only pointer + /// assert_eq!(value.pointer("/x"), Some(&1.0.into())); + /// // Change value with direct assignment + /// *value.pointer_mut("/x").unwrap() = 1.5.into(); + /// // Check that new value was written + /// assert_eq!(value.pointer("/x"), Some(&1.5.into())); + /// // Or change the value only if it exists + /// value.pointer_mut("/x").map(|v| *v = 1.5.into()); + /// + /// // "Steal" ownership of a value. Can replace with any valid Value. + /// let old_x = value.pointer_mut("/x").map(Value::take).unwrap(); + /// assert_eq!(old_x, 1.5); + /// assert_eq!(value.pointer("/x").unwrap(), &Value::Null); + /// } + /// ``` + pub fn pointer_mut(&mut self, pointer: &str) -> Option<&mut SpannedValue> { + if pointer.is_empty() { + return Some(self); + } + if !pointer.starts_with('/') { + return None; + } + pointer + .split('/') + .skip(1) + .map(|x| x.replace("~1", "/").replace("~0", "~")) + .try_fold(self, |target, token| match target { + SpannedValue::Object(map) => map + .get_mut(&Spanned::new_default_span(token)) + .map(Spanned::get_mut), + SpannedValue::Array(list) => parse_index(&token) + .and_then(move |x| list.get_mut(x)) + .map(Spanned::get_mut), + _ => None, + }) + } + + /// Takes the value out of the `Value`, leaving a `Null` in its place. + /// + /// ``` + /// # use serde_json::json; + /// # + /// let mut v = json!({ "x": "y" }); + /// assert_eq!(v["x"].take(), json!("y")); + /// assert_eq!(v, json!({ "x": null })); + /// ``` + pub fn take(&mut self) -> SpannedValue { + mem::replace(self, SpannedValue::Null) + } + + /// Reorders the entries of all `Value::Object` nested within this JSON + /// value according to `str`'s usual ordering. + /// + /// If serde_json's "preserve_order" feature is not enabled, this method + /// does no work because all JSON maps are always kept in a sorted state. + /// + /// If serde_json's "preserve_order" feature is enabled, this method + /// destroys the original source order or insertion order of the JSON + /// objects in favor of an alphanumerical order that matches how a BTreeMap + /// with the same contents would be ordered. + pub fn sort_all_objects(&mut self) { + #[cfg(feature = "preserve_order")] + { + match self { + SpannedValue::Object(map) => { + map.sort_keys(); + map.values_mut() + .for_each(|v| SpannedValue::sort_all_objects(v.get_mut())); + } + SpannedValue::Array(list) => { + list.iter_mut() + .for_each(|v| SpannedValue::sort_all_objects(v.get_mut())); + } + _ => {} + } + } + } +} + +/// The default value is `Value::Null`. +/// +/// This is useful for handling omitted `Value` fields when deserializing. +/// +/// # Examples +/// +/// ``` +/// # use serde::Deserialize; +/// use serde_json::Value; +/// +/// #[derive(Deserialize)] +/// struct Settings { +/// level: i32, +/// #[serde(default)] +/// extras: Value, +/// } +/// +/// # fn try_main() -> Result<(), serde_json::Error> { +/// let data = r#" { "level": 42 } "#; +/// let s: Settings = serde_json::from_str(data)?; +/// +/// assert_eq!(s.level, 42); +/// assert_eq!(s.extras, Value::Null); +/// # +/// # Ok(()) +/// # } +/// # +/// # try_main().unwrap() +/// ``` +impl Default for SpannedValue { + fn default() -> SpannedValue { + SpannedValue::Null + } +} + +mod de; +mod from; +mod index; +mod partial_eq; +mod ser; + +/// Interpret a `serde_json::Value` as an instance of type `T`. +/// +/// # Example +/// +/// ``` +/// use serde::Deserialize; +/// use serde_json::json; +/// +/// #[derive(Deserialize, Debug)] +/// struct User { +/// fingerprint: String, +/// location: String, +/// } +/// +/// fn main() { +/// // The type of `j` is `serde_json::Value` +/// let j = json!({ +/// "fingerprint": "0xF9BA143B95FF6D82", +/// "location": "Menlo Park, CA" +/// }); +/// +/// let u: User = serde_json::from_value(j).unwrap(); +/// println!("{:#?}", u); +/// } +/// ``` +/// +/// # Errors +/// +/// This conversion can fail if the structure of the Value does not match the +/// structure expected by `T`, for example if `T` is a struct type but the Value +/// contains something other than a JSON map. It can also fail if the structure +/// is correct but `T`'s implementation of `Deserialize` decides that something +/// is wrong with the data, for example required struct fields are missing from +/// the JSON map or some number is too big to fit in the expected primitive +/// type. +pub fn from_value(value: SpannedValue) -> Result +where + T: DeserializeOwned, +{ + T::deserialize(value) +} diff --git a/src/spanned/value/partial_eq.rs b/src/spanned/value/partial_eq.rs new file mode 100644 index 000000000..e04944fc2 --- /dev/null +++ b/src/spanned/value/partial_eq.rs @@ -0,0 +1,103 @@ +use super::SpannedValue; +use alloc::string::String; + +fn eq_i64(value: &SpannedValue, other: i64) -> bool { + value.as_i64() == Some(other) +} + +fn eq_u64(value: &SpannedValue, other: u64) -> bool { + value.as_u64() == Some(other) +} + +fn eq_f32(value: &SpannedValue, other: f32) -> bool { + match value { + SpannedValue::Number(n) => n.as_f32() == Some(other), + _ => false, + } +} + +fn eq_f64(value: &SpannedValue, other: f64) -> bool { + value.as_f64() == Some(other) +} + +fn eq_bool(value: &SpannedValue, other: bool) -> bool { + value.as_bool() == Some(other) +} + +fn eq_str(value: &SpannedValue, other: &str) -> bool { + value.as_str() == Some(other) +} + +impl PartialEq for SpannedValue { + fn eq(&self, other: &str) -> bool { + eq_str(self, other) + } +} + +impl PartialEq<&str> for SpannedValue { + fn eq(&self, other: &&str) -> bool { + eq_str(self, *other) + } +} + +impl PartialEq for str { + fn eq(&self, other: &SpannedValue) -> bool { + eq_str(other, self) + } +} + +impl PartialEq for &str { + fn eq(&self, other: &SpannedValue) -> bool { + eq_str(other, *self) + } +} + +impl PartialEq for SpannedValue { + fn eq(&self, other: &String) -> bool { + eq_str(self, other.as_str()) + } +} + +impl PartialEq for String { + fn eq(&self, other: &SpannedValue) -> bool { + eq_str(other, self.as_str()) + } +} + +macro_rules! partialeq_numeric { + ($($eq:ident [$($ty:ty)*])*) => { + $($( + impl PartialEq<$ty> for SpannedValue { + fn eq(&self, other: &$ty) -> bool { + $eq(self, *other as _) + } + } + + impl PartialEq for $ty { + fn eq(&self, other: &SpannedValue) -> bool { + $eq(other, *self as _) + } + } + + impl<'a> PartialEq<$ty> for &'a SpannedValue { + fn eq(&self, other: &$ty) -> bool { + $eq(*self, *other as _) + } + } + + impl<'a> PartialEq<$ty> for &'a mut SpannedValue { + fn eq(&self, other: &$ty) -> bool { + $eq(*self, *other as _) + } + } + )*)* + } +} + +partialeq_numeric! { + eq_i64[i8 i16 i32 i64 isize] + eq_u64[u8 u16 u32 u64 usize] + eq_f32[f32] + eq_f64[f64] + eq_bool[bool] +} diff --git a/src/spanned/value/ser.rs b/src/spanned/value/ser.rs new file mode 100644 index 000000000..acbc53d69 --- /dev/null +++ b/src/spanned/value/ser.rs @@ -0,0 +1,1068 @@ +use crate::error::{Error, ErrorCode, Result}; +use crate::map::Map; +use crate::spanned::SpannedValue; +use crate::value::{to_value, Value}; +use alloc::borrow::ToOwned; +use alloc::string::{String, ToString}; +use alloc::vec::Vec; +use core::fmt::Display; +use core::result; +use serde::ser::{Impossible, Serialize}; + +impl Serialize for SpannedValue { + #[inline] + fn serialize(&self, serializer: S) -> result::Result + where + S: ::serde::Serializer, + { + match self { + SpannedValue::Null => serializer.serialize_unit(), + SpannedValue::Bool(b) => serializer.serialize_bool(*b), + SpannedValue::Number(n) => n.serialize(serializer), + SpannedValue::String(s) => serializer.serialize_str(s), + SpannedValue::Array(v) => v.serialize(serializer), + #[cfg(any(feature = "std", feature = "alloc"))] + SpannedValue::Object(m) => { + use serde::ser::SerializeMap; + let mut map = tri!(serializer.serialize_map(Some(m.len()))); + for (k, v) in m { + tri!(map.serialize_entry(k, v)); + } + map.end() + } + #[cfg(not(any(feature = "std", feature = "alloc")))] + SpannedValue::Object(_) => unreachable!(), + } + } +} + +/// Serializer whose output is a `Value`. +/// +/// This is the serializer that backs [`serde_json::to_value`][crate::to_value]. +/// Unlike the main serde_json serializer which goes from some serializable +/// value of type `T` to JSON text, this one goes from `T` to +/// `serde_json::Value`. +/// +/// The `to_value` function is implementable as: +/// +/// ``` +/// use serde::Serialize; +/// use serde_json::{Error, Value}; +/// +/// pub fn to_value(input: T) -> Result +/// where +/// T: Serialize, +/// { +/// input.serialize(serde_json::value::Serializer) +/// } +/// ``` +pub struct Serializer; + +impl serde::Serializer for Serializer { + type Ok = Value; + type Error = Error; + + type SerializeSeq = SerializeVec; + type SerializeTuple = SerializeVec; + type SerializeTupleStruct = SerializeVec; + type SerializeTupleVariant = SerializeTupleVariant; + type SerializeMap = SerializeMap; + type SerializeStruct = SerializeMap; + type SerializeStructVariant = SerializeStructVariant; + + #[inline] + fn serialize_bool(self, value: bool) -> Result { + Ok(Value::Bool(value)) + } + + #[inline] + fn serialize_i8(self, value: i8) -> Result { + self.serialize_i64(value as i64) + } + + #[inline] + fn serialize_i16(self, value: i16) -> Result { + self.serialize_i64(value as i64) + } + + #[inline] + fn serialize_i32(self, value: i32) -> Result { + self.serialize_i64(value as i64) + } + + fn serialize_i64(self, value: i64) -> Result { + Ok(Value::Number(value.into())) + } + + fn serialize_i128(self, value: i128) -> Result { + #[cfg(feature = "arbitrary_precision")] + { + Ok(Value::Number(value.into())) + } + + #[cfg(not(feature = "arbitrary_precision"))] + { + if let Ok(value) = u64::try_from(value) { + Ok(Value::Number(value.into())) + } else if let Ok(value) = i64::try_from(value) { + Ok(Value::Number(value.into())) + } else { + Err(Error::syntax(ErrorCode::NumberOutOfRange, 0, 0)) + } + } + } + + #[inline] + fn serialize_u8(self, value: u8) -> Result { + self.serialize_u64(value as u64) + } + + #[inline] + fn serialize_u16(self, value: u16) -> Result { + self.serialize_u64(value as u64) + } + + #[inline] + fn serialize_u32(self, value: u32) -> Result { + self.serialize_u64(value as u64) + } + + #[inline] + fn serialize_u64(self, value: u64) -> Result { + Ok(Value::Number(value.into())) + } + + fn serialize_u128(self, value: u128) -> Result { + #[cfg(feature = "arbitrary_precision")] + { + Ok(Value::Number(value.into())) + } + + #[cfg(not(feature = "arbitrary_precision"))] + { + if let Ok(value) = u64::try_from(value) { + Ok(Value::Number(value.into())) + } else { + Err(Error::syntax(ErrorCode::NumberOutOfRange, 0, 0)) + } + } + } + + #[inline] + fn serialize_f32(self, float: f32) -> Result { + Ok(Value::from(float)) + } + + #[inline] + fn serialize_f64(self, float: f64) -> Result { + Ok(Value::from(float)) + } + + #[inline] + fn serialize_char(self, value: char) -> Result { + let mut s = String::new(); + s.push(value); + Ok(Value::String(s)) + } + + #[inline] + fn serialize_str(self, value: &str) -> Result { + Ok(Value::String(value.to_owned())) + } + + fn serialize_bytes(self, value: &[u8]) -> Result { + let vec = value.iter().map(|&b| Value::Number(b.into())).collect(); + Ok(Value::Array(vec)) + } + + #[inline] + fn serialize_unit(self) -> Result { + Ok(Value::Null) + } + + #[inline] + fn serialize_unit_struct(self, _name: &'static str) -> Result { + self.serialize_unit() + } + + #[inline] + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + ) -> Result { + self.serialize_str(variant) + } + + #[inline] + fn serialize_newtype_struct(self, _name: &'static str, value: &T) -> Result + where + T: ?Sized + Serialize, + { + value.serialize(self) + } + + fn serialize_newtype_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + value: &T, + ) -> Result + where + T: ?Sized + Serialize, + { + let mut values = Map::new(); + values.insert(String::from(variant), tri!(to_value(value))); + Ok(Value::Object(values)) + } + + #[inline] + fn serialize_none(self) -> Result { + self.serialize_unit() + } + + #[inline] + fn serialize_some(self, value: &T) -> Result + where + T: ?Sized + Serialize, + { + value.serialize(self) + } + + fn serialize_seq(self, len: Option) -> Result { + Ok(SerializeVec { + vec: Vec::with_capacity(len.unwrap_or(0)), + }) + } + + fn serialize_tuple(self, len: usize) -> Result { + self.serialize_seq(Some(len)) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + len: usize, + ) -> Result { + self.serialize_seq(Some(len)) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + len: usize, + ) -> Result { + Ok(SerializeTupleVariant { + name: String::from(variant), + vec: Vec::with_capacity(len), + }) + } + + fn serialize_map(self, len: Option) -> Result { + Ok(SerializeMap::Map { + map: Map::with_capacity(len.unwrap_or(0)), + next_key: None, + }) + } + + fn serialize_struct(self, name: &'static str, len: usize) -> Result { + match name { + #[cfg(feature = "arbitrary_precision")] + crate::number::TOKEN => Ok(SerializeMap::Number { out_value: None }), + #[cfg(feature = "raw_value")] + crate::raw::TOKEN => Ok(SerializeMap::RawValue { out_value: None }), + _ => self.serialize_map(Some(len)), + } + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + _len: usize, + ) -> Result { + Ok(SerializeStructVariant { + name: String::from(variant), + map: Map::new(), + }) + } + + fn collect_str(self, value: &T) -> Result + where + T: ?Sized + Display, + { + Ok(Value::String(value.to_string())) + } +} + +pub struct SerializeVec { + vec: Vec, +} + +pub struct SerializeTupleVariant { + name: String, + vec: Vec, +} + +pub enum SerializeMap { + Map { + map: Map, + next_key: Option, + }, + #[cfg(feature = "arbitrary_precision")] + Number { + out_value: Option, + }, + #[cfg(feature = "raw_value")] + RawValue { + out_value: Option, + }, +} + +pub struct SerializeStructVariant { + name: String, + map: Map, +} + +impl serde::ser::SerializeSeq for SerializeVec { + type Ok = Value; + type Error = Error; + + fn serialize_element(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + self.vec.push(tri!(to_value(value))); + Ok(()) + } + + fn end(self) -> Result { + Ok(Value::Array(self.vec)) + } +} + +impl serde::ser::SerializeTuple for SerializeVec { + type Ok = Value; + type Error = Error; + + fn serialize_element(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + serde::ser::SerializeSeq::serialize_element(self, value) + } + + fn end(self) -> Result { + serde::ser::SerializeSeq::end(self) + } +} + +impl serde::ser::SerializeTupleStruct for SerializeVec { + type Ok = Value; + type Error = Error; + + fn serialize_field(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + serde::ser::SerializeSeq::serialize_element(self, value) + } + + fn end(self) -> Result { + serde::ser::SerializeSeq::end(self) + } +} + +impl serde::ser::SerializeTupleVariant for SerializeTupleVariant { + type Ok = Value; + type Error = Error; + + fn serialize_field(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + self.vec.push(tri!(to_value(value))); + Ok(()) + } + + fn end(self) -> Result { + let mut object = Map::new(); + + object.insert(self.name, Value::Array(self.vec)); + + Ok(Value::Object(object)) + } +} + +impl serde::ser::SerializeMap for SerializeMap { + type Ok = Value; + type Error = Error; + + fn serialize_key(&mut self, key: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + match self { + SerializeMap::Map { next_key, .. } => { + *next_key = Some(tri!(key.serialize(MapKeySerializer))); + Ok(()) + } + #[cfg(feature = "arbitrary_precision")] + SerializeMap::Number { .. } => unreachable!(), + #[cfg(feature = "raw_value")] + SerializeMap::RawValue { .. } => unreachable!(), + } + } + + fn serialize_value(&mut self, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + match self { + SerializeMap::Map { map, next_key } => { + let key = next_key.take(); + // Panic because this indicates a bug in the program rather than an + // expected failure. + let key = key.expect("serialize_value called before serialize_key"); + map.insert(key, tri!(to_value(value))); + Ok(()) + } + #[cfg(feature = "arbitrary_precision")] + SerializeMap::Number { .. } => unreachable!(), + #[cfg(feature = "raw_value")] + SerializeMap::RawValue { .. } => unreachable!(), + } + } + + fn end(self) -> Result { + match self { + SerializeMap::Map { map, .. } => Ok(Value::Object(map)), + #[cfg(feature = "arbitrary_precision")] + SerializeMap::Number { .. } => unreachable!(), + #[cfg(feature = "raw_value")] + SerializeMap::RawValue { .. } => unreachable!(), + } + } +} + +struct MapKeySerializer; + +fn key_must_be_a_string() -> Error { + Error::syntax(ErrorCode::KeyMustBeAString, 0, 0) +} + +fn float_key_must_be_finite() -> Error { + Error::syntax(ErrorCode::FloatKeyMustBeFinite, 0, 0) +} + +impl serde::Serializer for MapKeySerializer { + type Ok = String; + type Error = Error; + + type SerializeSeq = Impossible; + type SerializeTuple = Impossible; + type SerializeTupleStruct = Impossible; + type SerializeTupleVariant = Impossible; + type SerializeMap = Impossible; + type SerializeStruct = Impossible; + type SerializeStructVariant = Impossible; + + #[inline] + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + variant: &'static str, + ) -> Result { + Ok(variant.to_owned()) + } + + #[inline] + fn serialize_newtype_struct(self, _name: &'static str, value: &T) -> Result + where + T: ?Sized + Serialize, + { + value.serialize(self) + } + + fn serialize_bool(self, value: bool) -> Result { + Ok(if value { "true" } else { "false" }.to_owned()) + } + + fn serialize_i8(self, value: i8) -> Result { + Ok(itoa::Buffer::new().format(value).to_owned()) + } + + fn serialize_i16(self, value: i16) -> Result { + Ok(itoa::Buffer::new().format(value).to_owned()) + } + + fn serialize_i32(self, value: i32) -> Result { + Ok(itoa::Buffer::new().format(value).to_owned()) + } + + fn serialize_i64(self, value: i64) -> Result { + Ok(itoa::Buffer::new().format(value).to_owned()) + } + + fn serialize_i128(self, value: i128) -> Result { + Ok(itoa::Buffer::new().format(value).to_owned()) + } + + fn serialize_u8(self, value: u8) -> Result { + Ok(itoa::Buffer::new().format(value).to_owned()) + } + + fn serialize_u16(self, value: u16) -> Result { + Ok(itoa::Buffer::new().format(value).to_owned()) + } + + fn serialize_u32(self, value: u32) -> Result { + Ok(itoa::Buffer::new().format(value).to_owned()) + } + + fn serialize_u64(self, value: u64) -> Result { + Ok(itoa::Buffer::new().format(value).to_owned()) + } + + fn serialize_u128(self, value: u128) -> Result { + Ok(itoa::Buffer::new().format(value).to_owned()) + } + + fn serialize_f32(self, value: f32) -> Result { + if value.is_finite() { + Ok(ryu::Buffer::new().format_finite(value).to_owned()) + } else { + Err(float_key_must_be_finite()) + } + } + + fn serialize_f64(self, value: f64) -> Result { + if value.is_finite() { + Ok(ryu::Buffer::new().format_finite(value).to_owned()) + } else { + Err(float_key_must_be_finite()) + } + } + + #[inline] + fn serialize_char(self, value: char) -> Result { + Ok({ + let mut s = String::new(); + s.push(value); + s + }) + } + + #[inline] + fn serialize_str(self, value: &str) -> Result { + Ok(value.to_owned()) + } + + fn serialize_bytes(self, _value: &[u8]) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_unit(self) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_newtype_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T, + ) -> Result + where + T: ?Sized + Serialize, + { + Err(key_must_be_a_string()) + } + + fn serialize_none(self) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_some(self, _value: &T) -> Result + where + T: ?Sized + Serialize, + { + Err(key_must_be_a_string()) + } + + fn serialize_seq(self, _len: Option) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_tuple(self, _len: usize) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_map(self, _len: Option) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { + Err(key_must_be_a_string()) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + Err(key_must_be_a_string()) + } + + fn collect_str(self, value: &T) -> Result + where + T: ?Sized + Display, + { + Ok(value.to_string()) + } +} + +impl serde::ser::SerializeStruct for SerializeMap { + type Ok = Value; + type Error = Error; + + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + match self { + SerializeMap::Map { .. } => serde::ser::SerializeMap::serialize_entry(self, key, value), + #[cfg(feature = "arbitrary_precision")] + SerializeMap::Number { out_value } => { + if key == crate::number::TOKEN { + *out_value = Some(tri!(value.serialize(NumberValueEmitter))); + Ok(()) + } else { + Err(invalid_number()) + } + } + #[cfg(feature = "raw_value")] + SerializeMap::RawValue { out_value } => { + if key == crate::raw::TOKEN { + *out_value = Some(tri!(value.serialize(RawValueEmitter))); + Ok(()) + } else { + Err(invalid_raw_value()) + } + } + } + } + + fn end(self) -> Result { + match self { + SerializeMap::Map { .. } => serde::ser::SerializeMap::end(self), + #[cfg(feature = "arbitrary_precision")] + SerializeMap::Number { out_value, .. } => { + Ok(out_value.expect("number value was not emitted")) + } + #[cfg(feature = "raw_value")] + SerializeMap::RawValue { out_value, .. } => { + Ok(out_value.expect("raw value was not emitted")) + } + } + } +} + +impl serde::ser::SerializeStructVariant for SerializeStructVariant { + type Ok = Value; + type Error = Error; + + fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<()> + where + T: ?Sized + Serialize, + { + self.map.insert(String::from(key), tri!(to_value(value))); + Ok(()) + } + + fn end(self) -> Result { + let mut object = Map::new(); + + object.insert(self.name, Value::Object(self.map)); + + Ok(Value::Object(object)) + } +} + +#[cfg(feature = "arbitrary_precision")] +struct NumberValueEmitter; + +#[cfg(feature = "arbitrary_precision")] +fn invalid_number() -> Error { + Error::syntax(ErrorCode::InvalidNumber, 0, 0) +} + +#[cfg(feature = "arbitrary_precision")] +impl serde::ser::Serializer for NumberValueEmitter { + type Ok = Value; + type Error = Error; + + type SerializeSeq = Impossible; + type SerializeTuple = Impossible; + type SerializeTupleStruct = Impossible; + type SerializeTupleVariant = Impossible; + type SerializeMap = Impossible; + type SerializeStruct = Impossible; + type SerializeStructVariant = Impossible; + + fn serialize_bool(self, _v: bool) -> Result { + Err(invalid_number()) + } + + fn serialize_i8(self, _v: i8) -> Result { + Err(invalid_number()) + } + + fn serialize_i16(self, _v: i16) -> Result { + Err(invalid_number()) + } + + fn serialize_i32(self, _v: i32) -> Result { + Err(invalid_number()) + } + + fn serialize_i64(self, _v: i64) -> Result { + Err(invalid_number()) + } + + fn serialize_u8(self, _v: u8) -> Result { + Err(invalid_number()) + } + + fn serialize_u16(self, _v: u16) -> Result { + Err(invalid_number()) + } + + fn serialize_u32(self, _v: u32) -> Result { + Err(invalid_number()) + } + + fn serialize_u64(self, _v: u64) -> Result { + Err(invalid_number()) + } + + fn serialize_f32(self, _v: f32) -> Result { + Err(invalid_number()) + } + + fn serialize_f64(self, _v: f64) -> Result { + Err(invalid_number()) + } + + fn serialize_char(self, _v: char) -> Result { + Err(invalid_number()) + } + + fn serialize_str(self, value: &str) -> Result { + let n = tri!(value.to_owned().parse()); + Ok(Value::Number(n)) + } + + fn serialize_bytes(self, _value: &[u8]) -> Result { + Err(invalid_number()) + } + + fn serialize_none(self) -> Result { + Err(invalid_number()) + } + + fn serialize_some(self, _value: &T) -> Result + where + T: ?Sized + Serialize, + { + Err(invalid_number()) + } + + fn serialize_unit(self) -> Result { + Err(invalid_number()) + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result { + Err(invalid_number()) + } + + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + ) -> Result { + Err(invalid_number()) + } + + fn serialize_newtype_struct(self, _name: &'static str, _value: &T) -> Result + where + T: ?Sized + Serialize, + { + Err(invalid_number()) + } + + fn serialize_newtype_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T, + ) -> Result + where + T: ?Sized + Serialize, + { + Err(invalid_number()) + } + + fn serialize_seq(self, _len: Option) -> Result { + Err(invalid_number()) + } + + fn serialize_tuple(self, _len: usize) -> Result { + Err(invalid_number()) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result { + Err(invalid_number()) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + Err(invalid_number()) + } + + fn serialize_map(self, _len: Option) -> Result { + Err(invalid_number()) + } + + fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { + Err(invalid_number()) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + Err(invalid_number()) + } +} + +#[cfg(feature = "raw_value")] +struct RawValueEmitter; + +#[cfg(feature = "raw_value")] +fn invalid_raw_value() -> Error { + Error::syntax(ErrorCode::ExpectedSomeValue, 0, 0) +} + +#[cfg(feature = "raw_value")] +impl serde::ser::Serializer for RawValueEmitter { + type Ok = Value; + type Error = Error; + + type SerializeSeq = Impossible; + type SerializeTuple = Impossible; + type SerializeTupleStruct = Impossible; + type SerializeTupleVariant = Impossible; + type SerializeMap = Impossible; + type SerializeStruct = Impossible; + type SerializeStructVariant = Impossible; + + fn serialize_bool(self, _v: bool) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_i8(self, _v: i8) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_i16(self, _v: i16) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_i32(self, _v: i32) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_i64(self, _v: i64) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_u8(self, _v: u8) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_u16(self, _v: u16) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_u32(self, _v: u32) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_u64(self, _v: u64) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_f32(self, _v: f32) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_f64(self, _v: f64) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_char(self, _v: char) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_str(self, value: &str) -> Result { + crate::from_str(value) + } + + fn serialize_bytes(self, _value: &[u8]) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_none(self) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_some(self, _value: &T) -> Result + where + T: ?Sized + Serialize, + { + Err(invalid_raw_value()) + } + + fn serialize_unit(self) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + ) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_newtype_struct(self, _name: &'static str, _value: &T) -> Result + where + T: ?Sized + Serialize, + { + Err(invalid_raw_value()) + } + + fn serialize_newtype_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T, + ) -> Result + where + T: ?Sized + Serialize, + { + Err(invalid_raw_value()) + } + + fn serialize_seq(self, _len: Option) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_tuple(self, _len: usize) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize, + ) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_map(self, _len: Option) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { + Err(invalid_raw_value()) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result { + Err(invalid_raw_value()) + } + + fn collect_str(self, value: &T) -> Result + where + T: ?Sized + Display, + { + self.serialize_str(&value.to_string()) + } +} diff --git a/src/value/de.rs b/src/value/de.rs index dd4698e80..3f73bed09 100644 --- a/src/value/de.rs +++ b/src/value/de.rs @@ -203,7 +203,7 @@ where } } -impl<'de> serde::Deserializer<'de> for Map { +impl<'de> serde::Deserializer<'de> for Map { type Error = Error; fn deserialize_any(self, visitor: V) -> Result @@ -645,12 +645,12 @@ impl<'de> SeqAccess<'de> for SeqDeserializer { } struct MapDeserializer { - iter: as IntoIterator>::IntoIter, + iter: ::IntoIter, value: Option, } impl MapDeserializer { - fn new(map: Map) -> Self { + fn new(map: Map) -> Self { MapDeserializer { iter: map.into_iter(), value: None, @@ -739,7 +739,7 @@ where } } -impl<'de> serde::Deserializer<'de> for &'de Map { +impl<'de> serde::Deserializer<'de> for &'de Map { type Error = Error; fn deserialize_any(self, visitor: V) -> Result @@ -1153,12 +1153,12 @@ impl<'de> SeqAccess<'de> for SeqRefDeserializer<'de> { } struct MapRefDeserializer<'de> { - iter: <&'de Map as IntoIterator>::IntoIter, + iter: <&'de Map as IntoIterator>::IntoIter, value: Option<&'de Value>, } impl<'de> MapRefDeserializer<'de> { - fn new(map: &'de Map) -> Self { + fn new(map: &'de Map) -> Self { MapRefDeserializer { iter: map.into_iter(), value: None, diff --git a/src/value/from.rs b/src/value/from.rs index df4b2038c..2f5e8a19e 100644 --- a/src/value/from.rs +++ b/src/value/from.rs @@ -150,7 +150,7 @@ impl From for Value { } } -impl From> for Value { +impl From for Value { /// Convert map (with string keys) to `Value::Object`. /// /// # Examples @@ -162,7 +162,7 @@ impl From> for Value { /// m.insert("Lorem".to_owned(), "ipsum".into()); /// let x: Value = m.into(); /// ``` - fn from(f: Map) -> Self { + fn from(f: Map) -> Self { Value::Object(f) } } diff --git a/src/value/index.rs b/src/value/index.rs index 7b0011004..6e1ce4ad9 100644 --- a/src/value/index.rs +++ b/src/value/index.rs @@ -162,7 +162,7 @@ impl<'a> Display for Type<'a> { // have different use cases than Value. If you are working with a Vec, you know // that you are working with a Vec and you can get the len of the Vec and make // sure your indices are within bounds. The Value use cases are more -// loosey-goosey. You got some JSON from an endpoint and you want to pull values +// loosey-goosey. You got some JSON from an endpoint, and you want to pull values // out of it. Outside of this Index impl, you already have the option of using // value.as_array() and working with the Vec directly, or matching on // Value::Array and getting the Vec directly. The Index impl means you can skip diff --git a/src/value/mod.rs b/src/value/mod.rs index 6b40f9a52..0dd6bd8c9 100644 --- a/src/value/mod.rs +++ b/src/value/mod.rs @@ -161,7 +161,7 @@ pub enum Value { /// Represents a JSON object. /// - /// By default the map is backed by a BTreeMap. Enable the `preserve_order` + /// By default, the map is backed by a BTreeMap. Enable the `preserve_order` /// feature of serde_json to use IndexMap instead, which preserves /// entries in the order they are inserted into the map. In particular, this /// allows JSON data to be deserialized into a Value and serialized to a @@ -172,7 +172,7 @@ pub enum Value { /// # /// let v = json!({ "an": "object" }); /// ``` - Object(Map), + Object(Map), } impl Debug for Value { @@ -363,7 +363,7 @@ impl Value { /// // The array `["an", "array"]` is not an object. /// assert_eq!(v["b"].as_object(), None); /// ``` - pub fn as_object(&self) -> Option<&Map> { + pub fn as_object(&self) -> Option<&Map> { match self { Value::Object(map) => Some(map), _ => None, @@ -381,7 +381,7 @@ impl Value { /// v["a"].as_object_mut().unwrap().clear(); /// assert_eq!(v, json!({ "a": {} })); /// ``` - pub fn as_object_mut(&mut self) -> Option<&mut Map> { + pub fn as_object_mut(&mut self) -> Option<&mut Map> { match self { Value::Object(map) => Some(map), _ => None, diff --git a/src/value/ser.rs b/src/value/ser.rs index 1ffe7b7f1..8f22f01fc 100644 --- a/src/value/ser.rs +++ b/src/value/ser.rs @@ -310,18 +310,22 @@ pub struct SerializeTupleVariant { pub enum SerializeMap { Map { - map: Map, + map: Map, next_key: Option, }, #[cfg(feature = "arbitrary_precision")] - Number { out_value: Option }, + Number { + out_value: Option, + }, #[cfg(feature = "raw_value")] - RawValue { out_value: Option }, + RawValue { + out_value: Option, + }, } pub struct SerializeStructVariant { name: String, - map: Map, + map: Map, } impl serde::ser::SerializeSeq for SerializeVec {