1 use serde::{
2     de::{DeserializeSeed, Deserializer, SeqAccess, Visitor},
3     ser::{Serialize, SerializeSeq, Serializer},
4 };
5 use static_assertions::assert_impl_all;
6 use std::convert::{TryFrom, TryInto};
7 
8 use crate::{
9     value::SignatureSeed, DynamicDeserialize, DynamicType, Error, Result, Signature, Type, Value,
10 };
11 
12 /// A helper type to wrap arrays in a [`Value`].
13 ///
14 /// API is provided to convert from, and to a [`Vec`].
15 ///
16 /// [`Value`]: enum.Value.html#variant.Array
17 /// [`Vec`]: https://doc.rust-lang.org/std/vec/struct.Vec.html
18 #[derive(Debug, Clone, PartialEq)]
19 pub struct Array<'a> {
20     element_signature: Signature<'a>,
21     elements: Vec<Value<'a>>,
22     signature: Signature<'a>,
23 }
24 
25 assert_impl_all!(Array<'_>: Send, Sync, Unpin);
26 
27 impl<'a> Array<'a> {
28     /// Create a new empty `Array`, given the signature of the elements.
new(element_signature: Signature<'_>) -> Array<'_>29     pub fn new(element_signature: Signature<'_>) -> Array<'_> {
30         let signature = create_signature(&element_signature);
31         Array {
32             element_signature,
33             elements: vec![],
34             signature,
35         }
36     }
37 
new_full_signature(signature: Signature<'_>) -> Array<'_>38     pub(crate) fn new_full_signature(signature: Signature<'_>) -> Array<'_> {
39         let element_signature = signature.slice(1..);
40         Array {
41             element_signature,
42             elements: vec![],
43             signature,
44         }
45     }
46 
47     /// Append `element`.
48     ///
49     /// # Errors
50     ///
51     /// if `element`'s signature doesn't match the element signature `self` was created for.
append<'e: 'a>(&mut self, element: Value<'e>) -> Result<()>52     pub fn append<'e: 'a>(&mut self, element: Value<'e>) -> Result<()> {
53         check_child_value_signature!(self.element_signature, element.value_signature(), "element");
54 
55         self.elements.push(element);
56 
57         Ok(())
58     }
59 
60     /// Get all the elements.
get(&self) -> &[Value<'a>]61     pub fn get(&self) -> &[Value<'a>] {
62         &self.elements
63     }
64 
65     /// Get the number of elements.
len(&self) -> usize66     pub fn len(&self) -> usize {
67         self.elements.len()
68     }
69 
is_empty(&self) -> bool70     pub fn is_empty(&self) -> bool {
71         self.elements.len() == 0
72     }
73 
74     /// Get the signature of this `Array`.
75     ///
76     /// NB: This method potentially allocates and copies. Use [`full_signature`] if you'd like to
77     /// avoid that.
78     ///
79     /// [`full_signature`]: #method.full_signature
signature(&self) -> Signature<'static>80     pub fn signature(&self) -> Signature<'static> {
81         self.signature.to_owned()
82     }
83 
84     /// Get the signature of this `Array`.
full_signature(&self) -> &Signature<'_>85     pub fn full_signature(&self) -> &Signature<'_> {
86         &self.signature
87     }
88 
89     /// Get the signature of the elements in the `Array`.
element_signature(&self) -> &Signature<'_>90     pub fn element_signature(&self) -> &Signature<'_> {
91         &self.element_signature
92     }
93 
to_owned(&self) -> Array<'static>94     pub(crate) fn to_owned(&self) -> Array<'static> {
95         Array {
96             element_signature: self.element_signature.to_owned(),
97             elements: self.elements.iter().map(|v| v.to_owned()).collect(),
98             signature: self.signature.to_owned(),
99         }
100     }
101 }
102 
103 /// Use this to deserialize an [Array].
104 pub struct ArraySeed<'a> {
105     signature: Signature<'a>,
106 }
107 
108 impl<'a> ArraySeed<'a> {
109     /// Create a new empty `Array`, given the signature of the elements.
new(element_signature: Signature<'_>) -> ArraySeed<'_>110     pub fn new(element_signature: Signature<'_>) -> ArraySeed<'_> {
111         let signature = create_signature(&element_signature);
112         ArraySeed { signature }
113     }
114 
new_full_signature(signature: Signature<'_>) -> ArraySeed<'_>115     pub(crate) fn new_full_signature(signature: Signature<'_>) -> ArraySeed<'_> {
116         ArraySeed { signature }
117     }
118 }
119 
120 assert_impl_all!(ArraySeed<'_>: Send, Sync, Unpin);
121 
122 impl<'a> DynamicType for Array<'a> {
dynamic_signature(&self) -> Signature<'_>123     fn dynamic_signature(&self) -> Signature<'_> {
124         self.signature.clone()
125     }
126 }
127 
128 impl<'a> DynamicType for ArraySeed<'a> {
dynamic_signature(&self) -> Signature<'_>129     fn dynamic_signature(&self) -> Signature<'_> {
130         self.signature.clone()
131     }
132 }
133 
134 impl<'a> DynamicDeserialize<'a> for Array<'a> {
135     type Deserializer = ArraySeed<'a>;
136 
deserializer_for_signature<S>(signature: S) -> zvariant::Result<Self::Deserializer> where S: TryInto<Signature<'a>>, S::Error: Into<zvariant::Error>,137     fn deserializer_for_signature<S>(signature: S) -> zvariant::Result<Self::Deserializer>
138     where
139         S: TryInto<Signature<'a>>,
140         S::Error: Into<zvariant::Error>,
141     {
142         let signature = signature.try_into().map_err(Into::into)?;
143         if signature.starts_with(zvariant::ARRAY_SIGNATURE_CHAR) {
144             Ok(ArraySeed::new_full_signature(signature))
145         } else {
146             Err(zvariant::Error::SignatureMismatch(
147                 signature.to_owned(),
148                 "an array signature".to_owned(),
149             ))
150         }
151     }
152 }
153 
154 impl<'a> std::ops::Deref for Array<'a> {
155     type Target = [Value<'a>];
156 
deref(&self) -> &Self::Target157     fn deref(&self) -> &Self::Target {
158         self.get()
159     }
160 }
161 
162 impl<'a, T> From<Vec<T>> for Array<'a>
163 where
164     T: Type + Into<Value<'a>>,
165 {
from(values: Vec<T>) -> Self166     fn from(values: Vec<T>) -> Self {
167         let element_signature = T::signature();
168         let elements = values.into_iter().map(Value::new).collect();
169         let signature = create_signature(&element_signature);
170 
171         Self {
172             element_signature,
173             elements,
174             signature,
175         }
176     }
177 }
178 
179 impl<'a, T> From<&[T]> for Array<'a>
180 where
181     T: Type + Into<Value<'a>> + Clone,
182 {
from(values: &[T]) -> Self183     fn from(values: &[T]) -> Self {
184         let element_signature = T::signature();
185         let elements = values
186             .iter()
187             .map(|value| Value::new(value.clone()))
188             .collect();
189         let signature = create_signature(&element_signature);
190 
191         Self {
192             element_signature,
193             elements,
194             signature,
195         }
196     }
197 }
198 
199 impl<'a, T> From<&Vec<T>> for Array<'a>
200 where
201     T: Type + Into<Value<'a>> + Clone,
202 {
from(values: &Vec<T>) -> Self203     fn from(values: &Vec<T>) -> Self {
204         Self::from(&values[..])
205     }
206 }
207 
208 impl<'a, T> TryFrom<Array<'a>> for Vec<T>
209 where
210     T: TryFrom<Value<'a>>,
211     T::Error: Into<crate::Error>,
212 {
213     type Error = Error;
214 
try_from(v: Array<'a>) -> core::result::Result<Self, Self::Error>215     fn try_from(v: Array<'a>) -> core::result::Result<Self, Self::Error> {
216         // there is no try_map yet..
217         let mut res = vec![];
218         for e in v.elements.into_iter() {
219             let value = if let Value::Value(v) = e {
220                 T::try_from(*v)
221             } else {
222                 T::try_from(e)
223             }
224             .map_err(Into::into)?;
225 
226             res.push(value);
227         }
228         Ok(res)
229     }
230 }
231 
232 // TODO: this could be useful
233 // impl<'a, 'b, T> TryFrom<&'a Array<'b>> for Vec<T>
234 
235 impl<'a> Serialize for Array<'a> {
serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error> where S: Serializer,236     fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
237     where
238         S: Serializer,
239     {
240         let mut seq = serializer.serialize_seq(Some(self.elements.len()))?;
241         for element in &self.elements {
242             element.serialize_value_as_seq_element(&mut seq)?;
243         }
244 
245         seq.end()
246     }
247 }
248 
249 impl<'de> DeserializeSeed<'de> for ArraySeed<'de> {
250     type Value = Array<'de>;
deserialize<D>(self, deserializer: D) -> std::result::Result<Self::Value, D::Error> where D: Deserializer<'de>,251     fn deserialize<D>(self, deserializer: D) -> std::result::Result<Self::Value, D::Error>
252     where
253         D: Deserializer<'de>,
254     {
255         deserializer.deserialize_seq(ArrayVisitor {
256             signature: self.signature,
257         })
258     }
259 }
260 
261 #[derive(Debug, Clone, PartialEq)]
262 struct ArrayVisitor<'a> {
263     signature: Signature<'a>,
264 }
265 
266 impl<'de> Visitor<'de> for ArrayVisitor<'de> {
267     type Value = Array<'de>;
268 
expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result269     fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
270         formatter.write_str("an Array value")
271     }
272 
visit_seq<V>(self, visitor: V) -> std::result::Result<Array<'de>, V::Error> where V: SeqAccess<'de>,273     fn visit_seq<V>(self, visitor: V) -> std::result::Result<Array<'de>, V::Error>
274     where
275         V: SeqAccess<'de>,
276     {
277         SignatureSeed {
278             signature: self.signature,
279         }
280         .visit_array(visitor)
281     }
282 }
283 
create_signature(element_signature: &Signature<'_>) -> Signature<'static>284 fn create_signature(element_signature: &Signature<'_>) -> Signature<'static> {
285     Signature::from_string_unchecked(format!("a{}", element_signature))
286 }
287