hl7_parser/datetime/
mod.rs

1use std::fmt::Display;
2
3mod timestamp;
4pub use timestamp::*;
5mod time;
6pub use time::*;
7mod date;
8pub use date::*;
9
10/// Utilies to convert back and forth between chrono's data structures and the hl7-parser ones
11#[cfg(feature = "chrono")]
12pub mod chrono;
13
14/// Utilies to convert back and forth between time's data structures and the hl7-parser ones
15#[cfg(feature = "time")]
16pub mod time_crate;
17
18/// Utilies to convert back and forth between jiff's data structures and the hl7-parser ones
19#[cfg(feature = "jiff")]
20pub mod jiff;
21
22#[derive(Debug, Copy, Clone, PartialEq, Eq)]
23pub enum ErroredDateTimeComponent {
24    Year,
25    Month,
26    Day,
27    Hour,
28    Minute,
29    Second,
30    Microsecond,
31    Offset,
32    Date,
33    Time,
34    DateTime,
35}
36
37impl Display for ErroredDateTimeComponent {
38    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
39        match self {
40            ErroredDateTimeComponent::Year => write!(f, "year"),
41            ErroredDateTimeComponent::Month => write!(f, "month"),
42            ErroredDateTimeComponent::Day => write!(f, "day"),
43            ErroredDateTimeComponent::Hour => write!(f, "hour"),
44            ErroredDateTimeComponent::Minute => write!(f, "minute"),
45            ErroredDateTimeComponent::Second => write!(f, "second"),
46            ErroredDateTimeComponent::Microsecond => write!(f, "microsecond"),
47            ErroredDateTimeComponent::Offset => write!(f, "offset"),
48            ErroredDateTimeComponent::Date => write!(f, "date"),
49            ErroredDateTimeComponent::Time => write!(f, "time"),
50            ErroredDateTimeComponent::DateTime => write!(f, "date and time"),
51        }
52    }
53}
54
55/// Errors that can result from parsing HL7 timestamps
56#[derive(thiserror::Error, Debug)]
57pub enum DateTimeParseError {
58    #[error("Failed to parse '{0}' component of timestamp")]
59    ParsingFailed(&'static str),
60    #[error("Unexpected character '{1}' in timestamp at position {0}")]
61    UnexpectedCharacter(usize, char),
62    #[error("Invalid component range: {0:}")]
63    InvalidComponentRange(ErroredDateTimeComponent),
64    #[error("Ambiguous time, could be {0} or {1}")]
65    AmbiguousTime(String, String),
66    #[error("Missing component: {0:}")]
67    MissingComponent(ErroredDateTimeComponent),
68}
69
70/// Trait for parsing HL7 date and time strings into `Date`, `Time`, and `TimeStamp` structs
71pub trait DateTime {
72    /// Parse an HL7 date and/or time string into a `Date`, `Time`, or `TimeStamp` struct
73    fn parse(s: &str, lenient_trailing_chars: bool) -> Result<Self, DateTimeParseError>
74    where
75        Self: Sized;
76
77    /// Parse an HL7 date and/or time string into a `Date`, `Time`, or `TimeStamp` struct, with
78    /// strict parsing dissallowing trailing characters
79    fn parse_strict(s: &str) -> Result<Self, DateTimeParseError>
80    where
81        Self: Sized,
82    {
83        Self::parse(s, false)
84    }
85}
86
87impl DateTime for Time {
88    fn parse(s: &str, lenient_trailing_chars: bool) -> Result<Self, DateTimeParseError> {
89        parse_time(s, lenient_trailing_chars)
90    }
91}
92
93impl DateTime for Date {
94    fn parse(s: &str, lenient_trailing_chars: bool) -> Result<Self, DateTimeParseError> {
95        parse_date(s, lenient_trailing_chars)
96    }
97}
98
99impl DateTime for TimeStamp {
100    fn parse(s: &str, lenient_trailing_chars: bool) -> Result<Self, DateTimeParseError> {
101        parse_timestamp(s, lenient_trailing_chars)
102    }
103}