| 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 | |