1#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
2pub struct RemoteTriggerOccurrenceRequest {
3 pub protocol_version: u32,
4 pub source_type: String,
5 pub source_key: String,
6 #[serde(default)]
7 pub payload: serde_json::Value,
8 pub idempotency_key: String,
9 #[serde(default, skip_serializing_if = "Option::is_none")]
10 pub source: Option<serde_json::Value>,
11}
12
13impl RemoteTriggerOccurrenceRequest {
14 pub fn new(
15 source_type: impl Into<String>,
16 source_key: impl Into<String>,
17 payload: serde_json::Value,
18 idempotency_key: impl Into<String>,
19 ) -> Self {
20 Self {
21 protocol_version: REMOTE_PROTOCOL_VERSION,
22 source_type: source_type.into(),
23 source_key: source_key.into(),
24 payload,
25 idempotency_key: idempotency_key.into(),
26 source: None,
27 }
28 }
29
30 pub fn with_source(mut self, source: serde_json::Value) -> Self {
31 self.source = Some(source);
32 self
33 }
34
35 pub fn validate(&self) -> Result<(), RemoteProtocolError> {
36 ensure_protocol_version(self.protocol_version)?;
37 require_non_empty(
38 "RemoteTriggerOccurrenceRequest",
39 "source_type",
40 &self.source_type,
41 )?;
42 require_non_empty(
43 "RemoteTriggerOccurrenceRequest",
44 "source_key",
45 &self.source_key,
46 )?;
47 require_non_empty(
48 "RemoteTriggerOccurrenceRequest",
49 "idempotency_key",
50 &self.idempotency_key,
51 )
52 }
53}
54
55#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
56pub struct RemoteTriggerOccurrenceRecord {
57 pub occurrence_id: String,
58 pub source_type: String,
59 pub source_key: String,
60 #[serde(default)]
61 pub payload: serde_json::Value,
62 pub idempotency_key: String,
63 #[serde(default, skip_serializing_if = "Option::is_none")]
64 pub source: Option<serde_json::Value>,
65 pub occurred_at_ms: u64,
66}
67
68#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
69pub struct RemoteTriggerEmitReport {
70 pub protocol_version: u32,
71 #[serde(default, skip_serializing_if = "String::is_empty")]
72 pub occurrence_id: String,
73 #[serde(default, skip_serializing_if = "Vec::is_empty")]
74 pub started_process_ids: Vec<String>,
75}
76
77impl RemoteTriggerEmitReport {
78 pub fn validate(&self) -> Result<(), RemoteProtocolError> {
79 ensure_protocol_version(self.protocol_version)
80 }
81}
82
83#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
84pub struct RemoteTriggerSubscriptionFilter {
85 pub protocol_version: u32,
86 #[serde(default, skip_serializing_if = "Option::is_none")]
87 pub session_id: Option<String>,
88 #[serde(default, skip_serializing_if = "Option::is_none")]
89 pub handle: Option<String>,
90 #[serde(default, skip_serializing_if = "Option::is_none")]
91 pub name: Option<String>,
92 #[serde(default, skip_serializing_if = "Option::is_none")]
93 pub source_type: Option<String>,
94 #[serde(default, skip_serializing_if = "Option::is_none")]
95 pub source_key: Option<String>,
96 #[serde(default, skip_serializing_if = "Option::is_none")]
97 pub target: Option<RemoteTriggerTargetIdentity>,
98 #[serde(default, skip_serializing_if = "Option::is_none")]
99 pub enabled: Option<bool>,
100}
101
102impl Default for RemoteTriggerSubscriptionFilter {
103 fn default() -> Self {
104 Self {
105 protocol_version: REMOTE_PROTOCOL_VERSION,
106 session_id: None,
107 handle: None,
108 name: None,
109 source_type: None,
110 source_key: None,
111 target: None,
112 enabled: None,
113 }
114 }
115}
116
117impl RemoteTriggerSubscriptionFilter {
118 pub fn for_session(session_id: impl Into<String>) -> Self {
119 Self {
120 protocol_version: REMOTE_PROTOCOL_VERSION,
121 session_id: Some(session_id.into()),
122 ..Self::default()
123 }
124 }
125
126 pub fn for_source_type(source_type: impl Into<String>) -> Self {
127 Self {
128 protocol_version: REMOTE_PROTOCOL_VERSION,
129 source_type: Some(source_type.into()),
130 ..Self::default()
131 }
132 }
133
134 pub fn validate(&self) -> Result<(), RemoteProtocolError> {
135 ensure_protocol_version(self.protocol_version)
136 }
137}
138
139#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
140pub struct RemoteTriggerRegistration {
141 pub handle: String,
142 pub source_key: String,
143 #[serde(default, skip_serializing_if = "Option::is_none")]
144 pub name: Option<String>,
145 pub source_type: String,
146 #[serde(default)]
147 pub source: serde_json::Value,
148 pub target: RemoteTriggerTargetSummary,
149 #[serde(default = "default_true")]
150 pub enabled: bool,
151}
152
153#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
154pub struct RemoteTriggerTargetSummary {
155 pub process_name: String,
156 #[serde(default)]
157 pub inputs: RemoteTriggerInputTemplate,
158}
159
160fn default_true() -> bool {
161 true
162}
163
164#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
165pub struct RemoteTriggerTargetIdentity {
166 pub module_ref: String,
167 pub host_requirements_ref: String,
168 pub process_ref: RemoteLashlangProcessRef,
169 pub process_name: String,
170}
171
172impl RemoteTriggerTargetIdentity {
173 pub fn validate(&self, type_name: &'static str) -> Result<(), RemoteProtocolError> {
174 require_non_empty(type_name, "module_ref", &self.module_ref)?;
175 require_non_empty(type_name, "host_requirements_ref", &self.host_requirements_ref)?;
176 self.process_ref.validate(type_name)?;
177 require_non_empty(type_name, "process_name", &self.process_name)
178 }
179}
180
181#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize, JsonSchema)]
182#[serde(transparent)]
183pub struct RemoteTriggerInputTemplate {
184 pub entries: BTreeMap<String, RemoteTriggerInputBinding>,
185}
186
187impl RemoteTriggerInputTemplate {
188 pub fn new(entries: BTreeMap<String, RemoteTriggerInputBinding>) -> Self {
189 Self { entries }
190 }
191
192 pub fn validate(&self, type_name: &'static str) -> Result<(), RemoteProtocolError> {
193 for name in self.entries.keys() {
194 require_non_empty(type_name, "input_template key", name)?;
195 }
196 Ok(())
197 }
198}
199
200#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
201#[serde(tag = "kind", rename_all = "snake_case")]
202pub enum RemoteTriggerInputBinding {
203 Event,
204 Fixed { value: serde_json::Value },
205}
206
207#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
208pub struct RemoteTriggerSubscriptionDraft {
209 pub protocol_version: u32,
210 pub registrant: RemoteProcessOriginator,
211 pub env_ref: String,
212 #[serde(default, skip_serializing_if = "Option::is_none")]
213 pub wake_target: Option<RemoteSessionScope>,
214 #[serde(default, skip_serializing_if = "Option::is_none")]
215 pub name: Option<String>,
216 pub source_type: String,
217 pub source_key: String,
218 #[serde(default)]
219 pub source: serde_json::Value,
220 #[serde(default)]
221 pub event_ty: serde_json::Value,
222 pub target: RemoteTriggerTargetIdentity,
223 #[serde(default)]
224 pub input_template: RemoteTriggerInputTemplate,
225}
226
227impl RemoteTriggerSubscriptionDraft {
228 pub fn validate(&self) -> Result<(), RemoteProtocolError> {
229 ensure_protocol_version(self.protocol_version)?;
230 self.registrant.validate("RemoteTriggerSubscriptionDraft")?;
231 require_non_empty("RemoteTriggerSubscriptionDraft", "env_ref", &self.env_ref)?;
232 if let Some(wake_target) = &self.wake_target {
233 wake_target.validate("RemoteTriggerSubscriptionDraft")?;
234 }
235 require_non_empty(
236 "RemoteTriggerSubscriptionDraft",
237 "source_type",
238 &self.source_type,
239 )?;
240 require_non_empty(
241 "RemoteTriggerSubscriptionDraft",
242 "source_key",
243 &self.source_key,
244 )?;
245 self.target.validate("RemoteTriggerSubscriptionDraft")?;
246 self.input_template
247 .validate("RemoteTriggerSubscriptionDraft")
248 }
249}
250
251#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
252pub struct RemoteTriggerSubscriptionRecord {
253 pub subscription_id: String,
254 pub registrant: RemoteProcessOriginator,
255 pub env_ref: String,
256 #[serde(default, skip_serializing_if = "Option::is_none")]
257 pub wake_target: Option<RemoteSessionScope>,
258 pub handle: String,
259 #[serde(default, skip_serializing_if = "Option::is_none")]
260 pub name: Option<String>,
261 pub source_type: String,
262 pub source_key: String,
263 #[serde(default)]
264 pub source: serde_json::Value,
265 #[serde(default)]
266 pub event_ty: serde_json::Value,
267 pub target: RemoteTriggerTargetIdentity,
268 #[serde(default)]
269 pub input_template: RemoteTriggerInputTemplate,
270 #[serde(default = "default_true")]
271 pub enabled: bool,
272 pub created_at_ms: u64,
273 pub updated_at_ms: u64,
274}
275
276impl RemoteTriggerSubscriptionRecord {
277 pub fn validate(&self, type_name: &'static str) -> Result<(), RemoteProtocolError> {
278 require_non_empty(type_name, "subscription_id", &self.subscription_id)?;
279 self.registrant.validate(type_name)?;
280 require_non_empty(type_name, "env_ref", &self.env_ref)?;
281 if let Some(wake_target) = &self.wake_target {
282 wake_target.validate(type_name)?;
283 }
284 require_non_empty(type_name, "handle", &self.handle)?;
285 require_non_empty(type_name, "source_type", &self.source_type)?;
286 require_non_empty(type_name, "source_key", &self.source_key)?;
287 self.target.validate(type_name)?;
288 self.input_template.validate(type_name)
289 }
290}
291
292#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
293pub struct RemoteTriggerRegisterSubscriptionRequest {
294 pub protocol_version: u32,
295 pub draft: RemoteTriggerSubscriptionDraft,
296}
297
298impl RemoteTriggerRegisterSubscriptionRequest {
299 pub fn validate(&self) -> Result<(), RemoteProtocolError> {
300 ensure_protocol_version(self.protocol_version)?;
301 if self.draft.protocol_version != self.protocol_version {
302 return Err(RemoteProtocolError::MismatchedNestedProtocolVersion {
303 parent: "RemoteTriggerRegisterSubscriptionRequest",
304 child: "draft",
305 parent_version: self.protocol_version,
306 child_version: self.draft.protocol_version,
307 });
308 }
309 self.draft.validate()
310 }
311}
312
313#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
314pub struct RemoteTriggerRegisterSubscriptionResult {
315 pub protocol_version: u32,
316 pub record: RemoteTriggerSubscriptionRecord,
317}
318
319impl RemoteTriggerRegisterSubscriptionResult {
320 pub fn validate(&self) -> Result<(), RemoteProtocolError> {
321 ensure_protocol_version(self.protocol_version)?;
322 self.record
323 .validate("RemoteTriggerRegisterSubscriptionResult")
324 }
325}
326
327#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
328pub struct RemoteTriggerListSubscriptionsResponse {
329 pub protocol_version: u32,
330 #[serde(default)]
331 pub subscriptions: Vec<RemoteTriggerSubscriptionRecord>,
332}
333
334impl RemoteTriggerListSubscriptionsResponse {
335 pub fn validate(&self) -> Result<(), RemoteProtocolError> {
336 ensure_protocol_version(self.protocol_version)?;
337 for record in &self.subscriptions {
338 record.validate("RemoteTriggerListSubscriptionsResponse")?;
339 }
340 Ok(())
341 }
342}
343
344#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
345pub struct RemoteTriggerCancelSubscriptionRequest {
346 pub protocol_version: u32,
347 pub session_id: String,
348 pub handle: String,
349}
350
351impl RemoteTriggerCancelSubscriptionRequest {
352 pub fn validate(&self) -> Result<(), RemoteProtocolError> {
353 ensure_protocol_version(self.protocol_version)?;
354 require_non_empty(
355 "RemoteTriggerCancelSubscriptionRequest",
356 "session_id",
357 &self.session_id,
358 )?;
359 require_non_empty(
360 "RemoteTriggerCancelSubscriptionRequest",
361 "handle",
362 &self.handle,
363 )
364 }
365}
366
367#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
368pub struct RemoteTriggerCancelSubscriptionResult {
369 pub protocol_version: u32,
370 pub session_id: String,
371 pub handle: String,
372 pub cancelled: bool,
373}
374
375impl RemoteTriggerCancelSubscriptionResult {
376 pub fn validate(&self) -> Result<(), RemoteProtocolError> {
377 ensure_protocol_version(self.protocol_version)?;
378 require_non_empty(
379 "RemoteTriggerCancelSubscriptionResult",
380 "session_id",
381 &self.session_id,
382 )?;
383 require_non_empty(
384 "RemoteTriggerCancelSubscriptionResult",
385 "handle",
386 &self.handle,
387 )
388 }
389}