printf_wrap/
printf_arg_impls.rs1use crate::{is_compat, LargerOf, NullString};
7use crate::{PrintfArgument, PrintfArgumentPrivate};
8
9use core::ffi::{c_char, c_double, c_int, c_uint, c_void, CStr};
10
11macro_rules! impl_empty_trait {
12 ($trait_name:ident ; $($implementor:ty),*) => {
13 $(
14 impl $trait_name for $implementor { }
15 )*
16 };
17}
18
19impl_empty_trait!(PrintfArgumentPrivate;
20 u8, u16, u32, u64, usize, i8, i16, i32, i64, isize, f32, f64,
21 NullString
22);
23
24macro_rules! impl_printf_arg_integer {
25 ( $( $t:ty, $signed:expr, $int_type:ty );* ) => {
26 $(
27 impl PrintfArgument for $t {
28 const IS_SIGNED: bool = $signed;
29
30 const IS_CHAR: bool = is_compat::<$t, core::ffi::c_char>();
31 const IS_SHORT: bool = is_compat::<$t, core::ffi::c_short>();
32 const IS_INT: bool = is_compat::<$t, core::ffi::c_int>();
33 const IS_LONG: bool = is_compat::<$t, core::ffi::c_long>();
34 const IS_LONG_LONG: bool = is_compat::<$t, core::ffi::c_longlong>();
35
36 #[cfg(any(feature = "libc", test, all(doc, feature = "doccfg")))]
37 const IS_SIZE: bool = is_compat::<$t, libc::size_t>();
38
39 #[cfg(any(feature = "libc", test, all(doc, feature = "doccfg")))]
40 const IS_MAX: bool = is_compat::<$t, libc::intmax_t>();
41
42 #[cfg(any(feature = "libc", test, all(doc, feature = "doccfg")))]
43 const IS_PTRDIFF: bool = is_compat::<$t, libc::ptrdiff_t>();
44
45 type CPrintfType = LargerOf<Self, $int_type>;
46
47 #[inline]
48 fn as_c_val(self) -> Self::CPrintfType {
49 self as LargerOf<Self, $int_type>
50 }
51 }
52 )*
53 };
54}
55
56impl_printf_arg_integer! {
57 u8, false, c_uint;
58 i8, true, c_int;
59 u16, false, c_uint;
60 i16, true, c_int;
61 u32, false, c_uint;
62 i32, true, c_int;
63 u64, false, c_uint;
64 i64, true, c_int;
65
66 usize, false, c_uint;
69 isize, true, c_int
70}
71
72impl PrintfArgument for f32 {
73 const IS_FLOAT: bool = true;
74
75 type CPrintfType = c_double;
76
77 #[inline]
78 fn as_c_val(self) -> c_double {
79 self as c_double
80 }
81}
82
83impl PrintfArgument for f64 {
84 const IS_FLOAT: bool = true;
85
86 type CPrintfType = c_double;
87
88 #[inline]
89 fn as_c_val(self) -> c_double {
90 self as c_double
91 }
92}
93
94impl PrintfArgument for NullString {
95 type CPrintfType = *const c_char;
96
97 const IS_C_STRING: bool = true;
98
99 #[inline]
100 fn as_c_val(self) -> *const c_char {
101 self.as_ptr()
102 }
103}
104
105impl<T: AsRef<CStr> + ?Sized> PrintfArgumentPrivate for &T {}
106
107impl<T: AsRef<CStr> + ?Sized> PrintfArgument for &T {
108 type CPrintfType = *const c_char;
109
110 const IS_C_STRING: bool = true;
111
112 #[inline]
113 fn as_c_val(self) -> *const c_char {
114 let cs: &CStr = self.as_ref();
115 cs.as_ptr()
116 }
117}
118
119impl<T: Sized> PrintfArgumentPrivate for *const T {}
120
121impl<T: Sized> PrintfArgument for *const T {
122 type CPrintfType = *const c_void;
123
124 const IS_POINTER: bool = true;
125
126 #[inline]
127 fn as_c_val(self) -> *const c_void {
128 self as *const c_void
129 }
130}
131
132impl<T: Sized> PrintfArgumentPrivate for *mut T {}
133
134impl<T: Sized> PrintfArgument for *mut T {
135 type CPrintfType = *const c_void;
136
137 const IS_POINTER: bool = true;
138
139 #[inline]
140 fn as_c_val(self) -> *const c_void {
141 self as *mut c_void as *const c_void
142 }
143}