Skip to main content

pite_core/
signals.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2//! Signal definitions and registry for engine and user signal routing.
3
4use std::collections::HashMap;
5
6/// A registered signal definition specifying its event name and typed payload arguments.
7#[derive(Debug, Clone, PartialEq)]
8pub struct SignalDef {
9    /// Signal identifier (e.g. `"timeout"`, `"pressed"`, or `"health_changed"`).
10    pub name: String,
11    /// Ordered list of payload argument type names (e.g. `["int", "string"]`).
12    pub payload: Vec<String>,
13}
14
15/// Registry storing signal definitions for validation and dynamic dispatch.
16#[derive(Debug, Default)]
17pub struct SignalRegistry {
18    defs: HashMap<String, SignalDef>,
19}
20
21impl SignalRegistry {
22    /// Creates a new empty signal registry.
23    pub fn new() -> Self {
24        Self::default()
25    }
26
27    /// Registers a new signal definition with the given name and payload signature.
28    pub fn register(&mut self, name: impl Into<String>, payload: Vec<String>) {
29        let name = name.into();
30        self.defs.insert(name.clone(), SignalDef { name, payload });
31    }
32
33    /// Looks up a signal definition by name.
34    pub fn get(&self, name: &str) -> Option<&SignalDef> {
35        self.defs.get(name)
36    }
37
38    /// Returns the number of registered signals.
39    pub fn len(&self) -> usize {
40        self.defs.len()
41    }
42
43    /// Returns true if no signals are registered.
44    pub fn is_empty(&self) -> bool {
45        self.defs.is_empty()
46    }
47}
48
49#[cfg(test)]
50mod tests {
51    use super::*;
52
53    #[test]
54    fn registry_records_name_and_payload() {
55        let mut registry = SignalRegistry::new();
56        registry.register("health_changed", vec!["int".to_string()]);
57        let def = registry.get("health_changed").unwrap();
58        assert_eq!(def.payload, vec!["int".to_string()]);
59    }
60}