zng_ext_config/
ron.rs

1use std::mem;
2
3use super::*;
4
5use ::ron as serde_ron;
6
7impl ConfigMap for indexmap::IndexMap<ConfigKey, serde_ron::Value> {
8    fn empty() -> Self {
9        Self::new()
10    }
11
12    fn read(mut file: WatchFile) -> io::Result<Self> {
13        file.ron().map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
14    }
15
16    fn write(self, file: &mut WriteFile) -> io::Result<()> {
17        file.write_ron(&self, true)
18    }
19
20    fn get_raw(&self, key: &ConfigKey) -> Result<Option<RawConfigValue>, Arc<dyn std::error::Error + Send + Sync>> {
21        match self.get(key) {
22            Some(e) => Ok(Some(RawConfigValue::try_from(e.clone())?)),
23            None => Ok(None),
24        }
25    }
26
27    fn set_raw(map: &mut VarModify<Self>, key: ConfigKey, value: RawConfigValue) -> Result<(), Arc<dyn std::error::Error + Send + Sync>> {
28        let value = value.try_into()?;
29        if map.get(&key) != Some(&value) {
30            map.to_mut().insert(key, value);
31        }
32        Ok(())
33    }
34
35    fn contains_key(&self, key: &ConfigKey) -> bool {
36        self.contains_key(key)
37    }
38
39    fn get<O: ConfigValue>(&self, key: &ConfigKey) -> Result<Option<O>, Arc<dyn std::error::Error + Send + Sync>> {
40        if let Some(value) = self.get(key) {
41            match value.clone().into_rust() {
42                Ok(v) => Ok(Some(v)),
43                Err(e) => Err(Arc::new(e)),
44            }
45        } else {
46            Ok(None)
47        }
48    }
49
50    fn set<O: ConfigValue>(map: &mut VarModify<Self>, key: ConfigKey, value: O) -> Result<(), Arc<dyn std::error::Error + Send + Sync>> {
51        match serde_ron::to_string(&value) {
52            Ok(value) => match serde_ron::from_str(&value) {
53                Ok(value) => {
54                    if map.get(&key) != Some(&value) {
55                        map.to_mut().insert(key, value);
56                    }
57                    Ok(())
58                }
59                Err(e) => Err(Arc::new(e)),
60            },
61            Err(e) => Err(Arc::new(e)),
62        }
63    }
64
65    fn remove(map: &mut VarModify<Self>, key: &ConfigKey) {
66        if map.contains_key(key) {
67            map.to_mut().shift_remove(key);
68        }
69    }
70}
71
72/// Represents a config source that synchronizes with a RON file.
73pub type RonConfig = SyncConfig<indexmap::IndexMap<ConfigKey, serde_ron::Value>>;
74
75impl TryFrom<serde_ron::Value> for RawConfigValue {
76    type Error = RonValueRawError;
77
78    fn try_from(value: serde_ron::Value) -> Result<Self, Self::Error> {
79        let ok = match value {
80            serde_ron::Value::Bool(b) => serde_json::Value::Bool(b),
81            serde_ron::Value::Char(c) => serde_json::Value::String(c.to_string()),
82            serde_ron::Value::String(s) => serde_json::Value::String(s),
83            serde_ron::Value::Number(n) => serde_json::Value::Number(match n {
84                serde_ron::Number::Integer(n) => serde_json::Number::from(n),
85                serde_ron::Number::Float(n) => match serde_json::Number::from_f64(n.get()) {
86                    Some(n) => n,
87                    None => return Err(RonValueRawError::InvalidFloat(n.get())),
88                },
89            }),
90            serde_ron::Value::Option(o) => match o {
91                Some(v) => return Self::try_from(*v),
92                None => serde_json::Value::Null,
93            },
94            serde_ron::Value::Seq(s) => serde_json::Value::Array({
95                let mut r = Vec::with_capacity(s.len());
96                for v in s {
97                    r.push(RawConfigValue::try_from(v)?.0);
98                }
99                r
100            }),
101            serde_ron::Value::Map(mut m) => serde_json::Value::Object({
102                let mut r = serde_json::Map::with_capacity(m.len());
103                // ron::Map is not IntoIter
104                for (k, v) in m.iter_mut() {
105                    r.insert(
106                        ron_map_key(k)?,
107                        RawConfigValue::try_from(mem::replace(v, serde_ron::Value::Unit))?.0,
108                    );
109                }
110                r
111            }),
112            serde_ron::Value::Unit => serde_json::Value::Null,
113        };
114        Ok(Self(ok))
115    }
116}
117impl TryFrom<RawConfigValue> for serde_ron::Value {
118    type Error = RonValueRawError;
119
120    fn try_from(value: RawConfigValue) -> Result<Self, Self::Error> {
121        let ok = match value.0 {
122            serde_json::Value::Null => serde_ron::Value::Unit,
123            serde_json::Value::Bool(b) => serde_ron::Value::Bool(b),
124            serde_json::Value::Number(n) => serde_ron::Value::Number(if let Some(i) = n.as_i64() {
125                serde_ron::Number::from(i)
126            } else {
127                let f = n.as_f64().unwrap();
128                serde_ron::Number::from(f)
129            }),
130            serde_json::Value::String(s) => serde_ron::Value::String(s),
131            serde_json::Value::Array(a) => serde_ron::Value::Seq({
132                let mut r = Vec::with_capacity(a.len());
133                for v in a {
134                    r.push(RawConfigValue(v).try_into()?);
135                }
136                r
137            }),
138            serde_json::Value::Object(o) => serde_ron::Value::Map({
139                // ron::Map has no with_capacity
140                let mut r = serde_ron::Map::new();
141                for (k, v) in o {
142                    r.insert(serde_ron::Value::String(k), RawConfigValue(v).try_into()?);
143                }
144                r
145            }),
146        };
147        Ok(ok)
148    }
149}
150
151fn ron_map_key(key: &serde_ron::Value) -> Result<String, RonValueRawError> {
152    let ok = match key {
153        serde_ron::Value::String(s) => s.clone(),
154        serde_ron::Value::Bool(b) => b.to_string(),
155        serde_ron::Value::Char(c) => format!("{c}"),
156        serde_ron::Value::Number(n) => match n {
157            serde_ron::Number::Integer(i) => i.to_string(),
158            serde_ron::Number::Float(_) => return Err(RonValueRawError::InvalidMapKey),
159        },
160        serde_ron::Value::Unit => String::new(),
161        serde_ron::Value::Option(o) => match o {
162            Some(o) => return ron_map_key(o),
163            None => String::new(),
164        },
165        serde_ron::Value::Map(_) | serde_ron::Value::Seq(_) => return Err(RonValueRawError::InvalidMapKey),
166    };
167    Ok(ok)
168}
169
170/// Error converting ron::Value, RawConfigValue.
171#[derive(Debug, Clone, Copy)]
172pub enum RonValueRawError {
173    /// JSON only supports finite floats.
174    InvalidFloat(f64),
175    /// JSON only supports key types that are [`fmt::Display`].
176    InvalidMapKey,
177}
178impl fmt::Display for RonValueRawError {
179    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
180        match self {
181            RonValueRawError::InvalidFloat(fl) => write!(f, "json does not support float `{fl}`"),
182            RonValueRawError::InvalidMapKey => write!(f, "json does not support non-display keys"),
183        }
184    }
185}
186impl std::error::Error for RonValueRawError {}
187impl From<RonValueRawError> for Arc<dyn std::error::Error + Send + Sync> {
188    fn from(value: RonValueRawError) -> Self {
189        Arc::new(value)
190    }
191}