use serde::{Deserialize, Serialize};
use std::fmt;
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct DagPosition {
pub wall_ms: u64,
pub counter: u16,
pub depth: u32,
pub lane: u32,
pub sequence: u32,
}
impl DagPosition {
pub const fn new(depth: u32, lane: u32, sequence: u32) -> Self {
Self {
wall_ms: 0,
counter: 0,
depth,
lane,
sequence,
}
}
pub const fn with_hlc(
wall_ms: u64,
counter: u16,
depth: u32,
lane: u32,
sequence: u32,
) -> Self {
Self {
wall_ms,
counter,
depth,
lane,
sequence,
}
}
pub const fn root() -> Self {
Self {
wall_ms: 0,
counter: 0,
depth: 0,
lane: 0,
sequence: 0,
}
}
pub const fn child(sequence: u32) -> Self {
Self {
wall_ms: 0,
counter: 0,
depth: 0,
lane: 0,
sequence,
}
}
pub const fn child_at(sequence: u32, wall_ms: u64, counter: u16) -> Self {
Self {
wall_ms,
counter,
depth: 0,
lane: 0,
sequence,
}
}
pub const fn fork(parent_depth: u32, new_lane: u32) -> Self {
Self {
wall_ms: 0,
counter: 0,
depth: parent_depth + 1,
lane: new_lane,
sequence: 0,
}
}
pub const fn is_root(&self) -> bool {
self.depth == 0 && self.lane == 0 && self.sequence == 0
}
pub const fn is_ancestor_of(&self, other: &DagPosition) -> bool {
self.lane == other.lane && self.depth == other.depth && self.sequence < other.sequence
}
}
impl fmt::Display for DagPosition {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{}:{}:{}@{}.{}",
self.depth, self.lane, self.sequence, self.wall_ms, self.counter
)
}
}
impl PartialOrd for DagPosition {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
if self.lane != other.lane || self.depth != other.depth {
return None; }
Some(self.sequence.cmp(&other.sequence))
}
}