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