Skip to main content

time_macros/format_description/public/
modifier.rs

1use std::num::NonZero;
2
3use proc_macro::{Delimiter, Group, Ident, Span, TokenStream, TokenTree};
4
5use crate::to_tokens::{ToTokenStream, ToTokenTree};
6
7macro_rules! to_tokens {
8    (
9        $(#[$struct_attr:meta])*
10        $struct_vis:vis struct $struct_name:ident {$(
11            $(#[$field_attr:meta])*
12            $field_vis:vis $field_name:ident : $field_ty:ty = $default:pat
13        ),* $(,)?}
14    ) => {
15        $(#[$struct_attr])*
16        $struct_vis struct $struct_name {$(
17            $(#[$field_attr])*
18            $field_vis $field_name: $field_ty
19        ),*}
20
21        impl ToTokenTree for $struct_name {
22            fn into_token_tree(self) -> TokenTree {
23                let Self {$($field_name),*} = self;
24
25                #[allow(clippy::redundant_pattern_matching)]
26                if matches!(($(&$field_name,)*), ($($default,)*)) {
27                    return TokenTree::Group(Group::new(
28                        Delimiter::None,
29                        quote_! { $struct_name::default() }
30                    ));
31                }
32
33                let mut tokens = quote_! {
34                    $struct_name::default()
35                };
36                $(
37                    #[allow(clippy::redundant_pattern_matching)]
38                    if !matches!($field_name, $default) {
39                        let method_name = Ident::new(concat!("with_", stringify!($field_name)), Span::mixed_site());
40                        quote_append!(tokens .#(method_name)(#S($field_name)));
41                    }
42                )*
43
44                TokenTree::Group(Group::new(
45                    Delimiter::Brace,
46                    tokens,
47                ))
48            }
49        }
50    };
51
52    (
53        $(#[$enum_attr:meta])*
54        $enum_vis:vis enum $enum_name:ident {$(
55            $(#[$variant_attr:meta])*
56            $variant_name:ident
57        ),+ $(,)?}
58    ) => {
59        $(#[$enum_attr])*
60        $enum_vis enum $enum_name {$(
61            $(#[$variant_attr])*
62            $variant_name
63        ),+}
64
65        impl ToTokenStream for $enum_name {
66            fn append_to(self, ts: &mut TokenStream) {
67                quote_append! { ts
68                    $enum_name::
69                };
70                let name = match self {
71                    $(Self::$variant_name => stringify!($variant_name)),+
72                };
73                ts.extend([TokenTree::Ident(Ident::new(name, Span::mixed_site()))]);
74            }
75        }
76    }
77}
78
79to_tokens! {
80    pub(crate) struct Day {
81        pub(crate) padding: Padding = Padding::Zero,
82    }
83}
84
85to_tokens! {
86    pub(crate) struct MonthShort {
87        pub(crate) case_sensitive: bool = true,
88    }
89}
90
91to_tokens! {
92    pub(crate) struct MonthLong {
93        pub(crate) case_sensitive: bool = true,
94    }
95}
96
97to_tokens! {
98    pub(crate) struct MonthNumerical {
99        pub(crate) padding: Padding = Padding::Zero,
100    }
101}
102
103to_tokens! {
104    pub(crate) struct Ordinal {
105        pub(crate) padding: Padding = Padding::Zero,
106    }
107}
108
109to_tokens! {
110    pub(crate) struct WeekdayShort {
111        pub(crate) case_sensitive: bool = true,
112    }
113}
114
115to_tokens! {
116    pub(crate) struct WeekdayLong {
117        pub(crate) case_sensitive: bool = true,
118    }
119}
120
121to_tokens! {
122    pub(crate) struct WeekdaySunday {
123        pub(crate) one_indexed: bool = true,
124    }
125}
126
127to_tokens! {
128    pub(crate) struct WeekdayMonday {
129        pub(crate) one_indexed: bool = true,
130    }
131}
132
133to_tokens! {
134    pub(crate) struct WeekNumberIso {
135        pub(crate) padding: Padding = Padding::Zero,
136    }
137}
138
139to_tokens! {
140    pub(crate) struct WeekNumberSunday {
141        pub(crate) padding: Padding = Padding::Zero,
142    }
143}
144
145to_tokens! {
146    pub(crate) struct WeekNumberMonday {
147        pub(crate) padding: Padding = Padding::Zero,
148    }
149}
150
151to_tokens! {
152    pub(crate) struct CalendarYearFullStandardRange {
153        pub(crate) padding: Padding = Padding::Zero,
154        pub(crate) sign_is_mandatory: bool = false,
155    }
156}
157
158to_tokens! {
159    pub(crate) struct CalendarYearFullExtendedRange {
160        pub(crate) padding: Padding = Padding::Zero,
161        pub(crate) sign_is_mandatory: bool = false,
162    }
163}
164
165to_tokens! {
166    pub(crate) struct CalendarYearCenturyStandardRange {
167        pub(crate) padding: Padding = Padding::Zero,
168        pub(crate) sign_is_mandatory: bool = false,
169    }
170}
171
172to_tokens! {
173    pub(crate) struct CalendarYearCenturyExtendedRange {
174        pub(crate) padding: Padding = Padding::Zero,
175        pub(crate) sign_is_mandatory: bool = false,
176    }
177}
178
179to_tokens! {
180    pub(crate) struct IsoYearFullStandardRange {
181        pub(crate) padding: Padding = Padding::Zero,
182        pub(crate) sign_is_mandatory: bool = false,
183    }
184}
185
186to_tokens! {
187    pub(crate) struct IsoYearFullExtendedRange {
188        pub(crate) padding: Padding = Padding::Zero,
189        pub(crate) sign_is_mandatory: bool = false,
190    }
191}
192
193to_tokens! {
194    pub(crate) struct IsoYearCenturyStandardRange {
195        pub(crate) padding: Padding = Padding::Zero,
196        pub(crate) sign_is_mandatory: bool = false,
197    }
198}
199
200to_tokens! {
201    pub(crate) struct IsoYearCenturyExtendedRange {
202        pub(crate) padding: Padding = Padding::Zero,
203        pub(crate) sign_is_mandatory: bool = false,
204    }
205}
206
207to_tokens! {
208    pub(crate) struct CalendarYearLastTwo {
209        pub(crate) padding: Padding = Padding::Zero,
210    }
211}
212
213to_tokens! {
214    pub(crate) struct IsoYearLastTwo {
215        pub(crate) padding: Padding = Padding::Zero,
216    }
217}
218
219to_tokens! {
220    pub(crate) struct Hour12 {
221        pub(crate) padding: Padding = Padding::Zero,
222    }
223}
224
225to_tokens! {
226    pub(crate) struct Hour24 {
227        pub(crate) padding: Padding = Padding::Zero,
228    }
229}
230
231to_tokens! {
232    pub(crate) struct Minute {
233        pub(crate) padding: Padding = Padding::Zero,
234    }
235}
236
237to_tokens! {
238    pub(crate) struct Period {
239        pub(crate) is_uppercase: bool = true,
240        pub(crate) case_sensitive: bool = true,
241    }
242}
243
244to_tokens! {
245    pub(crate) struct Second {
246        pub(crate) padding: Padding = Padding::Zero,
247    }
248}
249
250to_tokens! {
251    pub(crate) enum SubsecondDigits {
252        One,
253        Two,
254        Three,
255        Four,
256        Five,
257        Six,
258        Seven,
259        Eight,
260        Nine,
261        OneOrMore,
262    }
263}
264
265to_tokens! {
266    pub(crate) struct Subsecond {
267        pub(crate) digits: SubsecondDigits = SubsecondDigits::OneOrMore,
268    }
269}
270
271to_tokens! {
272    pub(crate) struct OffsetHour {
273        pub(crate) sign_is_mandatory: bool = false,
274        pub(crate) padding: Padding = Padding::Zero,
275    }
276}
277
278to_tokens! {
279    pub(crate) struct OffsetMinute {
280        pub(crate) padding: Padding = Padding::Zero,
281    }
282}
283
284to_tokens! {
285    pub(crate) struct OffsetSecond {
286        pub(crate) padding: Padding = Padding::Zero,
287    }
288}
289
290to_tokens! {
291    pub(crate) enum Padding {
292        Space,
293        Zero,
294        None,
295    }
296}
297
298pub(crate) struct Ignore {
299    pub(crate) count: NonZero<u16>,
300}
301
302impl ToTokenTree for Ignore {
303    fn into_token_tree(self) -> TokenTree {
304        quote_group! {{
305            Ignore::count(#(self.count))
306        }}
307    }
308}
309
310to_tokens! {
311    pub(crate) struct UnixTimestampSecond {
312        pub(crate) sign_is_mandatory: bool = false,
313    }
314}
315
316to_tokens! {
317    pub(crate) struct UnixTimestampMillisecond {
318        pub(crate) sign_is_mandatory: bool = false,
319    }
320}
321
322to_tokens! {
323    pub(crate) struct UnixTimestampMicrosecond {
324        pub(crate) sign_is_mandatory: bool = false,
325    }
326}
327
328to_tokens! {
329    pub(crate) struct UnixTimestampNanosecond {
330        pub(crate) sign_is_mandatory: bool = false,
331    }
332}
333
334to_tokens! {
335    pub(crate) enum TrailingInput {
336        Prohibit,
337        Discard,
338    }
339}
340
341to_tokens! {
342    pub(crate) struct End {
343        pub(crate) trailing_input: TrailingInput = TrailingInput::Prohibit,
344    }
345}