From 0e6a76331697050a13ba9ade6fd4d988fdaff962 Mon Sep 17 00:00:00 2001 From: wiiznokes <78230769+wiiznokes@users.noreply.github.com> Date: Sat, 23 Nov 2024 21:12:26 +0100 Subject: [PATCH] modif value type --- src/de/value.rs | 10 +- src/ser/value.rs | 57 +++++++++++- src/value/map.rs | 66 +++++++------ src/value/mod.rs | 93 ++++++++++++++++--- tests/238_array.rs | 4 +- tests/465_no_comment_char_value.rs | 4 +- tests/465_r_name_value.rs | 4 +- .../465_unwrap_some_newtype_variant_value.rs | 2 +- tests/value.rs | 6 +- 9 files changed, 188 insertions(+), 58 deletions(-) diff --git a/src/de/value.rs b/src/de/value.rs index b7e69b619..e9fbad35d 100644 --- a/src/de/value.rs +++ b/src/de/value.rs @@ -213,7 +213,7 @@ impl<'de> Visitor<'de> for ValueVisitor { vec.push(x); } - Ok(Value::Seq(vec)) + Ok(Value::List(vec)) } fn visit_map(self, mut map: A) -> Result @@ -263,7 +263,7 @@ mod tests { fn test_tuples_basic() { assert_eq!( eval("(3, 4.0, 5.0)"), - Value::Seq(vec![ + Value::List(vec![ Value::Number(Number::U8(3)), Value::Number(Number::F32(4.0.into())), Value::Number(Number::F32(5.0.into())), @@ -275,7 +275,7 @@ mod tests { fn test_tuples_ident() { assert_eq!( eval("(true, 3, 4, 5.0)"), - Value::Seq(vec![ + Value::List(vec![ Value::Bool(true), Value::Number(Number::U8(3)), Value::Number(Number::U8(4)), @@ -301,7 +301,7 @@ mod tests { fn test_floats() { assert_eq!( eval("(inf, -inf, NaN)"), - Value::Seq(vec![ + Value::List(vec![ Value::Number(Number::new(std::f32::INFINITY)), Value::Number(Number::new(std::f32::NEG_INFINITY)), Value::Number(Number::new(std::f32::NAN)), @@ -328,7 +328,7 @@ mod tests { ), ])" ), - Value::Option(Some(Box::new(Value::Seq(vec![ + Value::Option(Some(Box::new(Value::List(vec![ Value::Map( vec![ ( diff --git a/src/ser/value.rs b/src/ser/value.rs index 87fdbce83..05c43015b 100644 --- a/src/ser/value.rs +++ b/src/ser/value.rs @@ -1,4 +1,4 @@ -use serde::ser::{Serialize, Serializer}; +use serde::ser::{Serialize, SerializeStruct, SerializeTuple, SerializeTupleStruct, Serializer}; use crate::value::Value; @@ -16,8 +16,61 @@ impl Serialize for Value { Value::Option(None) => serializer.serialize_none(), Value::String(ref s) => serializer.serialize_str(s), Value::Bytes(ref b) => serializer.serialize_bytes(b), - Value::Seq(ref s) => Serialize::serialize(s, serializer), + Value::List(ref s) => Serialize::serialize(s, serializer), Value::Unit => serializer.serialize_unit(), + Value::Struct(name, map) => { + // serializer.serialize_struct(name, len) + // serializer.serialize_struct_variant(name, variant_index, variant, len) + + // serializer.serialize_newtype_struct(name, value) + // serializer.serialize_newtype_variant(name, variant_index, variant, value) + + // serializer.serialize_unit_struct(name) + // serializer.serialize_unit_variant(name, variant_index, variant) + + // serializer.serialize_map(len) + + // serializer.serialize_tuple(len) + // serializer.serialize_tuple_struct(name, len) + // serializer.serialize_tuple_variant(name, variant_index, variant, len) + + // https://github.com/serde-rs/json/blob/master/src/value/ser.rs + + match name { + Some(name) => { + let mut state = serializer.serialize_struct("", map.len())?; + + for (k, v) in map { + state.serialize_field(&k, &v)?; + } + + state.end() + } + None => { + todo!() + } + } + } + Value::Tuple(name, vec) => match name { + Some(name) => { + let mut state = serializer.serialize_tuple_struct("", vec.len())?; + + for v in vec { + state.serialize_field(&v)?; + } + + state.end() + } + None => { + let mut state = serializer.serialize_tuple(vec.len())?; + + for v in vec { + state.serialize_element(&v)?; + } + + state.end() + } + }, } } } diff --git a/src/value/map.rs b/src/value/map.rs index 8375184fa..1d79f90cd 100644 --- a/src/value/map.rs +++ b/src/value/map.rs @@ -15,16 +15,22 @@ use super::Value; /// [`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)] +#[derive(Clone, Debug, Deserialize, Serialize)] #[serde(transparent)] -pub struct Map(pub(crate) MapInner); +pub struct Map(pub(crate) MapInner); #[cfg(not(feature = "indexmap"))] -type MapInner = std::collections::BTreeMap; +type MapInner = std::collections::BTreeMap; #[cfg(feature = "indexmap")] -type MapInner = indexmap::IndexMap; +type MapInner = indexmap::IndexMap; -impl Map { +impl Default for Map { + fn default() -> Self { + Self(Default::default()) + } +} + +impl Map { /// Creates a new, empty [`Map`]. #[must_use] pub fn new() -> Self { @@ -45,23 +51,23 @@ impl Map { /// Immutably looks up an element by its `key`. #[must_use] - pub fn get(&self, key: &Value) -> Option<&Value> { + pub fn get(&self, key: &Key) -> Option<&Value> { self.0.get(key) } /// Mutably looks up an element by its `key`. - pub fn get_mut(&mut self, key: &Value) -> Option<&mut Value> { + pub fn get_mut(&mut self, key: &Key) -> Option<&mut Value> { self.0.get_mut(key) } /// Inserts a new element, returning the previous element with this `key` if /// there was any. - pub fn insert(&mut self, key: impl Into, value: impl Into) -> Option { + pub fn insert(&mut self, key: impl Into, value: impl Into) -> Option { self.0.insert(key.into(), value.into()) } /// Removes an element by its `key`. - pub fn remove(&mut self, key: &Value) -> Option { + pub fn remove(&mut self, key: &Key) -> Option { #[cfg(feature = "indexmap")] { self.0.shift_remove(key) @@ -74,19 +80,19 @@ impl Map { /// Iterate all key-value pairs. #[must_use] - pub fn iter(&self) -> impl DoubleEndedIterator { + pub fn iter(&self) -> impl DoubleEndedIterator { self.0.iter() } /// Iterate all key-value pairs mutably. #[must_use] - pub fn iter_mut(&mut self) -> impl DoubleEndedIterator { + pub fn iter_mut(&mut self) -> impl DoubleEndedIterator { self.0.iter_mut() } /// Iterate all keys. #[must_use] - pub fn keys(&self) -> impl DoubleEndedIterator { + pub fn keys(&self) -> impl DoubleEndedIterator { self.0.keys() } @@ -110,39 +116,39 @@ impl Map { /// The elements are visited in iteration order. pub fn retain(&mut self, keep: F) where - F: FnMut(&Value, &mut Value) -> bool, + F: FnMut(&Key, &mut Value) -> bool, { self.0.retain(keep); } } -impl Index<&Value> for Map { +impl Index<&Key> for Map { type Output = Value; #[allow(clippy::expect_used)] - fn index(&self, index: &Value) -> &Self::Output { + fn index(&self, index: &Key) -> &Self::Output { self.get(index).expect("no entry found for key") } } -impl IndexMut<&Value> for Map { +impl IndexMut<&Key> for Map { #[allow(clippy::expect_used)] - fn index_mut(&mut self, index: &Value) -> &mut Self::Output { + fn index_mut(&mut self, index: &Key) -> &mut Self::Output { self.get_mut(index).expect("no entry found for key") } } -impl IntoIterator for Map { - type Item = (Value, Value); +impl IntoIterator for Map { + type Item = (Key, Value); - type IntoIter = ::IntoIter; + type IntoIter = as IntoIterator>::IntoIter; fn into_iter(self) -> Self::IntoIter { self.0.into_iter() } } -impl, V: Into> FromIterator<(K, V)> for Map { +impl, V: Into> FromIterator<(K, V)> for Map { fn from_iter>(iter: T) -> Self { Map(iter .into_iter() @@ -152,28 +158,28 @@ impl, V: Into> FromIterator<(K, V)> for Map { } /// Note: equality is only given if both values and order of values match -impl PartialEq for Map { - fn eq(&self, other: &Map) -> bool { +impl PartialEq for Map { + fn eq(&self, other: &Map) -> bool { self.cmp(other).is_eq() } } /// Note: equality is only given if both values and order of values match -impl Eq for Map {} +impl Eq for Map {} -impl PartialOrd for Map { - fn partial_cmp(&self, other: &Map) -> Option { +impl PartialOrd for Map { + fn partial_cmp(&self, other: &Map) -> Option { Some(self.cmp(other)) } } -impl Ord for Map { - fn cmp(&self, other: &Map) -> Ordering { +impl Ord for Map { + fn cmp(&self, other: &Map) -> Ordering { self.iter().cmp(other.iter()) } } -impl Hash for Map { +impl Hash for Map { fn hash(&self, state: &mut H) { self.iter().for_each(|x| x.hash(state)); } @@ -254,7 +260,7 @@ mod tests { ); } - fn assert_same_hash(a: &Map, b: &Map) { + fn assert_same_hash(a: &Map, b: &Map) { use std::collections::hash_map::DefaultHasher; use std::hash::{Hash, Hasher}; diff --git a/src/value/mod.rs b/src/value/mod.rs index 28ea83f98..0a90de39e 100644 --- a/src/value/mod.rs +++ b/src/value/mod.rs @@ -22,12 +22,14 @@ pub use raw::RawValue; pub enum Value { Bool(bool), Char(char), - Map(Map), + Map(Map), + Struct(Option, Map), Number(Number), Option(Option>), String(String), Bytes(Vec), - Seq(Vec), + List(Vec), + Tuple(Option, Vec), Unit, } @@ -49,8 +51,8 @@ impl, V: Into> FromIterator<(K, V)> for Value { } } -impl From for Value { - fn from(value: Map) -> Self { +impl From> for Value { + fn from(value: Map) -> Self { Self::Map(value) } } @@ -94,7 +96,7 @@ impl From<&'static [u8; N]> for Value { impl> FromIterator for Value { fn from_iter>(iter: I) -> Self { - Self::Seq(iter.into_iter().map(Into::into).collect()) + Self::List(iter.into_iter().map(Into::into).collect()) } } @@ -174,7 +176,7 @@ impl<'de> Deserializer<'de> for Value { Value::Option(None) => visitor.visit_none(), Value::String(s) => visitor.visit_string(s), Value::Bytes(b) => visitor.visit_byte_buf(b), - Value::Seq(mut seq) => { + Value::List(mut seq) => { let old_len = seq.len(); seq.reverse(); @@ -256,9 +258,12 @@ impl<'a, 'de> MapAccess<'de> for MapAccessor<'a> { #[cfg(test)] mod tests { - use std::{collections::BTreeMap, fmt::Debug}; + use std::{ + collections::{BTreeMap, HashMap}, + fmt::Debug, + }; - use serde::Deserialize; + use serde::{Deserialize, Serialize}; use super::*; @@ -414,7 +419,7 @@ mod tests { assert_eq!( Value::from([-1_i8, 2, -3].as_slice()), - Value::Seq(vec![ + Value::List(vec![ Value::from(-1_i8), Value::from(2_i8), Value::from(-3_i8) @@ -422,7 +427,7 @@ mod tests { ); assert_eq!( Value::from(vec![-1_i8, 2, -3]), - Value::Seq(vec![ + Value::List(vec![ Value::from(-1_i8), Value::from(2_i8), Value::from(-3_i8) @@ -430,7 +435,7 @@ mod tests { ); assert_eq!( Value::from_iter([-1_i8, 2, -3]), - Value::Seq(vec![ + Value::List(vec![ Value::from(-1_i8), Value::from(2_i8), Value::from(-3_i8) @@ -499,4 +504,70 @@ mod tests { Value::from('🦀') ); } + + #[test] + fn test() { + #[derive(Serialize)] + enum B { + A, + B, + } + + #[derive(Serialize)] + struct A { + a: B, + b: HashMap, + } + + let v = A { + a: B::A, + b: [("a".into(), "a".into())].into_iter().collect(), + }; + + let ron_str = crate::to_string(&v).unwrap(); + + println!("{}", ron_str); + + let value = crate::from_str::(&ron_str).unwrap(); + + println!("{:?}", value); + + let ron_str2 = crate::to_string(&value).unwrap(); + + println!("{}", ron_str2); + + assert_eq!(ron_str, ron_str2); + } + + #[test] + fn test2() { + #[derive(Serialize)] + enum B { + A(Option, i32), + B, + } + + #[derive(Serialize)] + struct A { + a: B, + } + + let v = A { + a: B::A(Some("a".into()), 0), + }; + + let ron_str = crate::to_string(&v).unwrap(); + + println!("{}", ron_str); + + let value = crate::from_str::(&ron_str).unwrap(); + + println!("{:?}", value); + + let ron_str2 = crate::to_string(&value).unwrap(); + + println!("{}", ron_str2); + + assert_eq!(ron_str, ron_str2); + } } diff --git a/tests/238_array.rs b/tests/238_array.rs index ec339b271..c19d7dcf7 100644 --- a/tests/238_array.rs +++ b/tests/238_array.rs @@ -16,7 +16,7 @@ fn test_array() { let value: Value = ron::from_str(&ser).unwrap(); assert_eq!( value, - Value::Seq(vec![ + Value::List(vec![ Value::Number(Number::U8(1)), Value::Number(Number::U8(2)), Value::Number(Number::U8(3)), @@ -42,7 +42,7 @@ fn test_array() { let value: Value = ron::from_str(&ser).unwrap(); assert_eq!( value, - Value::Seq(vec![ + Value::List(vec![ Value::Number(Number::U8(1)), Value::Number(Number::U8(2)), Value::Number(Number::U8(3)), diff --git a/tests/465_no_comment_char_value.rs b/tests/465_no_comment_char_value.rs index 4d77f0ad1..2a229ac52 100644 --- a/tests/465_no_comment_char_value.rs +++ b/tests/465_no_comment_char_value.rs @@ -4,10 +4,10 @@ fn value_deserialises_r_name() { // searcher reads into the char and then finds a weird comment starter there assert_eq!( ron::from_str("A('/')"), - Ok(ron::Value::Seq(vec![ron::Value::Char('/')])) + Ok(ron::Value::List(vec![ron::Value::Char('/')])) ); assert_eq!( ron::from_str("A(\"/\")"), - Ok(ron::Value::Seq(vec![ron::Value::String(String::from("/"))])) + Ok(ron::Value::List(vec![ron::Value::String(String::from("/"))])) ); } diff --git a/tests/465_r_name_value.rs b/tests/465_r_name_value.rs index d6a63bc50..5ecdc30d8 100644 --- a/tests/465_r_name_value.rs +++ b/tests/465_r_name_value.rs @@ -1,10 +1,10 @@ #[test] fn value_deserialises_r_name() { assert_eq!(ron::from_str("r"), Ok(ron::Value::Unit)); - assert_eq!(ron::from_str("r()"), Ok(ron::Value::Seq(vec![]))); + assert_eq!(ron::from_str("r()"), Ok(ron::Value::List(vec![]))); assert_eq!( ron::from_str("r(42)"), - Ok(ron::Value::Seq(vec![ron::Value::Number( + Ok(ron::Value::List(vec![ron::Value::Number( ron::value::Number::U8(42) )])) ); diff --git a/tests/465_unwrap_some_newtype_variant_value.rs b/tests/465_unwrap_some_newtype_variant_value.rs index 512aaf8d6..eb243d56b 100644 --- a/tests/465_unwrap_some_newtype_variant_value.rs +++ b/tests/465_unwrap_some_newtype_variant_value.rs @@ -20,7 +20,7 @@ fn deserialise_value_with_unwrap_some_newtype_variant() { ); assert_eq!( ron::from_str("#![enable(unwrap_variant_newtypes)] Some(42, true)"), - Ok(ron::Value::Option(Some(Box::new(ron::Value::Seq(vec![ + Ok(ron::Value::Option(Some(Box::new(ron::Value::List(vec![ ron::Value::Number(ron::value::Number::U8(42)), ron::Value::Bool(true) ]))))), diff --git a/tests/value.rs b/tests/value.rs index 9b57a4d93..6a33ad44f 100644 --- a/tests/value.rs +++ b/tests/value.rs @@ -111,14 +111,14 @@ fn byte_string() { #[test] fn seq() { - let seq = Value::Seq(vec![ + let seq = Value::List(vec![ Value::Number(Number::U8(1)), Value::Number(Number::new(2f32)), ]); assert_eq!(ron::to_string(&seq).unwrap(), "[1,2.0]"); assert_eq!("[1, 2.0]".parse(), Ok(seq)); - let err = Value::Seq(vec![Value::Number(Number::new(1))]) + let err = Value::List(vec![Value::Number(Number::new(1))]) .into_rust::<[i32; 2]>() .unwrap_err(); @@ -130,7 +130,7 @@ fn seq() { } ); - let err = Value::Seq(vec![ + let err = Value::List(vec![ Value::Number(Number::new(1)), Value::Number(Number::new(2)), Value::Number(Number::new(3)),