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.
alignment(format: EncodingFormat) -> usize16     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 
alignment(format: EncodingFormat) -> usize26     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 // No i8 type in D-Bus/GVariant, let's pretend it's i16
65 impl Basic for i8 {
66     const SIGNATURE_CHAR: char = i16::SIGNATURE_CHAR;
67     const SIGNATURE_STR: &'static str = i16::SIGNATURE_STR;
68 
69     alignment_method!(
70         i16::alignment(EncodingFormat::DBus),
71         i16::alignment(EncodingFormat::GVariant)
72     );
73 }
74 impl_type!(i8);
75 
76 impl Basic for bool {
77     const SIGNATURE_CHAR: char = 'b';
78     const SIGNATURE_STR: &'static str = "b";
79 
80     alignment_method!(4);
81 }
82 impl_type!(bool);
83 
84 impl Basic for i16 {
85     const SIGNATURE_CHAR: char = 'n';
86     const SIGNATURE_STR: &'static str = "n";
87 
88     alignment_method!(2);
89 }
90 impl_type!(i16);
91 
92 impl Basic for u16 {
93     const SIGNATURE_CHAR: char = 'q';
94     const SIGNATURE_STR: &'static str = "q";
95 
96     alignment_method!(2);
97 }
98 impl_type!(u16);
99 
100 impl Basic for i32 {
101     const SIGNATURE_CHAR: char = 'i';
102     const SIGNATURE_STR: &'static str = "i";
103 
104     alignment_method!(4);
105 }
106 impl_type!(i32);
107 
108 impl Basic for u32 {
109     const SIGNATURE_CHAR: char = 'u';
110     const SIGNATURE_STR: &'static str = "u";
111 
112     alignment_method!(4);
113 }
114 impl_type!(u32);
115 
116 impl Basic for i64 {
117     const SIGNATURE_CHAR: char = 'x';
118     const SIGNATURE_STR: &'static str = "x";
119 
120     alignment_method!(8);
121 }
122 impl_type!(i64);
123 
124 impl Basic for u64 {
125     const SIGNATURE_CHAR: char = 't';
126     const SIGNATURE_STR: &'static str = "t";
127 
128     alignment_method!(8);
129 }
130 impl_type!(u64);
131 
132 // No f32 type in D-Bus/GVariant, let's pretend it's f64
133 impl Basic for f32 {
134     const SIGNATURE_CHAR: char = f64::SIGNATURE_CHAR;
135     const SIGNATURE_STR: &'static str = f64::SIGNATURE_STR;
136 
137     alignment_method!(
138         f64::alignment(EncodingFormat::DBus),
139         f64::alignment(EncodingFormat::GVariant)
140     );
141 }
142 impl_type!(f32);
143 
144 impl Basic for f64 {
145     const SIGNATURE_CHAR: char = 'd';
146     const SIGNATURE_STR: &'static str = "d";
147 
148     alignment_method!(8);
149 }
150 impl_type!(f64);
151 
152 impl Basic for str {
153     const SIGNATURE_CHAR: char = 's';
154     const SIGNATURE_STR: &'static str = "s";
155 
156     alignment_method!(4, 1);
157 }
158 impl_type!(str);
159 
160 impl Basic for String {
161     const SIGNATURE_CHAR: char = 's';
162     const SIGNATURE_STR: &'static str = "s";
163 
164     alignment_method!(4, 1);
165 }
166 impl_type!(String);
167 
168 impl Basic for char {
169     const SIGNATURE_CHAR: char = <&str>::SIGNATURE_CHAR;
170     const SIGNATURE_STR: &'static str = <&str>::SIGNATURE_STR;
171 
172     alignment_method!(4, 1);
173 }
174 impl_type!(char);
175