es_entity/clock/
config.rs

1use serde::{Deserialize, Serialize};
2
3use chrono::{DateTime, Utc};
4
5/// Configuration for artificial time.
6#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct ArtificialClockConfig {
8    /// What time should the clock start at (truncated to millisecond precision).
9    pub start_at: DateTime<Utc>,
10    /// How should time advance.
11    pub mode: ArtificialMode,
12}
13
14/// Truncate a DateTime to millisecond precision.
15/// This ensures consistency since we store time as epoch milliseconds.
16fn truncate_to_millis(time: DateTime<Utc>) -> DateTime<Utc> {
17    DateTime::from_timestamp_millis(time.timestamp_millis()).expect("valid timestamp")
18}
19
20impl ArtificialClockConfig {
21    /// Create a manual config starting at the current time.
22    pub fn manual() -> Self {
23        Self {
24            start_at: truncate_to_millis(Utc::now()),
25            mode: ArtificialMode::Manual,
26        }
27    }
28
29    /// Create a manual config starting at a specific time.
30    pub fn manual_at(start_at: DateTime<Utc>) -> Self {
31        Self {
32            start_at: truncate_to_millis(start_at),
33            mode: ArtificialMode::Manual,
34        }
35    }
36
37    /// Create an auto-advancing config.
38    pub fn auto(time_scale: f64) -> Self {
39        Self {
40            start_at: truncate_to_millis(Utc::now()),
41            mode: ArtificialMode::AutoAdvance { time_scale },
42        }
43    }
44
45    /// Create an auto-advancing config starting at a specific time.
46    pub fn auto_at(start_at: DateTime<Utc>, time_scale: f64) -> Self {
47        Self {
48            start_at: truncate_to_millis(start_at),
49            mode: ArtificialMode::AutoAdvance { time_scale },
50        }
51    }
52}
53
54impl Default for ArtificialClockConfig {
55    fn default() -> Self {
56        Self::manual()
57    }
58}
59
60/// How artificial time advances.
61#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
62#[serde(tag = "type", rename_all = "snake_case")]
63pub enum ArtificialMode {
64    /// Time advances automatically at the given scale.
65    /// A time_scale of 1000.0 means 1 real second = 1000 artificial seconds.
66    AutoAdvance {
67        /// Multiplier for time passage (e.g., 1000.0 = 1000x faster)
68        time_scale: f64,
69    },
70    /// Time only advances via explicit `advance()` or `set_time()` calls.
71    /// This is ideal for deterministic testing.
72    Manual,
73}