1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
use mlua::Value;
/// A scalar (or short list of scalars) read from `srd.set(key, value)`.
/// Deliberately simpler than the legacy C++ `LuaConfigValue`, which also had
/// `Table`/`Function` variants that, per docs/PRIOR_ART.md, were never
/// actually exercised by the flat dotted-key config style the example
/// configs (and `docs/DEFAULTS.md`) actually use.
#[derive(Debug, Clone, PartialEq)]
pub enum ConfigValue {
String(String),
Number(f64),
Bool(bool),
List(Vec<String>),
}
impl ConfigValue {
pub fn from_lua(value: &Value) -> Option<Self> {
match value {
Value::String(s) => Some(ConfigValue::String(s.to_str().ok()?.to_string())),
Value::Number(n) => Some(ConfigValue::Number(*n)),
Value::Integer(i) => Some(ConfigValue::Number(*i as f64)),
Value::Boolean(b) => Some(ConfigValue::Bool(*b)),
Value::Table(t) => {
let mut items = Vec::new();
for pair in t.clone().sequence_values::<String>() {
items.push(pair.ok()?);
}
Some(ConfigValue::List(items))
}
_ => None,
}
}
pub fn as_str(&self) -> Option<&str> {
match self {
ConfigValue::String(s) => Some(s),
_ => None,
}
}
pub fn as_f64(&self) -> Option<f64> {
match self {
ConfigValue::Number(n) => Some(*n),
_ => None,
}
}
pub fn as_bool(&self) -> Option<bool> {
match self {
ConfigValue::Bool(b) => Some(*b),
_ => None,
}
}
pub fn as_list(&self) -> Option<&[String]> {
match self {
ConfigValue::List(l) => Some(l),
_ => None,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use mlua::Lua;
#[test]
fn converts_string_number_bool_and_list() {
let lua = Lua::new();
assert_eq!(ConfigValue::from_lua(&lua.load("'hi'").eval().unwrap()), Some(ConfigValue::String("hi".into())));
assert_eq!(ConfigValue::from_lua(&lua.load("42").eval().unwrap()), Some(ConfigValue::Number(42.0)));
assert_eq!(ConfigValue::from_lua(&lua.load("true").eval().unwrap()), Some(ConfigValue::Bool(true)));
assert_eq!(
ConfigValue::from_lua(&lua.load("{'1','2','3'}").eval().unwrap()),
Some(ConfigValue::List(vec!["1".into(), "2".into(), "3".into()]))
);
}
}
|