gix_date/parse/
mod.rs

1use std::str::FromStr;
2
3use crate::{Error, Time};
4use smallvec::SmallVec;
5
6/// A container for just enough bytes to hold the largest-possible [`time`](Time) instance.
7/// It's used in conjunction with
8#[derive(Default, Clone)]
9pub struct TimeBuf {
10    buf: SmallVec<[u8; Time::MAX.size()]>,
11}
12
13impl TimeBuf {
14    /// Represent this instance as standard string, serialized in a format compatible with
15    /// signature fields in Git commits, also known as anything parseable as [raw format](function::parse_header()).
16    pub fn as_str(&self) -> &str {
17        // SAFETY: We know that serialized times are pure ASCII, a subset of UTF-8.
18        //         `buf` and `len` are written only by time-serialization code.
19        let time_bytes = self.buf.as_slice();
20        #[allow(unsafe_code)]
21        unsafe {
22            std::str::from_utf8_unchecked(time_bytes)
23        }
24    }
25
26    /// Clear the previous content.
27    fn clear(&mut self) {
28        self.buf.clear();
29    }
30}
31
32impl Time {
33    /// Serialize this instance into `buf`, exactly as it would appear in the header of a Git commit,
34    /// and return `buf` as `&str` for easy consumption.
35    pub fn to_str<'a>(&self, buf: &'a mut TimeBuf) -> &'a str {
36        buf.clear();
37        self.write_to(&mut buf.buf)
38            .expect("write to memory of just the right size cannot fail");
39        buf.as_str()
40    }
41}
42
43impl FromStr for Time {
44    type Err = Error;
45
46    fn from_str(s: &str) -> Result<Self, Self::Err> {
47        crate::parse_header(s).ok_or_else(|| Error::new_with_input("invalid time", s))
48    }
49}
50
51pub(crate) mod function;
52mod git;
53mod raw;
54mod relative;