Skip to main content

vantage_table/
cbor_ext.rs

1//! `serde_json::Value`-style accessors for `ciborium::Value`: the short names
2//! (`as_str`, `as_i64`) and string-keyed map lookup that ciborium lacks.
3
4use ciborium::Value as CborValue;
5
6/// Short accessors and string-keyed map lookup for `ciborium::Value`.
7pub trait CborValueExt {
8    /// Borrow the inner string if this is a `Text` value.
9    fn as_str(&self) -> Option<&str>;
10
11    /// Try to extract an `i64`. Returns `None` if the value is not an
12    /// integer or doesn't fit.
13    fn as_i64(&self) -> Option<i64>;
14
15    /// Try to extract a `u64`. Returns `None` if the value is not an
16    /// integer or doesn't fit.
17    fn as_u64(&self) -> Option<u64>;
18
19    /// Borrow the inner `f64` if this is a `Float` value.
20    fn as_f64(&self) -> Option<f64>;
21
22    /// Look up a value in a `Map` by string key. Returns `None` if the
23    /// value isn't a map or the key isn't present.
24    fn get(&self, key: &str) -> Option<&CborValue>;
25
26    /// Same as [`get`](Self::get), but returns a mutable reference.
27    fn get_mut(&mut self, key: &str) -> Option<&mut CborValue>;
28}
29
30impl CborValueExt for CborValue {
31    fn as_str(&self) -> Option<&str> {
32        self.as_text()
33    }
34
35    fn as_i64(&self) -> Option<i64> {
36        self.as_integer().and_then(|i| i64::try_from(i).ok())
37    }
38
39    fn as_u64(&self) -> Option<u64> {
40        self.as_integer().and_then(|i| u64::try_from(i).ok())
41    }
42
43    fn as_f64(&self) -> Option<f64> {
44        self.as_float()
45    }
46
47    fn get(&self, key: &str) -> Option<&CborValue> {
48        self.as_map()?
49            .iter()
50            .find(|(k, _)| k.as_text() == Some(key))
51            .map(|(_, v)| v)
52    }
53
54    fn get_mut(&mut self, key: &str) -> Option<&mut CborValue> {
55        self.as_map_mut()?
56            .iter_mut()
57            .find(|(k, _)| k.as_text() == Some(key))
58            .map(|(_, v)| v)
59    }
60}