1macro_rules! as_ref_borrow_cast {
7 ($parent:ty: $($cast:ident $ty:ty),+ $(,)?) => ($(
8 impl AsRef<$ty> for $parent {
9 #[inline]
10 fn as_ref(&self) -> &$ty { self.$cast() }
11 }
12
13 impl ::std::borrow::Borrow<$ty> for $parent {
14 #[inline]
15 fn borrow(&self) -> &$ty { self.$cast() }
16 }
17 )+);
18}
19
20macro_rules! display_str {
22 ($cast:ident $ty:ty) => (
23 impl ::std::fmt::Display for $ty {
24 #[inline]
25 fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
26 <str as ::std::fmt::Display>::fmt(self.$cast(), f)
27 }
28 }
29 );
30}
31
32macro_rules! first {
34 (@$mac:ident $first:tt $($_rest:tt)*) => ( $mac!($first) );
36
37 ($first:tt $($_rest:tt)*) => ( $first );
39}
40
41macro_rules! last {
43 (@$mac:ident $last:tt) => ( $mac!($last) );
45 (@$mac:ident $_next:tt $($rest:tt)+) => ( $crate::macros::last!(@$mac $($rest)+) );
46
47 ($last:tt) => ( $last );
49 ($_next:tt $($rest:tt)+) => ( $crate::macros::last!($($rest)+) );
50}
51
52macro_rules! pair {
57 (
59 @previous $dst:ident { $($args:tt)* }
60 $k1:ident $k2:ident $k3:ident $k4:ident $k5:ident $k6:ident $k7:ident
61 ) => (
62 $crate::macros::$dst!(
63 $($args)*
64 ($k1 $k7), ($k2 $k1), ($k3 $k2), ($k4 $k3), ($k5 $k4), ($k6 $k5),
65 ($k7 $k6),
66 )
67 );
68 (
69 @previous $dst:ident { $($args:tt)* }
70 $k1:ident $k2:ident $k3:ident $k4:ident $k5:ident $k6:ident $k7:ident $k8:ident $k9:ident $k10:ident $k11:ident $k12:ident
71 ) => (
72 $crate::macros::$dst!(
73 $($args)*
74 ($k1 $k12), ($k2 $k1), ($k3 $k2), ($k4 $k3), ($k5 $k4), ($k6 $k5),
75 ($k7 $k6), ($k8 $k7), ($k9 $k8), ($k10 $k9), ($k11 $k10), ($k12 $k11),
76 )
77 );
78
79 (
81 @next $dst:ident { $($args:tt)* }
82 $k1:ident $k2:ident $k3:ident $k4:ident $k5:ident $k6:ident $k7:ident
83 ) => (
84 $crate::macros::$dst!(
85 $($args)*
86 ($k1 $k2), ($k2 $k3), ($k3 $k4), ($k4 $k5), ($k5 $k6), ($k6 $k7),
87 ($k7 $k1),
88 )
89 );
90 (
91 @next $dst:ident { $($args:tt)* }
92 $k1:ident $k2:ident $k3:ident $k4:ident $k5:ident $k6:ident $k7:ident $k8:ident $k9:ident $k10:ident $k11:ident $k12:ident
93 ) => (
94 $crate::macros::$dst!(
95 $($args)*
96 ($k1 $k2), ($k2 $k3), ($k3 $k4), ($k4 $k5), ($k5 $k6), ($k6 $k7),
97 ($k7 $k8), ($k8 $k9), ($k9 $k10), ($k10 $k11), ($k11 $k12), ($k12 $k1),
98 )
99 );
100}
101
102macro_rules! weekmonth {
149 (@ex @range $ty:tt $($k:ident $v:literal)+) => (concat!(
151 stringify!($ty), "s range from `",
152 $crate::macros::first!(@stringify $($v)+),
153 "..=",
154 $crate::macros::last!(@stringify $($v)+),
155 "`, starting with ",
156 $crate::macros::first!(@stringify $($k)+),
157 ".",
158 ));
159
160 (@ex @addsub $uint:tt $ty:tt $op:literal $(($v:literal $k:ident $com:literal)),+ $(,)?) => (
162 concat!(
163 "let start = ", stringify!($ty), "::", $crate::macros::first!(@stringify $($k)+), ";\n",
164 $(
165 "assert_eq!(start ", $op, " ", $v, "_", stringify!($uint), ", ", stringify!($ty), "::", stringify!($k), "); ", $com, "\n",
166 )+
167 "// …\n",
168 )
169 );
170 (@ex @add $uint:tt $ty:tt $k1:ident $k2:ident $k3:ident $k4:ident $k5:ident $k6:ident $k7:ident) => (
171 $crate::macros::weekmonth!(
172 @ex @addsub
173 $uint $ty "+"
174 (0 $k1 "// Noop."),
175 (1 $k2 ""), (2 $k3 ""), (3 $k4 ""), (4 $k5 ""), (5 $k6 ""), (6 $k7 ""),
176 (7 $k1 "// Wrap."), (8 $k2 "// Wrap."), (9 $k3 "// Wrap."),
177 )
178 );
179 (@ex @add $uint:tt $ty:tt $k1:ident $k2:ident $k3:ident $k4:ident $k5:ident $k6:ident $k7:ident $k8:ident $k9:ident $k10:ident $k11:ident $k12:ident) => (
180 $crate::macros::weekmonth!(
181 @ex @addsub
182 $uint $ty "+"
183 (0 $k1 "// Noop."),
184 (1 $k2 ""), (2 $k3 ""), (3 $k4 ""), (4 $k5 ""), (5 $k6 ""), (6 $k7 ""),
185 (7 $k8 ""), (8 $k9 ""), (9 $k10 ""), (10 $k11 ""), (11 $k12 ""),
186 (12 $k1 "// Wrap."), (13 $k2 "// Wrap."), (14 $k3 "// Wrap."),
187 )
188 );
189 (@ex @sub $uint:tt $ty:tt $k1:ident $k2:ident $k3:ident $k4:ident $k5:ident $k6:ident $k7:ident) => (
190 $crate::macros::weekmonth!(
191 @ex @addsub
192 $uint $ty "-"
193 (0 $k1 "// Noop."),
194 (1 $k7 ""), (2 $k6 ""), (3 $k5 ""), (4 $k4 ""), (5 $k3 ""), (6 $k2 ""),
195 (7 $k1 "// Wrap."), (8 $k7 "// Wrap."), (9 $k6 "// Wrap."),
196 )
197 );
198 (@ex @sub $uint:tt $ty:tt $k1:ident $k2:ident $k3:ident $k4:ident $k5:ident $k6:ident $k7:ident $k8:ident $k9:ident $k10:ident $k11:ident $k12:ident) => (
199 $crate::macros::weekmonth!(
200 @ex @addsub
201 $uint $ty "-"
202 (0 $k1 "// Noop."),
203 (1 $k12 ""), (2 $k11 ""), (3 $k10 ""), (4 $k9 ""), (5 $k8 ""), (6 $k7 ""),
204 (7 $k6 ""), (8 $k5 ""), (9 $k4 ""), (10 $k3 ""), (11 $k2 ""),
205 (12 $k1 "// Wrap."), (13 $k12 "// Wrap."), (14 $k11 "// Wrap."),
206 )
207 );
208
209 (@ex @from_a $uint:tt $ty:tt $k1:ident $k2:ident $k3:ident $k4:ident $k5:ident $k6:ident $k7:ident) => (
211 concat!(
212 "assert_eq!(", stringify!($ty), "::from(8_", stringify!($uint), "), ", stringify!($ty), "::", stringify!($k1), "); // Wrap.\n",
213 "assert_eq!(", stringify!($ty), "::from(9_", stringify!($uint), "), ", stringify!($ty), "::", stringify!($k2), "); // Wrap.\n",
214 "assert_eq!(", stringify!($ty), "::from(10_", stringify!($uint), "), ", stringify!($ty), "::", stringify!($k3), "); // Wrap.\n",
215 "// …\n",
216 )
217 );
218 (@ex @from_a $uint:tt $ty:tt $k1:ident $k2:ident $k3:ident $k4:ident $k5:ident $k6:ident $k7:ident $k8:ident $k9:ident $k10:ident $k11:ident $k12:ident) => (
219 concat!(
220 "assert_eq!(", stringify!($ty), "::from(13_", stringify!($uint), "), ", stringify!($ty), "::", stringify!($k1), "); // Wrap.\n",
221 "assert_eq!(", stringify!($ty), "::from(14_", stringify!($uint), "), ", stringify!($ty), "::", stringify!($k2), "); // Wrap.\n",
222 "assert_eq!(", stringify!($ty), "::from(15_", stringify!($uint), "), ", stringify!($ty), "::", stringify!($k3), "); // Wrap.\n",
223 "// …\n",
224 )
225 );
226
227 (@ex @pairs $ty:ident $fn:literal $(($from:ident $to:ident)),+ $(,)?) => (concat!(
229 $(
230 "assert_eq!(",
231 stringify!($ty), "::", stringify!($from), ".", $fn, "(), ",
232 stringify!($ty), "::", stringify!($to),
233 ");\n",
234 )+
235 ));
236
237 (@ex @next $ty:tt $(($k:ident $com:literal)),+ $(,)?) => (concat!(
239 $(
240 "assert_eq!(iter.next(), Some(", stringify!($ty), "::", stringify!($k), ")); ", $com, "\n",
241 )+
242 ));
243
244 (@ex @iter $ty:tt $k1:ident $k2:ident $k3:ident $k4:ident $k5:ident $k6:ident $k7:ident) => (concat!(
246 "let mut iter = ", stringify!($ty), "::", stringify!($k1), ".into_iter();\n",
247 $crate::macros::weekmonth!(
248 @ex @next $ty
249 ($k1 ""), ($k2 ""), ($k3 ""), ($k4 ""), ($k5 ""), ($k6 ""), ($k7 ""),
250 ($k1 "// Wrap."), ($k2 "// Wrap."), ($k3 "// Wrap."),
251 ),
252 "// …\n\n",
253 "// Or like Ginger, backwards and in high heels.\n",
254 "let mut iter = ", stringify!($ty), "::", stringify!($k7), ".into_iter().rev();\n",
255 $crate::macros::weekmonth!(
256 @ex @next $ty
257 ($k7 ""), ($k6 ""), ($k5 ""), ($k4 ""), ($k3 ""), ($k2 ""), ($k1 ""),
258 ($k7 "// Wrap."), ($k6 "// Wrap."), ($k5 "// Wrap."),
259 ),
260 "// …\n",
261 ));
262 (@ex @iter $ty:tt $k1:ident $k2:ident $k3:ident $k4:ident $k5:ident $k6:ident $k7:ident $k8:ident $k9:ident $k10:ident $k11:ident $k12:ident) => (concat!(
263 "let mut iter = ", stringify!($ty), "::", stringify!($k1), ".into_iter();\n",
264 $crate::macros::weekmonth!(
265 @ex @next $ty
266 ($k1 ""), ($k2 ""), ($k3 ""), ($k4 ""), ($k5 ""), ($k6 ""), ($k7 ""),
267 ($k8 ""), ($k9 ""), ($k10 ""), ($k11 ""), ($k12 ""),
268 ($k1 "// Wrap."), ($k2 "// Wrap."), ($k3 "// Wrap."),
269 ),
270 "// …\n\n",
271 "// Or like Ginger:\n",
272 "let mut iter = ", stringify!($ty), "::", stringify!($k12), ".into_iter().rev();\n",
273 $crate::macros::weekmonth!(
274 @ex @next $ty
275 ($k12 ""), ($k11 ""), ($k10 ""), ($k9 ""), ($k8 ""), ($k7 ""), ($k6 ""),
276 ($k5 ""), ($k4 ""), ($k3 ""), ($k2 ""), ($k1 ""),
277 ($k12 "// Wrap."), ($k11 "// Wrap."), ($k10 "// Wrap."),
278 ),
279 "// …\n",
280 ));
281
282 (@wrong Month) => ( "Janissary" );
284 (@wrong Weekday) => ( "Sunlight" );
285
286 (@pairs $src:ident $(($from:ident $to:ident)),+ $(,)?) => (
288 match $src {
289 $( Self::$from => Self::$to, )+
290 }
291 );
292
293 (@add $uint:tt $ty:tt $( $k:ident $v:literal)+) => (
295 impl ::std::ops::Add<$uint> for $ty {
296 type Output = Self;
297
298 #[inline]
299 #[doc = concat!(
300 "# Wrapping `", stringify!($uint), "` Addition.\n\n",
301
302 $crate::macros::weekmonth!(@ex @range $ty $($k $v)+), "\n\n",
303
304 "## Examples\n\n",
305
306 "```\n",
307 "use utc2k::", stringify!($ty), ";\n\n",
308 $crate::macros::weekmonth!(@ex @add $uint $ty $($k)+),
309 "```",
310 )]
311 fn add(self, other: $uint) -> Self {
312 Self::from(self as $uint + other % $crate::macros::last!($($v)+),)
313 }
314 }
315
316 impl ::std::ops::AddAssign<$uint> for $ty {
317 #[inline]
318 fn add_assign(&mut self, other: $uint) { *self = *self + other; }
319 }
320 );
321
322 (@eq $uint:ident $ty:ident $( $k:ident $v:literal)+) => (
324 impl PartialEq<$uint> for $ty {
325 #[inline]
326 #[doc = concat!(
327 "# `", stringify!($ty), "`/`", stringify!($uint), "` Equality.\n\n",
328 "```\n",
329 "use utc2k::", stringify!($ty), ";\n\n",
330 $(
331 "assert_eq!(", stringify!($ty), "::", stringify!($k), ", ", stringify!($v), "_", stringify!($uint), ");\n",
332 )+
333 "\n// Nope.\n",
334 "assert_ne!(", stringify!($ty), "::", $crate::macros::first!(@stringify $($k)+), ", ", stringify!($uint), "::MIN);\n",
335 "```",
336 )]
337 fn eq(&self, other: &$uint) -> bool { (*self as $uint) == *other }
338 }
339
340 impl PartialEq<$ty> for $uint {
341 #[inline]
342 #[doc = concat!(
343 "# `", stringify!($uint), "`/`", stringify!($ty), "` Equality.\n\n",
344 "```\n",
345 "use utc2k::", stringify!($ty), ";\n\n",
346 $(
347 "assert_eq!(", stringify!($v), "_", stringify!($uint), ", ", stringify!($ty), "::", stringify!($k), ");\n",
348 )+
349 "```",
350 "\n// Nope.\n",
351 "assert_ne!(", stringify!($uint), "::MIN, ", stringify!($ty), "::", $crate::macros::first!(@stringify $($k)+), ");\n",
352 )]
353 fn eq(&self, other: &$ty) -> bool { <$ty as PartialEq<$uint>>::eq(other, self) }
354 }
355 );
356
357 (@from $uint:ident $ty:ident $( $k:ident $v:literal )+ @last $k_last:ident $v_last:literal) => (
359 impl From<$uint> for $ty {
360 #[inline]
361 #[doc = concat!(
362 "# `", stringify!($ty), "` From `", stringify!($uint), "` (Wrapping).\n\n",
363
364 $crate::macros::weekmonth!(@ex @range $ty $($k $v)+ $k_last $v_last), "\n\n",
365
366 "## Examples\n\n",
367
368 "```\n",
369 "use utc2k::", stringify!($ty), ";\n\n",
370 "assert_eq!(", stringify!($ty), "::from(0_", stringify!($uint), "), ", stringify!($ty), "::", stringify!($k_last), "); // Wrap.\n",
371 $(
372 "assert_eq!(", stringify!($ty), "::from(", stringify!($v), "_", stringify!($uint), "), ", stringify!($ty), "::", stringify!($k), ");\n",
373 )+
374 "assert_eq!(", stringify!($ty), "::from(", stringify!($v_last), "_", stringify!($uint), "), ", stringify!($ty), "::", stringify!($k_last), ");\n",
375 $crate::macros::weekmonth!(@ex @from_a $uint $ty $($k)+ $k_last ),
376 "```",
377 )]
378 fn from(src: $uint) -> Self {
379 match src % $v_last {
380 $( $v => Self::$k ),+,
381 _ => Self::$k_last,
382 }
383 }
384 }
385
386 impl From<$ty> for $uint {
387 #[inline]
388 #[doc = concat!(
389 "# `", stringify!($uint), "` From `", stringify!($ty), "`.\n\n",
390
391 $crate::macros::weekmonth!(@ex @range $ty $($k $v)+ $k_last $v_last), "\n\n",
392
393 "## Examples\n\n",
394
395 "```\n",
396 "use utc2k::", stringify!($ty), ";\n\n",
397 $(
398 "assert_eq!(", stringify!($uint), "::from(", stringify!($ty), "::", stringify!($k), "), ", stringify!($v), ");\n",
399 )+
400 "assert_eq!(", stringify!($uint), "::from(", stringify!($ty), "::", stringify!($k_last), "), ", stringify!($v_last), ");\n\n",
401 "// Same as `as` casting.\n",
402 "for v in ", stringify!($ty), "::ALL {\n",
403 " assert_eq!(", stringify!($uint), "::from(v), v as ", stringify!($uint), ");\n",
404 "}\n",
405 "```",
406 )]
407 fn from(src: $ty) -> Self {
408 match src {
409 $( <$ty>::$k => $v ),+,
410 <$ty>::$k_last => $v_last,
411 }
412 }
413 }
414 );
415 (
416 @from $uint:ident $ty:ident
417 $k1:ident $v1:literal $k2:ident $v2:literal $k3:ident $v3:literal $k4:ident $v4:literal $k5:ident $v5:literal $k6:ident $v6:literal $k7:ident $v7:literal
418 ) => (
419 $crate::macros::weekmonth!(
420 @from $uint $ty
421 $k1 $v1 $k2 $v2 $k3 $v3 $k4 $v4 $k5 $v5 $k6 $v6
422 @last $k7 $v7
423 );
424 );
425 (
426 @from $uint:ident $ty:ident
427 $k1:ident $v1:literal $k2:ident $v2:literal $k3:ident $v3:literal $k4:ident $v4:literal $k5:ident $v5:literal $k6:ident $v6:literal
428 $k7:ident $v7:literal $k8:ident $v8:literal $k9:ident $v9:literal $k10:ident $v10:literal $k11:ident $v11:literal $k12:ident $v12:literal
429 ) => (
430 $crate::macros::weekmonth!(
431 @from $uint $ty
432 $k1 $v1 $k2 $v2 $k3 $v3 $k4 $v4 $k5 $v5 $k6 $v6
433 $k7 $v7 $k8 $v8 $k9 $v9 $k10 $v10 $k11 $v11
434 @last $k12 $v12
435 );
436 );
437
438 (@from_u8 $ty:ident $($k:ident $v:literal)+ @last $k_last:ident $v_last:literal) => (
440 impl $ty {
441 #[inline]
442 #[must_use]
443 pub(crate) const fn from_u8(src: u8) -> Self {
445 match src % $v_last {
446 $( $v => Self::$k ),+,
447 _ => Self::$k_last,
448 }
449 }
450 }
451 );
452 (
453 @from_u8 $ty:ident
454 $k1:ident $v1:literal $k2:ident $v2:literal $k3:ident $v3:literal $k4:ident $v4:literal $k5:ident $v5:literal $k6:ident $v6:literal $k7:ident $v7:literal
455 ) => (
456 $crate::macros::weekmonth!(
457 @from_u8 $ty
458 $k1 $v1 $k2 $v2 $k3 $v3 $k4 $v4 $k5 $v5 $k6 $v6
459 @last $k7 $v7
460 );
461 );
462 (
463 @from_u8 $ty:ident
464 $k1:ident $v1:literal $k2:ident $v2:literal $k3:ident $v3:literal $k4:ident $v4:literal $k5:ident $v5:literal $k6:ident $v6:literal
465 $k7:ident $v7:literal $k8:ident $v8:literal $k9:ident $v9:literal $k10:ident $v10:literal $k11:ident $v11:literal $k12:ident $v12:literal
466 ) => (
467 $crate::macros::weekmonth!(
468 @from_u8 $ty
469 $k1 $v1 $k2 $v2 $k3 $v3 $k4 $v4 $k5 $v5 $k6 $v6
470 $k7 $v7 $k8 $v8 $k9 $v9 $k10 $v10 $k11 $v11
471 @last $k12 $v12
472 );
473 );
474
475 (@sub $uint:tt $ty:tt $k_first:ident $v_first:literal ($sub1_first:literal $sub2_first:literal), $( $k:ident $v:literal ($sub1:literal $sub2:literal) ),+ $(,)?) => (
477 impl ::std::ops::Sub<$uint> for $ty {
478 type Output = Self;
479
480 #[inline]
481 #[doc = concat!(
482 "# Wrapping `", stringify!($uint), "` Subtraction.\n\n",
483
484 $crate::macros::weekmonth!(@ex @range $ty $k_first $v_first $($k $v)+), "\n\n",
485
486 "## Examples\n\n",
487
488 "```\n",
489 "use utc2k::", stringify!($ty), ";\n\n",
490 $crate::macros::weekmonth!(@ex @sub $uint $ty $k_first $($k)+),
491 "```",
492 )]
493 fn sub(self, other: $uint) -> Self {
494 match (self as u8 - 1).wrapping_sub((other % $crate::macros::last!($($v)+)) as u8) {
495 0 => Self::$k_first,
496 $( $sub1 | $sub2 => Self::$k ),+,
497 _ => unreachable!(),
498 }
499 }
500 }
501
502 impl ::std::ops::SubAssign<$uint> for $ty {
503 #[inline]
504 fn sub_assign(&mut self, other: $uint) { *self = *self - other; }
505 }
506 );
507
508 (@try_from @as_bytes $ty:tt $($from:ty)+) => ($(
510 impl TryFrom<$from> for $ty {
511 type Error = Utc2kError;
512
513 #[inline]
514 fn try_from(src: $from) -> Result<Self, Self::Error> {
515 Self::try_from(src.as_bytes())
516 }
517 }
518 )+);
519
520 (@int $uint:ident $ty:ident $( $k:ident $v:literal ($sub1:literal $sub2:literal) ),+ $(,)?) => (
522 $crate::macros::weekmonth!(@add $uint $ty $($k $v)+);
523 $crate::macros::weekmonth!(@eq $uint $ty $($k $v)+);
524 $crate::macros::weekmonth!(@from $uint $ty $($k $v)+);
525 $crate::macros::weekmonth!(@sub $uint $ty $($k $v ($sub1 $sub2)),+);
526 );
527
528 ($ty:tt $lower:ident $iter:ident $($k:ident $v:literal $abbr:literal ($sub1:literal $sub2:literal)),+ $(,)?) => (
530 #[expect(missing_docs, reason = "Redundant.")]
531 #[repr(u8)]
532 #[derive(Debug, Clone, Copy, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
533 #[doc = concat!(
534 "# ", stringify!($ty), ".\n\n",
535
536 "This enum is used by [`Utc2k`] to differentiate between calendar ", stringify!($lower), "s.\n\n",
537
538 "## Examples\n\n",
539
540 "```\n",
541 "use utc2k::", stringify!($ty), ";\n\n",
542 "// The first.\n",
543 "# assert_eq!(", stringify!($ty), "::default(), ", stringify!($ty), "::", $crate::macros::first!(@stringify $($k)+), ");\n",
544 "assert_eq!(", stringify!($ty) ,"::", $crate::macros::first!(@stringify $($k)+), " as u8, 1_u8);\n",
545 "assert_eq!(", stringify!($ty) ,"::", $crate::macros::first!(@stringify $($k)+), ".as_str(), \"", $crate::macros::first!(@stringify $($k)+), "\");\n",
546 "assert_eq!(", stringify!($ty) ,"::", $crate::macros::first!(@stringify $($k)+), ".abbreviation(), \"", $crate::macros::first!($($abbr)+), "\");\n\n",
547 "// The last.\n",
548 "assert_eq!(", stringify!($ty) ,"::", $crate::macros::last!(@stringify $($k)+), " as u8, ", $crate::macros::last!(@stringify $($v)+), "_u8);\n",
549 "assert_eq!(", stringify!($ty) ,"::", $crate::macros::last!(@stringify $($k)+), ".as_str(), \"", $crate::macros::last!(@stringify $($k)+), "\");\n",
550 "assert_eq!(", stringify!($ty) ,"::", $crate::macros::last!(@stringify $($k)+), ".abbreviation(), \"", $crate::macros::last!($($abbr)+), "\");\n",
551 "```",
552 )]
553 pub enum $ty {
554 #[default]
555 $( $k = $v ),+
556 }
557
558 $crate::macros::as_ref_borrow_cast!($ty: as_str str);
559 $crate::macros::display_str!(as_str $ty);
560 $crate::macros::weekmonth!(
561 @try_from @as_bytes $ty
562 &str &String String &std::borrow::Cow<'_, str>
563 std::borrow::Cow<'_, str> &Box<str> Box<str>
564 );
565
566 impl From<Utc2k> for $ty {
567 #[inline]
568 #[doc = concat!(
569 "# From [`Utc2k`].\n\n",
570
571 "This is equivalent to calling [`Utc2k::", stringify!($lower), "`].\n\n",
572
573 "## Examples\n\n",
574
575 "```\n",
576 "use utc2k::{", stringify!($ty), ", Utc2k};\n\n",
577 "let utc = Utc2k::new(2030, 1, 6, 0, 0, 0);\n",
578 "assert_eq!(", stringify!($ty), "::", $crate::macros::first!(@stringify $($k)+), ", ", stringify!($ty), "::from(utc));\n",
579 "assert_eq!(", stringify!($ty), "::", $crate::macros::first!(@stringify $($k)+), ", utc.", stringify!($lower), "());\n",
580 "```",
581 )]
582 fn from(src: Utc2k) -> Self { src.$lower() }
583 }
584
585 impl ::std::str::FromStr for $ty {
586 type Err = Utc2kError;
587
588 #[inline]
589 #[doc = concat!(
590 "# Parse From String.\n\n",
591
592 "Parse a `", stringify!($ty), "` from the first three letters \
593 of a string, case-insensitively.\n\n",
594
595 "## Examples\n\n",
596
597 "```\n",
598 "use utc2k::", stringify!($ty), ";\n\n",
599 "for v in ", stringify!($ty), "::ALL {\n",
600 " assert_eq!(v.as_str().parse::<", stringify!($ty), ">(), Ok(v));\n",
601 " assert_eq!(v.abbreviation().parse::<", stringify!($ty), ">(), Ok(v));\n",
602 "}\n\n",
603 "// Remember that only the first three letters count!\n",
604 "assert_eq!(\"", $crate::macros::weekmonth!(@wrong $ty), "\".parse::<", stringify!($ty), ">(), Ok(", stringify!($ty), "::", $crate::macros::first!(@stringify $($k)+), "));\n",
605 "```",
606 )]
607 fn from_str(src: &str) -> Result<Self, Self::Err> { Self::try_from(src) }
608 }
609
610 impl IntoIterator for $ty {
611 type Item = Self;
612 type IntoIter = $iter;
613
614 #[inline]
615 #[doc = concat!(
616 "# Endless `", stringify!($ty), "` Iterator.\n\n",
617
618 "Return an iterator that will cycle endlessly through the ", stringify!($lower), "s, \
619 in order, forward or backward, starting with `self`.\n\n",
620
621 "## Examples\n\n",
622
623 "```\n",
624 "use utc2k::", stringify!($ty), ";\n\n",
625 $crate::macros::weekmonth!(@ex @iter $ty $($k)+),
626 "```",
627 )]
628 fn into_iter(self) -> Self::IntoIter { $iter(self) }
629 }
630
631 $crate::macros::weekmonth!(@int u8 $ty $($k $v ($sub1 $sub2)),+);
632 $crate::macros::weekmonth!(@int u16 $ty $($k $v ($sub1 $sub2)),+);
633 $crate::macros::weekmonth!(@int u32 $ty $($k $v ($sub1 $sub2)),+);
634 $crate::macros::weekmonth!(@int u64 $ty $($k $v ($sub1 $sub2)),+);
635 $crate::macros::weekmonth!(@int usize $ty $($k $v ($sub1 $sub2)),+);
636
637 impl $ty {
638 #[doc = concat!(
639 "# All ", stringify!($ty), "s.\n\n",
640 "This array contains all of the ", stringify!($lower), "s, in order.\n\n",
641 "## Examples\n\n",
642 "```\n",
643 "# assert!(utc2k::", stringify!($ty), "::ALL.is_sorted());\n",
644 "for pair in utc2k::", stringify!($ty), "::ALL.windows(2) {\n",
645 " assert!(pair[0] < pair[1]);\n",
646 "}\n",
647 "```",
648 )]
649 pub const ALL: [Self; $crate::macros::last!($($v)+)] = [ $( Self::$k ),+ ];
650
651 #[inline]
652 #[must_use]
653 #[doc = concat!(
654 "# As String Slice (Abbreviated).\n\n",
655
656 "Return the three-letter abbreviation for a given ", stringify!($lower), " as a static string slice.\n\n",
657
658 "## Examples\n\n",
659
660 "```\n",
661 "use utc2k::", stringify!($ty), ";\n\n",
662 $(
663 "assert_eq!(", stringify!($ty), "::", stringify!($k), ".abbreviation(), \"", $abbr, "\");\n",
664 )+
665 "# for v in ", stringify!($ty), "::ALL {\n",
666 "# assert_eq!(v.abbreviation(), &v.as_str()[..3]);\n",
667 "# }\n",
668 "```",
669 )]
670 pub const fn abbreviation(self) -> &'static str {
671 match self {
672 $( Self::$k => $abbr ),+
673 }
674 }
675
676 #[inline]
677 #[must_use]
678 #[doc = concat!(
679 "# As String Slice.\n\n",
680
681 "Return the name of a given ", stringify!($lower), " as a static string slice.\n\n",
682
683 "## Examples\n\n",
684
685 "```\n",
686 "use utc2k::", stringify!($ty), ";\n\n",
687 $(
688 "assert_eq!(", stringify!($ty), "::", stringify!($k), ".as_str(), \"", stringify!($k), "\");\n",
689 )+
690 "```",
691 )]
692 pub const fn as_str(self) -> &'static str {
693 match self {
694 $( Self::$k => stringify!($k) ),+
695 }
696 }
697
698 #[inline]
699 #[must_use]
700 #[doc = concat!(
701 "# Previous ", stringify!($ty), " (Wrapping).\n\n",
702
703 "Return the previous [`", stringify!($ty), "`].\n\n",
704
705 "## Examples\n\n",
706
707 "```\n",
708 "use utc2k::", stringify!($ty), ";\n\n",
709 $crate::macros::pair!(@previous weekmonth { @ex @pairs $ty "previous" } $($k)+), "\n",
710 "// Same as math:\n",
711 "assert_eq!(", stringify!($ty), "::", $crate::macros::first!(@stringify $($k)+), ".previous(), ", stringify!($ty), "::", $crate::macros::first!(@stringify $($k)+), " - 1_u8);\n\n",
712 "// Same as the proper iterator too (provided you skip the first value):\n",
713 "assert_eq!(\n",
714 " Some(", stringify!($ty), "::", $crate::macros::first!(@stringify $($k)+), ".previous()),\n",
715 " ", stringify!($ty), "::", $crate::macros::first!(@stringify $($k)+), ".into_iter().rev().skip(1).next(),\n",
716 ");\n",
717 "```",
718 )]
719 pub const fn previous(self) -> Self {
720 $crate::macros::pair!(@previous weekmonth { @pairs self } $($k)+)
721 }
722
723 #[inline]
724 #[must_use]
725 #[doc = concat!(
726 "# Next ", stringify!($ty), " (Wrapping).\n\n",
727
728 "Return the next [`", stringify!($ty), "`].\n\n",
729
730 "## Examples\n\n",
731
732 "```\n",
733 "use utc2k::", stringify!($ty), ";\n\n",
734 $crate::macros::pair!(@next weekmonth { @ex @pairs $ty "next" } $($k)+), "\n",
735 "// Same as math:\n",
736 "assert_eq!(", stringify!($ty), "::", $crate::macros::first!(@stringify $($k)+), ".next(), ", stringify!($ty), "::", $crate::macros::first!(@stringify $($k)+), " + 1_u8);\n\n",
737 "// Same as the proper iterator too (provided you skip the first value):\n",
738 "assert_eq!(\n",
739 " Some(", stringify!($ty), "::", $crate::macros::first!(@stringify $($k)+), ".next()),\n",
740 " ", stringify!($ty), "::", $crate::macros::first!(@stringify $($k)+), ".into_iter().skip(1).next(),\n",
741 ");\n",
742 "```",
743 )]
744 pub const fn next(self) -> Self {
745 $crate::macros::pair!(@next weekmonth { @pairs self } $($k)+)
746 }
747
748 #[inline]
749 #[must_use]
750 #[doc = concat!(
751 "# Compare Two `", stringify!($ty), "`s.\n\n",
752
753 "Same as `Ord`/`PartialOrd`, but constant.\n\n",
754
755 "## Examples\n\n",
756
757 "```\n",
758 "use utc2k::", stringify!($ty), ";\n\n",
759 "assert_eq!(\n",
760 " ", stringify!($ty), "::", $crate::macros::first!(@stringify $($k)+), ".cmp(&", stringify!($ty), "::", $crate::macros::first!(@stringify $($k)+), "),\n",
761 " ", stringify!($ty), "::cmp(", stringify!($ty), "::", $crate::macros::first!(@stringify $($k)+), ", ", stringify!($ty), "::", $crate::macros::first!(@stringify $($k)+), "), // Ordering::Equal\n",
762 ");\n",
763 "assert_eq!(\n",
764 " ", stringify!($ty), "::", $crate::macros::first!(@stringify $($k)+), ".cmp(&", stringify!($ty), "::", $crate::macros::last!(@stringify $($k)+), "),\n",
765 " ", stringify!($ty), "::cmp(", stringify!($ty), "::", $crate::macros::first!(@stringify $($k)+), ", ", stringify!($ty), "::", $crate::macros::last!(@stringify $($k)+), "), // Ordering::Less\n",
766 ");\n",
767 "assert_eq!(\n",
768 " ", stringify!($ty), "::", $crate::macros::last!(@stringify $($k)+), ".cmp(&", stringify!($ty), "::", $crate::macros::first!(@stringify $($k)+), "),\n",
769 " ", stringify!($ty), "::cmp(", stringify!($ty), "::", $crate::macros::last!(@stringify $($k)+), ", ", stringify!($ty), "::", $crate::macros::first!(@stringify $($k)+), "), // Ordering::Greater\n",
770 ");\n",
771 "```",
772 )]
773 pub const fn cmp(a: Self, b: Self) -> ::std::cmp::Ordering {
774 let a = a as u8;
775 let b = b as u8;
776 if a == b { ::std::cmp::Ordering::Equal }
777 else if a < b { ::std::cmp::Ordering::Less }
778 else { ::std::cmp::Ordering::Greater }
779 }
780 }
781
782 $crate::macros::weekmonth!(@from_u8 $ty $($k $v)+);
783
784 #[derive(Debug, Clone)]
785 #[doc = concat!(
786 "# Endless `", stringify!($ty), "` Iterator.\n\n",
787
788 "This iterator yields infinite [`", stringify!($ty), "`]s, \
789 in order, forward or backward, starting with any arbitrary variant.\n\n",
790
791 "See [`", stringify!($ty), "::into_iter`] for more details.",
792 )]
793 pub struct $iter($ty);
794
795 impl Iterator for $iter {
796 type Item = $ty;
797
798 #[inline]
799 #[doc = concat!("# Next [`", stringify!($ty), "`].")]
800 fn next(&mut self) -> Option<Self::Item> {
801 let next = self.0;
802 self.0 = next + 1_u8;
803 Some(next)
804 }
805
806 #[inline]
807 fn size_hint(&self) -> (usize, Option<usize>) { (usize::MAX, None) }
811 }
812
813 impl DoubleEndedIterator for $iter {
814 #[inline]
815 #[doc = concat!("# Previous [`", stringify!($ty), "`].")]
816 fn next_back(&mut self) -> Option<Self::Item> {
817 let next = self.0;
818 self.0 = next - 1_u8;
819 Some(next)
820 }
821 }
822 );
823}
824
825
826
827pub(super) use {
828 as_ref_borrow_cast,
829 display_str,
830 first,
831 last,
832 pair,
833 weekmonth,
834};