Skip to main content

photon_backend/
registry.rs

1//! Topic registry for discovering and looking up registered topics.
2
3#![allow(missing_docs)]
4
5use crate::descriptor::TopicDescriptor;
6use crate::error::{PhotonError, Result};
7
8quark::define_registry! {
9    /// Registry of all topics discovered via `#[photon::topic]`.
10    pub struct TopicRegistry for TopicDescriptor;
11}
12
13impl TopicRegistry {
14    /// Look up a topic by name, returning an error if not found.
15    ///
16    /// # Errors
17    ///
18    /// Returns an error if the operation fails.
19    pub fn get_or_err(&self, topic_name: &str) -> Result<&'static TopicDescriptor> {
20        self.get(topic_name)
21            .ok_or_else(|| PhotonError::TopicNotFound(topic_name.to_string()))
22    }
23
24    /// Topic names in sorted order for deterministic registration across platforms.
25    #[must_use]
26    pub fn sorted_topic_names(&self) -> Vec<&str> {
27        let mut names = self.list();
28        names.sort_unstable();
29        names
30    }
31}
32
33#[cfg(test)]
34mod tests {
35    use super::*;
36
37    #[test]
38    fn test_empty_registry() {
39        let registry = TopicRegistry::new();
40        assert!(registry.is_empty());
41        assert_eq!(registry.len(), 0);
42        assert!(registry.get("nonexistent").is_none());
43    }
44
45    #[test]
46    fn test_auto_discover() {
47        let registry = TopicRegistry::auto_discover();
48        let _ = registry.list();
49    }
50
51    #[test]
52    fn test_get_or_err_not_found() {
53        let registry = TopicRegistry::new();
54        let err = registry.get_or_err("nonexistent").unwrap_err();
55        assert!(matches!(err, PhotonError::TopicNotFound(_)));
56    }
57}