hyperclock/
config.rs

1//! Defines all configuration structures for the Hyperclock engine.
2//!
3//! These structs are designed to be deserialized from a configuration file
4//! (e.g., a TOML file) using `serde`. This allows the engine's behavior,
5//! including its speed, phase sequence, and calendar events, to be defined
6//! externally from the application code.
7
8use crate::common::PhaseId;
9// CORRECTED: Use NaiveDate instead of the deprecated Date.
10use chrono::{NaiveDate, NaiveTime};
11use chrono_tz::Tz;
12use serde::Deserialize;
13
14/// The top-level configuration for the `HyperclockEngine`.
15///
16/// This struct is the entry point for all engine settings. It is typically
17/// loaded from a TOML or JSON file at application startup.
18#[derive(Debug, Clone, Deserialize)]
19pub struct HyperclockConfig {
20    /// The tick speed of the master `SystemClock`.
21    pub resolution: ClockResolution,
22
23    /// Defines the sequence of phases to execute on each tick.
24    /// The engine will iterate through this vector in order.
25    #[serde(default = "default_phases")]
26    pub phases: Vec<PhaseConfig>,
27
28    /// Configuration for calendar-based "Gong" events.
29    #[serde(default)]
30    pub gong_config: GongConfig,
31}
32
33/// Defines the operational speed of the `SystemClock`.
34#[derive(Debug, Clone, Deserialize)]
35#[serde(rename_all = "lowercase")]
36pub enum ClockResolution {
37    /// ~120 ticks per second. Ideal for high-speed, competitive games.
38    Ultra,
39  /// ~60 ticks per second. Suitable for real-time applications.
40    High,
41    /// ~30 ticks per second. Suitable for general purpose simulations.
42    Medium,
43    /// ~1 tick per second. Suitable for strategic or turn-based logic.
44    Low,
45    /// A user-defined speed in ticks per second.
46    Custom { ticks_per_second: u64 },
47}
48
49/// Defines a single phase in the engine's cycle.
50#[derive(Debug, Clone, Deserialize)]
51pub struct PhaseConfig {
52    /// The numeric ID for this phase. Listeners will subscribe to this ID.
53    pub id: PhaseId,
54    /// A human-readable label for debugging and logging purposes.
55    pub label: String,
56}
57
58/// Configuration for calendar-based `GongEvent`s.
59#[derive(Debug, Clone, Deserialize)]
60pub struct GongConfig {
61    /// The timezone the engine should operate in for calendar calculations.
62    /// Defaults to UTC. Uses the string names from the IANA Time Zone Database
63    /// (e.g., "America/New_York").
64    #[serde(default = "default_timezone")]
65    pub timezone: Tz,
66
67    /// A list of custom holidays the GongWatcher should be aware of.
68    #[serde(default)]
69    pub holidays: Vec<Holiday>,
70
71    /// A list of custom times for workday-related gongs.
72    #[serde(default)]
73    pub workday_milestones: Vec<NaiveTime>,
74}
75
76/// Represents a custom holiday for the `GongWatcher`.
77#[derive(Debug, Clone, Deserialize)]
78pub struct Holiday {
79    pub name: String,
80    // CORRECTED: Use NaiveDate, which implements Deserialize.
81    pub date: NaiveDate,
82}
83
84// --- Default value functions for serde ---
85
86fn default_phases() -> Vec<PhaseConfig> {
87    vec![PhaseConfig {
88        id: PhaseId(0),
89        label: "default_phase".to_string(),
90    }]
91}
92
93fn default_timezone() -> Tz {
94    Tz::UTC
95}
96
97impl Default for GongConfig {
98    fn default() -> Self {
99        Self {
100            timezone: default_timezone(),
101            holidays: Vec::new(),
102            workday_milestones: Vec::new(),
103        }
104    }
105}