es_entity/operation/
with_time.rs1use crate::{clock::ClockHandle, db};
2
3use super::{AtomicOperation, hooks};
4
5pub trait AtomicOperationWithTime: AtomicOperation {
6 fn now(&self) -> chrono::DateTime<chrono::Utc>;
7}
8
9pub struct OpWithTime<'a, Op: AtomicOperation + ?Sized> {
11 inner: &'a mut Op,
12 now: chrono::DateTime<chrono::Utc>,
13}
14
15impl<'a, Op: AtomicOperation + ?Sized> AtomicOperationWithTime for OpWithTime<'a, Op> {
16 fn now(&self) -> chrono::DateTime<chrono::Utc> {
17 self.now
18 }
19}
20
21impl<'a, Op: AtomicOperation + ?Sized> OpWithTime<'a, Op> {
22 pub async fn cached_or_db_time(op: &'a mut Op) -> Result<Self, sqlx::Error> {
29 let now = if let Some(time) = op.maybe_now() {
30 time
31 } else if let Some(manual_time) = op.clock().manual_now() {
32 manual_time
33 } else {
34 db::database_now(op.connection()).await?
35 };
36 Ok(Self { inner: op, now })
37 }
38
39 pub fn cached_or_time(op: &'a mut Op, time: chrono::DateTime<chrono::Utc>) -> Self {
41 let now = op.maybe_now().unwrap_or(time);
42 Self { inner: op, now }
43 }
44
45 pub fn cached_or_clock_time(op: &'a mut Op) -> Self {
49 let now = op.maybe_now().unwrap_or_else(|| op.clock().now());
50 Self { inner: op, now }
51 }
52
53 pub fn now(&self) -> chrono::DateTime<chrono::Utc> {
54 self.now
55 }
56}
57
58impl<'a, Op: AtomicOperation + ?Sized> AtomicOperation for OpWithTime<'a, Op> {
59 fn maybe_now(&self) -> Option<chrono::DateTime<chrono::Utc>> {
60 Some(self.now)
61 }
62
63 fn clock(&self) -> &ClockHandle {
64 self.inner.clock()
65 }
66
67 fn connection(&mut self) -> &mut db::Connection {
68 self.inner.connection()
69 }
70
71 fn add_commit_hook_dyn(
72 &mut self,
73 type_id: std::any::TypeId,
74 hook: Box<dyn hooks::DynHook>,
75 ) -> Result<(), Box<dyn hooks::DynHook>> {
76 self.inner.add_commit_hook_dyn(type_id, hook)
77 }
78
79 fn commit_hook_dyn(&self, type_id: std::any::TypeId) -> Option<&dyn hooks::DynHook> {
80 self.inner.commit_hook_dyn(type_id)
81 }
82
83 fn supports_hooks(&self) -> bool {
84 self.inner.supports_hooks()
85 }
86
87 fn savepoint_parts(&mut self) -> (&mut db::Connection, super::savepoint::HookSlot<'_>) {
88 self.inner.savepoint_parts()
89 }
90}