use std::fmt; use crate::clock::DateTime; #[derive(Clone, Copy, Debug, Eq, PartialEq, serde::Serialize)] pub struct Instant { pub at: DateTime, #[serde(skip)] pub sequence: Sequence, } impl From for Sequence { fn from(instant: Instant) -> Self { instant.sequence } } #[derive( Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, serde::Deserialize, serde::Serialize, sqlx::Type, )] #[serde(transparent)] #[sqlx(transparent)] pub struct Sequence(i64); impl fmt::Display for Sequence { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let Self(value) = self; value.fmt(f) } } impl Sequence { pub fn up_to(resume_point: Option) -> impl for<'e> Fn(&'e E) -> bool where E: Sequenced, { move |event| resume_point.map_or(true, |resume_point| event.sequence() <= resume_point) } pub fn after(resume_point: Option) -> impl for<'e> Fn(&'e E) -> bool where E: Sequenced, { move |event| resume_point < Some(event.sequence()) } pub fn start_from(resume_point: Self) -> impl for<'e> Fn(&'e E) -> bool where E: Sequenced, { move |event| resume_point <= event.sequence() } } pub trait Sequenced { fn instant(&self) -> Instant; fn sequence(&self) -> Sequence { self.instant().into() } } impl Sequenced for &E where E: Sequenced, { fn instant(&self) -> Instant { (*self).instant() } fn sequence(&self) -> Sequence { (*self).sequence() } }