Skip to main content

lash_remote_protocol/
turn_control.rs

1//! Transport-neutral foreground-turn cancellation envelopes.
2
3use schemars::JsonSchema;
4use serde::{Deserialize, Serialize};
5
6use crate::registry_errors::{RemoteProtocolError, require_non_empty};
7use crate::{REMOTE_PROTOCOL_VERSION, ensure_protocol_version};
8
9#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
10#[serde(rename_all = "snake_case")]
11pub enum RemoteTurnControlDurabilityTier {
12    Inline,
13    Durable,
14}
15
16#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
17pub struct RemoteTurnCancellationEvidence {
18    pub request_id: String,
19    /// Opaque host-domain data; Lash records and returns it unchanged.
20    #[serde(default, skip_serializing_if = "Option::is_none")]
21    pub origin: Option<String>,
22    #[serde(default, skip_serializing_if = "Option::is_none")]
23    pub reason: Option<String>,
24}
25
26impl RemoteTurnCancellationEvidence {
27    pub fn validate(&self) -> Result<(), RemoteProtocolError> {
28        require_non_empty(
29            "RemoteTurnCancellationEvidence",
30            "request_id",
31            &self.request_id,
32        )
33    }
34}
35
36#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
37pub struct RemoteTurnCancelRequest {
38    pub protocol_version: u32,
39    pub session_id: String,
40    pub turn_id: String,
41    pub request_id: String,
42    /// Opaque host-domain data; Lash never interprets this value.
43    #[serde(default, skip_serializing_if = "Option::is_none")]
44    pub origin: Option<String>,
45    #[serde(default, skip_serializing_if = "Option::is_none")]
46    pub reason: Option<String>,
47}
48
49impl RemoteTurnCancelRequest {
50    pub fn validate(&self) -> Result<(), RemoteProtocolError> {
51        ensure_protocol_version(self.protocol_version)?;
52        require_non_empty("RemoteTurnCancelRequest", "session_id", &self.session_id)?;
53        require_non_empty("RemoteTurnCancelRequest", "turn_id", &self.turn_id)?;
54        require_non_empty("RemoteTurnCancelRequest", "request_id", &self.request_id)
55    }
56}
57
58#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
59#[serde(tag = "outcome", rename_all = "snake_case")]
60pub enum RemoteTurnCancelOutcome {
61    Requested {
62        cancellation: RemoteTurnCancellationEvidence,
63    },
64    AlreadyRequested {
65        cancellation: RemoteTurnCancellationEvidence,
66    },
67    CompletionWonRace,
68    UnknownOrRevoked,
69}
70
71impl RemoteTurnCancelOutcome {
72    fn validate(&self) -> Result<(), RemoteProtocolError> {
73        match self {
74            Self::Requested { cancellation } | Self::AlreadyRequested { cancellation } => {
75                cancellation.validate()
76            }
77            Self::CompletionWonRace | Self::UnknownOrRevoked => Ok(()),
78        }
79    }
80}
81
82#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
83pub struct RemoteTurnCancelReceipt {
84    pub protocol_version: u32,
85    pub session_id: String,
86    pub turn_id: String,
87    pub durability_tier: RemoteTurnControlDurabilityTier,
88    pub outcome: RemoteTurnCancelOutcome,
89}
90
91impl RemoteTurnCancelReceipt {
92    pub fn new(
93        session_id: impl Into<String>,
94        turn_id: impl Into<String>,
95        durability_tier: RemoteTurnControlDurabilityTier,
96        outcome: RemoteTurnCancelOutcome,
97    ) -> Self {
98        Self {
99            protocol_version: REMOTE_PROTOCOL_VERSION,
100            session_id: session_id.into(),
101            turn_id: turn_id.into(),
102            durability_tier,
103            outcome,
104        }
105    }
106
107    pub fn validate(&self) -> Result<(), RemoteProtocolError> {
108        ensure_protocol_version(self.protocol_version)?;
109        require_non_empty("RemoteTurnCancelReceipt", "session_id", &self.session_id)?;
110        require_non_empty("RemoteTurnCancelReceipt", "turn_id", &self.turn_id)?;
111        self.outcome.validate()
112    }
113}