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