1 use super::*;
2 use {message, Signature};
3 use std::any;
4 
5 #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
6 /// A simple wrapper to specify a D-Bus variant.
7 ///
8 /// See the argument guide and module level documentation for details and examples.
9 pub struct Variant<T>(pub T);
10 
11 impl Variant<Box<RefArg>> {
12     /// Creates a new refarg from an Iter. Mainly for internal use.
new_refarg<'a>(i: &mut Iter<'a>) -> Option<Self>13     pub fn new_refarg<'a>(i: &mut Iter<'a>) -> Option<Self> {
14         i.recurse(ArgType::Variant).and_then(|mut si| si.get_refarg()).map(|v| Variant(v))
15     }
16 }
17 
18 impl Default for Variant<Box<RefArg>> {
19     // This is a bit silly, because there is no such thing as a default argument.
20     // Unfortunately due to a design mistake while making the SignalArgs trait, we'll
21     // have to work around that by adding a default implementation here.
22     // https://github.com/diwic/dbus-rs/issues/136
default() -> Self23     fn default() -> Self { Variant(Box::new(0u8) as Box<RefArg>) }
24 }
25 
26 impl<T:Default> Default for Variant<T> {
default() -> Self27     fn default() -> Self { Variant(T::default()) }
28 }
29 
30 
31 impl<T> Arg for Variant<T> {
32     const ARG_TYPE: ArgType = ArgType::Variant;
signature() -> Signature<'static>33     fn signature() -> Signature<'static> { unsafe { Signature::from_slice_unchecked(b"v\0") } }
34 }
35 
36 impl<T: Arg + Append> Append for Variant<T> {
append(self, i: &mut IterAppend)37     fn append(self, i: &mut IterAppend) {
38         let z = self.0;
39         i.append_container(ArgType::Variant, Some(T::signature().as_cstr()), |s| z.append(s));
40     }
41 }
42 
43 impl Append for Variant<message::MessageItem> {
append(self, i: &mut IterAppend)44     fn append(self, i: &mut IterAppend) {
45         let z = self.0;
46         let asig = z.signature();
47         let sig = asig.as_cstr();
48         i.append_container(ArgType::Variant, Some(&sig), |s| z.append(s));
49     }
50 }
51 
52 impl Append for Variant<Box<RefArg>> {
append(self, i: &mut IterAppend)53     fn append(self, i: &mut IterAppend) {
54         let z = self.0;
55         i.append_container(ArgType::Variant, Some(z.signature().as_cstr()), |s| z.append(s));
56     }
57 }
58 
59 impl<'a, T: Get<'a>> Get<'a> for Variant<T> {
get(i: &mut Iter<'a>) -> Option<Variant<T>>60     fn get(i: &mut Iter<'a>) -> Option<Variant<T>> {
61         i.recurse(ArgType::Variant).and_then(|mut si| si.get().map(|v| Variant(v)))
62     }
63 }
64 
65 impl<'a> Get<'a> for Variant<Iter<'a>> {
get(i: &mut Iter<'a>) -> Option<Variant<Iter<'a>>>66     fn get(i: &mut Iter<'a>) -> Option<Variant<Iter<'a>>> {
67         i.recurse(ArgType::Variant).map(|v| Variant(v))
68     }
69 }
70 /*
71 impl<'a> Get<'a> for Variant<Box<RefArg>> {
72     fn get(i: &mut Iter<'a>) -> Option<Variant<Box<RefArg>>> {
73         i.recurse(ArgType::Variant).and_then(|mut si| si.get_refarg().map(|v| Variant(v)))
74     }
75 }
76 */
77 impl<T: RefArg> RefArg for Variant<T> {
arg_type(&self) -> ArgType78     fn arg_type(&self) -> ArgType { ArgType::Variant }
signature(&self) -> Signature<'static>79     fn signature(&self) -> Signature<'static> { unsafe { Signature::from_slice_unchecked(b"v\0") } }
append(&self, i: &mut IterAppend)80     fn append(&self, i: &mut IterAppend) {
81         let z = &self.0;
82         i.append_container(ArgType::Variant, Some(z.signature().as_cstr()), |s| z.append(s));
83     }
84     #[inline]
as_any(&self) -> &any::Any where T: 'static85     fn as_any(&self) -> &any::Any where T: 'static { self }
86     #[inline]
as_any_mut(&mut self) -> &mut any::Any where T: 'static87     fn as_any_mut(&mut self) -> &mut any::Any where T: 'static { self }
88     #[inline]
as_i64(&self) -> Option<i64>89     fn as_i64(&self) -> Option<i64> { self.0.as_i64() }
90     #[inline]
as_u64(&self) -> Option<u64>91     fn as_u64(&self) -> Option<u64> { self.0.as_u64() }
92     #[inline]
as_f64(&self) -> Option<f64>93     fn as_f64(&self) -> Option<f64> { self.0.as_f64() }
94     #[inline]
as_str(&self) -> Option<&str>95     fn as_str(&self) -> Option<&str> { self.0.as_str() }
96     #[inline]
as_iter<'a>(&'a self) -> Option<Box<Iterator<Item=&'a RefArg> + 'a>>97     fn as_iter<'a>(&'a self) -> Option<Box<Iterator<Item=&'a RefArg> + 'a>> {
98         use std::iter;
99         let z: &RefArg = &self.0;
100         Some(Box::new(iter::once(z)))
101     }
102     #[inline]
box_clone(&self) -> Box<RefArg + 'static>103     fn box_clone(&self) -> Box<RefArg + 'static> { Box::new(Variant(self.0.box_clone())) }
104 }
105 
106 macro_rules! struct_impl {
107     ( $($n: ident $t: ident,)+ ) => {
108 
109 /// Tuples are represented as D-Bus structs.
110 impl<$($t: Arg),*> Arg for ($($t,)*) {
111     const ARG_TYPE: ArgType = ArgType::Struct;
112     fn signature() -> Signature<'static> {
113         let mut s = String::from("(");
114         $( s.push_str(&$t::signature()); )*
115         s.push_str(")");
116         Signature::from(s)
117     }
118 }
119 
120 impl<$($t: Append),*> Append for ($($t,)*) {
121     fn append(self, i: &mut IterAppend) {
122         let ( $($n,)*) = self;
123         i.append_container(ArgType::Struct, None, |s| { $( $n.append(s); )* });
124     }
125 }
126 
127 impl<'a, $($t: Get<'a>),*> Get<'a> for ($($t,)*) {
128     fn get(i: &mut Iter<'a>) -> Option<Self> {
129         let si = i.recurse(ArgType::Struct);
130         if si.is_none() { return None; }
131         let mut si = si.unwrap();
132         let mut _valid_item = true;
133         $(
134             if !_valid_item { return None; }
135             let $n: Option<$t> = si.get();
136             if $n.is_none() { return None; }
137             _valid_item = si.next();
138         )*
139         Some(($( $n.unwrap(), )* ))
140     }
141 }
142 
143 impl<$($t: RefArg),*> RefArg for ($($t,)*) {
144     fn arg_type(&self) -> ArgType { ArgType::Struct }
145     fn signature(&self) -> Signature<'static> {
146         let &( $(ref $n,)*) = self;
147         let mut s = String::from("(");
148         $( s.push_str(&$n.signature()); )*
149         s.push_str(")");
150         Signature::from(s)
151     }
152     fn append(&self, i: &mut IterAppend) {
153         let &( $(ref $n,)*) = self;
154         i.append_container(ArgType::Struct, None, |s| { $( $n.append(s); )* });
155     }
156     fn as_any(&self) -> &any::Any where Self: 'static { self }
157     fn as_any_mut(&mut self) -> &mut any::Any where Self: 'static { self }
158     fn as_iter<'a>(&'a self) -> Option<Box<Iterator<Item=&'a RefArg> + 'a>> {
159         let &( $(ref $n,)*) = self;
160         let v = vec!(
161         $( $n as &RefArg, )*
162         );
163         Some(Box::new(v.into_iter()))
164     }
165     #[inline]
166     fn box_clone(&self) -> Box<RefArg + 'static> {
167         let &( $(ref $n,)*) = self;
168         let mut z = vec!();
169         $( z.push($n.box_clone()); )*
170         Box::new(z)
171     }
172 }
173 
174 
175 }} // macro_rules end
176 
177 struct_impl!(a A,);
178 struct_impl!(a A, b B,);
179 struct_impl!(a A, b B, c C,);
180 struct_impl!(a A, b B, c C, d D,);
181 struct_impl!(a A, b B, c C, d D, e E,);
182 struct_impl!(a A, b B, c C, d D, e E, f F,);
183 struct_impl!(a A, b B, c C, d D, e E, f F, g G,);
184 struct_impl!(a A, b B, c C, d D, e E, f F, g G, h H,);
185 struct_impl!(a A, b B, c C, d D, e E, f F, g G, h H, i I,);
186 struct_impl!(a A, b B, c C, d D, e E, f F, g G, h H, i I, j J,);
187 struct_impl!(a A, b B, c C, d D, e E, f F, g G, h H, i I, j J, k K,);
188 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,);
189 
190 impl RefArg for Vec<Box<RefArg>> {
arg_type(&self) -> ArgType191     fn arg_type(&self) -> ArgType { ArgType::Struct }
signature(&self) -> Signature<'static>192     fn signature(&self) -> Signature<'static> {
193         let mut s = String::from("(");
194         for z in self {
195             s.push_str(&z.signature());
196         }
197         s.push_str(")");
198         Signature::from(s)
199     }
append(&self, i: &mut IterAppend)200     fn append(&self, i: &mut IterAppend) {
201         i.append_container(ArgType::Struct, None, |s| {
202             for z in self { z.append(s); }
203         });
204     }
205     #[inline]
as_any(&self) -> &any::Any where Self: 'static206     fn as_any(&self) -> &any::Any where Self: 'static { self }
207     #[inline]
as_any_mut(&mut self) -> &mut any::Any where Self: 'static208     fn as_any_mut(&mut self) -> &mut any::Any where Self: 'static { self }
as_iter<'a>(&'a self) -> Option<Box<Iterator<Item=&'a RefArg> + 'a>>209     fn as_iter<'a>(&'a self) -> Option<Box<Iterator<Item=&'a RefArg> + 'a>> {
210         Some(Box::new(self.iter().map(|b| &**b)))
211     }
212     #[inline]
box_clone(&self) -> Box<RefArg + 'static>213     fn box_clone(&self) -> Box<RefArg + 'static> {
214         let t: Vec<Box<RefArg + 'static>> = self.iter().map(|x| x.box_clone()).collect();
215         Box::new(t)
216     }
217 }
218 
219 impl Append for message::MessageItem {
append(self, i: &mut IterAppend)220     fn append(self, i: &mut IterAppend) {
221         message::append_messageitem(&mut i.0, &self)
222     }
223 }
224 
225 impl<'a> Get<'a> for message::MessageItem {
get(i: &mut Iter<'a>) -> Option<Self>226     fn get(i: &mut Iter<'a>) -> Option<Self> {
227         message::get_messageitem(&mut i.0)
228     }
229 }
230 
231 impl RefArg for message::MessageItem {
arg_type(&self) -> ArgType232     fn arg_type(&self) -> ArgType { ArgType::from_i32(self.array_type()).unwrap() }
signature(&self) -> Signature<'static>233     fn signature(&self) -> Signature<'static> { message::MessageItem::signature(&self) }
append(&self, i: &mut IterAppend)234     fn append(&self, i: &mut IterAppend) { message::append_messageitem(&mut i.0, self) }
235     #[inline]
as_any(&self) -> &any::Any where Self: 'static236     fn as_any(&self) -> &any::Any where Self: 'static { self }
237     #[inline]
as_any_mut(&mut self) -> &mut any::Any where Self: 'static238     fn as_any_mut(&mut self) -> &mut any::Any where Self: 'static { self }
239     #[inline]
box_clone(&self) -> Box<RefArg + 'static>240     fn box_clone(&self) -> Box<RefArg + 'static> { Box::new(self.clone()) }
241 }
242 
243