Skip to main content

lxmf_sdk/
domain.rs

1use crate::types::{Ack, MessageId};
2use serde::{Deserialize, Serialize};
3use serde_json::Value as JsonValue;
4use std::collections::BTreeMap;
5
6#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
7pub struct TopicId(pub String);
8
9#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
10pub struct TopicPath(pub String);
11
12#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
13pub struct TopicCreateRequest {
14    pub topic_path: Option<TopicPath>,
15    #[serde(default)]
16    pub metadata: BTreeMap<String, JsonValue>,
17    #[serde(default)]
18    pub extensions: BTreeMap<String, JsonValue>,
19}
20
21#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
22pub struct TopicRecord {
23    pub topic_id: TopicId,
24    pub topic_path: Option<TopicPath>,
25    pub created_ts_ms: u64,
26    #[serde(default)]
27    pub metadata: BTreeMap<String, JsonValue>,
28    #[serde(default)]
29    pub extensions: BTreeMap<String, JsonValue>,
30}
31
32#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
33pub struct TopicPublishRequest {
34    pub topic_id: TopicId,
35    pub payload: JsonValue,
36    pub correlation_id: Option<String>,
37    #[serde(default)]
38    pub extensions: BTreeMap<String, JsonValue>,
39}
40
41#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
42pub struct TopicListRequest {
43    pub cursor: Option<String>,
44    pub limit: Option<usize>,
45    #[serde(default)]
46    pub extensions: BTreeMap<String, JsonValue>,
47}
48
49#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
50pub struct TopicListResult {
51    pub topics: Vec<TopicRecord>,
52    pub next_cursor: Option<String>,
53}
54
55#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
56pub struct TopicSubscriptionRequest {
57    pub topic_id: TopicId,
58    pub cursor: Option<String>,
59    #[serde(default)]
60    pub extensions: BTreeMap<String, JsonValue>,
61}
62
63#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
64pub struct TelemetryQuery {
65    pub peer_id: Option<String>,
66    pub topic_id: Option<TopicId>,
67    pub from_ts_ms: Option<u64>,
68    pub to_ts_ms: Option<u64>,
69    pub limit: Option<usize>,
70    #[serde(default)]
71    pub extensions: BTreeMap<String, JsonValue>,
72}
73
74#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
75pub struct TelemetryPoint {
76    pub ts_ms: u64,
77    pub key: String,
78    pub value: JsonValue,
79    pub unit: Option<String>,
80    #[serde(default)]
81    pub tags: BTreeMap<String, String>,
82    #[serde(default)]
83    pub extensions: BTreeMap<String, JsonValue>,
84}
85
86#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
87pub struct AttachmentId(pub String);
88
89#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
90pub struct AttachmentStoreRequest {
91    pub name: String,
92    pub content_type: String,
93    pub bytes_base64: String,
94    pub expires_ts_ms: Option<u64>,
95    #[serde(default)]
96    pub topic_ids: Vec<TopicId>,
97    #[serde(default)]
98    pub extensions: BTreeMap<String, JsonValue>,
99}
100
101#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
102pub struct AttachmentMeta {
103    pub attachment_id: AttachmentId,
104    pub name: String,
105    pub content_type: String,
106    pub byte_len: u64,
107    pub checksum_sha256: String,
108    pub created_ts_ms: u64,
109    pub expires_ts_ms: Option<u64>,
110    #[serde(default)]
111    pub topic_ids: Vec<TopicId>,
112    #[serde(default)]
113    pub extensions: BTreeMap<String, JsonValue>,
114}
115
116#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
117pub struct AttachmentListRequest {
118    pub topic_id: Option<TopicId>,
119    pub cursor: Option<String>,
120    pub limit: Option<usize>,
121    #[serde(default)]
122    pub extensions: BTreeMap<String, JsonValue>,
123}
124
125#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
126pub struct AttachmentListResult {
127    pub attachments: Vec<AttachmentMeta>,
128    pub next_cursor: Option<String>,
129}
130
131#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
132pub struct AttachmentUploadId(pub String);
133
134#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
135pub struct AttachmentUploadStartRequest {
136    pub name: String,
137    pub content_type: String,
138    pub total_size: u64,
139    pub checksum_sha256: String,
140    pub expires_ts_ms: Option<u64>,
141    #[serde(default)]
142    pub topic_ids: Vec<TopicId>,
143    #[serde(default)]
144    pub extensions: BTreeMap<String, JsonValue>,
145}
146
147#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
148pub struct AttachmentUploadSession {
149    pub upload_id: AttachmentUploadId,
150    pub attachment_id: AttachmentId,
151    pub chunk_size_hint: usize,
152    pub next_offset: u64,
153}
154
155#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
156pub struct AttachmentUploadChunkRequest {
157    pub upload_id: AttachmentUploadId,
158    pub offset: u64,
159    pub bytes_base64: String,
160    #[serde(default)]
161    pub extensions: BTreeMap<String, JsonValue>,
162}
163
164#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
165pub struct AttachmentUploadChunkAck {
166    pub accepted: bool,
167    pub next_offset: u64,
168    pub complete: bool,
169}
170
171#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
172pub struct AttachmentUploadCommitRequest {
173    pub upload_id: AttachmentUploadId,
174    #[serde(default)]
175    pub extensions: BTreeMap<String, JsonValue>,
176}
177
178#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
179pub struct AttachmentDownloadChunkRequest {
180    pub attachment_id: AttachmentId,
181    pub offset: u64,
182    pub max_bytes: usize,
183    #[serde(default)]
184    pub extensions: BTreeMap<String, JsonValue>,
185}
186
187#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
188pub struct AttachmentDownloadChunk {
189    pub attachment_id: AttachmentId,
190    pub offset: u64,
191    pub next_offset: u64,
192    pub total_size: u64,
193    pub done: bool,
194    pub checksum_sha256: String,
195    pub bytes_base64: String,
196}
197
198#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
199pub struct MarkerId(pub String);
200
201#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
202pub struct GeoPoint {
203    pub lat: f64,
204    pub lon: f64,
205    pub alt_m: Option<f64>,
206}
207
208#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
209pub struct MarkerCreateRequest {
210    pub label: String,
211    pub position: GeoPoint,
212    pub topic_id: Option<TopicId>,
213    #[serde(default)]
214    pub extensions: BTreeMap<String, JsonValue>,
215}
216
217#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
218pub struct MarkerUpdatePositionRequest {
219    pub marker_id: MarkerId,
220    pub expected_revision: u64,
221    pub position: GeoPoint,
222    #[serde(default)]
223    pub extensions: BTreeMap<String, JsonValue>,
224}
225
226#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
227pub struct MarkerDeleteRequest {
228    pub marker_id: MarkerId,
229    pub expected_revision: u64,
230    #[serde(default)]
231    pub extensions: BTreeMap<String, JsonValue>,
232}
233
234#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
235pub struct MarkerRecord {
236    pub marker_id: MarkerId,
237    pub label: String,
238    pub position: GeoPoint,
239    pub topic_id: Option<TopicId>,
240    pub revision: u64,
241    pub updated_ts_ms: u64,
242    #[serde(default)]
243    pub extensions: BTreeMap<String, JsonValue>,
244}
245
246#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
247pub struct MarkerListRequest {
248    pub topic_id: Option<TopicId>,
249    pub cursor: Option<String>,
250    pub limit: Option<usize>,
251    #[serde(default)]
252    pub extensions: BTreeMap<String, JsonValue>,
253}
254
255#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
256pub struct MarkerListResult {
257    pub markers: Vec<MarkerRecord>,
258    pub next_cursor: Option<String>,
259}
260
261#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
262pub struct IdentityRef(pub String);
263
264#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
265pub struct IdentityBundle {
266    pub identity: IdentityRef,
267    pub public_key: String,
268    pub display_name: Option<String>,
269    #[serde(default)]
270    pub capabilities: Vec<String>,
271    #[serde(default)]
272    pub extensions: BTreeMap<String, JsonValue>,
273}
274
275#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
276pub struct IdentityImportRequest {
277    pub bundle_base64: String,
278    pub passphrase: Option<String>,
279    #[serde(default)]
280    pub extensions: BTreeMap<String, JsonValue>,
281}
282
283#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
284pub struct IdentityResolveRequest {
285    pub hash: String,
286    #[serde(default)]
287    pub extensions: BTreeMap<String, JsonValue>,
288}
289
290#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
291#[serde(rename_all = "snake_case")]
292pub enum TrustLevel {
293    Unknown,
294    Untrusted,
295    Trusted,
296    Blocked,
297}
298
299#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
300pub struct ContactUpdateRequest {
301    pub identity: IdentityRef,
302    pub display_name: Option<String>,
303    pub trust_level: Option<TrustLevel>,
304    pub bootstrap: Option<bool>,
305    #[serde(default)]
306    pub metadata: BTreeMap<String, JsonValue>,
307    #[serde(default)]
308    pub extensions: BTreeMap<String, JsonValue>,
309}
310
311#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
312pub struct ContactRecord {
313    pub identity: IdentityRef,
314    pub display_name: Option<String>,
315    pub trust_level: TrustLevel,
316    pub bootstrap: bool,
317    pub updated_ts_ms: u64,
318    #[serde(default)]
319    pub metadata: BTreeMap<String, JsonValue>,
320    #[serde(default)]
321    pub extensions: BTreeMap<String, JsonValue>,
322}
323
324#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
325pub struct ContactListRequest {
326    pub cursor: Option<String>,
327    pub limit: Option<usize>,
328    #[serde(default)]
329    pub extensions: BTreeMap<String, JsonValue>,
330}
331
332#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
333pub struct ContactListResult {
334    pub contacts: Vec<ContactRecord>,
335    pub next_cursor: Option<String>,
336}
337
338#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
339pub struct PresenceListRequest {
340    pub cursor: Option<String>,
341    pub limit: Option<usize>,
342    #[serde(default)]
343    pub extensions: BTreeMap<String, JsonValue>,
344}
345
346#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
347pub struct PresenceRecord {
348    pub peer_id: String,
349    pub last_seen_ts_ms: i64,
350    pub first_seen_ts_ms: i64,
351    pub seen_count: u64,
352    pub name: Option<String>,
353    pub name_source: Option<String>,
354    pub trust_level: Option<TrustLevel>,
355    pub bootstrap: Option<bool>,
356    #[serde(default)]
357    pub extensions: BTreeMap<String, JsonValue>,
358}
359
360#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
361pub struct PresenceListResult {
362    pub peers: Vec<PresenceRecord>,
363    pub next_cursor: Option<String>,
364}
365
366#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
367pub struct IdentityBootstrapRequest {
368    pub identity: IdentityRef,
369    #[serde(default = "default_auto_sync")]
370    pub auto_sync: bool,
371    #[serde(default)]
372    pub extensions: BTreeMap<String, JsonValue>,
373}
374
375fn default_auto_sync() -> bool {
376    true
377}
378
379#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
380pub struct PaperMessageEnvelope {
381    pub uri: String,
382    pub transient_id: Option<String>,
383    pub destination_hint: Option<String>,
384    #[serde(default)]
385    pub extensions: BTreeMap<String, JsonValue>,
386}
387
388#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
389pub struct RemoteCommandRequest {
390    pub command: String,
391    pub target: Option<String>,
392    pub payload: JsonValue,
393    pub timeout_ms: Option<u64>,
394    #[serde(default)]
395    pub extensions: BTreeMap<String, JsonValue>,
396}
397
398#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
399pub struct RemoteCommandResponse {
400    pub accepted: bool,
401    pub payload: JsonValue,
402    #[serde(default)]
403    pub extensions: BTreeMap<String, JsonValue>,
404}
405
406#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
407#[serde(rename_all = "snake_case")]
408pub enum RemoteCommandState {
409    Dispatched,
410    ReceiptAcknowledged,
411    Processing,
412    Completed,
413    Failed,
414    #[serde(other)]
415    Unknown,
416}
417
418#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
419pub struct RemoteCommandSession {
420    pub command_id: String,
421    pub correlation_id: String,
422    pub command: String,
423    pub target: Option<String>,
424    pub timeout_ms: Option<u64>,
425    pub delivery_state: Option<String>,
426    pub command_state: RemoteCommandState,
427    pub created_at_ms: u64,
428    pub updated_at_ms: u64,
429    pub request_payload: JsonValue,
430    pub response_payload: Option<JsonValue>,
431    pub accepted: Option<bool>,
432    #[serde(default)]
433    pub extensions: BTreeMap<String, JsonValue>,
434}
435
436#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
437pub struct RemoteCommandSessionListRequest {
438    pub cursor: Option<String>,
439    pub limit: Option<usize>,
440    #[serde(default)]
441    pub extensions: BTreeMap<String, JsonValue>,
442}
443
444#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
445pub struct RemoteCommandSessionListResult {
446    pub sessions: Vec<RemoteCommandSession>,
447    pub next_cursor: Option<String>,
448}
449
450#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
451pub struct VoiceSessionId(pub String);
452
453#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
454#[serde(rename_all = "snake_case")]
455pub enum VoiceSessionState {
456    New,
457    Ringing,
458    Active,
459    Holding,
460    Closed,
461    Failed,
462    #[serde(other)]
463    Unknown,
464}
465
466#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
467pub struct VoiceSessionOpenRequest {
468    pub peer_id: String,
469    pub codec_hint: Option<String>,
470    #[serde(default)]
471    pub extensions: BTreeMap<String, JsonValue>,
472}
473
474#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
475pub struct VoiceSessionUpdateRequest {
476    pub session_id: VoiceSessionId,
477    pub state: VoiceSessionState,
478    #[serde(default)]
479    pub extensions: BTreeMap<String, JsonValue>,
480}
481
482#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
483pub struct WorkflowPeerReadyRequest {
484    pub identity: IdentityRef,
485    pub display_name: Option<String>,
486    pub trust_level: Option<TrustLevel>,
487    pub bootstrap: Option<bool>,
488    pub announce: Option<bool>,
489    #[serde(default)]
490    pub metadata: BTreeMap<String, JsonValue>,
491    #[serde(default)]
492    pub extensions: BTreeMap<String, JsonValue>,
493}
494
495#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
496pub struct WorkflowPeerReadyResult {
497    pub identity: IdentityRef,
498    pub contact: ContactRecord,
499    pub was_created: bool,
500    pub announced: bool,
501}
502
503#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
504pub struct WorkflowTopicSyncRequest {
505    pub topic_path: TopicPath,
506    #[serde(default)]
507    pub metadata: BTreeMap<String, JsonValue>,
508    pub telemetry_limit: Option<usize>,
509    #[serde(default)]
510    pub extensions: BTreeMap<String, JsonValue>,
511}
512
513#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
514pub struct WorkflowTopicSyncResult {
515    pub topic: TopicRecord,
516    pub was_created: bool,
517    pub subscribed: bool,
518    pub telemetry: Vec<TelemetryPoint>,
519}
520
521#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
522pub struct WorkflowAttachmentDraft {
523    pub name: String,
524    pub content_type: String,
525    pub bytes_base64: String,
526}
527
528#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
529pub struct WorkflowAttachmentReportRequest {
530    pub topic_path: TopicPath,
531    pub attachment: WorkflowAttachmentDraft,
532    pub summary_payload: Option<JsonValue>,
533    pub correlation_id: Option<String>,
534    #[serde(default)]
535    pub topic_metadata: BTreeMap<String, JsonValue>,
536    #[serde(default)]
537    pub extensions: BTreeMap<String, JsonValue>,
538}
539
540#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
541pub struct WorkflowAttachmentReportResult {
542    pub topic: TopicRecord,
543    pub attachment: AttachmentMeta,
544    pub published: Ack,
545}
546
547#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
548pub struct WorkflowMissionUpdateRequest {
549    pub peer_identity: IdentityRef,
550    pub content: String,
551    pub topic_path: Option<TopicPath>,
552    #[serde(default)]
553    pub attachments: Vec<WorkflowAttachmentDraft>,
554    #[serde(default)]
555    pub metadata: BTreeMap<String, JsonValue>,
556    pub correlation_id: Option<String>,
557    pub idempotency_key: Option<String>,
558    pub display_name: Option<String>,
559    pub trust_level: Option<TrustLevel>,
560    pub bootstrap: Option<bool>,
561    pub announce: Option<bool>,
562    #[serde(default)]
563    pub extensions: BTreeMap<String, JsonValue>,
564}
565
566#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
567pub struct WorkflowMissionUpdateResult {
568    pub peer: WorkflowPeerReadyResult,
569    pub message_id: MessageId,
570    pub topic: Option<TopicRecord>,
571    pub attachments: Vec<AttachmentMeta>,
572}
573
574#[cfg(test)]
575mod tests {
576    use super::VoiceSessionState;
577
578    #[test]
579    fn voice_session_state_deserializes_unknown_variant() {
580        let value = serde_json::json!("paused_by_gateway");
581        let state: VoiceSessionState =
582            serde_json::from_value(value).expect("unknown voice state should map to Unknown");
583        assert_eq!(state, VoiceSessionState::Unknown);
584    }
585}