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 sum_type::{SCHEDULE_AT_INTERVAL_TAG, SCHEDULE_AT_TIME_TAG},
10 AlgebraicType, AlgebraicValue,
11};
12
13#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
21pub enum ScheduleAt {
22 Interval(TimeDuration),
25 Time(Timestamp),
27}
28impl_st!([] ScheduleAt, ScheduleAt::get_type());
29
30impl ScheduleAt {
31 #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
35 pub fn to_duration_from(&self, from: Timestamp) -> std::time::Duration {
36 use std::time::Duration;
37 match self {
38 ScheduleAt::Time(time) => time.duration_since(from).unwrap_or(Duration::ZERO),
39 ScheduleAt::Interval(dur) => dur.to_duration_abs(),
44 }
45 }
46
47 #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
51 pub fn to_timestamp_from(&self, from: Timestamp) -> Timestamp {
52 match *self {
53 ScheduleAt::Time(time) => time,
54 ScheduleAt::Interval(dur) => from + dur.abs(),
55 }
56 }
57
58 pub fn get_type() -> AlgebraicType {
60 AlgebraicType::sum([
61 (SCHEDULE_AT_INTERVAL_TAG, AlgebraicType::time_duration()),
62 (SCHEDULE_AT_TIME_TAG, AlgebraicType::timestamp()),
63 ])
64 }
65}
66
67impl From<TimeDuration> for ScheduleAt {
68 fn from(value: TimeDuration) -> Self {
69 ScheduleAt::Interval(value)
70 }
71}
72
73impl From<std::time::Duration> for ScheduleAt {
74 fn from(value: std::time::Duration) -> Self {
75 ScheduleAt::Interval(TimeDuration::from_duration(value))
76 }
77}
78
79impl From<std::time::SystemTime> for ScheduleAt {
80 fn from(value: std::time::SystemTime) -> Self {
81 Timestamp::from(value).into()
82 }
83}
84
85impl From<crate::Timestamp> for ScheduleAt {
86 fn from(value: crate::Timestamp) -> Self {
87 ScheduleAt::Time(value)
88 }
89}
90
91impl TryFrom<AlgebraicValue> for ScheduleAt {
92 type Error = ValueDeserializeError;
93 fn try_from(value: AlgebraicValue) -> Result<Self, Self::Error> {
94 ScheduleAt::deserialize(ValueDeserializer::new(value))
95 }
96}
97
98#[cfg(test)]
99mod tests {
100 use super::*;
101 use spacetimedb_sats::bsatn;
102
103 #[test]
104 fn test_bsatn_roundtrip() {
105 let schedule_at = ScheduleAt::Interval(TimeDuration::from_micros(10000));
106 let ser = bsatn::to_vec(&schedule_at).unwrap();
107 let de = bsatn::from_slice(&ser).unwrap();
108 assert_eq!(schedule_at, de);
109 }
110
111 #[test]
112 fn schedule_at_is_special() {
113 assert!(ScheduleAt::get_type().is_special());
114 }
115}