zvariant/
into_value.rs
1use std::{collections::HashMap, hash::BuildHasher};
2
3#[cfg(feature = "gvariant")]
4use crate::Maybe;
5use crate::{Array, Dict, NoneValue, ObjectPath, Optional, Signature, Str, Structure, Type, Value};
6
7#[cfg(unix)]
8use crate::Fd;
9
10macro_rules! into_value {
14 ($from:ty, $kind:ident) => {
15 impl<'a> From<$from> for Value<'a> {
16 fn from(v: $from) -> Self {
17 Value::$kind(v.into())
18 }
19 }
20 };
21}
22
23macro_rules! into_value_from_ref {
24 ($from:ty, $kind:ident) => {
25 impl<'a> From<&'a $from> for Value<'a> {
26 fn from(v: &'a $from) -> Self {
27 Value::$kind(v.clone().into())
28 }
29 }
30 };
31}
32
33macro_rules! into_value_from_both {
34 ($from:ty, $kind:ident) => {
35 into_value!($from, $kind);
36 into_value_from_ref!($from, $kind);
37 };
38}
39
40into_value_from_both!(u8, U8);
41into_value_from_both!(i8, I16);
42into_value_from_both!(bool, Bool);
43into_value_from_both!(u16, U16);
44into_value_from_both!(i16, I16);
45into_value_from_both!(u32, U32);
46into_value_from_both!(i32, I32);
47into_value_from_both!(u64, U64);
48into_value_from_both!(i64, I64);
49into_value_from_both!(f32, F64);
50into_value_from_both!(f64, F64);
51
52into_value_from_both!(&'a str, Str);
53into_value_from_both!(Str<'a>, Str);
54into_value_from_both!(Signature<'a>, Signature);
55into_value_from_both!(ObjectPath<'a>, ObjectPath);
56
57macro_rules! try_into_value_from_ref {
58 ($from:ty, $kind:ident) => {
59 impl<'a> TryFrom<&'a $from> for Value<'a> {
60 type Error = crate::Error;
61
62 fn try_from(v: &'a $from) -> crate::Result<Self> {
63 v.try_clone().map(Value::$kind)
64 }
65 }
66 };
67}
68
69into_value!(Array<'a>, Array);
70try_into_value_from_ref!(Array<'a>, Array);
71into_value!(Dict<'a, 'a>, Dict);
72try_into_value_from_ref!(Dict<'a, 'a>, Dict);
73#[cfg(feature = "gvariant")]
74into_value!(Maybe<'a>, Maybe);
75#[cfg(feature = "gvariant")]
76try_into_value_from_ref!(Maybe<'a>, Maybe);
77#[cfg(unix)]
78into_value!(Fd<'a>, Fd);
79#[cfg(unix)]
80try_into_value_from_ref!(Fd<'a>, Fd);
81
82impl From<String> for Value<'_> {
83 fn from(v: String) -> Self {
84 Value::Str(crate::Str::from(v))
85 }
86}
87
88impl<'v, 's: 'v, T> From<T> for Value<'v>
89where
90 T: Into<Structure<'s>>,
91{
92 fn from(v: T) -> Value<'v> {
93 Value::Structure(v.into())
94 }
95}
96
97impl<'v, V> From<&'v [V]> for Value<'v>
98where
99 &'v [V]: Into<Array<'v>>,
100{
101 fn from(v: &'v [V]) -> Value<'v> {
102 Value::Array(v.into())
103 }
104}
105
106impl<'v, V> From<Vec<V>> for Value<'v>
107where
108 Vec<V>: Into<Array<'v>>,
109{
110 fn from(v: Vec<V>) -> Value<'v> {
111 Value::Array(v.into())
112 }
113}
114
115impl<'v, V> From<&'v Vec<V>> for Value<'v>
116where
117 &'v Vec<V>: Into<Array<'v>>,
118{
119 fn from(v: &'v Vec<V>) -> Value<'v> {
120 Value::Array(v.into())
121 }
122}
123
124impl<'a, 'k, 'v, K, V, H> From<HashMap<K, V, H>> for Value<'a>
125where
126 'k: 'a,
127 'v: 'a,
128 K: Type + Into<Value<'k>> + std::hash::Hash + std::cmp::Eq,
129 V: Type + Into<Value<'v>>,
130 H: BuildHasher + Default,
131{
132 fn from(value: HashMap<K, V, H>) -> Self {
133 Self::Dict(value.into())
134 }
135}
136
137impl<'v> From<&'v String> for Value<'v> {
138 fn from(v: &'v String) -> Value<'v> {
139 Value::Str(v.into())
140 }
141}
142
143impl<'v, V> From<Optional<V>> for Value<'v>
144where
145 V: Into<Value<'v>> + NoneValue<NoneType = V>,
146{
147 fn from(v: Optional<V>) -> Value<'v> {
148 Option::<V>::from(v)
149 .unwrap_or_else(|| V::null_value())
150 .into()
151 }
152}
153
154#[cfg(all(feature = "gvariant", not(feature = "option-as-array")))]
155impl<'v, V> From<Option<V>> for Value<'v>
156where
157 Option<V>: Into<Maybe<'v>>,
158{
159 fn from(v: Option<V>) -> Value<'v> {
160 Value::Maybe(v.into())
161 }
162}
163
164#[cfg(feature = "option-as-array")]
165impl<'v, V> From<Option<V>> for Value<'v>
166where
167 V: Into<Value<'v>> + Type,
168{
169 fn from(v: Option<V>) -> Value<'v> {
170 let mut array = Array::new(V::signature());
171 if let Some(v) = v {
172 array.append(v.into()).expect("signature mismatch");
174 }
175
176 array.into()
177 }
178}