1 | use crate::{EncodingFormat, Signature, Type}; |
2 | |
3 | /// Trait for basic types. |
4 | /// |
5 | /// All basic types are also [`Type`] implementers. |
6 | /// |
7 | /// [`Type`]: trait.Type.html |
8 | /// [`Value`]: enum.Value.html |
9 | pub trait Basic: Type { |
10 | /// The type signature, as a character. |
11 | const SIGNATURE_CHAR: char; |
12 | /// The type signature, as a string. |
13 | const SIGNATURE_STR: &'static str; |
14 | |
15 | /// The required padding alignment for the given format. |
16 | fn alignment(format: EncodingFormat) -> usize; |
17 | } |
18 | |
19 | impl<B: ?Sized> Basic for &B |
20 | where |
21 | B: Basic, |
22 | { |
23 | const SIGNATURE_CHAR: char = B::SIGNATURE_CHAR; |
24 | const SIGNATURE_STR: &'static str = B::SIGNATURE_STR; |
25 | |
26 | fn alignment(format: EncodingFormat) -> usize { |
27 | B::alignment(format) |
28 | } |
29 | } |
30 | |
31 | macro_rules! impl_type { |
32 | ($for:ty) => { |
33 | impl Type for $for { |
34 | fn signature() -> Signature<'static> { |
35 | Signature::from_static_str_unchecked(<$for>::SIGNATURE_STR) |
36 | } |
37 | } |
38 | }; |
39 | } |
40 | |
41 | macro_rules! alignment_method { |
42 | ($alignment:expr) => { |
43 | alignment_method!($alignment, $alignment); |
44 | }; |
45 | ($dbus_alignment:expr, $gvariant_alignment:expr) => { |
46 | fn alignment(format: EncodingFormat) -> usize { |
47 | match format { |
48 | EncodingFormat::DBus => $dbus_alignment, |
49 | #[cfg(feature = "gvariant" )] |
50 | EncodingFormat::GVariant => $gvariant_alignment, |
51 | } |
52 | } |
53 | }; |
54 | } |
55 | |
56 | impl Basic for u8 { |
57 | const SIGNATURE_CHAR: char = 'y' ; |
58 | const SIGNATURE_STR: &'static str = "y" ; |
59 | |
60 | alignment_method!(1); |
61 | } |
62 | impl_type!(u8); |
63 | |
64 | impl Basic for std::num::NonZeroU8 { |
65 | const SIGNATURE_CHAR: char = u8::SIGNATURE_CHAR; |
66 | const SIGNATURE_STR: &'static str = u8::SIGNATURE_STR; |
67 | |
68 | alignment_method!(1); |
69 | } |
70 | impl_type!(std::num::NonZeroU8); |
71 | |
72 | // No i8 type in D-Bus/GVariant, let's pretend it's i16 |
73 | impl Basic for i8 { |
74 | const SIGNATURE_CHAR: char = i16::SIGNATURE_CHAR; |
75 | const SIGNATURE_STR: &'static str = i16::SIGNATURE_STR; |
76 | |
77 | alignment_method!( |
78 | i16::alignment(EncodingFormat::DBus), |
79 | i16::alignment(EncodingFormat::GVariant) |
80 | ); |
81 | } |
82 | impl_type!(i8); |
83 | |
84 | impl Basic for std::num::NonZeroI8 { |
85 | const SIGNATURE_CHAR: char = i8::SIGNATURE_CHAR; |
86 | const SIGNATURE_STR: &'static str = i8::SIGNATURE_STR; |
87 | |
88 | alignment_method!( |
89 | i16::alignment(EncodingFormat::DBus), |
90 | i16::alignment(EncodingFormat::GVariant) |
91 | ); |
92 | } |
93 | impl_type!(std::num::NonZeroI8); |
94 | |
95 | impl Basic for bool { |
96 | const SIGNATURE_CHAR: char = 'b' ; |
97 | const SIGNATURE_STR: &'static str = "b" ; |
98 | |
99 | alignment_method!(4); |
100 | } |
101 | impl_type!(bool); |
102 | |
103 | impl Basic for i16 { |
104 | const SIGNATURE_CHAR: char = 'n' ; |
105 | const SIGNATURE_STR: &'static str = "n" ; |
106 | |
107 | alignment_method!(2); |
108 | } |
109 | impl_type!(i16); |
110 | |
111 | impl Basic for std::num::NonZeroI16 { |
112 | const SIGNATURE_CHAR: char = i16::SIGNATURE_CHAR; |
113 | const SIGNATURE_STR: &'static str = i16::SIGNATURE_STR; |
114 | |
115 | alignment_method!(2); |
116 | } |
117 | impl_type!(std::num::NonZeroI16); |
118 | |
119 | impl Basic for u16 { |
120 | const SIGNATURE_CHAR: char = 'q' ; |
121 | const SIGNATURE_STR: &'static str = "q" ; |
122 | |
123 | alignment_method!(2); |
124 | } |
125 | impl_type!(u16); |
126 | |
127 | impl Basic for std::num::NonZeroU16 { |
128 | const SIGNATURE_CHAR: char = u16::SIGNATURE_CHAR; |
129 | const SIGNATURE_STR: &'static str = u16::SIGNATURE_STR; |
130 | |
131 | alignment_method!(2); |
132 | } |
133 | impl_type!(std::num::NonZeroU16); |
134 | |
135 | impl Basic for i32 { |
136 | const SIGNATURE_CHAR: char = 'i' ; |
137 | const SIGNATURE_STR: &'static str = "i" ; |
138 | |
139 | alignment_method!(4); |
140 | } |
141 | impl_type!(i32); |
142 | |
143 | impl Basic for std::num::NonZeroI32 { |
144 | const SIGNATURE_CHAR: char = i32::SIGNATURE_CHAR; |
145 | const SIGNATURE_STR: &'static str = i32::SIGNATURE_STR; |
146 | |
147 | alignment_method!(4); |
148 | } |
149 | impl_type!(std::num::NonZeroI32); |
150 | |
151 | impl Basic for u32 { |
152 | const SIGNATURE_CHAR: char = 'u' ; |
153 | const SIGNATURE_STR: &'static str = "u" ; |
154 | |
155 | alignment_method!(4); |
156 | } |
157 | impl_type!(u32); |
158 | |
159 | impl Basic for std::num::NonZeroU32 { |
160 | const SIGNATURE_CHAR: char = u32::SIGNATURE_CHAR; |
161 | const SIGNATURE_STR: &'static str = u32::SIGNATURE_STR; |
162 | |
163 | alignment_method!(4); |
164 | } |
165 | impl_type!(std::num::NonZeroU32); |
166 | |
167 | impl Basic for i64 { |
168 | const SIGNATURE_CHAR: char = 'x' ; |
169 | const SIGNATURE_STR: &'static str = "x" ; |
170 | |
171 | alignment_method!(8); |
172 | } |
173 | impl_type!(i64); |
174 | |
175 | impl Basic for std::num::NonZeroI64 { |
176 | const SIGNATURE_CHAR: char = i64::SIGNATURE_CHAR; |
177 | const SIGNATURE_STR: &'static str = i64::SIGNATURE_STR; |
178 | |
179 | alignment_method!(8); |
180 | } |
181 | impl_type!(std::num::NonZeroI64); |
182 | |
183 | impl Basic for u64 { |
184 | const SIGNATURE_CHAR: char = 't' ; |
185 | const SIGNATURE_STR: &'static str = "t" ; |
186 | |
187 | alignment_method!(8); |
188 | } |
189 | impl_type!(u64); |
190 | |
191 | impl Basic for std::num::NonZeroU64 { |
192 | const SIGNATURE_CHAR: char = u64::SIGNATURE_CHAR; |
193 | const SIGNATURE_STR: &'static str = u64::SIGNATURE_STR; |
194 | |
195 | alignment_method!(8); |
196 | } |
197 | impl_type!(std::num::NonZeroU64); |
198 | |
199 | // No f32 type in D-Bus/GVariant, let's pretend it's f64 |
200 | impl Basic for f32 { |
201 | const SIGNATURE_CHAR: char = f64::SIGNATURE_CHAR; |
202 | const SIGNATURE_STR: &'static str = f64::SIGNATURE_STR; |
203 | |
204 | alignment_method!( |
205 | f64::alignment(EncodingFormat::DBus), |
206 | f64::alignment(EncodingFormat::GVariant) |
207 | ); |
208 | } |
209 | impl_type!(f32); |
210 | |
211 | impl Basic for f64 { |
212 | const SIGNATURE_CHAR: char = 'd' ; |
213 | const SIGNATURE_STR: &'static str = "d" ; |
214 | |
215 | alignment_method!(8); |
216 | } |
217 | impl_type!(f64); |
218 | |
219 | impl Basic for str { |
220 | const SIGNATURE_CHAR: char = 's' ; |
221 | const SIGNATURE_STR: &'static str = "s" ; |
222 | |
223 | alignment_method!(4, 1); |
224 | } |
225 | impl_type!(str); |
226 | |
227 | impl Basic for String { |
228 | const SIGNATURE_CHAR: char = 's' ; |
229 | const SIGNATURE_STR: &'static str = "s" ; |
230 | |
231 | alignment_method!(4, 1); |
232 | } |
233 | impl_type!(String); |
234 | |
235 | impl Basic for char { |
236 | const SIGNATURE_CHAR: char = <&str>::SIGNATURE_CHAR; |
237 | const SIGNATURE_STR: &'static str = <&str>::SIGNATURE_STR; |
238 | |
239 | alignment_method!(4, 1); |
240 | } |
241 | impl_type!(char); |
242 | |