use std::time::SystemTime;
use sqlx::{Database, Encode, Type};
use crate::inbox::queue::Queue;
#[cfg(feature = "testing")]
use crate::inbox::testing::TestClock;
use crate::inbox::time::{QueueTime, TimeColumn, TimeSource};
#[derive(Debug, Clone, Copy)]
pub struct Claiming {
pub queue: &'static Queue,
pub limit: i64,
pub now: Now,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Leasing<Token> {
pub at: SystemTime,
pub now: Token,
pub expiry: Token,
}
#[cfg(any(feature = "chrono", feature = "time"))]
impl<Token> Leasing<Token> {
pub(crate) fn map<Other>(self, into: impl Fn(Token) -> Other) -> Leasing<Other> {
Leasing {
at: self.at,
now: into(self.now),
expiry: into(self.expiry),
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct Settling {
pub queue: &'static Queue,
pub now: Now,
}
#[derive(Debug, Clone, Copy, Default)]
pub struct Now {
#[cfg(feature = "testing")]
test: Option<TestClock>,
_private: (),
}
impl Now {
#[cfg_attr(not(feature = "testing"), allow(clippy::unused_self))]
pub(super) fn instant<Source: TimeSource>(self) -> Option<SystemTime> {
#[cfg(feature = "testing")]
if let Some(clock) = self.test
&& !Source::DATABASE
{
return Some(clock.now());
}
Source::now()
}
#[cfg(feature = "testing")]
pub(crate) const fn test(clock: Option<TestClock>) -> Self {
Self {
test: clock,
_private: (),
}
}
}
pub trait Via<Marker> {
type Is: ?Sized;
}
impl<Marker, T: ?Sized> Via<Marker> for T {
type Is = T;
}
pub trait TimeFor<DB: Database> {
type Time: QueueTime + for<'q> Encode<'q, DB> + Type<DB>;
}
impl<DB, C> TimeFor<DB> for C
where
DB: Database,
C: TimeColumn,
C::Time: for<'q> Encode<'q, DB> + Type<DB>,
{
type Time = C::Time;
}