//! Value module. 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, Deserialize, Serialize, }; use crate::de::Error; use crate::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)] pub struct Map(MapInner); impl Map { /// Creates a new, empty `Map`. pub fn new() -> Map { Default::default() } /// Returns the number of elements in the map. pub fn len(&self) -> usize { self.0.len() } /// Returns `true` if `self.len() == 0`, `false` otherwise. pub fn is_empty(&self) -> bool { self.0.len() == 0 } /// Inserts a new element, returning the previous element with this `key` if /// there was any. pub fn insert(&mut self, key: Value, value: Value) -> Option { self.0.insert(key, value) } /// Removes an element by its `key`. pub fn remove(&mut self, key: &Value) -> Option { self.0.remove(key) } /// Iterate all key-value pairs. pub fn iter(&self) -> impl Iterator + DoubleEndedIterator { self.0.iter() } /// Iterate all key-value pairs mutably. pub fn iter_mut(&mut self) -> impl Iterator + DoubleEndedIterator { self.0.iter_mut() } /// Iterate all keys. pub fn keys(&self) -> impl Iterator + DoubleEndedIterator { self.0.keys() } /// Iterate all values. pub fn values(&self) -> impl Iterator + DoubleEndedIterator { self.0.values() } /// Iterate all values mutably. pub fn values_mut(&mut self) -> impl Iterator + DoubleEndedIterator { self.0.values_mut() } } impl FromIterator<(Value, Value)> for Map { fn from_iter>(iter: T) -> Self { Map(MapInner::from_iter(iter)) } } /// Note: equality is only given if both values and order of values match impl Eq for Map {} impl Hash for Map { fn hash(&self, state: &mut H) { self.iter().for_each(|x| x.hash(state)); } } impl Index<&Value> for Map { type Output = Value; fn index(&self, index: &Value) -> &Self::Output { &self.0[index] } } impl IndexMut<&Value> for Map { fn index_mut(&mut self, index: &Value) -> &mut Self::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) } } impl PartialOrd for Map { fn partial_cmp(&self, other: &Map) -> Option { self.iter().partial_cmp(other.iter()) } } #[cfg(not(feature = "indexmap"))] type MapInner = std::collections::BTreeMap; #[cfg(feature = "indexmap")] type MapInner = indexmap::IndexMap; /// A wrapper for a number, which can be either `f64` or `i64`. #[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Hash, Ord)] pub enum 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)] pub struct Float(f64); impl Float { /// Construct a new `Float`. pub fn new(v: f64) -> Self { Float(v) } /// Returns the wrapped float. pub fn get(self) -> f64 { self.0 } } impl Number { /// Construct a new number. pub fn new(v: impl Into) -> 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); /// ``` pub fn 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)); /// ``` pub fn as_f64(self) -> Option { 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); /// ``` pub fn as_i64(self) -> Option { 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)); /// ``` pub fn map_to( self, integer_fn: impl FnOnce(i64) -> T, float_fn: impl FnOnce(f64) -> T, ) -> T { match self { Number::Integer(i) => integer_fn(i), Number::Float(Float(f)) => float_fn(f), } } } impl From for Number { fn from(f: f64) -> Number { Number::Float(Float(f)) } } impl From for Number { fn from(i: i64) -> Number { Number::Integer(i) } } impl From 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 float. impl From 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 equals 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 equals to each other. It is not the case for /// underlying `f64` values itself. impl Eq for Float {} impl Hash for Float { fn hash(&self, state: &mut H) { state.write_u64(self.0.to_bits()); } } /// Partial ordering comparison /// In order to be able to use `Number` as a mapping key, NaN floating values /// wrapped in `Number` are equals 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 { 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 equals 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)] pub enum Value { Bool(bool), Char(char), Map(Map), Number(Number), Option(Option>), String(String), Seq(Vec), Unit, } impl Value { /// Tries to deserialize this `Value` into `T`. pub fn into_rust(self) -> Result where T: DeserializeOwned, { T::deserialize(self) } } /// Deserializer implementation for RON `Value`. /// This does not support enums (because `Value` doesn't store them). impl<'de> Deserializer<'de> for Value { type Error = Error; forward_to_deserialize_any! { bool f32 f64 char str string bytes byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct map struct enum identifier ignored_any } fn deserialize_any(self, visitor: V) -> Result where V: Visitor<'de>, { match self { Value::Bool(b) => visitor.visit_bool(b), Value::Char(c) => visitor.visit_char(c), Value::Map(m) => visitor.visit_map(MapAccessor { keys: m.keys().cloned().rev().collect(), values: m.values().cloned().rev().collect(), }), Value::Number(Number::Float(ref f)) => visitor.visit_f64(f.get()), Value::Number(Number::Integer(i)) => visitor.visit_i64(i), Value::Option(Some(o)) => visitor.visit_some(*o), Value::Option(None) => visitor.visit_none(), Value::String(s) => visitor.visit_string(s), Value::Seq(mut seq) => { seq.reverse(); visitor.visit_seq(Seq { seq }) } Value::Unit => visitor.visit_unit(), } } fn deserialize_i8(self, visitor: V) -> Result where V: Visitor<'de>, { self.deserialize_i64(visitor) } fn deserialize_i16(self, visitor: V) -> Result where V: Visitor<'de>, { self.deserialize_i64(visitor) } fn deserialize_i32(self, visitor: V) -> Result where V: Visitor<'de>, { self.deserialize_i64(visitor) } fn deserialize_i64(self, visitor: V) -> Result where V: Visitor<'de>, { match self { Value::Number(Number::Integer(i)) => visitor.visit_i64(i), v => Err(Error::Message(format!("Expected a number, got {:?}", v))), } } fn deserialize_u8(self, visitor: V) -> Result where V: Visitor<'de>, { self.deserialize_u64(visitor) } fn deserialize_u16(self, visitor: V) -> Result where V: Visitor<'de>, { self.deserialize_u64(visitor) } fn deserialize_u32(self, visitor: V) -> Result where V: Visitor<'de>, { self.deserialize_u64(visitor) } fn deserialize_u64(self, visitor: V) -> Result where V: Visitor<'de>, { match self { Value::Number(Number::Integer(i)) => visitor.visit_u64(i as u64), v => Err(Error::Message(format!("Expected a number, got {:?}", v))), } } } struct MapAccessor { keys: Vec, values: Vec, } impl<'de> MapAccess<'de> for MapAccessor { type Error = Error; fn next_key_seed(&mut self, seed: K) -> Result> where K: DeserializeSeed<'de>, { // The `Vec` is reversed, so we can pop to get the originally first element self.keys .pop() .map_or(Ok(None), |v| seed.deserialize(v).map(Some)) } fn next_value_seed(&mut self, seed: V) -> Result where V: DeserializeSeed<'de>, { // The `Vec` is reversed, so we can pop to get the originally first element self.values .pop() .map(|v| seed.deserialize(v)) .expect("Contract violation") } } struct Seq { seq: Vec, } impl<'de> SeqAccess<'de> for Seq { type Error = Error; fn next_element_seed(&mut self, seed: T) -> Result> 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)) } } #[cfg(test)] mod tests { use super::*; use serde::Deserialize; use std::{collections::BTreeMap, fmt::Debug}; fn assert_same<'de, T>(s: &'de str) where T: Debug + Deserialize<'de> + PartialEq, { use crate::de::from_str; let direct: T = from_str(s).unwrap(); let value: Value = from_str(s).unwrap(); let value = T::deserialize(value).unwrap(); assert_eq!(direct, value, "Deserialization for {:?} is not the same", s); } #[test] fn boolean() { assert_same::("true"); assert_same::("false"); } #[test] fn float() { assert_same::("0.123"); assert_same::("-4.19"); } #[test] fn int() { assert_same::("626"); assert_same::("-50"); } #[test] fn char() { assert_same::("'4'"); assert_same::("'c'"); } #[test] fn map() { assert_same::>( "{ 'a': \"Hello\", 'b': \"Bye\", }", ); } #[test] fn option() { assert_same::>("Some('a')"); assert_same::>("None"); } #[test] fn seq() { assert_same::>("[1.0, 2.0, 3.0, 4.0]"); } #[test] fn unit() { assert_same::<()>("()"); } }