use crate::id::types::{Attempt, Generation};
use serde::{Deserialize, Serialize};
use std::sync::atomic::{AtomicU64, Ordering};
use std::time::{Duration, SystemTime, UNIX_EPOCH};
use uuid::Uuid;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct EventSequence {
pub value: u64,
}
impl EventSequence {
pub fn new(value: u64) -> Self {
Self { value }
}
}
#[derive(Debug)]
pub struct EventSequenceSource {
next_value: AtomicU64,
}
impl EventSequenceSource {
pub fn new() -> Self {
Self {
next_value: AtomicU64::new(1),
}
}
pub fn next(&self) -> EventSequence {
EventSequence::new(self.next_value.fetch_add(1, Ordering::Relaxed))
}
}
impl Default for EventSequenceSource {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct CorrelationId {
pub value: Uuid,
}
impl CorrelationId {
pub fn new() -> Self {
Self {
value: Uuid::new_v4(),
}
}
pub fn from_uuid(value: Uuid) -> Self {
Self { value }
}
}
impl Default for CorrelationId {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct EventTime {
pub unix_nanos: u128,
pub monotonic_nanos: u128,
pub supervisor_uptime_ms: u64,
pub generation: Generation,
pub attempt: Attempt,
}
impl EventTime {
pub fn from_parts(
monotonic_nanos: u128,
supervisor_uptime_ms: u64,
generation: Generation,
attempt: Attempt,
) -> Self {
Self {
unix_nanos: system_time_nanos(SystemTime::now()),
monotonic_nanos,
supervisor_uptime_ms,
generation,
attempt,
}
}
pub fn deterministic(
unix_nanos: u128,
monotonic_nanos: u128,
supervisor_uptime_ms: u64,
generation: Generation,
attempt: Attempt,
) -> Self {
Self {
unix_nanos,
monotonic_nanos,
supervisor_uptime_ms,
generation,
attempt,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct When {
pub time: EventTime,
}
impl When {
pub fn new(time: EventTime) -> Self {
Self { time }
}
}
fn system_time_nanos(time: SystemTime) -> u128 {
time.duration_since(UNIX_EPOCH)
.unwrap_or(Duration::ZERO)
.as_nanos()
}