ahri_tre_protocol/
protocol_envelope.rs1use crate::{
2 ProtocolVersion, RequestId, public_error::ProtocolError, request::ProtocolRequest,
3 warning::ProtocolWarning,
4};
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
8pub struct ProtocolRequestEnvelope {
9 #[serde(default, skip_serializing_if = "Option::is_none")]
10 pub request_id: Option<RequestId>,
11 pub protocol_version: ProtocolVersion,
12 #[serde(flatten)]
13 pub request: ProtocolRequest,
14}
15
16impl ProtocolRequestEnvelope {
17 pub fn reject_unsupported_version(
20 value: &serde_json::Value,
21 ) -> Option<ProtocolFailureEnvelope> {
22 let requested = value.get("protocol_version")?.as_str()?;
23 let version = ProtocolVersion::parse(requested).ok()?;
24 let current = ProtocolVersion::current();
25 version.ensure_supported(¤t).err()?;
26 let request_id = value
27 .get("request_id")
28 .cloned()
29 .and_then(|id| serde_json::from_value(id).ok())
30 .unwrap_or_default();
31 Some(ProtocolFailureEnvelope::new(
32 request_id,
33 version,
34 crate::request::kind::PROTOCOL_INVALID_REQUEST,
35 ProtocolError::new(
36 crate::public_error::ProtocolErrorCode::UnsupportedProtocolVersion,
37 "unsupported protocol version",
38 )
39 .with_target("protocol_version")
40 .with_details(
41 crate::public_error::ProtocolErrorDetails::UnsupportedProtocolVersion {
42 requested: requested.to_string(),
43 supported: current.to_string(),
44 },
45 ),
46 ))
47 }
48
49 pub fn new(protocol_version: ProtocolVersion, request: ProtocolRequest) -> Self {
50 Self {
51 request_id: None,
52 protocol_version,
53 request,
54 }
55 }
56
57 pub fn kind(&self) -> &'static str {
58 self.request.kind()
59 }
60}
61
62#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
63#[serde(untagged)]
64pub enum ProtocolResponseEnvelope<T> {
65 Success(ProtocolSuccessEnvelope<T>),
66 Failure(ProtocolFailureEnvelope),
67}
68
69#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
70pub struct ProtocolSuccessEnvelope<T> {
71 pub ok: bool,
72 pub request_id: RequestId,
73 pub protocol_version: ProtocolVersion,
74 pub kind: String,
75 pub warnings: Vec<ProtocolWarning>,
76 pub data: T,
77 #[serde(default, skip_serializing_if = "Option::is_none")]
79 pub content_transfer: Option<Box<crate::content::ContentDescriptor>>,
80}
81
82impl<T> ProtocolSuccessEnvelope<T> {
83 pub fn new(
84 request_id: RequestId,
85 protocol_version: ProtocolVersion,
86 kind: impl Into<String>,
87 data: T,
88 ) -> Self {
89 Self {
90 ok: true,
91 request_id,
92 protocol_version,
93 kind: kind.into(),
94 warnings: Vec::new(),
95 data,
96 content_transfer: None,
97 }
98 }
99}
100
101#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
102pub struct ProtocolFailureEnvelope {
103 pub ok: bool,
104 pub request_id: RequestId,
105 pub protocol_version: ProtocolVersion,
106 pub kind: String,
107 pub warnings: Vec<ProtocolWarning>,
108 pub error: ProtocolError,
109}
110
111impl ProtocolFailureEnvelope {
112 pub fn new(
113 request_id: RequestId,
114 protocol_version: ProtocolVersion,
115 kind: impl Into<String>,
116 error: ProtocolError,
117 ) -> Self {
118 Self {
119 ok: false,
120 request_id,
121 protocol_version,
122 kind: kind.into(),
123 warnings: Vec::new(),
124 error,
125 }
126 }
127}