cuenv_events/
metadata.rs

1//! Metadata management for cuenv events.
2//!
3//! Provides correlation ID tracking and metadata context for event emission.
4
5use std::sync::OnceLock;
6use uuid::Uuid;
7
8/// Global correlation ID for the current session.
9static CORRELATION_ID: OnceLock<Uuid> = OnceLock::new();
10
11/// Get or create a correlation ID for the current session.
12///
13/// This returns the same ID throughout the lifetime of the process,
14/// allowing all events to be correlated together.
15#[must_use]
16pub fn correlation_id() -> Uuid {
17    *CORRELATION_ID.get_or_init(Uuid::new_v4)
18}
19
20/// Set the correlation ID for the current session.
21///
22/// This can only be called once; subsequent calls will be ignored.
23/// Returns `true` if the ID was set, `false` if it was already set.
24pub fn set_correlation_id(id: Uuid) -> bool {
25    CORRELATION_ID.set(id).is_ok()
26}
27
28/// Metadata context for event emission.
29///
30/// Holds configuration and state used when creating events.
31#[derive(Debug, Clone)]
32pub struct MetadataContext {
33    /// The correlation ID for this context.
34    pub correlation_id: Uuid,
35    /// Optional default target for events.
36    pub default_target: Option<String>,
37}
38
39impl MetadataContext {
40    /// Create a new metadata context with the global correlation ID.
41    #[must_use]
42    pub fn new() -> Self {
43        Self {
44            correlation_id: correlation_id(),
45            default_target: None,
46        }
47    }
48
49    /// Create a new metadata context with a specific correlation ID.
50    #[must_use]
51    pub fn with_correlation_id(id: Uuid) -> Self {
52        Self {
53            correlation_id: id,
54            default_target: None,
55        }
56    }
57
58    /// Set a default target for events created with this context.
59    #[must_use]
60    pub fn with_target(mut self, target: impl Into<String>) -> Self {
61        self.default_target = Some(target.into());
62        self
63    }
64}
65
66impl Default for MetadataContext {
67    fn default() -> Self {
68        Self::new()
69    }
70}
71
72#[cfg(test)]
73mod tests {
74    use super::*;
75
76    #[test]
77    fn test_correlation_id_consistency() {
78        let id1 = correlation_id();
79        let id2 = correlation_id();
80        assert_eq!(id1, id2);
81    }
82
83    #[test]
84    fn test_metadata_context_creation() {
85        let ctx = MetadataContext::new();
86        assert!(!ctx.correlation_id.is_nil());
87        assert!(ctx.default_target.is_none());
88    }
89
90    #[test]
91    fn test_metadata_context_with_target() {
92        let ctx = MetadataContext::new().with_target("cuenv::test");
93        assert_eq!(ctx.default_target, Some("cuenv::test".to_string()));
94    }
95}