1use crate::error::{Error, Result};
6
7#[derive(Debug)]
9pub enum Forbid {}
10
11impl std::fmt::Display for Forbid {
12 fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
13 unreachable!()
14 }
15}
16
17#[derive(Debug)]
19pub enum Value<OutOfLine = Forbid> {
20 Null,
21 Bool(bool),
22 U8(u8),
23 U16(u16),
24 U32(u32),
25 U64(u64),
26 I8(i8),
27 I16(i16),
28 I32(i32),
29 I64(i64),
30 F32(f32),
31 F64(f64),
32 String(String),
33 Object(Vec<(String, Self)>),
34 Bits(String, Box<Self>),
35 Enum(String, Box<Self>),
36 Union(String, String, Box<Self>),
37 List(Vec<Self>),
38 ServerEnd(fidl::Channel, String),
39 ClientEnd(fidl::Channel, String),
40 Handle(fidl::Handle, fidl::ObjectType),
41 OutOfLine(OutOfLine),
42}
43
44impl Value {
45 pub(crate) fn bits(&self) -> Option<u64> {
48 match self {
49 Value::U8(x) => Some(*x as u64),
50 Value::U16(x) => Some(*x as u64),
51 Value::U32(x) => Some(*x as u64),
52 Value::U64(x) => Some(*x),
53 Value::I8(x) => Some(u8::from_le_bytes(x.to_le_bytes()) as u64),
54 Value::I16(x) => Some(u16::from_le_bytes(x.to_le_bytes()) as u64),
55 Value::I32(x) => Some(u32::from_le_bytes(x.to_le_bytes()) as u64),
56 Value::I64(x) => Some(u64::from_le_bytes(x.to_le_bytes())),
57 _ => None,
58 }
59 }
60
61 pub(crate) fn cast_equals(&self, other: &Value) -> bool {
64 match self {
65 Value::U8(x) => u8::try_from(other).map(|y| *x == y).unwrap_or(false),
66 Value::U16(x) => u16::try_from(other).map(|y| *x == y).unwrap_or(false),
67 Value::U32(x) => u32::try_from(other).map(|y| *x == y).unwrap_or(false),
68 Value::U64(x) => u64::try_from(other).map(|y| *x == y).unwrap_or(false),
69 Value::I8(x) => i8::try_from(other).map(|y| *x == y).unwrap_or(false),
70 Value::I16(x) => i16::try_from(other).map(|y| *x == y).unwrap_or(false),
71 Value::I32(x) => i32::try_from(other).map(|y| *x == y).unwrap_or(false),
72 Value::I64(x) => i64::try_from(other).map(|y| *x == y).unwrap_or(false),
73 Value::F32(x) => f32::try_from(other).map(|y| *x == y).unwrap_or(false),
74 Value::F64(x) => f64::try_from(other).map(|y| *x == y).unwrap_or(false),
75 _ => self == other,
76 }
77 }
78
79 pub fn upcast<T>(self) -> Value<T> {
81 match self {
82 Value::Null => Value::Null,
83 Value::Bool(a) => Value::Bool(a),
84 Value::U8(a) => Value::U8(a),
85 Value::U16(a) => Value::U16(a),
86 Value::U32(a) => Value::U32(a),
87 Value::U64(a) => Value::U64(a),
88 Value::I8(a) => Value::I8(a),
89 Value::I16(a) => Value::I16(a),
90 Value::I32(a) => Value::I32(a),
91 Value::I64(a) => Value::I64(a),
92 Value::F32(a) => Value::F32(a),
93 Value::F64(a) => Value::F64(a),
94 Value::String(a) => Value::String(a),
95 Value::Object(a) => {
96 Value::Object(a.into_iter().map(|(a, b)| (a, b.upcast())).collect())
97 }
98 Value::Bits(a, b) => Value::Bits(a, Box::new(b.upcast())),
99 Value::Enum(a, b) => Value::Enum(a, Box::new(b.upcast())),
100 Value::Union(a, b, c) => Value::Union(a, b, Box::new(c.upcast())),
101 Value::List(a) => Value::List(a.into_iter().map(Value::upcast).collect()),
102 Value::ServerEnd(a, b) => Value::ServerEnd(a, b),
103 Value::ClientEnd(a, b) => Value::ClientEnd(a, b),
104 Value::Handle(a, b) => Value::Handle(a, b),
105 }
106 }
107}
108
109impl PartialEq for Value {
110 fn eq(&self, other: &Self) -> bool {
111 match (self, other) {
112 (Self::Bool(l0), Self::Bool(r0)) => l0 == r0,
113 (Self::U8(l0), Self::U8(r0)) => l0 == r0,
114 (Self::U16(l0), Self::U16(r0)) => l0 == r0,
115 (Self::U32(l0), Self::U32(r0)) => l0 == r0,
116 (Self::U64(l0), Self::U64(r0)) => l0 == r0,
117 (Self::I8(l0), Self::I8(r0)) => l0 == r0,
118 (Self::I16(l0), Self::I16(r0)) => l0 == r0,
119 (Self::I32(l0), Self::I32(r0)) => l0 == r0,
120 (Self::I64(l0), Self::I64(r0)) => l0 == r0,
121 (Self::F32(l0), Self::F32(r0)) => l0 == r0,
122 (Self::F64(l0), Self::F64(r0)) => l0 == r0,
123 (Self::String(l0), Self::String(r0)) => l0 == r0,
124 (Self::Object(l0), Self::Object(r0)) => {
125 let mut values = std::collections::HashMap::new();
126 for (k, v) in l0 {
127 if values.insert(k, v).is_some() {
128 return false;
129 }
130 }
131 for (k, v) in r0 {
132 let Some(other) = values.remove(&k) else {
133 return false;
134 };
135
136 if v != other {
137 return false;
138 }
139 }
140 true
141 }
142 (Self::Bits(l0, l1), Self::Bits(r0, r1)) => l0 == r0 && l1 == r1,
143 (Self::Enum(l0, l1), Self::Enum(r0, r1)) => l0 == r0 && l1 == r1,
144 (Self::Union(l0, l1, l2), Self::Union(r0, r1, r2)) => l0 == r0 && l1 == r1 && l2 == r2,
145 (Self::List(l0), Self::List(r0)) => l0 == r0,
146 (Self::ServerEnd(l0, l1), Self::ServerEnd(r0, r1)) => l0 == r0 && l1 == r1,
147 (Self::ClientEnd(l0, l1), Self::ClientEnd(r0, r1)) => l0 == r0 && l1 == r1,
148 (Self::Handle(l0, l1), Self::Handle(r0, r1)) => l0 == r0 && l1 == r1,
149 _ => core::mem::discriminant(self) == core::mem::discriminant(other),
150 }
151 }
152}
153
154impl From<&str> for Value {
155 fn from(v: &str) -> Value {
156 Value::from(v.to_owned())
157 }
158}
159
160impl From<String> for Value {
161 fn from(v: String) -> Value {
162 Value::String(v)
163 }
164}
165
166impl From<bool> for Value {
167 fn from(v: bool) -> Value {
168 Value::Bool(v)
169 }
170}
171
172impl From<u8> for Value {
173 fn from(v: u8) -> Value {
174 Value::U8(v)
175 }
176}
177
178impl From<u16> for Value {
179 fn from(v: u16) -> Value {
180 Value::U16(v)
181 }
182}
183
184impl From<u32> for Value {
185 fn from(v: u32) -> Value {
186 Value::U32(v)
187 }
188}
189
190impl From<u64> for Value {
191 fn from(v: u64) -> Value {
192 Value::U64(v)
193 }
194}
195
196impl From<i8> for Value {
197 fn from(v: i8) -> Value {
198 Value::I8(v)
199 }
200}
201
202impl From<i16> for Value {
203 fn from(v: i16) -> Value {
204 Value::I16(v)
205 }
206}
207
208impl From<i32> for Value {
209 fn from(v: i32) -> Value {
210 Value::I32(v)
211 }
212}
213
214impl From<i64> for Value {
215 fn from(v: i64) -> Value {
216 Value::I64(v)
217 }
218}
219
220impl From<f32> for Value {
221 fn from(v: f32) -> Value {
222 Value::F32(v)
223 }
224}
225
226impl From<f64> for Value {
227 fn from(v: f64) -> Value {
228 Value::F64(v)
229 }
230}
231
232impl<T> From<Vec<T>> for Value
233where
234 Value: From<T>,
235{
236 fn from(v: Vec<T>) -> Value {
237 Value::List(v.into_iter().map(Value::from).collect())
238 }
239}
240
241impl<T> From<Option<T>> for Value
242where
243 Value: From<T>,
244{
245 fn from(v: Option<T>) -> Value {
246 v.map(Value::from).unwrap_or(Value::Null)
247 }
248}
249
250impl<A> FromIterator<A> for Value
251where
252 Value: From<A>,
253{
254 fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Value {
255 iter.into_iter().collect::<Vec<_>>().into()
256 }
257}
258
259macro_rules! try_from_int {
260 ($int:ident) => {
261 impl TryFrom<&mut Value> for $int {
262 type Error = $crate::error::Error;
263
264 fn try_from(value: &mut Value) -> Result<$int> {
265 Self::try_from(&*value)
266 }
267 }
268
269 impl TryFrom<&Value> for $int {
270 type Error = $crate::error::Error;
271
272 fn try_from(value: &Value) -> Result<$int> {
273 match value {
274 Value::U8(x) => $int::try_from(*x).ok(),
275 Value::U16(x) => $int::try_from(*x).ok(),
276 Value::U32(x) => $int::try_from(*x).ok(),
277 Value::U64(x) => $int::try_from(*x).ok(),
278 Value::I8(x) => $int::try_from(*x).ok(),
279 Value::I16(x) => $int::try_from(*x).ok(),
280 Value::I32(x) => $int::try_from(*x).ok(),
281 Value::I64(x) => $int::try_from(*x).ok(),
282 _ => None,
283 }
284 .ok_or(Error::ValueError(format!("Cannot convert to {}", stringify!($int))))
285 }
286 }
287
288 impl TryFrom<Value> for $int {
289 type Error = $crate::error::Error;
290
291 fn try_from(value: Value) -> Result<$int> {
292 $int::try_from(&value)
293 }
294 }
295 };
296}
297
298try_from_int!(u8);
299try_from_int!(u16);
300try_from_int!(u32);
301try_from_int!(u64);
302try_from_int!(i8);
303try_from_int!(i16);
304try_from_int!(i32);
305try_from_int!(i64);
306
307impl TryFrom<&mut Value> for bool {
308 type Error = crate::error::Error;
309
310 fn try_from(value: &mut Value) -> Result<bool> {
311 bool::try_from(&*value)
312 }
313}
314
315impl TryFrom<&Value> for bool {
316 type Error = crate::error::Error;
317
318 fn try_from(value: &Value) -> Result<bool> {
319 match value {
320 Value::Bool(x) => Ok(*x),
321 Value::U8(x) => Ok(*x != 0),
322 Value::U16(x) => Ok(*x != 0),
323 Value::U32(x) => Ok(*x != 0),
324 Value::U64(x) => Ok(*x != 0),
325 Value::I8(x) => Ok(*x != 0),
326 Value::I16(x) => Ok(*x != 0),
327 Value::I32(x) => Ok(*x != 0),
328 Value::I64(x) => Ok(*x != 0),
329 _ => Err(Error::ValueError(format!("Cannot convert {} to bool", value))),
330 }
331 }
332}
333
334impl TryFrom<Value> for bool {
335 type Error = Error;
336
337 fn try_from(value: Value) -> Result<bool> {
338 bool::try_from(&value)
339 }
340}
341
342impl TryFrom<&mut Value> for f32 {
343 type Error = crate::error::Error;
344
345 fn try_from(value: &mut Value) -> Result<f32> {
346 f32::try_from(&*value)
347 }
348}
349
350impl TryFrom<&Value> for f32 {
351 type Error = Error;
352
353 fn try_from(value: &Value) -> Result<f32> {
354 match value {
355 Value::U8(x) => Ok(*x as f32),
356 Value::U16(x) => Ok(*x as f32),
357 Value::U32(x) => Ok(*x as f32),
358 Value::U64(x) => Ok(*x as f32),
359 Value::I8(x) => Ok(*x as f32),
360 Value::I16(x) => Ok(*x as f32),
361 Value::I32(x) => Ok(*x as f32),
362 Value::I64(x) => Ok(*x as f32),
363 Value::F32(x) => Ok(*x),
364 Value::F64(x) => Ok(*x as f32),
365 _ => Err(Error::ValueError(format!("Cannot convert {} to f32", value))),
366 }
367 }
368}
369
370impl TryFrom<Value> for f32 {
371 type Error = Error;
372
373 fn try_from(value: Value) -> Result<f32> {
374 f32::try_from(&value)
375 }
376}
377
378impl TryFrom<&mut Value> for f64 {
379 type Error = crate::error::Error;
380
381 fn try_from(value: &mut Value) -> Result<f64> {
382 f64::try_from(&*value)
383 }
384}
385
386impl TryFrom<&Value> for f64 {
387 type Error = Error;
388
389 fn try_from(value: &Value) -> Result<f64> {
390 match value {
391 Value::U8(x) => Ok(*x as f64),
392 Value::U16(x) => Ok(*x as f64),
393 Value::U32(x) => Ok(*x as f64),
394 Value::U64(x) => Ok(*x as f64),
395 Value::I8(x) => Ok(*x as f64),
396 Value::I16(x) => Ok(*x as f64),
397 Value::I32(x) => Ok(*x as f64),
398 Value::I64(x) => Ok(*x as f64),
399 Value::F32(x) => Ok(*x as f64),
400 Value::F64(x) => Ok(*x),
401 _ => Err(Error::ValueError(format!("Cannot convert {} to f32", value))),
402 }
403 }
404}
405
406impl TryFrom<Value> for f64 {
407 type Error = Error;
408
409 fn try_from(value: Value) -> Result<f64> {
410 f64::try_from(&value)
411 }
412}
413
414macro_rules! write_list {
415 ($f:ident, $pattern:pat, $members:expr, $element:expr, $open:expr, $close:expr) => {{
416 $open;
417 let mut first = true;
418 for $pattern in $members {
419 if !first {
420 write!($f, ", ")?
421 } else {
422 first = false;
423 write!($f, " ")?;
424 }
425
426 $element;
427 }
428
429 if !first {
430 write!($f, "{}", " ")?;
431 }
432
433 write!($f, "{}", $close)
434 }};
435}
436
437impl<T: std::fmt::Display> std::fmt::Display for Value<T> {
438 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
439 use Value::*;
440 match self {
441 Null => write!(f, "null"),
442 Bool(true) => write!(f, "true"),
443 Bool(false) => write!(f, "false"),
444 U8(x) => write!(f, "{}u8", x),
445 U16(x) => write!(f, "{}u16", x),
446 U32(x) => write!(f, "{}u32", x),
447 U64(x) => write!(f, "{}u64", x),
448 I8(x) => write!(f, "{}i8", x),
449 I16(x) => write!(f, "{}i16", x),
450 I32(x) => write!(f, "{}i32", x),
451 I64(x) => write!(f, "{}i64", x),
452 F32(x) => write!(f, "{}f32", x),
453 F64(x) => write!(f, "{}f64", x),
454 String(x) => write!(f, "\"{}\"", x),
455 Object(members) => write_list!(
456 f,
457 (name, value),
458 members,
459 write!(f, "\"{}\": {}", name, value)?,
460 write!(f, "{}", "{")?,
461 "}"
462 ),
463 Bits(ty, value) => write!(f, "{}({})", ty, value),
464 Enum(ty, value) => write!(f, "{}({})", ty, value),
465 Union(name, field, value) => write!(f, "{}::{}({})", name, field, value),
466 List(values) => {
467 write_list!(f, value, values, write!(f, "{}", value)?, write!(f, "[")?, "]")
468 }
469 ServerEnd(_, ty) => write!(f, "ServerEnd<{ty}>"),
470 ClientEnd(_, ty) => write!(f, "ClientEnd<{ty}>"),
471 Handle(_, ty) => write!(f, "<{:?}>", ty),
472 OutOfLine(t) => write!(f, "{t}"),
473 }
474 }
475}
476
477#[macro_export]
480macro_rules! vobject {
481 ($name:ident $($tokens:tt)*) => {{
482 vobject!((stringify!($name)) $($tokens)*)
483 }};
484 (($name:expr) $($tokens:tt)*) => {{
485 #[allow(unused_mut)]
486 let mut items = Vec::<(String, $crate::value::Value)>::new();
487 vobject!(~private items | ($name) $($tokens)*);
488 $crate::value::Value::Struct(items)
489 }};
490 () => {{ $crate::value::Value::Struct(Vec::new()) }};
491
492 (~private $items:path | $name:ident $($tokens:tt)*) => {
493 vobject!(~private $items | (stringify!($name)) $($tokens)*);
494 };
495 (~private $items:path | ($name:expr) : $value:expr , $($excess:tt)*) => {
496 $items.push(($name.to_string(), $crate::value::Value::from($value)));
497 vobject!(~private $items | $($excess)*);
498 };
499 (~private $items:path | ($name:expr) : $value:expr) => {
500 vobject!(~private $items | ($name) : $value ,);
501 };
502 (~private $items:path |) => {};
503}
504
505#[macro_export]
507macro_rules! vunion {
508 ($name:expr, $variant:expr, $value:expr) => {{
509 $crate::value::Value::Union($name.to_owned(), $variant.to_owned(), Box::new($value.into()))
510 }};
511}