const_format_proc_macros/
formatting.rs

1use proc_macro2::{Ident, Span, TokenStream as TokenStream2};
2
3use quote::{quote, ToTokens, TokenStreamExt};
4
5#[derive(Debug, Copy, Clone, PartialEq)]
6pub(crate) enum Formatting {
7    Debug(NumberFormatting),
8    Display,
9}
10
11#[derive(Debug, Copy, Clone, PartialEq)]
12pub(crate) enum NumberFormatting {
13    Decimal,
14    Hexadecimal,
15    LowerHexadecimal,
16    Binary,
17}
18
19impl NumberFormatting {
20    pub(crate) fn is_regular(self) -> bool {
21        matches!(self, NumberFormatting::Decimal)
22    }
23}
24
25impl ToTokens for NumberFormatting {
26    fn to_tokens(&self, ts: &mut TokenStream2) {
27        ts.append_all(match self {
28            Self::Decimal => return,
29            Self::Hexadecimal => quote!(.set_hexadecimal()),
30            Self::LowerHexadecimal => quote!(.set_lower_hexadecimal()),
31            Self::Binary => quote!(.set_binary()),
32        });
33    }
34}
35
36////////////////////////////////////////////////////////////////////////////////
37
38#[derive(Debug, Copy, Clone, PartialEq)]
39pub(crate) enum IsAlternate {
40    Yes,
41    No,
42}
43
44////////////////////////////////////////////////////////////////////////////////
45
46#[derive(Debug, Copy, Clone, PartialEq)]
47pub(crate) struct FormattingFlags {
48    pub(crate) formatting: Formatting,
49    pub(crate) is_alternate: IsAlternate,
50}
51
52impl FormattingFlags {
53    #[inline]
54    pub(crate) const fn display(is_alternate: IsAlternate) -> Self {
55        Self {
56            formatting: Formatting::Display,
57            is_alternate,
58        }
59    }
60
61    #[inline]
62    pub(crate) const fn debug(num_fmt: NumberFormatting, is_alternate: IsAlternate) -> Self {
63        Self {
64            formatting: Formatting::Debug(num_fmt),
65            is_alternate,
66        }
67    }
68}
69
70impl FormattingFlags {
71    pub(crate) fn to_pargument_method_name(self) -> Ident {
72        let name = match self.formatting {
73            Formatting::Display => "to_pargument_display",
74            Formatting::Debug { .. } => "to_pargument_debug",
75        };
76
77        Ident::new(name, Span::mixed_site())
78    }
79
80    #[allow(dead_code)]
81    pub(crate) fn fmt_method_name(self) -> Ident {
82        let name = match self.formatting {
83            Formatting::Display => "const_display_fmt",
84            Formatting::Debug { .. } => "const_debug_fmt",
85        };
86
87        Ident::new(name, Span::mixed_site())
88    }
89
90    #[allow(dead_code)]
91    pub(crate) fn len_method_name(self) -> Ident {
92        let name = match self.formatting {
93            Formatting::Display => "const_display_fmt",
94            Formatting::Debug { .. } => "const_debug_fmt",
95        };
96
97        Ident::new(name, Span::mixed_site())
98    }
99}
100
101impl ToTokens for FormattingFlags {
102    fn to_tokens(&self, ts: &mut TokenStream2) {
103        use self::{IsAlternate as IA, NumberFormatting as FM};
104
105        let formatting = match self.formatting {
106            Formatting::Display => NumberFormatting::Decimal,
107            Formatting::Debug(num_fmt) => num_fmt,
108        };
109
110        ts.append_all(match (self.is_alternate, formatting) {
111            (IA::No, FM::Decimal) => quote!(__cf_osRcTFl4A::pmr::FormattingFlags::__REG),
112            (IA::No, FM::Hexadecimal) => quote!(__cf_osRcTFl4A::pmr::FormattingFlags::__HEX),
113            (IA::No, FM::LowerHexadecimal) => {
114                quote!(__cf_osRcTFl4A::pmr::FormattingFlags::__LOWHEX)
115            }
116            (IA::No, FM::Binary) => quote!(__cf_osRcTFl4A::pmr::FormattingFlags::__BIN),
117            (IA::Yes, FM::Decimal) => quote!(__cf_osRcTFl4A::pmr::FormattingFlags::__A_REG),
118            (IA::Yes, FM::Hexadecimal) => quote!(__cf_osRcTFl4A::pmr::FormattingFlags::__A_HEX),
119            (IA::Yes, FM::LowerHexadecimal) => {
120                quote!(__cf_osRcTFl4A::pmr::FormattingFlags::__A_LOWHEX)
121            }
122            (IA::Yes, FM::Binary) => quote!(__cf_osRcTFl4A::pmr::FormattingFlags::__A_BIN),
123        });
124    }
125}