rustbridge_transport/
envelope.rs1use serde::{Deserialize, Serialize, de::DeserializeOwned};
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct RequestEnvelope {
11 pub type_tag: String,
13
14 pub payload: serde_json::Value,
16
17 #[serde(skip_serializing_if = "Option::is_none")]
19 pub request_id: Option<u64>,
20
21 #[serde(skip_serializing_if = "Option::is_none")]
23 pub correlation_id: Option<String>,
24}
25
26impl RequestEnvelope {
27 pub fn new(type_tag: impl Into<String>, payload: serde_json::Value) -> Self {
29 Self {
30 type_tag: type_tag.into(),
31 payload,
32 request_id: None,
33 correlation_id: None,
34 }
35 }
36
37 pub fn with_request_id(mut self, id: u64) -> Self {
39 self.request_id = Some(id);
40 self
41 }
42
43 pub fn with_correlation_id(mut self, id: impl Into<String>) -> Self {
45 self.correlation_id = Some(id.into());
46 self
47 }
48
49 pub fn from_typed<T: Serialize>(
51 type_tag: impl Into<String>,
52 payload: &T,
53 ) -> Result<Self, serde_json::Error> {
54 Ok(Self {
55 type_tag: type_tag.into(),
56 payload: serde_json::to_value(payload)?,
57 request_id: None,
58 correlation_id: None,
59 })
60 }
61
62 pub fn payload_as<T: DeserializeOwned>(&self) -> Result<T, serde_json::Error> {
66 T::deserialize(&self.payload)
67 }
68
69 pub fn to_bytes(&self) -> Result<Vec<u8>, serde_json::Error> {
71 serde_json::to_vec(self)
72 }
73
74 pub fn from_bytes(data: &[u8]) -> Result<Self, serde_json::Error> {
76 serde_json::from_slice(data)
77 }
78}
79
80#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
82#[serde(rename_all = "snake_case")]
83pub enum ResponseStatus {
84 Success,
86 Error,
88}
89
90#[derive(Debug, Clone, Serialize, Deserialize)]
92pub struct ResponseEnvelope {
93 pub status: ResponseStatus,
95
96 #[serde(skip_serializing_if = "Option::is_none")]
98 pub payload: Option<serde_json::Value>,
99
100 #[serde(skip_serializing_if = "Option::is_none")]
102 pub error_code: Option<u32>,
103
104 #[serde(skip_serializing_if = "Option::is_none")]
106 pub error_message: Option<String>,
107
108 #[serde(skip_serializing_if = "Option::is_none")]
110 pub request_id: Option<u64>,
111}
112
113impl ResponseEnvelope {
114 pub fn success(payload: serde_json::Value) -> Self {
116 Self {
117 status: ResponseStatus::Success,
118 payload: Some(payload),
119 error_code: None,
120 error_message: None,
121 request_id: None,
122 }
123 }
124
125 pub fn success_typed<T: Serialize>(value: &T) -> Result<Self, serde_json::Error> {
127 Ok(Self::success(serde_json::to_value(value)?))
128 }
129
130 pub fn success_raw(data: &[u8]) -> Result<Self, serde_json::Error> {
132 let payload: serde_json::Value = serde_json::from_slice(data)?;
133 Ok(Self::success(payload))
134 }
135
136 pub fn error(code: u32, message: impl Into<String>) -> Self {
138 Self {
139 status: ResponseStatus::Error,
140 payload: None,
141 error_code: Some(code),
142 error_message: Some(message.into()),
143 request_id: None,
144 }
145 }
146
147 pub fn from_error(err: &rustbridge_core::PluginError) -> Self {
149 Self::error(err.error_code(), err.to_string())
150 }
151
152 pub fn with_request_id(mut self, id: u64) -> Self {
154 self.request_id = Some(id);
155 self
156 }
157
158 pub fn is_success(&self) -> bool {
160 self.status == ResponseStatus::Success
161 }
162
163 pub fn payload_as<T: DeserializeOwned>(&self) -> Result<Option<T>, serde_json::Error> {
167 match &self.payload {
168 Some(v) => Ok(Some(T::deserialize(v)?)),
169 None => Ok(None),
170 }
171 }
172
173 pub fn to_bytes(&self) -> Result<Vec<u8>, serde_json::Error> {
175 serde_json::to_vec(self)
176 }
177
178 pub fn from_bytes(data: &[u8]) -> Result<Self, serde_json::Error> {
180 serde_json::from_slice(data)
181 }
182}
183
184impl Default for ResponseEnvelope {
185 fn default() -> Self {
186 Self::success(serde_json::Value::Null)
187 }
188}
189
190#[cfg(test)]
191#[path = "envelope/envelope_tests.rs"]
192mod envelope_tests;