git_bug/replica/entity/timestamp.rs
1// git-bug-rs - A rust library for interfacing with git-bug repositories
2//
3// Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de>
4// Copyright (C) 2025 Benedikt Peetz <benedikt.peetz@b-peetz.de>
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
7// This file is part of git-bug-rs/git-gub.
8//
9// You should have received a copy of the License along with this program.
10// If not, see <https://www.gnu.org/licenses/agpl.txt>.
11
12//! Handling of UNIX time stamps.
13
14use std::fmt::Display;
15
16use chrono::DateTime;
17use serde::{Deserialize, Serialize};
18
19/// An UNIX time stamp.
20///
21/// These should only ever be used for human-display, because timestamps are
22/// unreliably in a distributed system.
23/// Because of this reason, there is no `value()` function.
24// As explained in the toplevel doc comment, this Derive is only a implementation detail.
25#[allow(clippy::unsafe_derive_deserialize)]
26#[derive(Debug, Default, Clone, Copy, Deserialize, Serialize)]
27pub struct TimeStamp {
28 value: u64,
29}
30impl From<u64> for TimeStamp {
31 fn from(value: u64) -> Self {
32 Self { value }
33 }
34}
35impl Display for TimeStamp {
36 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
37 let date =
38 DateTime::from_timestamp(i64::try_from(self.value).expect("Should not wrap?"), 0)
39 .expect("This timestamp should be vaild");
40
41 let newdate = date.format("%Y-%m-%d %H:%M:%S");
42 f.write_str(newdate.to_string().as_str())
43 }
44}
45
46/// An UNIX time stamp.
47///
48/// These should only ever be used for human-display, because timestamps are
49/// unreliably in a distributed system.
50///
51/// This one allows underlying access to it's value and is only obtainable via
52/// `unsafe` code. The reason behind this is, that you might need to access this
53/// to improve the display for humans (i.e., sorting by date).
54#[derive(Debug, Default, Clone, Copy, Ord, PartialOrd, Eq, PartialEq)]
55pub struct UnsafeTimeStamp {
56 /// The seconds since the UNIX epoch.
57 pub value: u64,
58}
59impl TimeStamp {
60 /// Turn this time stamp into one that exposes it's numerical value.
61 ///
62 /// # Safety
63 /// This is not really unsafe, but there is just no way your can trust a
64 /// time stamp in a distributed system. As such access to the raw value
65 /// could lead to bugs.
66 #[must_use]
67 pub unsafe fn to_unsafe(self) -> UnsafeTimeStamp {
68 UnsafeTimeStamp { value: self.value }
69 }
70}