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