1use std::str::FromStr;
2
3use smallvec::SmallVec;
4
5use crate::Time;
6
7#[derive(thiserror::Error, Debug, Clone)]
8#[allow(missing_docs)]
9pub enum Error {
10 #[error("Could not convert a duration into a date")]
11 RelativeTimeConversion,
12 #[error("Date string can not be parsed")]
13 InvalidDateString { input: String },
14 #[error("The heat-death of the universe happens before this date")]
15 InvalidDate(#[from] std::num::TryFromIntError),
16 #[error("Current time is missing but required to handle relative dates.")]
17 MissingCurrentTime,
18}
19
20#[derive(Default, Clone)]
23pub struct TimeBuf {
24 buf: SmallVec<[u8; Time::MAX.size()]>,
25}
26
27impl TimeBuf {
28 pub fn as_str(&self) -> &str {
31 let time_bytes = self.buf.as_slice();
34 #[allow(unsafe_code)]
35 unsafe {
36 std::str::from_utf8_unchecked(time_bytes)
37 }
38 }
39
40 fn clear(&mut self) {
42 self.buf.clear();
43 }
44}
45
46impl std::io::Write for TimeBuf {
47 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
48 self.buf.write(buf)
49 }
50
51 fn flush(&mut self) -> std::io::Result<()> {
52 self.buf.flush()
53 }
54}
55
56impl Time {
57 pub fn to_str<'a>(&self, buf: &'a mut TimeBuf) -> &'a str {
60 buf.clear();
61 self.write_to(buf)
62 .expect("write to memory of just the right size cannot fail");
63 buf.as_str()
64 }
65}
66
67impl FromStr for Time {
68 type Err = Error;
69
70 fn from_str(s: &str) -> Result<Self, Self::Err> {
71 crate::parse_header(s).ok_or_else(|| Error::InvalidDateString { input: s.into() })
72 }
73}
74
75pub(crate) mod function;
76mod git;
77mod raw;
78mod relative;