1use 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 #[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 #[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}