oxiproto_reflect/native/
value.rs1use std::collections::HashMap;
9
10use super::dynamic::DynamicMessage;
11
12#[derive(Clone, Debug, PartialEq)]
19pub enum Value {
20 F64(f64),
22 F32(f32),
24 I32(i32),
26 I64(i64),
28 U32(u32),
30 U64(u64),
32 Bool(bool),
34 String(String),
36 Bytes(Vec<u8>),
38 EnumNumber(i32),
40 Message(Box<DynamicMessage>),
42 List(Vec<Value>),
44 Map(HashMap<MapKey, Value>),
46}
47
48#[derive(Clone, Debug, PartialEq, Eq, Hash)]
52pub enum MapKey {
53 String(String),
55 I32(i32),
57 I64(i64),
59 U32(u32),
61 U64(u64),
63 Bool(bool),
65}
66
67impl Value {
68 pub fn is_default(&self) -> bool {
74 match self {
75 Value::F64(v) => *v == 0.0,
76 Value::F32(v) => *v == 0.0,
77 Value::I32(v) => *v == 0,
78 Value::I64(v) => *v == 0,
79 Value::U32(v) => *v == 0,
80 Value::U64(v) => *v == 0,
81 Value::Bool(v) => !*v,
82 Value::String(s) => s.is_empty(),
83 Value::Bytes(b) => b.is_empty(),
84 Value::EnumNumber(n) => *n == 0,
85 Value::Message(_) => false,
86 Value::List(l) => l.is_empty(),
87 Value::Map(m) => m.is_empty(),
88 }
89 }
90
91 pub fn as_f64(&self) -> Option<f64> {
93 match self {
94 Value::F64(v) => Some(*v),
95 _ => None,
96 }
97 }
98
99 pub fn as_f32(&self) -> Option<f32> {
101 match self {
102 Value::F32(v) => Some(*v),
103 _ => None,
104 }
105 }
106
107 pub fn as_i32(&self) -> Option<i32> {
109 match self {
110 Value::I32(v) => Some(*v),
111 _ => None,
112 }
113 }
114
115 pub fn as_i64(&self) -> Option<i64> {
117 match self {
118 Value::I64(v) => Some(*v),
119 _ => None,
120 }
121 }
122
123 pub fn as_u32(&self) -> Option<u32> {
125 match self {
126 Value::U32(v) => Some(*v),
127 _ => None,
128 }
129 }
130
131 pub fn as_u64(&self) -> Option<u64> {
133 match self {
134 Value::U64(v) => Some(*v),
135 _ => None,
136 }
137 }
138
139 pub fn as_bool(&self) -> Option<bool> {
141 match self {
142 Value::Bool(v) => Some(*v),
143 _ => None,
144 }
145 }
146
147 pub fn as_str(&self) -> Option<&str> {
149 match self {
150 Value::String(s) => Some(s.as_str()),
151 _ => None,
152 }
153 }
154
155 pub fn as_bytes(&self) -> Option<&[u8]> {
157 match self {
158 Value::Bytes(b) => Some(b.as_slice()),
159 _ => None,
160 }
161 }
162
163 pub fn as_enum_number(&self) -> Option<i32> {
165 match self {
166 Value::EnumNumber(n) => Some(*n),
167 _ => None,
168 }
169 }
170
171 pub fn as_message(&self) -> Option<&DynamicMessage> {
173 match self {
174 Value::Message(m) => Some(m.as_ref()),
175 _ => None,
176 }
177 }
178
179 pub fn as_list(&self) -> Option<&[Value]> {
181 match self {
182 Value::List(l) => Some(l.as_slice()),
183 _ => None,
184 }
185 }
186
187 pub fn as_map(&self) -> Option<&HashMap<MapKey, Value>> {
189 match self {
190 Value::Map(m) => Some(m),
191 _ => None,
192 }
193 }
194}
195
196impl MapKey {
197 pub fn to_value(&self) -> Value {
199 match self {
200 MapKey::String(s) => Value::String(s.clone()),
201 MapKey::I32(v) => Value::I32(*v),
202 MapKey::I64(v) => Value::I64(*v),
203 MapKey::U32(v) => Value::U32(*v),
204 MapKey::U64(v) => Value::U64(*v),
205 MapKey::Bool(v) => Value::Bool(*v),
206 }
207 }
208}
209
210#[cfg(test)]
211mod tests {
212 use super::*;
213
214 #[test]
215 fn is_default_scalars() {
216 assert!(Value::I32(0).is_default());
217 assert!(!Value::I32(1).is_default());
218 assert!(Value::Bool(false).is_default());
219 assert!(!Value::Bool(true).is_default());
220 assert!(Value::String(String::new()).is_default());
221 assert!(!Value::String("x".to_owned()).is_default());
222 assert!(Value::Bytes(Vec::new()).is_default());
223 assert!(Value::F64(0.0).is_default());
224 assert!(Value::EnumNumber(0).is_default());
225 assert!(Value::List(Vec::new()).is_default());
226 }
227
228 #[test]
229 fn accessors() {
230 assert_eq!(Value::I32(7).as_i32(), Some(7));
231 assert_eq!(Value::I32(7).as_i64(), None);
232 assert_eq!(Value::String("hi".to_owned()).as_str(), Some("hi"));
233 assert_eq!(Value::Bytes(vec![1, 2]).as_bytes(), Some(&[1u8, 2][..]));
234 assert_eq!(Value::Bool(true).as_bool(), Some(true));
235 assert_eq!(Value::EnumNumber(3).as_enum_number(), Some(3));
236 }
237
238 #[test]
239 fn map_key_to_value() {
240 assert_eq!(
241 MapKey::String("k".to_owned()).to_value(),
242 Value::String("k".to_owned())
243 );
244 assert_eq!(MapKey::I64(5).to_value(), Value::I64(5));
245 assert_eq!(MapKey::Bool(true).to_value(), Value::Bool(true));
246 }
247}