use std::{
cmp::{Eq, Ordering},
hash::{Hash, Hasher},
iter::FromIterator,
ops::{Index, IndexMut},
};
use serde::{
de::{DeserializeOwned, DeserializeSeed, Deserializer, MapAccess, SeqAccess, Visitor},
forward_to_deserialize_any,
}; use serde_derive::{Deserialize, Serialize};
usecrate::{de::Error, error::Result};
/// A [`Value`] to [`Value`] map. /// /// This structure either uses a [BTreeMap](std::collections::BTreeMap) or the /// [IndexMap](indexmap::IndexMap) internally. /// The latter can be used by enabling the `indexmap` feature. This can be used /// to preserve the order of the parsed map. #[derive(Clone, Debug, Default, Deserialize, Serialize)] #[serde(transparent)] pubstruct Map(MapInner);
/// Inserts a new element, returning the previous element with this `key` if /// there was any. pubfn insert(&mutself, key: Value, value: Value) -> Option<Value> { self.0.insert(key, value)
}
/// Removes an element by its `key`. pubfn remove(&mutself, key: &Value) -> Option<Value> { self.0.remove(key)
}
/// Retains only the elements specified by the `keep` predicate. /// /// In other words, remove all pairs `(k, v)` for which `keep(&k, &mut v)` /// returns `false`. /// /// The elements are visited in iteration order. pubfn retain<F>(&mutself, keep: F) where
F: FnMut(&Value, &mut Value) -> bool,
{ self.0.retain(keep);
}
}
impl IndexMut<&Value> for Map { fn index_mut(&mutself, index: &Value) -> &mutSelf::Output { self.0.get_mut(index).expect("no entry found for key")
}
}
impl Ord for Map { fn cmp(&self, other: &Map) -> Ordering { self.iter().cmp(other.iter())
}
}
/// Note: equality is only given if both values and order of values match impl PartialEq for Map { fn eq(&self, other: &Map) -> bool { self.iter().zip(other.iter()).all(|(a, b)| a == b)
}
}
#[cfg(not(feature = "indexmap"))] type MapInner = std::collections::BTreeMap<Value, Value>; #[cfg(feature = "indexmap")] type MapInner = indexmap::IndexMap<Value, Value>;
/// A wrapper for a number, which can be either [`f64`] or [`i64`]. #[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Hash, Ord)] pubenum Number {
Integer(i64),
Float(Float),
}
/// A wrapper for [`f64`], which guarantees that the inner value /// is finite and thus implements [`Eq`], [`Hash`] and [`Ord`]. #[derive(Copy, Clone, Debug)] pubstruct Float(f64);
impl Float { /// Construct a new [`Float`]. pubfn new(v: f64) -> Self {
Float(v)
}
impl Number { /// Construct a new number. pubfn new(v: impl Into<Number>) -> Self {
v.into()
}
/// Returns the [`f64`] representation of the [`Number`] regardless of /// whether the number is stored as a float or integer. /// /// # Example /// /// ``` /// # use ron::value::Number; /// let i = Number::new(5); /// let f = Number::new(2.0); /// assert_eq!(i.into_f64(), 5.0); /// assert_eq!(f.into_f64(), 2.0); /// ``` pubfn into_f64(self) -> f64 { self.map_to(|i| i as f64, |f| f)
}
/// If the [`Number`] is a float, return it. Otherwise return [`None`]. /// /// # Example /// /// ``` /// # use ron::value::Number; /// let i = Number::new(5); /// let f = Number::new(2.0); /// assert_eq!(i.as_f64(), None); /// assert_eq!(f.as_f64(), Some(2.0)); /// ``` pubfn as_f64(self) -> Option<f64> { self.map_to(|_| None, Some)
}
/// If the [`Number`] is an integer, return it. Otherwise return [`None`]. /// /// # Example /// /// ``` /// # use ron::value::Number; /// let i = Number::new(5); /// let f = Number::new(2.0); /// assert_eq!(i.as_i64(), Some(5)); /// assert_eq!(f.as_i64(), None); /// ``` pubfn as_i64(self) -> Option<i64> { self.map_to(Some, |_| None)
}
/// Map this number to a single type using the appropriate closure. /// /// # Example /// /// ``` /// # use ron::value::Number; /// let i = Number::new(5); /// let f = Number::new(2.0); /// assert!(i.map_to(|i| i > 3, |f| f > 3.0)); /// assert!(!f.map_to(|i| i > 3, |f| f > 3.0)); /// ``` pubfn map_to<T>( self,
integer_fn: impl FnOnce(i64) -> T,
float_fn: impl FnOnce(f64) -> T,
) -> T { matchself {
Number::Integer(i) => integer_fn(i),
Number::Float(Float(f)) => float_fn(f),
}
}
}
impl From<f64> for Number { fn from(f: f64) -> Number {
Number::Float(Float(f))
}
}
impl From<i64> for Number { fn from(i: i64) -> Number {
Number::Integer(i)
}
}
impl From<i32> for Number { fn from(i: i32) -> Number {
Number::Integer(i64::from(i))
}
}
/// The following [`Number`] conversion checks if the integer fits losslessly /// into an [`i64`], before constructing a [`Number::Integer`] variant. /// If not, the conversion defaults to [`Number::Float`].
impl From<u64> for Number { fn from(i: u64) -> Number { if i <= std::i64::MAX as u64 {
Number::Integer(i as i64)
} else {
Number::new(i as f64)
}
}
}
/// Partial equality comparison /// In order to be able to use [`Number`] as a mapping key, NaN floating values /// wrapped in [`Float`] are equal to each other. It is not the case for /// underlying [`f64`] values itself. impl PartialEq for Float { fn eq(&self, other: &Self) -> bool { self.0.is_nan() && other.0.is_nan() || self.0 == other.0
}
}
/// Equality comparison /// In order to be able to use [`Float`] as a mapping key, NaN floating values /// wrapped in [`Float`] are equal to each other. It is not the case for /// underlying [`f64`] values itself. impl Eq for Float {}
/// Partial ordering comparison /// In order to be able to use [`Number`] as a mapping key, NaN floating values /// wrapped in [`Number`] are equal to each other and are less then any other /// floating value. It is not the case for the underlying [`f64`] values /// themselves. /// /// ``` /// use ron::value::Number; /// assert!(Number::new(std::f64::NAN) < Number::new(std::f64::NEG_INFINITY)); /// assert_eq!(Number::new(std::f64::NAN), Number::new(std::f64::NAN)); /// ``` impl PartialOrd for Float { fn partial_cmp(&self, other: &Self) -> Option<Ordering> { match (self.0.is_nan(), other.0.is_nan()) {
(true, true) => Some(Ordering::Equal),
(true, false) => Some(Ordering::Less),
(false, true) => Some(Ordering::Greater),
_ => self.0.partial_cmp(&other.0),
}
}
}
/// Ordering comparison /// In order to be able to use [`Float`] as a mapping key, NaN floating values /// wrapped in [`Float`] are equal to each other and are less then any other /// floating value. It is not the case for underlying [`f64`] values itself. /// See the [`PartialEq`] implementation. impl Ord for Float { fn cmp(&self, other: &Self) -> Ordering { self.partial_cmp(other).expect("Bug: Contract violation")
}
}
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] pubenum Value {
Bool(bool),
Char(char),
Map(Map),
Number(Number),
Option(Option<Box<Value>>),
String(String),
Seq(Vec<Value>),
Unit,
}
impl Value { /// Tries to deserialize this [`Value`] into `T`. pubfn into_rust<T>(self) -> Result<T> where
T: DeserializeOwned,
{
T::deserialize(self)
}
}
/// Deserializer implementation for RON [`Value`]. /// This does not support enums (because [`Value`] does not store them). impl<'de> Deserializer<'de> for Value { type Error = Error;
impl<'a, 'de> MapAccess<'de> for MapAccessor<'a> { type Error = Error;
fn next_key_seed<K>(&mutself, seed: K) -> Result<Option<K::Value>> where
K: DeserializeSeed<'de>,
{ // The `Vec` is reversed, so we can pop to get the originally first element matchself.items.pop() {
Some((key, value)) => { self.value = Some(value);
seed.deserialize(key).map(Some)
}
None => Ok(None),
}
}
fn next_value_seed<V>(&mutself, seed: V) -> Result<V::Value> where
V: DeserializeSeed<'de>,
{ matchself.value.take() {
Some(value) => seed.deserialize(value),
None => panic!("Contract violation: value before key"),
}
}
impl<'a, 'de> SeqAccess<'de> for Seq<'a> { type Error = Error;
fn next_element_seed<T>(&mutself, seed: T) -> Result<Option<T::Value>> where
T: DeserializeSeed<'de>,
{ // The `Vec` is reversed, so we can pop to get the originally first element self.seq
.pop()
.map_or(Ok(None), |v| seed.deserialize(v).map(Some))
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.