use super::{CaHash, ContentAddr, GraphAddr, Hasher};
use serde::{Deserialize, Serialize};
use std::{fmt, ops, time::Duration};
#[derive(Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord, Deserialize, Serialize)]
pub struct Commit {
pub timestamp: Timestamp,
pub parent: Option<CommitAddr>,
pub graph: GraphAddr,
}
pub type Timestamp = std::time::Duration;
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord, Deserialize, Serialize)]
pub struct CommitAddr(ContentAddr);
pub type Branch = String;
#[derive(Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord, Deserialize, Serialize)]
pub enum Head {
Commit(CommitAddr),
Branch(Branch),
}
impl std::fmt::Display for Head {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Head::Branch(name) => write!(f, "{name}"),
Head::Commit(ca) => write!(f, "{}", ca.display_short()),
}
}
}
impl Commit {
pub fn new(timestamp: Duration, parent: Option<CommitAddr>, graph: GraphAddr) -> Self {
Self {
timestamp,
parent,
graph,
}
}
}
impl CaHash for Commit {
fn hash(&self, hasher: &mut Hasher) {
self.timestamp.as_secs().hash(hasher);
self.timestamp.subsec_nanos().hash(hasher);
self.parent.hash(hasher);
self.graph.hash(hasher);
}
}
impl ops::Deref for CommitAddr {
type Target = ContentAddr;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl From<ContentAddr> for CommitAddr {
fn from(ca: ContentAddr) -> Self {
Self(ca)
}
}
impl From<CommitAddr> for ContentAddr {
fn from(addr: CommitAddr) -> Self {
addr.0
}
}
impl CaHash for CommitAddr {
fn hash(&self, hasher: &mut Hasher) {
CaHash::hash(&self.0, hasher);
}
}
impl fmt::Display for CommitAddr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
pub fn addr(commit: &Commit) -> CommitAddr {
CommitAddr(crate::content_addr(commit))
}