1 | use super::*; |
2 | use crate::Signature; |
3 | use std::any; |
4 | use std::collections::VecDeque; |
5 | |
6 | #[derive (Copy, Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)] |
7 | /// A simple wrapper to specify a D-Bus variant. |
8 | /// |
9 | /// See the argument guide and module level documentation for details and examples. |
10 | pub struct Variant<T>(pub T); |
11 | |
12 | impl Variant<Box<dyn RefArg>> { |
13 | /// Creates a new refarg from an Iter. Mainly for internal use. |
14 | pub fn new_refarg<'a>(i: &mut Iter<'a>) -> Option<Self> { |
15 | i.recurse(ArgType::Variant).and_then(|mut si: Iter<'a>| si.get_refarg()).map(Variant) |
16 | } |
17 | } |
18 | |
19 | impl<T:Default> Default for Variant<T> { |
20 | fn default() -> Self { Variant(T::default()) } |
21 | } |
22 | |
23 | |
24 | impl<T> Arg for Variant<T> { |
25 | const ARG_TYPE: ArgType = ArgType::Variant; |
26 | fn signature() -> Signature<'static> { unsafe { Signature::from_slice_unchecked("v \0" ) } } |
27 | } |
28 | |
29 | impl<T: Arg + Append> Append for Variant<T> { |
30 | fn append_by_ref(&self, i: &mut IterAppend) { |
31 | let z: &T = &self.0; |
32 | i.append_container(ArgType::Variant, sig:Some(T::signature().as_cstr()), |s: &mut IterAppend<'_>| z.append_by_ref(s)); |
33 | } |
34 | } |
35 | |
36 | impl Append for Variant<Box<dyn RefArg>> { |
37 | fn append_by_ref(&self, i: &mut IterAppend) { |
38 | let z: &Box = &self.0; |
39 | i.append_container(ArgType::Variant, sig:Some(z.signature().as_cstr()), |s: &mut IterAppend<'_>| z.append(s)); |
40 | } |
41 | } |
42 | |
43 | impl<'a, T: Get<'a>> Get<'a> for Variant<T> { |
44 | fn get(i: &mut Iter<'a>) -> Option<Variant<T>> { |
45 | i.recurse(ArgType::Variant).and_then(|mut si: Iter<'a>| si.get().map(Variant)) |
46 | } |
47 | } |
48 | |
49 | impl<'a> Get<'a> for Variant<Iter<'a>> { |
50 | fn get(i: &mut Iter<'a>) -> Option<Variant<Iter<'a>>> { |
51 | i.recurse(ArgType::Variant).map(Variant) |
52 | } |
53 | } |
54 | /* |
55 | impl<'a> Get<'a> for Variant<Box<dyn RefArg>> { |
56 | fn get(i: &mut Iter<'a>) -> Option<Variant<Box<dyn RefArg>>> { |
57 | i.recurse(ArgType::Variant).and_then(|mut si| si.get_refarg().map(|v| Variant(v))) |
58 | } |
59 | } |
60 | */ |
61 | impl<T: RefArg> RefArg for Variant<T> { |
62 | fn arg_type(&self) -> ArgType { ArgType::Variant } |
63 | fn signature(&self) -> Signature<'static> { unsafe { Signature::from_slice_unchecked("v \0" ) } } |
64 | fn append(&self, i: &mut IterAppend) { |
65 | let z = &self.0; |
66 | i.append_container(ArgType::Variant, Some(z.signature().as_cstr()), |s| z.append(s)); |
67 | } |
68 | #[inline ] |
69 | fn as_any(&self) -> &dyn any::Any where T: 'static { self } |
70 | #[inline ] |
71 | fn as_any_mut(&mut self) -> &mut dyn any::Any where T: 'static { self } |
72 | #[inline ] |
73 | fn as_i64(&self) -> Option<i64> { self.0.as_i64() } |
74 | #[inline ] |
75 | fn as_u64(&self) -> Option<u64> { self.0.as_u64() } |
76 | #[inline ] |
77 | fn as_f64(&self) -> Option<f64> { self.0.as_f64() } |
78 | #[inline ] |
79 | fn as_str(&self) -> Option<&str> { self.0.as_str() } |
80 | #[inline ] |
81 | fn as_iter<'a>(&'a self) -> Option<Box<dyn Iterator<Item=&'a dyn RefArg> + 'a>> { |
82 | use std::iter; |
83 | let z: &dyn RefArg = &self.0; |
84 | Some(Box::new(iter::once(z))) |
85 | } |
86 | #[inline ] |
87 | fn box_clone(&self) -> Box<dyn RefArg + 'static> { Box::new(Variant(self.0.box_clone())) } |
88 | #[inline ] |
89 | fn as_static_inner(&self, index: usize) -> Option<&(dyn RefArg + 'static)> where Self: 'static { |
90 | if index == 0 { Some(&self.0) } else { None } |
91 | } |
92 | } |
93 | |
94 | macro_rules! struct_impl { |
95 | ( $($n: ident $t: ident,)+ ) => { |
96 | |
97 | /// Tuples are represented as D-Bus structs. |
98 | impl<$($t: Arg),*> Arg for ($($t,)*) { |
99 | const ARG_TYPE: ArgType = ArgType::Struct; |
100 | fn signature() -> Signature<'static> { |
101 | let mut s = String::from("(" ); |
102 | $( s.push_str(&$t::signature()); )* |
103 | s.push_str(")" ); |
104 | Signature::from(s) |
105 | } |
106 | } |
107 | |
108 | impl<$($t: Append),*> Append for ($($t,)*) { |
109 | fn append_by_ref(&self, i: &mut IterAppend) { |
110 | let ( $($n,)*) = self; |
111 | i.append_container(ArgType::Struct, None, |s| { $( $n.append_by_ref(s); )* }); |
112 | } |
113 | } |
114 | |
115 | impl<'a, $($t: Get<'a>),*> Get<'a> for ($($t,)*) { |
116 | fn get(i: &mut Iter<'a>) -> Option<Self> { |
117 | let si = i.recurse(ArgType::Struct); |
118 | if si.is_none() { return None; } |
119 | let mut si = si.unwrap(); |
120 | let mut _valid_item = true; |
121 | $( |
122 | if !_valid_item { return None; } |
123 | let $n: Option<$t> = si.get(); |
124 | if $n.is_none() { return None; } |
125 | _valid_item = si.next(); |
126 | )* |
127 | Some(($( $n.unwrap(), )* )) |
128 | } |
129 | } |
130 | |
131 | impl<$($t: RefArg),*> RefArg for ($($t,)*) { |
132 | fn arg_type(&self) -> ArgType { ArgType::Struct } |
133 | fn signature(&self) -> Signature<'static> { |
134 | let &( $(ref $n,)*) = self; |
135 | let mut s = String::from("(" ); |
136 | $( s.push_str(&$n.signature()); )* |
137 | s.push_str(")" ); |
138 | Signature::from(s) |
139 | } |
140 | fn append(&self, i: &mut IterAppend) { |
141 | let &( $(ref $n,)*) = self; |
142 | i.append_container(ArgType::Struct, None, |s| { $( $n.append(s); )* }); |
143 | } |
144 | fn as_any(&self) -> &dyn any::Any where Self: 'static { self } |
145 | fn as_any_mut(&mut self) -> &mut dyn any::Any where Self: 'static { self } |
146 | fn as_iter<'a>(&'a self) -> Option<Box<dyn Iterator<Item=&'a dyn RefArg> + 'a>> { |
147 | let &( $(ref $n,)*) = self; |
148 | let v = vec!( |
149 | $( $n as &dyn RefArg, )* |
150 | ); |
151 | Some(Box::new(v.into_iter())) |
152 | } |
153 | fn as_static_inner(&self, index: usize) -> Option<&(dyn RefArg + 'static)> where Self: 'static { |
154 | let &( $(ref $n,)*) = self; |
155 | let arr = [ $($n as &dyn RefArg,)*]; |
156 | arr.get(index).map(|x| *x) |
157 | } |
158 | #[inline] |
159 | fn box_clone(&self) -> Box<dyn RefArg + 'static> { |
160 | let &( $(ref $n,)*) = self; |
161 | let mut z = VecDeque::new(); |
162 | $( z.push_back($n.box_clone()); )* |
163 | Box::new(z) |
164 | } |
165 | } |
166 | |
167 | |
168 | }} // macro_rules end |
169 | |
170 | struct_impl!(a A,); |
171 | struct_impl!(a A, b B,); |
172 | struct_impl!(a A, b B, c C,); |
173 | struct_impl!(a A, b B, c C, d D,); |
174 | struct_impl!(a A, b B, c C, d D, e E,); |
175 | struct_impl!(a A, b B, c C, d D, e E, f F,); |
176 | struct_impl!(a A, b B, c C, d D, e E, f F, g G,); |
177 | struct_impl!(a A, b B, c C, d D, e E, f F, g G, h H,); |
178 | struct_impl!(a A, b B, c C, d D, e E, f F, g G, h H, i I,); |
179 | struct_impl!(a A, b B, c C, d D, e E, f F, g G, h H, i I, j J,); |
180 | struct_impl!(a A, b B, c C, d D, e E, f F, g G, h H, i I, j J, k K,); |
181 | struct_impl!(a A, b B, c C, d D, e E, f F, g G, h H, i I, j J, k K, l L,); |
182 | |
183 | impl RefArg for VecDeque<Box<dyn RefArg>> { |
184 | fn arg_type(&self) -> ArgType { ArgType::Struct } |
185 | fn signature(&self) -> Signature<'static> { |
186 | let mut s = String::from("(" ); |
187 | for z in self { |
188 | s.push_str(&z.signature()); |
189 | } |
190 | s.push_str(")" ); |
191 | Signature::from(s) |
192 | } |
193 | fn append(&self, i: &mut IterAppend) { |
194 | i.append_container(ArgType::Struct, None, |s| { |
195 | for z in self { z.append(s); } |
196 | }); |
197 | } |
198 | #[inline ] |
199 | fn as_any(&self) -> &dyn any::Any where Self: 'static { self } |
200 | #[inline ] |
201 | fn as_any_mut(&mut self) -> &mut dyn any::Any where Self: 'static { self } |
202 | fn as_iter<'a>(&'a self) -> Option<Box<dyn Iterator<Item=&'a dyn RefArg> + 'a>> { |
203 | Some(Box::new(self.iter().map(|b| &**b))) |
204 | } |
205 | #[inline ] |
206 | fn as_static_inner(&self, index: usize) -> Option<&(dyn RefArg + 'static)> where Self: 'static { |
207 | self.get(index).map(|x| x as &dyn RefArg) |
208 | } |
209 | #[inline ] |
210 | fn box_clone(&self) -> Box<dyn RefArg + 'static> { |
211 | let t: VecDeque<Box<dyn RefArg + 'static>> = self.iter().map(|x| x.box_clone()).collect(); |
212 | Box::new(t) |
213 | } |
214 | } |
215 | |