vantage_table/
cbor_ext.rs1use ciborium::Value as CborValue;
11
12pub trait CborValueExt {
13 fn as_str(&self) -> Option<&str>;
15
16 fn as_i64(&self) -> Option<i64>;
19
20 fn as_u64(&self) -> Option<u64>;
23
24 fn as_f64(&self) -> Option<f64>;
26
27 fn get(&self, key: &str) -> Option<&CborValue>;
30
31 fn get_mut(&mut self, key: &str) -> Option<&mut CborValue>;
33}
34
35impl CborValueExt for CborValue {
36 fn as_str(&self) -> Option<&str> {
37 self.as_text()
38 }
39
40 fn as_i64(&self) -> Option<i64> {
41 self.as_integer().and_then(|i| i64::try_from(i).ok())
42 }
43
44 fn as_u64(&self) -> Option<u64> {
45 self.as_integer().and_then(|i| u64::try_from(i).ok())
46 }
47
48 fn as_f64(&self) -> Option<f64> {
49 self.as_float()
50 }
51
52 fn get(&self, key: &str) -> Option<&CborValue> {
53 self.as_map()?
54 .iter()
55 .find(|(k, _)| k.as_text() == Some(key))
56 .map(|(_, v)| v)
57 }
58
59 fn get_mut(&mut self, key: &str) -> Option<&mut CborValue> {
60 self.as_map_mut()?
61 .iter_mut()
62 .find(|(k, _)| k.as_text() == Some(key))
63 .map(|(_, v)| v)
64 }
65}
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70
71 fn map(pairs: Vec<(&str, CborValue)>) -> CborValue {
72 CborValue::Map(
73 pairs
74 .into_iter()
75 .map(|(k, v)| (CborValue::Text(k.to_string()), v))
76 .collect(),
77 )
78 }
79
80 #[test]
81 fn as_str_and_int_accessors() {
82 let v = CborValue::Text("hello".into());
83 assert_eq!(v.as_str(), Some("hello"));
84 assert_eq!(v.as_i64(), None);
85
86 let n = CborValue::Integer(42i64.into());
87 assert_eq!(n.as_i64(), Some(42));
88 assert_eq!(n.as_u64(), Some(42));
89 assert_eq!(n.as_str(), None);
90 }
91
92 #[test]
93 fn map_lookup_by_str_key() {
94 let mut record = map(vec![
95 ("name", CborValue::Text("alice".into())),
96 ("age", CborValue::Integer(30i64.into())),
97 ]);
98 assert_eq!(record.get("name").and_then(|v| v.as_str()), Some("alice"));
99 assert_eq!(record.get("age").and_then(|v| v.as_i64()), Some(30));
100 assert!(record.get("missing").is_none());
101
102 if let Some(age) = record.get_mut("age") {
104 *age = CborValue::Integer(31i64.into());
105 }
106 assert_eq!(record.get("age").and_then(|v| v.as_i64()), Some(31));
107 }
108}