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