const_format/
pargument.rs

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 = 0;
22
23        while let [curr, rem @ ..] = 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(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 = 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 = 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}