//! # Strings that represent time use crate::{ int, str, str::{ParseError, Seq, ascii}, }; use super::{ Day, Hours, LooseDate, Mins, Month, PreciseTime, Secs, SecsTime, Time, Timestamp, Year, time::SubsecNanos, timestamp::LooseTimestamp, }; // == TimestampStr == /// Precise string timestamp representation. /// /// format: `dd.mm.YYYY HH:MM:SS.NNNNNNNNN`. #[str(fixed(error = ParseError), crate = crate)] pub struct TimestampStr(DateStr, ascii::Space, PreciseTimeStr); impl TimestampStr { pub const fn new(date: DateStr, time: PreciseTimeStr) -> Self { Self(date, ascii::Space::POS32, time) } pub const fn parse_compact(self) -> Option { let Some(loose) = self.parse() else { return None; }; Some(loose.compact_loose().compact()) } pub const fn parse(self) -> Option> { let Some(date) = self.0.parse() else { return None; }; let Some(time) = self.2.parse() else { return None; }; Some(LooseTimestamp::<_>::new(date, time)) } } // == PreciseTimeStr == /// [`TimeStr`] with seconds an nanoseconds. /// /// format: `HH:MM:SS.NNNNNNNNN`, where N is nanosecond digit. #[str(fixed(error = ParseError), crate = crate)] pub struct PreciseTimeStr(SecsTimeStr, ascii::Dot, SubsecNanosStr); impl PreciseTimeStr { pub const fn new(secs_time: SecsTimeStr, subsec_nanos: SubsecNanosStr) -> Self { Self(secs_time, ascii::Dot::POS46, subsec_nanos) } pub const fn parse(self) -> Option { let Some(time) = self.0.parse() else { return None; }; let nanos = self.2.parse(); Some(PreciseTime::new(time, nanos)) } } // == SecsTimeStr == /// [`TimeStr`] with seconds part. /// /// format: `HH:MM:SS`. #[str(fixed(error = ParseError), crate = crate)] pub struct SecsTimeStr(TimeStr, ascii::Colon, SecsStr); impl SecsTimeStr { pub const fn new(time: TimeStr, secs: SecsStr) -> Self { Self(time, ascii::Colon::POS58, secs) } pub const fn parse(self) -> Option { let Some(time) = self.0.parse() else { return None; }; let secs = self.2.parse(); Some(SecsTime::new(time, secs)) } } // == DateStr == #[str(fixed(error = ParseError), crate = crate)] pub struct DateStr(DayStr, ascii::Dot, MonthStr, ascii::Dot, YearStr); impl DateStr { pub const fn new(day: DayStr, month: MonthStr, year: YearStr) -> Self { Self(day, ascii::Dot::POS46, month, ascii::Dot::POS46, year) } pub const fn parse(self) -> Option { let Some(day) = self.0.parse() else { return None; }; let Some(month) = self.2.parse() else { return None; }; let Some(year) = self.4.parse() else { return None; }; LooseDate::from_dmy(day, month, year) } } // == TimeStr == /// Partly valid time string. Contains hours and minutes. /// /// Format: `HH:MM`. #[str(fixed(error = ParseError), crate = crate)] pub struct TimeStr(HoursStr, ascii::Colon, MinsStr); impl TimeStr { pub const fn new(hours: HoursStr, minutes: MinsStr) -> Self { Self(hours, ascii::Colon::POS58, minutes) } pub const fn parse(self) -> Option