124 lines · 3.7 KB · Rust
RawDownload
use std::str::FromStr; use smallvec::SmallVec; use crate::Time; /// Errors that can occur when parsing dates.#[derive(Debug, Clone)]#[allow(missing_docs)]pub enum Error {    RelativeTimeConversion,    InvalidDateString { input: String },    InvalidDate(std::num::TryFromIntError),    MissingCurrentTime,} impl std::fmt::Display for Error {    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {        match self {            Error::RelativeTimeConversion => write!(f, "Could not convert a duration into a date"),            Error::InvalidDateString { input } => write!(f, "Date string can not be parsed: {input}"),            Error::InvalidDate(err) => write!(f, "The heat-death of the universe happens before this date: {err}"),            Error::MissingCurrentTime => write!(f, "Current time is missing but required to handle relative dates."),        }    }} impl std::error::Error for Error {    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {        match self {            Error::InvalidDate(err) => Some(err),            _ => None,        }    }} /// A wrapper around `exn::Exn<Error>` that implements `std::error::Error`.////// This type is returned by functions that integrate with external APIs requiring `std::error::Error`,/// while internally using exn for context-aware error tracking.#[derive(Debug)]pub struct ParseError(exn::Exn<Error>); impl ParseError {    /// Create a ParseError from an exn error.    pub fn from_exn(exn: exn::Exn<Error>) -> Self {        Self(exn)    }     /// Get a reference to the underlying error.    pub fn as_error(&self) -> &Error {        self.0.as_error()    }} impl std::fmt::Display for ParseError {    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {        std::fmt::Display::fmt(&self.0, f)    }} impl std::error::Error for ParseError {    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {        Some(self.0.as_error())    }} impl From<exn::Exn<Error>> for ParseError {    fn from(exn: exn::Exn<Error>) -> Self {        Self(exn)    }} /// A container for just enough bytes to hold the largest-possible [`time`](Time) instance./// It's used in conjunction with#[derive(Default, Clone)]pub struct TimeBuf {    buf: SmallVec<[u8; Time::MAX.size()]>,} impl TimeBuf {    /// Represent this instance as standard string, serialized in a format compatible with    /// signature fields in Git commits, also known as anything parseable as [raw format](function::parse_header()).    pub fn as_str(&self) -> &str {        // SAFETY: We know that serialized times are pure ASCII, a subset of UTF-8.        //         `buf` and `len` are written only by time-serialization code.        let time_bytes = self.buf.as_slice();        #[allow(unsafe_code)]        unsafe {            std::str::from_utf8_unchecked(time_bytes)        }    }     /// Clear the previous content.    fn clear(&mut self) {        self.buf.clear();    }} impl Time {    /// Serialize this instance into `buf`, exactly as it would appear in the header of a Git commit,    /// and return `buf` as `&str` for easy consumption.    pub fn to_str<'a>(&self, buf: &'a mut TimeBuf) -> &'a str {        buf.clear();        self.write_to(&mut buf.buf)            .expect("write to memory of just the right size cannot fail");        buf.as_str()    }} impl FromStr for Time {    type Err = ParseError;     fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {        crate::parse_header(s)            .ok_or_else(|| Error::InvalidDateString { input: s.into() })            .map_err(|e| ParseError::from_exn(exn::Exn::from(e)))    }} pub(crate) mod function;mod git;mod raw;mod relative;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t