1#![allow(clippy::wrong_self_convention)]
2
3use crate::{
4 char_encoding::FmtChar,
5 formatting::{Formatting, FormattingFlags},
6 wrapper_types::PWrapper,
7};
8
9#[doc(hidden)]
10/// The uniform representation for every argument of the concatcp macro.
11pub struct PArgument {
12 pub elem: PVariant,
13 pub fmt_len: usize,
14 pub fmt: Formatting,
15 pub fmt_flags: FormattingFlags,
16}
17
18impl PArgument {
19 /// Calculates the length of the string after adding up all the PArguments
20 pub const fn calc_len(mut args: &[PArgument]) -> usize {
21 let mut sum: usize = 0;
22
23 while let [curr: &PArgument, rem: &[PArgument] @ ..] = args {
24 args = rem;
25 sum += curr.fmt_len;
26 }
27
28 sum
29 }
30}
31
32#[doc(hidden)]
33pub enum PVariant {
34 Str(&'static str),
35 Int(Integer),
36 Char(FmtChar),
37}
38
39#[derive(Debug, Copy, Clone)]
40pub struct Integer {
41 pub is_negative: bool,
42 pub unsigned: u128,
43 pub mask: &'static u128, // A mask which disables the bits that weren't in the original number
44}
45
46#[doc(hidden)]
47pub struct PConvWrapper<T>(pub T);
48
49macro_rules! pconvwrapper_impls {
50 ( $( ($Signed:ty, $Unsigned:ty) )* ) => (
51 pconvwrapper_impls!{
52 @inner to_pargument_display, compute_display_len, Formatting::Display;
53 $(($Signed, $Unsigned))*
54 }
55 pconvwrapper_impls!{
56 @inner to_pargument_debug, compute_debug_len, Formatting::Debug;
57 $(($Signed, $Unsigned))*
58 }
59
60 $(
61 #[doc(hidden)]
62 impl PConvWrapper<$Signed>{
63 pub const fn to_integer(self)->Integer{
64 Integer{
65 is_negative: self.0 < 0,
66 unsigned: PWrapper(self.0).unsigned_abs() as u128,
67 mask: &(((!(0 as $Signed)) as $Unsigned) as u128),
68 }
69 }
70 }
71
72 #[doc(hidden)]
73 impl PConvWrapper<$Unsigned>{
74 pub const fn to_integer(self)->Integer{
75 Integer{
76 is_negative: false,
77 unsigned: self.0 as u128,
78 mask: &((!(0 as $Unsigned)) as u128),
79 }
80 }
81 }
82 )*
83 );
84 (@inner
85 $method:ident,
86 $called:ident,
87 $formatting:expr;
88 $( ($Signed:ty, $Unsigned:ty) )*
89 ) => (
90 $(
91 #[doc(hidden)]
92 impl PConvWrapper<$Signed> {
93 pub const fn $method(self, fmt_flags: FormattingFlags)->PArgument{
94 PArgument {
95 fmt_len: $crate::pmr::PWrapper(self.0).$called(fmt_flags),
96 fmt: $formatting,
97 fmt_flags,
98 elem: PVariant::Int(self.to_integer()),
99 }
100 }
101 }
102
103 #[doc(hidden)]
104 impl PConvWrapper<$Unsigned> {
105 pub const fn $method(self, fmt_flags: FormattingFlags)->PArgument{
106 PArgument {
107 fmt_len: $crate::pmr::PWrapper(self.0).$called(fmt_flags),
108 fmt: $formatting,
109 fmt_flags,
110 elem: PVariant::Int(self.to_integer()),
111 }
112 }
113 }
114 )*
115 );
116}
117
118pconvwrapper_impls! {
119 (i8, u8)
120 (i16, u16)
121 (i32, u32)
122 (i64, u64)
123 (i128, u128)
124 (isize, usize)
125}
126
127#[doc(hidden)]
128impl PConvWrapper<PArgument> {
129 #[inline]
130 pub const fn to_pargument_display(self, _: FormattingFlags) -> PArgument {
131 self.0
132 }
133 #[inline]
134 pub const fn to_pargument_debug(self, _: FormattingFlags) -> PArgument {
135 self.0
136 }
137}
138
139#[doc(hidden)]
140impl PConvWrapper<bool> {
141 #[inline]
142 pub const fn to_pargument_display(self, _: FormattingFlags) -> PArgument {
143 PConvWrapper(if self.0 { "true" } else { "false" })
144 .to_pargument_display(fmt_flags:FormattingFlags::DEFAULT)
145 }
146 #[inline]
147 pub const fn to_pargument_debug(self, fmt_flags: FormattingFlags) -> PArgument {
148 self.to_pargument_display(fmt_flags)
149 }
150}
151
152#[doc(hidden)]
153impl PConvWrapper<char> {
154 #[inline]
155 pub const fn to_pargument_display(self, fmt_flags: FormattingFlags) -> PArgument {
156 let elem: FmtChar = crate::char_encoding::char_to_display(self.0);
157 PArgument {
158 fmt_len: elem.len(),
159 fmt_flags,
160 fmt: Formatting::Display,
161 elem: PVariant::Char(elem),
162 }
163 }
164 #[inline]
165 pub const fn to_pargument_debug(self, fmt_flags: FormattingFlags) -> PArgument {
166 let elem: FmtChar = crate::char_encoding::char_to_debug(self.0);
167 PArgument {
168 fmt_len: elem.len(),
169 fmt_flags,
170 fmt: Formatting::Debug,
171 elem: PVariant::Char(elem),
172 }
173 }
174}
175
176#[doc(hidden)]
177impl PConvWrapper<&'static str> {
178 #[inline]
179 pub const fn to_pargument_display(self, fmt_flags: FormattingFlags) -> PArgument {
180 PArgument {
181 fmt_len: PWrapper(self.0).compute_display_len(fmt_flags),
182 fmt_flags,
183 fmt: Formatting::Display,
184 elem: PVariant::Str(self.0),
185 }
186 }
187 #[inline]
188 pub const fn to_pargument_debug(self, fmt_flags: FormattingFlags) -> PArgument {
189 PArgument {
190 fmt_len: PWrapper(self.0).compute_debug_len(fmt_flags),
191 fmt_flags,
192 fmt: Formatting::Debug,
193 elem: PVariant::Str(self.0),
194 }
195 }
196}
197