use std::time::{Duration, SystemTime};
use uuid::Uuid;
use crate::session::SessionId;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct LeaseId(Uuid);
impl LeaseId {
#[must_use]
pub fn new() -> Self {
Self(Uuid::now_v7())
}
#[must_use]
pub fn into_uuid(self) -> Uuid {
self.0
}
}
impl Default for LeaseId {
fn default() -> Self {
Self::new()
}
}
impl From<Uuid> for LeaseId {
fn from(value: Uuid) -> Self {
Self(value)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct LeaseTtl(Duration);
impl LeaseTtl {
#[must_use]
pub const fn new(duration: Duration) -> Self {
Self(duration)
}
#[must_use]
pub const fn duration(self) -> Duration {
self.0
}
#[must_use]
pub const fn is_zero(self) -> bool {
self.0.is_zero()
}
}
impl Default for LeaseTtl {
fn default() -> Self {
Self(Duration::from_secs(30))
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct LeaseUntil(SystemTime);
impl LeaseUntil {
#[must_use]
pub fn new(value: SystemTime) -> Self {
Self(value)
}
#[must_use]
pub fn from_acquired_at(acquired_at: SystemTime, ttl: LeaseTtl) -> Self {
Self(acquired_at + ttl.duration())
}
#[must_use]
pub fn into_inner(self) -> SystemTime {
self.0
}
#[must_use]
pub fn is_active_at(self, now: SystemTime) -> bool {
now < self.0
}
#[must_use]
pub fn is_expired_at(self, now: SystemTime) -> bool {
!self.is_active_at(now)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct RenewalLease {
pub session_id: SessionId,
pub lease_id: LeaseId,
pub acquired_at: SystemTime,
pub lease_until: LeaseUntil,
}
impl RenewalLease {
#[must_use]
pub fn new(
session_id: SessionId,
lease_id: LeaseId,
acquired_at: SystemTime,
lease_until: LeaseUntil,
) -> Self {
Self {
session_id,
lease_id,
acquired_at,
lease_until,
}
}
#[must_use]
pub fn from_ttl(
session_id: SessionId,
lease_id: LeaseId,
acquired_at: SystemTime,
ttl: LeaseTtl,
) -> Self {
Self {
session_id,
lease_id,
acquired_at,
lease_until: LeaseUntil::from_acquired_at(acquired_at, ttl),
}
}
#[must_use]
pub fn is_active_at(self, now: SystemTime) -> bool {
self.lease_until.is_active_at(now)
}
#[must_use]
pub fn is_expired_at(self, now: SystemTime) -> bool {
self.lease_until.is_expired_at(now)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum LeaseAcquisition {
Acquired(RenewalLease),
HeldByOther {
active_lease: RenewalLease,
},
Unavailable,
}