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