1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
use crate::Value;
use crate::{Array, Dict, Error, Fd, ObjectPath, Signature, Str, Structure};
use std::convert::TryFrom;
macro_rules! value_try_from {
($kind:ident, $to:ty) => {
impl<'a> TryFrom<Value<'a>> for $to {
type Error = Error;
fn try_from(value: Value<'a>) -> Result<Self, Self::Error> {
if let Value::$kind(value) = value {
Ok(value.into())
} else {
Err(Error::IncorrectType)
}
}
}
};
}
macro_rules! value_try_from_ref {
($kind:ident, $to:ty) => {
impl<'a> TryFrom<&'a Value<'a>> for &'a $to {
type Error = Error;
fn try_from(value: &'a Value<'a>) -> Result<Self, Self::Error> {
if let Value::$kind(value) = value {
Ok(value)
} else {
Err(Error::IncorrectType)
}
}
}
};
}
macro_rules! value_try_from_ref_clone {
($kind:ident, $to:ty) => {
impl<'a> TryFrom<&'a Value<'a>> for $to {
type Error = Error;
fn try_from(value: &'a Value) -> Result<Self, Self::Error> {
if let Value::$kind(value) = value {
Ok(value.clone().into())
} else {
Err(Error::IncorrectType)
}
}
}
};
}
macro_rules! value_try_from_all {
($from:ident, $to:ty) => {
value_try_from!($from, $to);
value_try_from_ref!($from, $to);
value_try_from_ref_clone!($from, $to);
};
}
value_try_from_all!(U8, u8);
value_try_from_all!(Bool, bool);
value_try_from_all!(I16, i16);
value_try_from_all!(U16, u16);
value_try_from_all!(I32, i32);
value_try_from_all!(U32, u32);
value_try_from_all!(I64, i64);
value_try_from_all!(U64, u64);
value_try_from_all!(F64, f64);
value_try_from_all!(Fd, Fd);
value_try_from_all!(Str, Str<'a>);
value_try_from_all!(Signature, Signature<'a>);
value_try_from_all!(ObjectPath, ObjectPath<'a>);
value_try_from_all!(Structure, Structure<'a>);
value_try_from_all!(Dict, Dict<'a, 'a>);
value_try_from_all!(Array, Array<'a>);
value_try_from!(Str, String);
value_try_from_ref!(Str, str);
value_try_from_ref_clone!(Str, String);
impl<'a, T> TryFrom<Value<'a>> for Vec<T>
where
T: TryFrom<Value<'a>, Error = Error> + 'a,
{
type Error = Error;
fn try_from(value: Value<'a>) -> Result<Self, Self::Error> {
if let Value::Array(v) = value {
Self::try_from(v)
} else {
Err(Error::IncorrectType)
}
}
}