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 let mut value = $struct_name::default();
35 };
36 $(
37 #[allow(clippy::redundant_pattern_matching)]
38 if !matches!($field_name, $default) {
39 quote_append!(tokens value.$field_name =);
40 $field_name.append_to(&mut tokens);
41 quote_append!(tokens ;);
42 }
43 )*
44 quote_append!(tokens value);
45
46 TokenTree::Group(Group::new(
47 Delimiter::Brace,
48 tokens,
49 ))
50 }
51 }
52 };
53
54 (
55 $(#[$enum_attr:meta])*
56 $enum_vis:vis enum $enum_name:ident {$(
57 $(#[$variant_attr:meta])*
58 $variant_name:ident
59 ),+ $(,)?}
60 ) => {
61 $(#[$enum_attr])*
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) enum MonthRepr {
89 Numerical,
90 Long,
91 Short,
92 }
93}
94
95to_tokens! {
96 pub(crate) struct Month {
97 pub(crate) padding: Padding = Padding::Zero,
98 pub(crate) repr: MonthRepr = MonthRepr::Numerical,
99 pub(crate) case_sensitive: bool = true,
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) enum WeekdayRepr {
111 Short,
112 Long,
113 Sunday,
114 Monday,
115 }
116}
117
118to_tokens! {
119 pub(crate) struct Weekday {
120 pub(crate) repr: WeekdayRepr = WeekdayRepr::Long,
121 pub(crate) one_indexed: bool = true,
122 pub(crate) case_sensitive: bool = true,
123 }
124}
125
126to_tokens! {
127 pub(crate) enum WeekNumberRepr {
128 Iso,
129 Sunday,
130 Monday,
131 }
132}
133
134to_tokens! {
135 pub(crate) struct WeekNumber {
136 pub(crate) padding: Padding = Padding::Zero,
137 pub(crate) repr: WeekNumberRepr = WeekNumberRepr::Iso,
138 }
139}
140
141to_tokens! {
142 pub(crate) enum YearRepr {
143 Full,
144 Century,
145 LastTwo,
146 }
147}
148
149to_tokens! {
150 pub(crate) enum YearRange {
151 Standard,
152 Extended,
153 }
154}
155
156to_tokens! {
157 pub(crate) struct Year {
158 pub(crate) padding: Padding = Padding::Zero,
159 pub(crate) repr: YearRepr = YearRepr::Full,
160 pub(crate) range: YearRange = YearRange::Extended,
161 pub(crate) iso_week_based: bool = false,
162 pub(crate) sign_is_mandatory: bool = false,
163 }
164}
165
166to_tokens! {
167 pub(crate) struct Hour {
168 pub(crate) padding: Padding = Padding::Zero,
169 pub(crate) is_12_hour_clock: bool = false,
170 }
171}
172
173to_tokens! {
174 pub(crate) struct Minute {
175 pub(crate) padding: Padding = Padding::Zero,
176 }
177}
178
179to_tokens! {
180 pub(crate) struct Period {
181 pub(crate) is_uppercase: bool = true,
182 pub(crate) case_sensitive: bool = true,
183 }
184}
185
186to_tokens! {
187 pub(crate) struct Second {
188 pub(crate) padding: Padding = Padding::Zero,
189 }
190}
191
192to_tokens! {
193 pub(crate) enum SubsecondDigits {
194 One,
195 Two,
196 Three,
197 Four,
198 Five,
199 Six,
200 Seven,
201 Eight,
202 Nine,
203 OneOrMore,
204 }
205}
206
207to_tokens! {
208 pub(crate) struct Subsecond {
209 pub(crate) digits: SubsecondDigits = SubsecondDigits::OneOrMore,
210 }
211}
212
213to_tokens! {
214 pub(crate) struct OffsetHour {
215 pub(crate) sign_is_mandatory: bool = false,
216 pub(crate) padding: Padding = Padding::Zero,
217 }
218}
219
220to_tokens! {
221 pub(crate) struct OffsetMinute {
222 pub(crate) padding: Padding = Padding::Zero,
223 }
224}
225
226to_tokens! {
227 pub(crate) struct OffsetSecond {
228 pub(crate) padding: Padding = Padding::Zero,
229 }
230}
231
232to_tokens! {
233 pub(crate) enum Padding {
234 Space,
235 Zero,
236 None,
237 }
238}
239
240pub(crate) struct Ignore {
241 pub(crate) count: NonZero<u16>,
242}
243
244impl ToTokenTree for Ignore {
245 fn into_token_tree(self) -> TokenTree {
246 quote_group! {{
247 Ignore::count(#(self.count))
248 }}
249 }
250}
251
252to_tokens! {
253 pub(crate) enum UnixTimestampPrecision {
254 Second,
255 Millisecond,
256 Microsecond,
257 Nanosecond,
258 }
259}
260
261to_tokens! {
262 pub(crate) struct UnixTimestamp {
263 pub(crate) precision: UnixTimestampPrecision = UnixTimestampPrecision::Second,
264 pub(crate) sign_is_mandatory: bool = false,
265 }
266}
267
268to_tokens! {
269 pub(crate) struct End {}
270}