1use 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
9pub 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
19impl<B: ?Sized> Basic for &B
20where
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
31macro_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
41macro_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
56impl Basic for u8 {
57 const SIGNATURE_CHAR: char = 'y';
58 const SIGNATURE_STR: &'static str = "y";
59
60 alignment_method!(1);
61}
62impl_type!(u8);
63
64impl 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}
70impl_type!(std::num::NonZeroU8);
71
72// No i8 type in D-Bus/GVariant, let's pretend it's i16
73impl 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}
82impl_type!(i8);
83
84impl 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}
93impl_type!(std::num::NonZeroI8);
94
95impl Basic for bool {
96 const SIGNATURE_CHAR: char = 'b';
97 const SIGNATURE_STR: &'static str = "b";
98
99 alignment_method!(4);
100}
101impl_type!(bool);
102
103impl Basic for i16 {
104 const SIGNATURE_CHAR: char = 'n';
105 const SIGNATURE_STR: &'static str = "n";
106
107 alignment_method!(2);
108}
109impl_type!(i16);
110
111impl 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}
117impl_type!(std::num::NonZeroI16);
118
119impl Basic for u16 {
120 const SIGNATURE_CHAR: char = 'q';
121 const SIGNATURE_STR: &'static str = "q";
122
123 alignment_method!(2);
124}
125impl_type!(u16);
126
127impl 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}
133impl_type!(std::num::NonZeroU16);
134
135impl Basic for i32 {
136 const SIGNATURE_CHAR: char = 'i';
137 const SIGNATURE_STR: &'static str = "i";
138
139 alignment_method!(4);
140}
141impl_type!(i32);
142
143impl 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}
149impl_type!(std::num::NonZeroI32);
150
151impl Basic for u32 {
152 const SIGNATURE_CHAR: char = 'u';
153 const SIGNATURE_STR: &'static str = "u";
154
155 alignment_method!(4);
156}
157impl_type!(u32);
158
159impl 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}
165impl_type!(std::num::NonZeroU32);
166
167impl Basic for i64 {
168 const SIGNATURE_CHAR: char = 'x';
169 const SIGNATURE_STR: &'static str = "x";
170
171 alignment_method!(8);
172}
173impl_type!(i64);
174
175impl 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}
181impl_type!(std::num::NonZeroI64);
182
183impl Basic for u64 {
184 const SIGNATURE_CHAR: char = 't';
185 const SIGNATURE_STR: &'static str = "t";
186
187 alignment_method!(8);
188}
189impl_type!(u64);
190
191impl 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}
197impl_type!(std::num::NonZeroU64);
198
199// No f32 type in D-Bus/GVariant, let's pretend it's f64
200impl 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}
209impl_type!(f32);
210
211impl Basic for f64 {
212 const SIGNATURE_CHAR: char = 'd';
213 const SIGNATURE_STR: &'static str = "d";
214
215 alignment_method!(8);
216}
217impl_type!(f64);
218
219impl Basic for str {
220 const SIGNATURE_CHAR: char = 's';
221 const SIGNATURE_STR: &'static str = "s";
222
223 alignment_method!(4, 1);
224}
225impl_type!(str);
226
227impl Basic for String {
228 const SIGNATURE_CHAR: char = 's';
229 const SIGNATURE_STR: &'static str = "s";
230
231 alignment_method!(4, 1);
232}
233impl_type!(String);
234
235impl 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}
241impl_type!(char);
242