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