time_macros/format_description/public/
modifier.rs1use 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}