1 | use std::num::NonZeroU16; |
2 | |
3 | use proc_macro::{Ident, Span, TokenStream, TokenTree}; |
4 | |
5 | use crate::to_tokens::{ToTokenStream, ToTokenTree}; |
6 | |
7 | macro_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 |
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 mut tokens = TokenStream::new(); |
24 | let Self {$($field_name),*} = self; |
25 | |
26 | quote_append! { tokens |
27 | let mut value = ::time::format_description::modifier::$struct_name::default(); |
28 | }; |
29 | $( |
30 | quote_append!(tokens value.$field_name =); |
31 | $field_name.append_to(&mut tokens); |
32 | quote_append!(tokens ;); |
33 | )* |
34 | quote_append!(tokens value); |
35 | |
36 | proc_macro::TokenTree::Group(proc_macro::Group::new( |
37 | proc_macro::Delimiter::Brace, |
38 | tokens, |
39 | )) |
40 | } |
41 | } |
42 | }; |
43 | |
44 | ( |
45 | $(#[$enum_attr:meta])* |
46 | $enum_vis:vis enum $enum_name:ident {$( |
47 | $(#[$variant_attr:meta])* |
48 | $variant_name:ident |
49 | ),+ $(,)?} |
50 | ) => { |
51 | $(#[$enum_attr])* |
52 | $enum_vis enum $enum_name {$( |
53 | $(#[$variant_attr])* |
54 | $variant_name |
55 | ),+} |
56 | |
57 | impl ToTokenStream for $enum_name { |
58 | fn append_to(self, ts: &mut TokenStream) { |
59 | quote_append! { ts |
60 | ::time::format_description::modifier::$enum_name:: |
61 | }; |
62 | let name = match self { |
63 | $(Self::$variant_name => stringify!($variant_name)),+ |
64 | }; |
65 | ts.extend([TokenTree::Ident(Ident::new(name, Span::mixed_site()))]); |
66 | } |
67 | } |
68 | } |
69 | } |
70 | |
71 | to_tokens! { |
72 | pub(crate) struct Day { |
73 | pub(crate) padding: Padding, |
74 | } |
75 | } |
76 | |
77 | to_tokens! { |
78 | pub(crate) enum MonthRepr { |
79 | Numerical, |
80 | Long, |
81 | Short, |
82 | } |
83 | } |
84 | |
85 | to_tokens! { |
86 | pub(crate) struct Month { |
87 | pub(crate) padding: Padding, |
88 | pub(crate) repr: MonthRepr, |
89 | pub(crate) case_sensitive: bool, |
90 | } |
91 | } |
92 | |
93 | to_tokens! { |
94 | pub(crate) struct Ordinal { |
95 | pub(crate) padding: Padding, |
96 | } |
97 | } |
98 | |
99 | to_tokens! { |
100 | pub(crate) enum WeekdayRepr { |
101 | Short, |
102 | Long, |
103 | Sunday, |
104 | Monday, |
105 | } |
106 | } |
107 | |
108 | to_tokens! { |
109 | pub(crate) struct Weekday { |
110 | pub(crate) repr: WeekdayRepr, |
111 | pub(crate) one_indexed: bool, |
112 | pub(crate) case_sensitive: bool, |
113 | } |
114 | } |
115 | |
116 | to_tokens! { |
117 | pub(crate) enum WeekNumberRepr { |
118 | Iso, |
119 | Sunday, |
120 | Monday, |
121 | } |
122 | } |
123 | |
124 | to_tokens! { |
125 | pub(crate) struct WeekNumber { |
126 | pub(crate) padding: Padding, |
127 | pub(crate) repr: WeekNumberRepr, |
128 | } |
129 | } |
130 | |
131 | to_tokens! { |
132 | pub(crate) enum YearRepr { |
133 | Full, |
134 | Century, |
135 | LastTwo, |
136 | } |
137 | } |
138 | |
139 | to_tokens! { |
140 | pub(crate) struct Year { |
141 | pub(crate) padding: Padding, |
142 | pub(crate) repr: YearRepr, |
143 | pub(crate) iso_week_based: bool, |
144 | pub(crate) sign_is_mandatory: bool, |
145 | } |
146 | } |
147 | |
148 | to_tokens! { |
149 | pub(crate) struct Hour { |
150 | pub(crate) padding: Padding, |
151 | pub(crate) is_12_hour_clock: bool, |
152 | } |
153 | } |
154 | |
155 | to_tokens! { |
156 | pub(crate) struct Minute { |
157 | pub(crate) padding: Padding, |
158 | } |
159 | } |
160 | |
161 | to_tokens! { |
162 | pub(crate) struct Period { |
163 | pub(crate) is_uppercase: bool, |
164 | pub(crate) case_sensitive: bool, |
165 | } |
166 | } |
167 | |
168 | to_tokens! { |
169 | pub(crate) struct Second { |
170 | pub(crate) padding: Padding, |
171 | } |
172 | } |
173 | |
174 | to_tokens! { |
175 | pub(crate) enum SubsecondDigits { |
176 | One, |
177 | Two, |
178 | Three, |
179 | Four, |
180 | Five, |
181 | Six, |
182 | Seven, |
183 | Eight, |
184 | Nine, |
185 | OneOrMore, |
186 | } |
187 | } |
188 | |
189 | to_tokens! { |
190 | pub(crate) struct Subsecond { |
191 | pub(crate) digits: SubsecondDigits, |
192 | } |
193 | } |
194 | |
195 | to_tokens! { |
196 | pub(crate) struct OffsetHour { |
197 | pub(crate) sign_is_mandatory: bool, |
198 | pub(crate) padding: Padding, |
199 | } |
200 | } |
201 | |
202 | to_tokens! { |
203 | pub(crate) struct OffsetMinute { |
204 | pub(crate) padding: Padding, |
205 | } |
206 | } |
207 | |
208 | to_tokens! { |
209 | pub(crate) struct OffsetSecond { |
210 | pub(crate) padding: Padding, |
211 | } |
212 | } |
213 | |
214 | to_tokens! { |
215 | pub(crate) enum Padding { |
216 | Space, |
217 | Zero, |
218 | None, |
219 | } |
220 | } |
221 | |
222 | pub(crate) struct Ignore { |
223 | pub(crate) count: NonZeroU16, |
224 | } |
225 | |
226 | impl ToTokenTree for Ignore { |
227 | fn into_token_tree(self) -> TokenTree { |
228 | quote_group! {{ |
229 | ::time::format_description::modifier::Ignore::count(#(self.count)) |
230 | }} |
231 | } |
232 | } |
233 | |
234 | to_tokens! { |
235 | pub(crate) enum UnixTimestampPrecision { |
236 | Second, |
237 | Millisecond, |
238 | Microsecond, |
239 | Nanosecond, |
240 | } |
241 | } |
242 | |
243 | to_tokens! { |
244 | pub(crate) struct UnixTimestamp { |
245 | pub(crate) precision: UnixTimestampPrecision, |
246 | pub(crate) sign_is_mandatory: bool, |
247 | } |
248 | } |
249 | |
250 | to_tokens! { |
251 | pub(crate) struct End {} |
252 | } |
253 | |