ex3_ic_agent/agent/
status.rs1use std::{collections::BTreeMap, fmt::Debug};
4
5#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Clone, Hash)]
9pub enum Value {
10 Null,
12 String(String),
14 Integer(i64),
16 Bool(bool),
18 Bytes(Vec<u8>),
20 Vec(Vec<Value>),
22 Map(BTreeMap<String, Box<Value>>),
24}
25
26impl std::fmt::Display for Value {
27 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
28 match self {
29 Value::Null => f.write_str("null"),
30 Value::String(s) => f.write_fmt(format_args!(r#""{}""#, s.escape_debug())),
31 Value::Integer(i) => f.write_str(&i.to_string()),
32 Value::Bool(true) => f.write_str("true"),
33 Value::Bool(false) => f.write_str("false"),
34 Value::Bytes(b) => f.debug_list().entries(b).finish(),
35 Value::Vec(v) => f.debug_list().entries(v).finish(),
36 Value::Map(m) => f.debug_map().entries(m).finish(),
37 }
38 }
39}
40
41#[derive(Debug, Ord, PartialOrd, PartialEq, Eq)]
44pub struct Status {
45 pub ic_api_version: String,
50
51 pub impl_source: Option<String>,
54
55 pub impl_version: Option<String>,
59
60 pub impl_revision: Option<String>,
62
63 pub replica_health_status: Option<String>,
65
66 pub root_key: Option<Vec<u8>>,
68
69 pub values: BTreeMap<String, Box<Value>>,
71}
72
73impl std::fmt::Display for Status {
74 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
75 f.write_str("{\n")?;
76 for (key, value) in &self.values {
77 f.write_fmt(format_args!(r#" "{}": "#, key.escape_debug()))?;
78 std::fmt::Display::fmt(&value, f)?;
79 }
80 f.write_str("\n}")
81 }
82}
83
84fn cbor_value_to_value(value: &serde_cbor::Value) -> Result<Value, ()> {
85 match value {
86 serde_cbor::Value::Null => Ok(Value::Null),
87 serde_cbor::Value::Bool(b) => Ok(Value::Bool(*b)),
88 serde_cbor::Value::Integer(i) => Ok(Value::Integer(*i as i64)),
89 serde_cbor::Value::Bytes(b) => Ok(Value::Bytes(b.to_owned())),
90 serde_cbor::Value::Text(s) => Ok(Value::String(s.to_owned())),
91 serde_cbor::Value::Array(a) => Ok(Value::Vec(
92 a.iter()
93 .map(cbor_value_to_value)
94 .collect::<Result<Vec<Value>, ()>>()
95 .map_err(|_| ())?,
96 )),
97 serde_cbor::Value::Map(m) => {
98 let mut map = BTreeMap::new();
99 for (key, value) in m.iter() {
100 let k = match key {
101 serde_cbor::Value::Text(t) => t.to_owned(),
102 serde_cbor::Value::Integer(i) => i.to_string(),
103 _ => return Err(()),
104 };
105 let v = Box::new(cbor_value_to_value(value)?);
106
107 map.insert(k, v);
108 }
109 Ok(Value::Map(map))
110 }
111 serde_cbor::Value::Tag(_, v) => cbor_value_to_value(v.as_ref()),
112 _ => Err(()),
113 }
114}
115
116impl std::convert::TryFrom<&serde_cbor::Value> for Status {
117 type Error = ();
118
119 fn try_from(value: &serde_cbor::Value) -> Result<Self, ()> {
120 let v = cbor_value_to_value(value)?;
121
122 match v {
123 Value::Map(map) => {
124 let ic_api_version = map.get("ic_api_version").ok_or(()).and_then(|v| {
126 if let Value::String(s) = v.as_ref() {
127 Ok(s.to_owned())
128 } else {
129 Err(())
130 }
131 })?;
132 let impl_source = map.get("impl_source").and_then(|v| {
133 if let Value::String(s) = v.as_ref() {
134 Some(s.to_owned())
135 } else {
136 None
137 }
138 });
139 let impl_version: Option<String> = map.get("impl_version").and_then(|v| {
140 if let Value::String(s) = v.as_ref() {
141 Some(s.to_owned())
142 } else {
143 None
144 }
145 });
146 let impl_revision: Option<String> = map.get("impl_revision").and_then(|v| {
147 if let Value::String(s) = v.as_ref() {
148 Some(s.to_owned())
149 } else {
150 None
151 }
152 });
153 let replica_health_status: Option<String> =
154 map.get("replica_health_status").and_then(|v| {
155 if let Value::String(s) = v.as_ref() {
156 Some(s.to_owned())
157 } else {
158 None
159 }
160 });
161 let root_key: Option<Vec<u8>> = map.get("root_key").and_then(|v| {
162 if let Value::Bytes(bytes) = v.as_ref() {
163 Some(bytes.to_owned())
164 } else {
165 None
166 }
167 });
168
169 Ok(Status {
170 ic_api_version,
171 impl_source,
172 impl_version,
173 impl_revision,
174 replica_health_status,
175 root_key,
176 values: map,
177 })
178 }
179 _ => Err(()),
180 }
181 }
182}