zvariant/
tuple.rs
1use crate::{
2 signature_parser::SignatureParser, utils::*, DynamicDeserialize, DynamicType, Signature,
3};
4use serde::{
5 de::{Deserialize, DeserializeSeed, Deserializer, Error, Visitor},
6 Serialize, Serializer,
7};
8use std::marker::PhantomData;
9
10#[derive(Debug, Copy, Clone)]
19pub struct DynamicTuple<T>(pub T);
20
21impl DynamicType for DynamicTuple<()> {
22 fn dynamic_signature(&self) -> Signature<'_> {
23 Signature::from_static_str_unchecked("")
24 }
25}
26
27impl<T: Serialize> Serialize for DynamicTuple<T> {
28 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
29 self.0.serialize(serializer)
30 }
31}
32
33impl<'de> Deserialize<'de> for DynamicTuple<()> {
34 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
35 <()>::deserialize(deserializer).map(DynamicTuple)
36 }
37}
38
39#[derive(Debug, Clone, PartialEq, Eq)]
41pub struct TupleSeed<'a, T, S> {
42 sig: Signature<'a>,
43 seeds: S,
44 marker: PhantomData<T>,
45}
46
47impl<'a, T, S> DynamicType for TupleSeed<'a, T, S> {
48 fn dynamic_signature(&self) -> Signature<'_> {
49 self.sig.clone()
50 }
51}
52
53struct TupleVisitor<T, S> {
54 seeds: S,
55 marker: PhantomData<T>,
56}
57
58macro_rules! tuple_impls {
59 ($($len:expr => ($($n:tt $name:ident)+))+) => {
60 $(
61 impl<$($name),+> DynamicType for DynamicTuple<($($name,)+)>
62 where
63 $($name: DynamicType,)+
64 {
65 fn dynamic_signature(&self) -> Signature<'_> {
66 let mut sig = String::with_capacity(255);
67 sig.push(STRUCT_SIG_START_CHAR);
68 $(
69 sig.push_str(DynamicType::dynamic_signature(&self.0.$n).as_str());
70 )+
71 sig.push(STRUCT_SIG_END_CHAR);
72
73 Signature::from_string_unchecked(sig)
74 }
75 }
76
77 impl<'de, $($name),+> DeserializeSeed<'de> for TupleSeed<'de, ($($name,)+), ($(<$name as DynamicDeserialize<'de>>::Deserializer,)+)>
78 where
79 $($name: DynamicDeserialize<'de>,)+
80 {
81 type Value = DynamicTuple<($($name,)+)>;
82
83 fn deserialize<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Value, D::Error> {
84 deserializer.deserialize_tuple($len, TupleVisitor { seeds: self.seeds, marker: self.marker })
85 }
86 }
87
88 impl<'de, $($name),+> Visitor<'de> for TupleVisitor<($($name,)+), ($(<$name as DynamicDeserialize<'de>>::Deserializer,)+)>
89 where
90 $($name: DynamicDeserialize<'de>,)+
91 {
92 type Value = DynamicTuple<($($name,)+)>;
93
94 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
95 formatter.write_str("a tuple")
96 }
97
98 fn visit_seq<V>(self, mut visitor: V) -> Result<DynamicTuple<($($name,)+)>, V::Error>
99 where
100 V: serde::de::SeqAccess<'de>,
101 {
102 Ok(DynamicTuple(($({
103 match visitor.next_element_seed(self.seeds.$n) {
104 Ok(Some(elt)) => elt,
105 Ok(None) => return Err(V::Error::invalid_length($len, &"")),
106 Err(e) => return Err(e),
107 }
108 },)+)))
109 }
110 }
111
112 impl<'de, $($name),+> DynamicDeserialize<'de> for DynamicTuple<($($name,)+)>
113 where
114 $($name: DynamicDeserialize<'de>,)+
115 {
116 type Deserializer = TupleSeed<'de, ($($name,)+), ($(<$name as DynamicDeserialize<'de>>::Deserializer,)+)>;
117
118 fn deserializer_for_signature<S>(signature: S) -> zvariant::Result<Self::Deserializer>
119 where S: TryInto<Signature<'de>>, S::Error: Into<zvariant::Error>
120 {
121 let sig = signature.try_into().map_err(Into::into)?;
122 if !sig.starts_with(zvariant::STRUCT_SIG_START_CHAR) {
123 return Err(zvariant::Error::IncorrectType);
124 }
125 if !sig.ends_with(zvariant::STRUCT_SIG_END_CHAR) {
126 return Err(zvariant::Error::IncorrectType);
127 }
128
129 let end = sig.len() - 1;
130 let mut sig_parser = SignatureParser::new(sig.slice(1..end));
131
132 let seeds = ($({
133 let elt_sig = sig_parser.parse_next_signature()?;
134 $name::deserializer_for_signature(elt_sig)?
135 },)+);
136
137 Ok(TupleSeed { sig, seeds, marker: PhantomData })
138 }
139 }
140 )+
141 }
142}
143
144tuple_impls! {
145 1 => (0 T0)
146 2 => (0 T0 1 T1)
147 3 => (0 T0 1 T1 2 T2)
148 4 => (0 T0 1 T1 2 T2 3 T3)
149 5 => (0 T0 1 T1 2 T2 3 T3 4 T4)
150 6 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5)
151 7 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6)
152 8 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7)
153 9 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8)
154 10 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9)
155 11 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10)
156 12 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11)
157 13 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12)
158 14 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13)
159 15 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14)
160 16 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15)
161}