1use crate::error::RuntimeResult;
15use crate::ids::{validate_identifier, AppId, CommandName, EventName, NodeId};
16use crate::trace::TraceContext;
17
18#[derive(Debug, Clone, PartialEq, Eq)]
20pub struct CommandEnvelope {
21 pub command_name: CommandName,
23 pub command_id: String,
25 pub app_id: AppId,
27 pub node_id: NodeId,
29 pub issued_at_ms: u64,
31 pub idempotency_key: Option<String>,
33 pub payload: Vec<u8>,
35 pub trace: Option<TraceContext>,
37}
38
39impl CommandEnvelope {
40 pub fn new(
42 command_name: CommandName,
43 command_id: String,
44 app_id: AppId,
45 node_id: NodeId,
46 issued_at_ms: u64,
47 idempotency_key: Option<String>,
48 payload: Vec<u8>,
49 ) -> RuntimeResult<Self> {
50 validate_identifier("CommandId", &command_id)?;
51 if let Some(key) = &idempotency_key {
52 validate_identifier("IdempotencyKey", key)?;
53 }
54 command_name.validate()?;
55 app_id.validate()?;
56 node_id.validate()?;
57
58 Ok(Self {
59 command_name,
60 command_id,
61 app_id,
62 node_id,
63 issued_at_ms,
64 idempotency_key,
65 payload,
66 trace: None,
67 })
68 }
69
70 pub fn with_trace(mut self, trace: TraceContext) -> Self {
72 self.trace = Some(trace);
73 self
74 }
75
76 pub fn command_name(&self) -> &CommandName {
78 &self.command_name
79 }
80
81 pub fn payload(&self) -> &[u8] {
83 &self.payload
84 }
85}
86
87#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
89pub struct EventEnvelope {
90 pub event_name: EventName,
92 pub event_id: String,
94 pub app_id: AppId,
96 pub node_id: NodeId,
98 pub occurred_at_ms: u64,
100 pub payload: Vec<u8>,
102 pub trace: Option<TraceContext>,
104}
105
106impl EventEnvelope {
107 pub fn new(
109 event_name: EventName,
110 event_id: String,
111 app_id: AppId,
112 node_id: NodeId,
113 occurred_at_ms: u64,
114 payload: Vec<u8>,
115 ) -> RuntimeResult<Self> {
116 validate_identifier("EventId", &event_id)?;
117 event_name.validate()?;
118 app_id.validate()?;
119 node_id.validate()?;
120
121 Ok(Self {
122 event_name,
123 event_id,
124 app_id,
125 node_id,
126 occurred_at_ms,
127 payload,
128 trace: None,
129 })
130 }
131
132 pub fn with_trace(mut self, trace: TraceContext) -> Self {
134 self.trace = Some(trace);
135 self
136 }
137
138 pub fn event_name(&self) -> &EventName {
140 &self.event_name
141 }
142
143 pub fn payload(&self) -> &[u8] {
145 &self.payload
146 }
147}
148
149#[cfg(test)]
150#[path = "envelope_tests.rs"]
151mod tests;