spacetimedb_lib/
scheduler.rs1use std::fmt::Debug;
2
3use spacetimedb_lib::{TimeDuration, Timestamp};
4use spacetimedb_sats::{
5 algebraic_value::de::{ValueDeserializeError, ValueDeserializer},
6 de::Deserialize,
7 impl_st,
8 ser::Serialize,
9 AlgebraicType, AlgebraicValue,
10};
11
12#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
20pub enum ScheduleAt {
21 Interval(TimeDuration),
24 Time(Timestamp),
26}
27impl_st!([] ScheduleAt, ScheduleAt::get_type());
28
29impl ScheduleAt {
30 #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
34 pub fn to_duration_from_now(&self) -> std::time::Duration {
35 use std::time::{Duration, SystemTime};
36 match self {
37 ScheduleAt::Time(time) => {
38 let now = SystemTime::now();
39 let time = SystemTime::from(*time);
40 time.duration_since(now).unwrap_or(Duration::ZERO)
41 }
42 ScheduleAt::Interval(dur) => dur.to_duration_abs(),
47 }
48 }
49
50 pub fn get_type() -> AlgebraicType {
52 AlgebraicType::sum([
53 ("Interval", AlgebraicType::time_duration()),
54 ("Time", AlgebraicType::timestamp()),
55 ])
56 }
57}
58
59impl From<TimeDuration> for ScheduleAt {
60 fn from(value: TimeDuration) -> Self {
61 ScheduleAt::Interval(value)
62 }
63}
64
65impl From<std::time::Duration> for ScheduleAt {
66 fn from(value: std::time::Duration) -> Self {
67 ScheduleAt::Interval(TimeDuration::from_duration(value))
68 }
69}
70
71impl From<std::time::SystemTime> for ScheduleAt {
72 fn from(value: std::time::SystemTime) -> Self {
73 Timestamp::from(value).into()
74 }
75}
76
77impl From<crate::Timestamp> for ScheduleAt {
78 fn from(value: crate::Timestamp) -> Self {
79 ScheduleAt::Time(value)
80 }
81}
82
83impl TryFrom<AlgebraicValue> for ScheduleAt {
84 type Error = ValueDeserializeError;
85 fn try_from(value: AlgebraicValue) -> Result<Self, Self::Error> {
86 ScheduleAt::deserialize(ValueDeserializer::new(value))
87 }
88}
89
90#[cfg(test)]
91mod tests {
92 use super::*;
93 use spacetimedb_sats::bsatn;
94
95 #[test]
96 fn test_bsatn_roundtrip() {
97 let schedule_at = ScheduleAt::Interval(TimeDuration::from_micros(10000));
98 let ser = bsatn::to_vec(&schedule_at).unwrap();
99 let de = bsatn::from_slice(&ser).unwrap();
100 assert_eq!(schedule_at, de);
101 }
102
103 #[test]
104 fn schedule_at_is_special() {
105 assert!(ScheduleAt::get_type().is_special());
106 }
107}