1 //! Formatting helpers for a `Time`.
2 
3 #![allow(non_snake_case)]
4 
5 use crate::{
6     error,
7     format::{
8         parse::{
9             try_consume_exact_digits, try_consume_first_match,
10             AmPm::{AM, PM},
11         },
12         Padding, ParseResult, ParsedItems,
13     },
14     Time,
15 };
16 use core::{
17     fmt::{self, Formatter},
18     num::NonZeroU8,
19 };
20 #[allow(unused_imports)]
21 use standback::prelude::*;
22 
23 /// Hour in 24h format (`00`-`23`)
fmt_H(f: &mut Formatter<'_>, time: Time, padding: Padding) -> fmt::Result24 pub(crate) fn fmt_H(f: &mut Formatter<'_>, time: Time, padding: Padding) -> fmt::Result {
25     pad!(f, padding, 2, time.hour())
26 }
27 
28 /// Hour in 24h format (`00`-`23`)
parse_H(items: &mut ParsedItems, s: &mut &str, padding: Padding) -> ParseResult<()>29 pub(crate) fn parse_H(items: &mut ParsedItems, s: &mut &str, padding: Padding) -> ParseResult<()> {
30     items.hour_24 = Some(try_consume_exact_digits(s, 2, padding).ok_or(error::Parse::InvalidHour)?);
31     Ok(())
32 }
33 
34 /// Hour in 12h format (`01`-`12`)
fmt_I(f: &mut Formatter<'_>, time: Time, padding: Padding) -> fmt::Result35 pub(crate) fn fmt_I(f: &mut Formatter<'_>, time: Time, padding: Padding) -> fmt::Result {
36     pad!(f, padding, 2, (time.hour() as i8 - 1).rem_euclid(12) + 1)
37 }
38 
39 /// Hour in 12h format (`01`-`12`)
parse_I(items: &mut ParsedItems, s: &mut &str, padding: Padding) -> ParseResult<()>40 pub(crate) fn parse_I(items: &mut ParsedItems, s: &mut &str, padding: Padding) -> ParseResult<()> {
41     items.hour_12 = Some(
42         try_consume_exact_digits(s, 2, padding)
43             .and_then(NonZeroU8::new)
44             .ok_or(error::Parse::InvalidHour)?,
45     );
46     Ok(())
47 }
48 
49 /// Minutes, zero-padded (`00`-`59`)
fmt_M(f: &mut Formatter<'_>, time: Time, padding: Padding) -> fmt::Result50 pub(crate) fn fmt_M(f: &mut Formatter<'_>, time: Time, padding: Padding) -> fmt::Result {
51     pad!(f, padding, 2, time.minute())
52 }
53 
54 /// Minutes, zero-added (`00`-`59`)
parse_M(items: &mut ParsedItems, s: &mut &str, padding: Padding) -> ParseResult<()>55 pub(crate) fn parse_M(items: &mut ParsedItems, s: &mut &str, padding: Padding) -> ParseResult<()> {
56     items.minute =
57         Some(try_consume_exact_digits(s, 2, padding).ok_or(error::Parse::InvalidMinute)?);
58     Ok(())
59 }
60 
61 /// Subsecond nanoseconds. Always 9 digits
fmt_N(f: &mut Formatter<'_>, time: Time) -> fmt::Result62 pub(crate) fn fmt_N(f: &mut Formatter<'_>, time: Time) -> fmt::Result {
63     write!(f, "{:09}", time.nanosecond)
64 }
65 
66 /// Subsecond nanoseconds. Always 9 digits
parse_N(items: &mut ParsedItems, s: &mut &str) -> ParseResult<()>67 pub(crate) fn parse_N(items: &mut ParsedItems, s: &mut &str) -> ParseResult<()> {
68     items.nanosecond = Some(
69         try_consume_exact_digits(s, 9, Padding::Space).ok_or(error::Parse::InvalidNanosecond)?,
70     );
71     Ok(())
72 }
73 
74 /// am/pm
fmt_p(f: &mut Formatter<'_>, time: Time) -> fmt::Result75 pub(crate) fn fmt_p(f: &mut Formatter<'_>, time: Time) -> fmt::Result {
76     if time.hour() < 12 {
77         f.write_str("am")
78     } else {
79         f.write_str("pm")
80     }
81 }
82 
83 /// am/pm
parse_p(items: &mut ParsedItems, s: &mut &str) -> ParseResult<()>84 pub(crate) fn parse_p(items: &mut ParsedItems, s: &mut &str) -> ParseResult<()> {
85     items.am_pm = Some(
86         try_consume_first_match(s, [("am", AM), ("pm", PM)].iter().cloned())
87             .ok_or(error::Parse::InvalidAmPm)?,
88     );
89     Ok(())
90 }
91 
92 /// AM/PM
fmt_P(f: &mut Formatter<'_>, time: Time) -> fmt::Result93 pub(crate) fn fmt_P(f: &mut Formatter<'_>, time: Time) -> fmt::Result {
94     if time.hour() < 12 {
95         f.write_str("AM")
96     } else {
97         f.write_str("PM")
98     }
99 }
100 
101 /// AM/PM
parse_P(items: &mut ParsedItems, s: &mut &str) -> ParseResult<()>102 pub(crate) fn parse_P(items: &mut ParsedItems, s: &mut &str) -> ParseResult<()> {
103     items.am_pm = Some(
104         try_consume_first_match(s, [("AM", AM), ("PM", PM)].iter().cloned())
105             .ok_or(error::Parse::InvalidAmPm)?,
106     );
107     Ok(())
108 }
109 
110 /// Seconds, zero-padded (`00`-`59`)
fmt_S(f: &mut Formatter<'_>, time: Time, padding: Padding) -> fmt::Result111 pub(crate) fn fmt_S(f: &mut Formatter<'_>, time: Time, padding: Padding) -> fmt::Result {
112     pad!(f, padding, 2, time.second())
113 }
114 
115 /// Seconds, zero-added (`00`-`59`)
parse_S(items: &mut ParsedItems, s: &mut &str, padding: Padding) -> ParseResult<()>116 pub(crate) fn parse_S(items: &mut ParsedItems, s: &mut &str, padding: Padding) -> ParseResult<()> {
117     items.second =
118         Some(try_consume_exact_digits(s, 2, padding).ok_or(error::Parse::InvalidSecond)?);
119     Ok(())
120 }
121