git-bug 0.2.4

A rust library for interfacing with git-bug repositories
Documentation
// git-bug-rs - A rust library for interfacing with git-bug repositories
//
// Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de>
// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
// SPDX-License-Identifier: GPL-3.0-or-later
//
// This file is part of git-bug-rs/git-gub.
//
// You should have received a copy of the License along with this program.
// If not, see <https://www.gnu.org/licenses/agpl.txt>.

//! Handling of UNIX time stamps.

use std::fmt::Display;

use chrono::DateTime;
use serde::{Deserialize, Serialize};

/// An UNIX time stamp.
///
/// These should only ever be used for human-display, because timestamps are
/// unreliably in a distributed system.
/// Because of this reason, there is no `value()` function.
// As explained in the toplevel doc comment, this Derive is only a implementation detail.
#[allow(clippy::unsafe_derive_deserialize)]
#[derive(Debug, Default, Clone, Copy, Deserialize, Serialize)]
pub struct TimeStamp {
    value: u64,
}
impl From<u64> for TimeStamp {
    fn from(value: u64) -> Self {
        Self { value }
    }
}
impl Display for TimeStamp {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let date =
            DateTime::from_timestamp(i64::try_from(self.value).expect("Should not wrap?"), 0)
                .expect("This timestamp should be vaild");

        let newdate = date.format("%Y-%m-%d %H:%M:%S");
        f.write_str(newdate.to_string().as_str())
    }
}

/// An UNIX time stamp.
///
/// These should only ever be used for human-display, because timestamps are
/// unreliably in a distributed system.
///
/// This one allows underlying access to it's value and is only obtainable via
/// `unsafe` code. The reason behind this is, that you might need to access this
/// to improve the display for humans (i.e., sorting by date).
#[derive(Debug, Default, Clone, Copy, Ord, PartialOrd, Eq, PartialEq)]
pub struct UnsafeTimeStamp {
    /// The seconds since the UNIX epoch.
    pub value: u64,
}
impl TimeStamp {
    /// Turn this time stamp into one that exposes it's numerical value.
    ///
    /// # Safety
    /// This is not really unsafe, but there is just no way your can trust a
    /// time stamp in a distributed system. As such access to the raw value
    /// could lead to bugs.
    #[must_use]
    pub unsafe fn to_unsafe(self) -> UnsafeTimeStamp {
        UnsafeTimeStamp { value: self.value }
    }
}