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 Time {
47 pub fn to_str<'a>(&self, buf: &'a mut TimeBuf) -> &'a str {
50 buf.clear();
51 self.write_to(&mut buf.buf)
52 .expect("write to memory of just the right size cannot fail");
53 buf.as_str()
54 }
55}
56
57impl FromStr for Time {
58 type Err = Error;
59
60 fn from_str(s: &str) -> Result<Self, Self::Err> {
61 crate::parse_header(s).ok_or_else(|| Error::InvalidDateString { input: s.into() })
62 }
63}
64
65pub(crate) mod function;
66mod git;
67mod raw;
68mod relative;