temporal_field/
config.rs

1//! Field configuration
2
3#[cfg(feature = "serde")]
4use serde::{Deserialize, Serialize};
5
6/// Configuration for a temporal field.
7#[derive(Clone, Debug)]
8#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9pub struct FieldConfig {
10    /// Number of dimensions per frame.
11    pub dims: usize,
12
13    /// Number of frames in the ring buffer.
14    pub frame_count: usize,
15
16    /// Decay retention per tick (0.0 = instant zero, 1.0 = no decay).
17    pub retention: f32,
18
19    /// Tick rate in Hz (for time calculations).
20    pub tick_rate_hz: u32,
21}
22
23impl FieldConfig {
24    /// Create a standard configuration.
25    pub fn new(dims: usize, frame_count: usize, retention: f32) -> Self {
26        Self {
27            dims,
28            frame_count,
29            retention,
30            tick_rate_hz: 100,
31        }
32    }
33
34    /// Get temporal window duration in milliseconds.
35    pub fn window_ms(&self) -> f32 {
36        (self.frame_count as f32 * 1000.0) / self.tick_rate_hz as f32
37    }
38
39    /// Validate configuration.
40    pub fn validate(&self) -> Result<(), &'static str> {
41        if self.dims == 0 {
42            return Err("dims must be > 0");
43        }
44        if self.frame_count == 0 {
45            return Err("frame_count must be > 0");
46        }
47        if !(0.0..=1.0).contains(&self.retention) {
48            return Err("retention must be in [0, 1]");
49        }
50        Ok(())
51    }
52}