1use crate::{Signature, Type, impl_type_with_repr, serialized::Format};
2
3pub trait Basic: Type {
10 const SIGNATURE_CHAR: char;
12 const SIGNATURE_STR: &'static str;
14
15 fn alignment(format: Format) -> usize {
20 Self::SIGNATURE.alignment(format)
21 }
22}
23
24macro_rules! impl_type {
25 ($for:ty) => {
26 impl Type for $for {
27 const SIGNATURE: &'static Signature = {
28 match Self::SIGNATURE_CHAR {
29 'y' => &Signature::U8,
30 'b' => &Signature::Bool,
31 'n' => &Signature::I16,
32 'q' => &Signature::U16,
33 'i' => &Signature::I32,
34 'u' => &Signature::U32,
35 'x' => &Signature::I64,
36 't' => &Signature::U64,
37 'd' => &Signature::F64,
38 's' => &Signature::Str,
39 'g' => &Signature::Signature,
40 'o' => &Signature::ObjectPath,
41 'v' => &Signature::Variant,
42 #[cfg(unix)]
43 'h' => &Signature::Fd,
44 _ => unreachable!(),
45 }
46 };
47 }
48 };
49}
50
51impl Basic for u8 {
52 const SIGNATURE_CHAR: char = 'y';
53 const SIGNATURE_STR: &'static str = "y";
54}
55impl_type!(u8);
56
57impl Basic for std::num::NonZeroU8 {
58 const SIGNATURE_CHAR: char = u8::SIGNATURE_CHAR;
59 const SIGNATURE_STR: &'static str = u8::SIGNATURE_STR;
60}
61impl_type!(std::num::NonZeroU8);
62
63impl Basic for i8 {
65 const SIGNATURE_CHAR: char = i16::SIGNATURE_CHAR;
66 const SIGNATURE_STR: &'static str = i16::SIGNATURE_STR;
67}
68impl_type!(i8);
69
70impl Basic for std::num::NonZeroI8 {
71 const SIGNATURE_CHAR: char = i8::SIGNATURE_CHAR;
72 const SIGNATURE_STR: &'static str = i8::SIGNATURE_STR;
73}
74impl_type!(std::num::NonZeroI8);
75
76impl Basic for bool {
77 const SIGNATURE_CHAR: char = 'b';
78 const SIGNATURE_STR: &'static str = "b";
79}
80impl_type!(bool);
81
82impl Basic for i16 {
83 const SIGNATURE_CHAR: char = 'n';
84 const SIGNATURE_STR: &'static str = "n";
85}
86impl_type!(i16);
87
88impl Basic for std::num::NonZeroI16 {
89 const SIGNATURE_CHAR: char = i16::SIGNATURE_CHAR;
90 const SIGNATURE_STR: &'static str = i16::SIGNATURE_STR;
91}
92impl_type!(std::num::NonZeroI16);
93
94impl Basic for u16 {
95 const SIGNATURE_CHAR: char = 'q';
96 const SIGNATURE_STR: &'static str = "q";
97}
98impl_type!(u16);
99
100impl Basic for std::num::NonZeroU16 {
101 const SIGNATURE_CHAR: char = u16::SIGNATURE_CHAR;
102 const SIGNATURE_STR: &'static str = u16::SIGNATURE_STR;
103}
104impl_type!(std::num::NonZeroU16);
105
106impl Basic for i32 {
107 const SIGNATURE_CHAR: char = 'i';
108 const SIGNATURE_STR: &'static str = "i";
109}
110impl_type!(i32);
111
112impl Basic for std::num::NonZeroI32 {
113 const SIGNATURE_CHAR: char = i32::SIGNATURE_CHAR;
114 const SIGNATURE_STR: &'static str = i32::SIGNATURE_STR;
115}
116impl_type!(std::num::NonZeroI32);
117
118impl Basic for u32 {
119 const SIGNATURE_CHAR: char = 'u';
120 const SIGNATURE_STR: &'static str = "u";
121}
122impl_type!(u32);
123
124impl Basic for std::num::NonZeroU32 {
125 const SIGNATURE_CHAR: char = u32::SIGNATURE_CHAR;
126 const SIGNATURE_STR: &'static str = u32::SIGNATURE_STR;
127}
128impl_type!(std::num::NonZeroU32);
129
130impl Basic for i64 {
131 const SIGNATURE_CHAR: char = 'x';
132 const SIGNATURE_STR: &'static str = "x";
133}
134impl_type!(i64);
135
136impl Basic for std::num::NonZeroI64 {
137 const SIGNATURE_CHAR: char = i64::SIGNATURE_CHAR;
138 const SIGNATURE_STR: &'static str = i64::SIGNATURE_STR;
139}
140impl_type!(std::num::NonZeroI64);
141
142impl Basic for u64 {
143 const SIGNATURE_CHAR: char = 't';
144 const SIGNATURE_STR: &'static str = "t";
145}
146impl_type!(u64);
147
148impl Basic for std::num::NonZeroU64 {
149 const SIGNATURE_CHAR: char = u64::SIGNATURE_CHAR;
150 const SIGNATURE_STR: &'static str = u64::SIGNATURE_STR;
151}
152impl_type!(std::num::NonZeroU64);
153
154impl Basic for f32 {
156 const SIGNATURE_CHAR: char = f64::SIGNATURE_CHAR;
157 const SIGNATURE_STR: &'static str = f64::SIGNATURE_STR;
158}
159impl_type!(f32);
160
161impl Basic for f64 {
162 const SIGNATURE_CHAR: char = 'd';
163 const SIGNATURE_STR: &'static str = "d";
164}
165impl_type!(f64);
166
167impl Basic for str {
168 const SIGNATURE_CHAR: char = 's';
169 const SIGNATURE_STR: &'static str = "s";
170}
171impl_type!(str);
172
173impl Basic for String {
174 const SIGNATURE_CHAR: char = 's';
175 const SIGNATURE_STR: &'static str = "s";
176}
177impl_type!(String);
178
179impl Basic for char {
180 const SIGNATURE_CHAR: char = <&str>::SIGNATURE_CHAR;
181 const SIGNATURE_STR: &'static str = <&str>::SIGNATURE_STR;
182}
183impl_type!(char);
184
185impl Basic for usize {
188 const SIGNATURE_CHAR: char = <u64 as Basic>::SIGNATURE_CHAR;
189 const SIGNATURE_STR: &'static str = <u64 as Basic>::SIGNATURE_STR;
190}
191
192impl_type_with_repr! {
193 usize => u64 {
196 usize {
197 samples = [usize::MAX, usize::MIN],
198 repr(n) = n as u64,
199 }
200 }
201}
202
203impl_type_with_repr! {
204 isize => i64 {
207 isize {
208 samples = [isize::MAX, isize::MIN],
209 repr(n) = n as i64,
210 }
211 }
212}
213
214impl Basic for isize {
215 const SIGNATURE_CHAR: char = <i64 as Basic>::SIGNATURE_CHAR;
216 const SIGNATURE_STR: &'static str = <i64 as Basic>::SIGNATURE_STR;
217}
218
219macro_rules! impl_basic_for_deref {
222 (
223 $type:ty,
224 <$($desc:tt)+
225 ) => {
226 impl <$($desc)+ {
227 const SIGNATURE_CHAR: char = <$type>::SIGNATURE_CHAR;
228 const SIGNATURE_STR: &'static str = <$type>::SIGNATURE_STR;
229 }
230 };
231}
232
233impl_basic_for_deref!(T, <T: ?Sized + Basic> Basic for &T);
234impl_basic_for_deref!(T, <T: ?Sized + Basic> Basic for &mut T);
235impl_basic_for_deref!(T, <T: ?Sized + Basic + ToOwned> Basic for std::borrow::Cow<'_,T>);
236impl_basic_for_deref!(T, <T: ?Sized + Basic> Basic for std::sync::Arc<T>);
237impl_basic_for_deref!(T, <T: ?Sized + Basic> Basic for std::sync::Weak<T>);
238impl_basic_for_deref!(T, <T: ?Sized + Basic> Basic for std::sync::Mutex<T>);
239impl_basic_for_deref!(T, <T: ?Sized + Basic> Basic for std::sync::RwLock<T>);
240impl_basic_for_deref!(T, <T: ?Sized + Basic> Basic for std::boxed::Box<T>);
241impl_basic_for_deref!(T, <T: ?Sized + Basic> Basic for std::rc::Rc<T>);
242impl_basic_for_deref!(T, <T: ?Sized + Basic> Basic for std::rc::Weak<T>);
243impl_basic_for_deref!(T, <T: ?Sized + Basic> Basic for std::cell::Cell<T>);
244impl_basic_for_deref!(T, <T: ?Sized + Basic> Basic for std::cell::RefCell<T>);
245
246use std::{
249 cmp::Reverse,
250 num::{Saturating, Wrapping},
251};
252
253macro_rules! impl_basic_for_wrapper {
254 ($($wrapper:ident<$T:ident>),+) => {
255 $(
256 impl<$T: Basic> Basic for $wrapper<$T> {
257 const SIGNATURE_CHAR: char = <$T>::SIGNATURE_CHAR;
258 const SIGNATURE_STR: &'static str = <$T>::SIGNATURE_STR;
259 }
260 )+
261 };
262}
263
264impl_basic_for_wrapper!(Wrapping<T>, Saturating<T>, Reverse<T>);
265
266macro_rules! atomic_impl {
269 ($($ty:ident $size:expr => $primitive:ident)*) => {
270 $(
271 #[cfg(target_has_atomic = $size)]
272 impl Basic for $ty {
273 const SIGNATURE_CHAR: char = <$primitive as Basic>::SIGNATURE_CHAR;
274 const SIGNATURE_STR: &'static str = <$primitive as Basic>::SIGNATURE_STR;
275 }
276 impl_type!($ty);
277 )*
278 }
279}
280
281use std::sync::atomic::{
282 AtomicBool, AtomicI8, AtomicI16, AtomicI32, AtomicIsize, AtomicU8, AtomicU16, AtomicU32,
283 AtomicUsize,
284};
285#[cfg(target_has_atomic = "64")]
286use std::sync::atomic::{AtomicI64, AtomicU64};
287
288atomic_impl! {
289 AtomicBool "8" => bool
290 AtomicI8 "8" => i8
291 AtomicI16 "16" => i16
292 AtomicI32 "32" => i32
293 AtomicIsize "ptr" => isize
294 AtomicU8 "8" => u8
295 AtomicU16 "16" => u16
296 AtomicU32 "32" => u32
297 AtomicUsize "ptr" => usize
298}
299
300#[cfg(target_has_atomic = "64")]
301atomic_impl! {
302 AtomicI64 "64" => i64
303 AtomicU64 "64" => u64
304}
305
306#[cfg(feature = "heapless")]
309impl<const CAP: usize> Basic for heapless::String<CAP> {
310 const SIGNATURE_CHAR: char = <&str as Basic>::SIGNATURE_CHAR;
311 const SIGNATURE_STR: &'static str = <&str as Basic>::SIGNATURE_STR;
312}