Skip to main content

mesh_llm_runtime_event_contracts/
identity.rs

1//! Process-local runtime event identities.
2//!
3//! Event sequence is the sole reducer order key. Native sequence is source data
4//! only, and identities carry no cross-process ordering or correlation promise.
5//! A request root `OperationId` stores the same UUID bytes as the logging
6//! request ID, allowing correlation without a mapping table.
7
8use std::fmt;
9
10use uuid::Uuid;
11
12macro_rules! uuid_identity {
13    ($name:ident) => {
14        #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
15        pub struct $name(Uuid);
16
17        impl $name {
18            #[must_use]
19            pub fn new() -> Self {
20                Self(Uuid::new_v4())
21            }
22
23            #[must_use]
24            pub const fn from_uuid(value: Uuid) -> Self {
25                Self(value)
26            }
27
28            #[must_use]
29            pub const fn from_bytes(value: [u8; 16]) -> Self {
30                Self(Uuid::from_bytes(value))
31            }
32
33            #[must_use]
34            pub const fn into_bytes(self) -> [u8; 16] {
35                self.0.into_bytes()
36            }
37
38            #[must_use]
39            pub const fn as_uuid(&self) -> &Uuid {
40                &self.0
41            }
42        }
43
44        impl Default for $name {
45            fn default() -> Self {
46                Self::new()
47            }
48        }
49
50        impl fmt::Display for $name {
51            fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
52                self.0.fmt(formatter)
53            }
54        }
55    };
56}
57
58uuid_identity!(ProcessInstanceId);
59uuid_identity!(OperationId);
60uuid_identity!(ChildOperationId);
61
62#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
63pub struct EventSequence(u64);
64
65impl EventSequence {
66    #[must_use]
67    pub const fn new(value: u64) -> Self {
68        Self(value)
69    }
70
71    #[must_use]
72    pub const fn get(self) -> u64 {
73        self.0
74    }
75}
76
77#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
78pub struct EventId {
79    process_instance_id: ProcessInstanceId,
80    sequence: EventSequence,
81}
82
83impl EventId {
84    #[must_use]
85    pub const fn new(process_instance_id: ProcessInstanceId, sequence: EventSequence) -> Self {
86        Self {
87            process_instance_id,
88            sequence,
89        }
90    }
91
92    #[must_use]
93    pub const fn process_instance_id(self) -> ProcessInstanceId {
94        self.process_instance_id
95    }
96
97    #[must_use]
98    pub const fn sequence(self) -> EventSequence {
99        self.sequence
100    }
101}
102
103#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
104pub enum OperationScope {
105    Root(OperationId),
106    Child {
107        root: OperationId,
108        child: ChildOperationId,
109    },
110}
111
112impl OperationScope {
113    #[must_use]
114    pub const fn root_only(root: OperationId) -> Self {
115        Self::Root(root)
116    }
117
118    #[must_use]
119    pub const fn with_child(root: OperationId, child: ChildOperationId) -> Self {
120        Self::Child { root, child }
121    }
122
123    #[must_use]
124    pub const fn root(self) -> OperationId {
125        match self {
126            Self::Root(root) | Self::Child { root, .. } => root,
127        }
128    }
129
130    #[must_use]
131    pub const fn child(self) -> Option<ChildOperationId> {
132        match self {
133            Self::Root(_) => None,
134            Self::Child { child, .. } => Some(child),
135        }
136    }
137}