use crate::types::{Ack, MessageId};
use serde::{Deserialize, Serialize};
use serde_json::Value as JsonValue;
use std::collections::BTreeMap;
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub struct TopicId(pub String);
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub struct TopicPath(pub String);
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct TopicCreateRequest {
pub topic_path: Option<TopicPath>,
#[serde(default)]
pub metadata: BTreeMap<String, JsonValue>,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct TopicRecord {
pub topic_id: TopicId,
pub topic_path: Option<TopicPath>,
pub created_ts_ms: u64,
#[serde(default)]
pub metadata: BTreeMap<String, JsonValue>,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct TopicPublishRequest {
pub topic_id: TopicId,
pub payload: JsonValue,
pub correlation_id: Option<String>,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct TopicListRequest {
pub cursor: Option<String>,
pub limit: Option<usize>,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct TopicListResult {
pub topics: Vec<TopicRecord>,
pub next_cursor: Option<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct TopicSubscriptionRequest {
pub topic_id: TopicId,
pub cursor: Option<String>,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct TelemetryQuery {
pub peer_id: Option<String>,
pub topic_id: Option<TopicId>,
pub from_ts_ms: Option<u64>,
pub to_ts_ms: Option<u64>,
pub limit: Option<usize>,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct TelemetryPoint {
pub ts_ms: u64,
pub key: String,
pub value: JsonValue,
pub unit: Option<String>,
#[serde(default)]
pub tags: BTreeMap<String, String>,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub struct AttachmentId(pub String);
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct AttachmentStoreRequest {
pub name: String,
pub content_type: String,
pub bytes_base64: String,
pub expires_ts_ms: Option<u64>,
#[serde(default)]
pub topic_ids: Vec<TopicId>,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct AttachmentMeta {
pub attachment_id: AttachmentId,
pub name: String,
pub content_type: String,
pub byte_len: u64,
pub checksum_sha256: String,
pub created_ts_ms: u64,
pub expires_ts_ms: Option<u64>,
#[serde(default)]
pub topic_ids: Vec<TopicId>,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct AttachmentListRequest {
pub topic_id: Option<TopicId>,
pub cursor: Option<String>,
pub limit: Option<usize>,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct AttachmentListResult {
pub attachments: Vec<AttachmentMeta>,
pub next_cursor: Option<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub struct AttachmentUploadId(pub String);
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct AttachmentUploadStartRequest {
pub name: String,
pub content_type: String,
pub total_size: u64,
pub checksum_sha256: String,
pub expires_ts_ms: Option<u64>,
#[serde(default)]
pub topic_ids: Vec<TopicId>,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct AttachmentUploadSession {
pub upload_id: AttachmentUploadId,
pub attachment_id: AttachmentId,
pub chunk_size_hint: usize,
pub next_offset: u64,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct AttachmentUploadChunkRequest {
pub upload_id: AttachmentUploadId,
pub offset: u64,
pub bytes_base64: String,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct AttachmentUploadChunkAck {
pub accepted: bool,
pub next_offset: u64,
pub complete: bool,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct AttachmentUploadCommitRequest {
pub upload_id: AttachmentUploadId,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct AttachmentDownloadChunkRequest {
pub attachment_id: AttachmentId,
pub offset: u64,
pub max_bytes: usize,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct AttachmentDownloadChunk {
pub attachment_id: AttachmentId,
pub offset: u64,
pub next_offset: u64,
pub total_size: u64,
pub done: bool,
pub checksum_sha256: String,
pub bytes_base64: String,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub struct MarkerId(pub String);
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct GeoPoint {
pub lat: f64,
pub lon: f64,
pub alt_m: Option<f64>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct MarkerCreateRequest {
pub label: String,
pub position: GeoPoint,
pub topic_id: Option<TopicId>,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct MarkerUpdatePositionRequest {
pub marker_id: MarkerId,
pub expected_revision: u64,
pub position: GeoPoint,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct MarkerDeleteRequest {
pub marker_id: MarkerId,
pub expected_revision: u64,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct MarkerRecord {
pub marker_id: MarkerId,
pub label: String,
pub position: GeoPoint,
pub topic_id: Option<TopicId>,
pub revision: u64,
pub updated_ts_ms: u64,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct MarkerListRequest {
pub topic_id: Option<TopicId>,
pub cursor: Option<String>,
pub limit: Option<usize>,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct MarkerListResult {
pub markers: Vec<MarkerRecord>,
pub next_cursor: Option<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub struct IdentityRef(pub String);
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct IdentityBundle {
pub identity: IdentityRef,
pub public_key: String,
pub display_name: Option<String>,
#[serde(default)]
pub capabilities: Vec<String>,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct IdentityImportRequest {
pub bundle_base64: String,
pub passphrase: Option<String>,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct IdentityResolveRequest {
pub hash: String,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum TrustLevel {
Unknown,
Untrusted,
Trusted,
Blocked,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct ContactUpdateRequest {
pub identity: IdentityRef,
pub display_name: Option<String>,
pub trust_level: Option<TrustLevel>,
pub bootstrap: Option<bool>,
#[serde(default)]
pub metadata: BTreeMap<String, JsonValue>,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct ContactRecord {
pub identity: IdentityRef,
pub display_name: Option<String>,
pub trust_level: TrustLevel,
pub bootstrap: bool,
pub updated_ts_ms: u64,
#[serde(default)]
pub metadata: BTreeMap<String, JsonValue>,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct ContactListRequest {
pub cursor: Option<String>,
pub limit: Option<usize>,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct ContactListResult {
pub contacts: Vec<ContactRecord>,
pub next_cursor: Option<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct PresenceListRequest {
pub cursor: Option<String>,
pub limit: Option<usize>,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct PresenceRecord {
pub peer_id: String,
pub last_seen_ts_ms: i64,
pub first_seen_ts_ms: i64,
pub seen_count: u64,
pub name: Option<String>,
pub name_source: Option<String>,
pub trust_level: Option<TrustLevel>,
pub bootstrap: Option<bool>,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct PresenceListResult {
pub peers: Vec<PresenceRecord>,
pub next_cursor: Option<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct IdentityBootstrapRequest {
pub identity: IdentityRef,
#[serde(default = "default_auto_sync")]
pub auto_sync: bool,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
fn default_auto_sync() -> bool {
true
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct PaperMessageEnvelope {
pub uri: String,
pub transient_id: Option<String>,
pub destination_hint: Option<String>,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct RemoteCommandRequest {
pub command: String,
pub target: Option<String>,
pub payload: JsonValue,
pub timeout_ms: Option<u64>,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct RemoteCommandResponse {
pub accepted: bool,
pub payload: JsonValue,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum RemoteCommandState {
Dispatched,
ReceiptAcknowledged,
Processing,
Completed,
Failed,
#[serde(other)]
Unknown,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct RemoteCommandSession {
pub command_id: String,
pub correlation_id: String,
pub command: String,
pub target: Option<String>,
pub timeout_ms: Option<u64>,
pub delivery_state: Option<String>,
pub command_state: RemoteCommandState,
pub created_at_ms: u64,
pub updated_at_ms: u64,
pub request_payload: JsonValue,
pub response_payload: Option<JsonValue>,
pub accepted: Option<bool>,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct RemoteCommandSessionListRequest {
pub cursor: Option<String>,
pub limit: Option<usize>,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct RemoteCommandSessionListResult {
pub sessions: Vec<RemoteCommandSession>,
pub next_cursor: Option<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub struct VoiceSessionId(pub String);
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum VoiceSessionState {
New,
Ringing,
Active,
Holding,
Closed,
Failed,
#[serde(other)]
Unknown,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct VoiceSessionOpenRequest {
pub peer_id: String,
pub codec_hint: Option<String>,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct VoiceSessionUpdateRequest {
pub session_id: VoiceSessionId,
pub state: VoiceSessionState,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct WorkflowPeerReadyRequest {
pub identity: IdentityRef,
pub display_name: Option<String>,
pub trust_level: Option<TrustLevel>,
pub bootstrap: Option<bool>,
pub announce: Option<bool>,
#[serde(default)]
pub metadata: BTreeMap<String, JsonValue>,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct WorkflowPeerReadyResult {
pub identity: IdentityRef,
pub contact: ContactRecord,
pub was_created: bool,
pub announced: bool,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct WorkflowTopicSyncRequest {
pub topic_path: TopicPath,
#[serde(default)]
pub metadata: BTreeMap<String, JsonValue>,
pub telemetry_limit: Option<usize>,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct WorkflowTopicSyncResult {
pub topic: TopicRecord,
pub was_created: bool,
pub subscribed: bool,
pub telemetry: Vec<TelemetryPoint>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct WorkflowAttachmentDraft {
pub name: String,
pub content_type: String,
pub bytes_base64: String,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct WorkflowAttachmentReportRequest {
pub topic_path: TopicPath,
pub attachment: WorkflowAttachmentDraft,
pub summary_payload: Option<JsonValue>,
pub correlation_id: Option<String>,
#[serde(default)]
pub topic_metadata: BTreeMap<String, JsonValue>,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct WorkflowAttachmentReportResult {
pub topic: TopicRecord,
pub attachment: AttachmentMeta,
pub published: Ack,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct WorkflowMissionUpdateRequest {
pub peer_identity: IdentityRef,
pub content: String,
pub topic_path: Option<TopicPath>,
#[serde(default)]
pub attachments: Vec<WorkflowAttachmentDraft>,
#[serde(default)]
pub metadata: BTreeMap<String, JsonValue>,
pub correlation_id: Option<String>,
pub idempotency_key: Option<String>,
pub display_name: Option<String>,
pub trust_level: Option<TrustLevel>,
pub bootstrap: Option<bool>,
pub announce: Option<bool>,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct WorkflowMissionUpdateResult {
pub peer: WorkflowPeerReadyResult,
pub message_id: MessageId,
pub topic: Option<TopicRecord>,
pub attachments: Vec<AttachmentMeta>,
}
#[cfg(test)]
mod tests {
use super::VoiceSessionState;
#[test]
fn voice_session_state_deserializes_unknown_variant() {
let value = serde_json::json!("paused_by_gateway");
let state: VoiceSessionState =
serde_json::from_value(value).expect("unknown voice state should map to Unknown");
assert_eq!(state, VoiceSessionState::Unknown);
}
}