diff --git a/src/file/format/ron.rs b/src/file/format/ron.rs index 9ac81a9d..67b19f57 100644 --- a/src/file/format/ron.rs +++ b/src/file/format/ron.rs @@ -2,62 +2,12 @@ use std::error::Error; use crate::format; use crate::map::Map; -use crate::value::{Value, ValueKind}; +use crate::value::Value; pub fn parse( uri: Option<&String>, text: &str, ) -> Result, Box> { - let value = from_ron_value(uri, ron::from_str(text)?)?; + let value = format::from_parsed_value(uri, ron::from_str(text)?); format::extract_root_table(uri, value) } - -fn from_ron_value( - uri: Option<&String>, - value: ron::Value, -) -> Result> { - let kind = match value { - ron::Value::Option(value) => match value { - Some(value) => from_ron_value(uri, *value)?.kind, - None => ValueKind::Nil, - }, - - ron::Value::Unit => ValueKind::Nil, - - ron::Value::Bool(value) => ValueKind::Boolean(value), - - ron::Value::Number(value) => match value { - ron::Number::Float(value) => ValueKind::Float(value.get()), - ron::Number::Integer(value) => ValueKind::I64(value), - }, - - ron::Value::Char(value) => ValueKind::String(value.to_string()), - - ron::Value::String(value) => ValueKind::String(value), - - ron::Value::Seq(values) => { - let array = values - .into_iter() - .map(|value| from_ron_value(uri, value)) - .collect::, _>>()?; - - ValueKind::Array(array) - } - - ron::Value::Map(values) => { - let map = values - .iter() - .map(|(key, value)| -> Result<_, Box> { - let key = key.clone().into_rust::()?; - let value = from_ron_value(uri, value.clone())?; - - Ok((key, value)) - }) - .collect::, _>>()?; - - ValueKind::Table(map) - } - }; - - Ok(Value::new(uri, kind)) -} diff --git a/src/format.rs b/src/format.rs index a691ec92..485bfbf5 100644 --- a/src/format.rs +++ b/src/format.rs @@ -64,6 +64,7 @@ pub enum ParsedValue { String(String), Table(Map), Array(Vec), + Option(Option>), // If nothing else above matched, use Nil: #[serde(deserialize_with = "deserialize_ignore_any")] Nil, @@ -97,6 +98,12 @@ pub fn from_parsed_value(uri: Option<&String>, value: ParsedValue) -> Value { ValueKind::Array(l) } + + // Boxed value must be dereferenced: + ParsedValue::Option(v) => match v { + Some(boxed) => from_parsed_value(uri, *boxed).kind, + None => ValueKind::Nil, + } }; Value::new(uri, vk) @@ -115,11 +122,18 @@ where // Config specific support for types that need string conversion: #[cfg(feature = "toml")] TomlDateTime(toml::value::Datetime), + #[cfg(feature = "ron")] + RonChar(ron::Value), } - Ok(match ParsedString::deserialize(deserializer)? { - ParsedString::String(v) => v, + match ParsedString::deserialize(deserializer)? { + ParsedString::String(v) => Ok(v), #[cfg(feature = "toml")] - ParsedString::TomlDateTime(v) => v.to_string(), - }) + ParsedString::TomlDateTime(v) => Ok(v.to_string()), + #[cfg(feature = "ron")] + ParsedString::RonChar(variant) => match variant { + ron::Value::Char(v) => Ok(v.to_string()), + _ => Err(serde::de::Error::custom("should not be serialized to string")) + } + } }