1use std::collections::{BTreeMap, HashMap};
2use std::hash::BuildHasher;
3
4use tokio_dbus::{Alignment, ObjectPath, ObjectPathBuf, Raw, Signature, SignatureBuf};
5
6pub trait Encode {
24 const ALIGNMENT: Alignment;
27
28 fn encode(&self, raw: &mut Raw<'_>);
30}
31
32impl<T> Encode for &T
33where
34 T: ?Sized + Encode,
35{
36 const ALIGNMENT: Alignment = T::ALIGNMENT;
37
38 #[inline]
39 fn encode(&self, raw: &mut Raw<'_>) {
40 (**self).encode(raw);
41 }
42}
43
44macro_rules! encode_frame {
45 ($($ty:ty, $alignment:ident),* $(,)?) => {
46 $(
47 impl Encode for $ty {
48 const ALIGNMENT: Alignment = Alignment::$alignment;
49
50 #[inline]
51 fn encode(&self, raw: &mut Raw<'_>) {
52 raw.store(*self);
53 }
54 }
55 )*
56 }
57}
58
59encode_frame! {
60 u8, BYTE,
61 bool, U32,
62 i16, U16,
63 u16, U16,
64 i32, U32,
65 u32, U32,
66 i64, U64,
67 u64, U64,
68 f64, U64,
69}
70
71impl Encode for str {
72 const ALIGNMENT: Alignment = Alignment::U32;
73
74 #[inline]
75 fn encode(&self, raw: &mut Raw<'_>) {
76 raw.store(self);
77 }
78}
79
80impl Encode for String {
81 const ALIGNMENT: Alignment = Alignment::U32;
82
83 #[inline]
84 fn encode(&self, raw: &mut Raw<'_>) {
85 raw.store(self.as_str());
86 }
87}
88
89impl Encode for ObjectPath {
90 const ALIGNMENT: Alignment = Alignment::U32;
91
92 #[inline]
93 fn encode(&self, raw: &mut Raw<'_>) {
94 raw.store(self);
95 }
96}
97
98impl Encode for ObjectPathBuf {
99 const ALIGNMENT: Alignment = Alignment::U32;
100
101 #[inline]
102 fn encode(&self, raw: &mut Raw<'_>) {
103 raw.store(&**self);
104 }
105}
106
107impl Encode for Signature {
108 const ALIGNMENT: Alignment = Alignment::BYTE;
109
110 #[inline]
111 fn encode(&self, raw: &mut Raw<'_>) {
112 raw.store(self);
113 }
114}
115
116impl Encode for SignatureBuf {
117 const ALIGNMENT: Alignment = Alignment::BYTE;
118
119 #[inline]
120 fn encode(&self, raw: &mut Raw<'_>) {
121 raw.store(&**self);
122 }
123}
124
125impl<T> Encode for [T]
126where
127 T: Encode,
128{
129 const ALIGNMENT: Alignment = Alignment::U32;
132
133 #[inline]
134 fn encode(&self, raw: &mut Raw<'_>) {
135 let mut array = raw.store_array(T::ALIGNMENT);
136
137 for value in self {
138 value.encode(&mut array.as_raw());
139 }
140 }
141}
142
143impl<T> Encode for Vec<T>
144where
145 T: Encode,
146{
147 const ALIGNMENT: Alignment = Alignment::U32;
148
149 #[inline]
150 fn encode(&self, raw: &mut Raw<'_>) {
151 <[T] as Encode>::encode(self, raw);
152 }
153}
154
155impl<T, const N: usize> Encode for [T; N]
156where
157 T: Encode,
158{
159 const ALIGNMENT: Alignment = Alignment::U32;
160
161 #[inline]
162 fn encode(&self, raw: &mut Raw<'_>) {
163 <[T] as Encode>::encode(self, raw);
164 }
165}
166
167fn encode_entries<'a, K, V, I>(raw: &mut Raw<'_>, entries: I)
169where
170 K: 'a + Encode,
171 V: 'a + Encode,
172 I: IntoIterator<Item = (&'a K, &'a V)>,
173{
174 let mut array = raw.store_array(Alignment::U64);
175
176 for (key, value) in entries {
177 let mut entry = array.as_raw();
178 entry.align(Alignment::U64);
180 key.encode(&mut entry);
181 value.encode(&mut entry);
182 }
183}
184
185impl<K, V, S> Encode for HashMap<K, V, S>
186where
187 K: Encode,
188 V: Encode,
189 S: BuildHasher,
190{
191 const ALIGNMENT: Alignment = Alignment::U32;
192
193 #[inline]
194 fn encode(&self, raw: &mut Raw<'_>) {
195 encode_entries(raw, self);
196 }
197}
198
199impl<K, V> Encode for BTreeMap<K, V>
200where
201 K: Encode,
202 V: Encode,
203{
204 const ALIGNMENT: Alignment = Alignment::U32;
205
206 #[inline]
207 fn encode(&self, raw: &mut Raw<'_>) {
208 encode_entries(raw, self);
209 }
210}
211
212macro_rules! encode_tuple {
213 ($($ty:ident $var:ident),*) => {
214 impl<$($ty,)*> Encode for ($($ty,)*)
215 where
216 $($ty: Encode,)*
217 {
218 const ALIGNMENT: Alignment = Alignment::U64;
220
221 #[inline]
222 fn encode(&self, raw: &mut Raw<'_>) {
223 let ($($var,)*) = self;
224 raw.align(Alignment::U64);
225 $($var.encode(raw);)*
226 }
227 }
228 }
229}
230
231encode_tuple!(A a);
232encode_tuple!(A a, B b);
233encode_tuple!(A a, B b, C c);
234encode_tuple!(A a, B b, C c, D d);
235encode_tuple!(A a, B b, C c, D d, E e);
236encode_tuple!(A a, B b, C c, D d, E e, F f);
237encode_tuple!(A a, B b, C c, D d, E e, F f, G g);
238encode_tuple!(A a, B b, C c, D d, E e, F f, G g, H h);
239encode_tuple!(A a, B b, C c, D d, E e, F f, G g, H h, I i);
240encode_tuple!(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j);
241encode_tuple!(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k);
242encode_tuple!(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k, L l);