spin_locked_app/
values.rs

1//! Dynamically-typed value helpers.
2
3use serde::Serialize;
4use serde_json::Value;
5
6/// A String-keyed map with dynamically-typed values.
7pub type ValuesMap = serde_json::Map<String, Value>;
8
9/// ValuesMapBuilder assists in building a ValuesMap.
10#[derive(Default)]
11pub struct ValuesMapBuilder(ValuesMap);
12
13impl ValuesMapBuilder {
14    /// Returns a new empty ValuesMapBuilder.
15    pub fn new() -> Self {
16        Self::default()
17    }
18
19    /// Returns a ValuesMapBuilder populated from the given map-serializable
20    /// value.
21    pub fn try_from<S: Serialize>(s: S) -> serde_json::Result<Self> {
22        let value = serde_json::to_value(s)?;
23        let map = serde_json::from_value(value)?;
24        Ok(Self(map))
25    }
26
27    /// Inserts a string value into the map.
28    pub fn string(&mut self, key: impl Into<String>, value: impl Into<String>) -> &mut Self {
29        let value = value.into();
30        if value.is_empty() {
31            return self;
32        }
33        self.entry(key, value)
34    }
35
36    /// Inserts a string value into the map only if the given Option is Some.
37    pub fn string_option(
38        &mut self,
39        key: impl Into<String>,
40        value: Option<impl Into<String>>,
41    ) -> &mut Self {
42        if let Some(value) = value {
43            self.0.insert(key.into(), value.into().into());
44        }
45        self
46    }
47
48    /// Inserts a string array into the map.
49    pub fn string_array<T: Into<String>>(
50        &mut self,
51        key: impl Into<String>,
52        iter: impl IntoIterator<Item = T>,
53    ) -> &mut Self {
54        let entries = iter.into_iter().map(|s| s.into()).collect::<Vec<_>>();
55        if entries.is_empty() {
56            return self;
57        }
58        self.entry(key, entries)
59    }
60
61    /// Inserts an entry into the map using the value's `impl Into<Value>`.
62    pub fn entry(&mut self, key: impl Into<String>, value: impl Into<Value>) -> &mut Self {
63        self.0.insert(key.into(), value.into());
64        self
65    }
66
67    /// Inserts an entry into the map using the value's `impl Serialize`.
68    pub fn serializable(
69        &mut self,
70        key: impl Into<String>,
71        value: impl Serialize,
72    ) -> serde_json::Result<&mut Self> {
73        let value = serde_json::to_value(value)?;
74        if !value.is_null() {
75            self.0.insert(key.into(), value);
76        }
77        Ok(self)
78    }
79
80    /// Returns the built ValuesMap.
81    pub fn build(self) -> ValuesMap {
82        self.0
83    }
84
85    /// Returns the build ValuesMap and resets the builder to empty.
86    pub fn take(&mut self) -> ValuesMap {
87        std::mem::take(&mut self.0)
88    }
89}