Skip to content

Commit 1c8ed59

Browse files
committed
fix: Support Ron values
- `Char` variant needed to be converted to `String`. - `Option` variant could be introduced generically. NOTE: With `v0.9` of Ron, more types are introduced. Without tests, if these do not deserialize into a supported type they will be treated as `Nil` type. Signed-off-by: Brennan Kinney <5098581+polarathene@users.noreply.github.com>
1 parent dd15797 commit 1c8ed59

File tree

2 files changed

+20
-56
lines changed

2 files changed

+20
-56
lines changed

src/file/format/ron.rs

+2-52
Original file line numberDiff line numberDiff line change
@@ -2,62 +2,12 @@ use std::error::Error;
22

33
use crate::format;
44
use crate::map::Map;
5-
use crate::value::{Value, ValueKind};
5+
use crate::value::Value;
66

77
pub fn parse(
88
uri: Option<&String>,
99
text: &str,
1010
) -> Result<Map<String, Value>, Box<dyn Error + Send + Sync>> {
11-
let value = from_ron_value(uri, ron::from_str(text)?)?;
11+
let value = format::from_parsed_value(uri, ron::from_str(text)?);
1212
format::extract_root_table(uri, value)
1313
}
14-
15-
fn from_ron_value(
16-
uri: Option<&String>,
17-
value: ron::Value,
18-
) -> Result<Value, Box<dyn Error + Send + Sync>> {
19-
let kind = match value {
20-
ron::Value::Option(value) => match value {
21-
Some(value) => from_ron_value(uri, *value)?.kind,
22-
None => ValueKind::Nil,
23-
},
24-
25-
ron::Value::Unit => ValueKind::Nil,
26-
27-
ron::Value::Bool(value) => ValueKind::Boolean(value),
28-
29-
ron::Value::Number(value) => match value {
30-
ron::Number::Float(value) => ValueKind::Float(value.get()),
31-
ron::Number::Integer(value) => ValueKind::I64(value),
32-
},
33-
34-
ron::Value::Char(value) => ValueKind::String(value.to_string()),
35-
36-
ron::Value::String(value) => ValueKind::String(value),
37-
38-
ron::Value::Seq(values) => {
39-
let array = values
40-
.into_iter()
41-
.map(|value| from_ron_value(uri, value))
42-
.collect::<Result<Vec<_>, _>>()?;
43-
44-
ValueKind::Array(array)
45-
}
46-
47-
ron::Value::Map(values) => {
48-
let map = values
49-
.iter()
50-
.map(|(key, value)| -> Result<_, Box<dyn Error + Send + Sync>> {
51-
let key = key.clone().into_rust::<String>()?;
52-
let value = from_ron_value(uri, value.clone())?;
53-
54-
Ok((key, value))
55-
})
56-
.collect::<Result<Map<_, _>, _>>()?;
57-
58-
ValueKind::Table(map)
59-
}
60-
};
61-
62-
Ok(Value::new(uri, kind))
63-
}

src/format.rs

+18-4
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ pub enum ParsedValue {
6464
String(String),
6565
Table(Map<String, Self>),
6666
Array(Vec<Self>),
67+
Option(Option<Box<Self>>),
6768
// If nothing else above matched, use Nil:
6869
#[serde(deserialize_with = "deserialize_ignore_any")]
6970
Nil,
@@ -97,6 +98,12 @@ pub fn from_parsed_value(uri: Option<&String>, value: ParsedValue) -> Value {
9798

9899
ValueKind::Array(l)
99100
}
101+
102+
// Boxed value must be dereferenced:
103+
ParsedValue::Option(v) => match v {
104+
Some(boxed) => from_parsed_value(uri, *boxed).kind,
105+
None => ValueKind::Nil,
106+
}
100107
};
101108

102109
Value::new(uri, vk)
@@ -115,11 +122,18 @@ where
115122
// Config specific support for types that need string conversion:
116123
#[cfg(feature = "toml")]
117124
TomlDateTime(toml::value::Datetime),
125+
#[cfg(feature = "ron")]
126+
RonChar(ron::Value),
118127
}
119128

120-
Ok(match ParsedString::deserialize(deserializer)? {
121-
ParsedString::String(v) => v,
129+
match ParsedString::deserialize(deserializer)? {
130+
ParsedString::String(v) => Ok(v),
122131
#[cfg(feature = "toml")]
123-
ParsedString::TomlDateTime(v) => v.to_string(),
124-
})
132+
ParsedString::TomlDateTime(v) => Ok(v.to_string()),
133+
#[cfg(feature = "ron")]
134+
ParsedString::RonChar(variant) => match variant {
135+
ron::Value::Char(v) => Ok(v.to_string()),
136+
_ => Err(serde::de::Error::custom("should not be serialized to string"))
137+
}
138+
}
125139
}

0 commit comments

Comments
 (0)