rustbridge_transport/
envelope.rs1use serde::{Deserialize, Serialize};
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: for<'de> Deserialize<'de>>(&self) -> Result<T, serde_json::Error> {
64 serde_json::from_value(self.payload.clone())
65 }
66
67 pub fn to_bytes(&self) -> Result<Vec<u8>, serde_json::Error> {
69 serde_json::to_vec(self)
70 }
71
72 pub fn from_bytes(data: &[u8]) -> Result<Self, serde_json::Error> {
74 serde_json::from_slice(data)
75 }
76}
77
78#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
80#[serde(rename_all = "snake_case")]
81pub enum ResponseStatus {
82 Success,
84 Error,
86}
87
88#[derive(Debug, Clone, Serialize, Deserialize)]
90pub struct ResponseEnvelope {
91 pub status: ResponseStatus,
93
94 #[serde(skip_serializing_if = "Option::is_none")]
96 pub payload: Option<serde_json::Value>,
97
98 #[serde(skip_serializing_if = "Option::is_none")]
100 pub error_code: Option<u32>,
101
102 #[serde(skip_serializing_if = "Option::is_none")]
104 pub error_message: Option<String>,
105
106 #[serde(skip_serializing_if = "Option::is_none")]
108 pub request_id: Option<u64>,
109}
110
111impl ResponseEnvelope {
112 pub fn success(payload: serde_json::Value) -> Self {
114 Self {
115 status: ResponseStatus::Success,
116 payload: Some(payload),
117 error_code: None,
118 error_message: None,
119 request_id: None,
120 }
121 }
122
123 pub fn success_typed<T: Serialize>(value: &T) -> Result<Self, serde_json::Error> {
125 Ok(Self::success(serde_json::to_value(value)?))
126 }
127
128 pub fn success_raw(data: &[u8]) -> Result<Self, serde_json::Error> {
130 let payload: serde_json::Value = serde_json::from_slice(data)?;
131 Ok(Self::success(payload))
132 }
133
134 pub fn error(code: u32, message: impl Into<String>) -> Self {
136 Self {
137 status: ResponseStatus::Error,
138 payload: None,
139 error_code: Some(code),
140 error_message: Some(message.into()),
141 request_id: None,
142 }
143 }
144
145 pub fn from_error(err: &rustbridge_core::PluginError) -> Self {
147 Self::error(err.error_code(), err.to_string())
148 }
149
150 pub fn with_request_id(mut self, id: u64) -> Self {
152 self.request_id = Some(id);
153 self
154 }
155
156 pub fn is_success(&self) -> bool {
158 self.status == ResponseStatus::Success
159 }
160
161 pub fn payload_as<T: for<'de> Deserialize<'de>>(&self) -> Result<Option<T>, serde_json::Error> {
163 match &self.payload {
164 Some(v) => Ok(Some(serde_json::from_value(v.clone())?)),
165 None => Ok(None),
166 }
167 }
168
169 pub fn to_bytes(&self) -> Result<Vec<u8>, serde_json::Error> {
171 serde_json::to_vec(self)
172 }
173
174 pub fn from_bytes(data: &[u8]) -> Result<Self, serde_json::Error> {
176 serde_json::from_slice(data)
177 }
178}
179
180impl Default for ResponseEnvelope {
181 fn default() -> Self {
182 Self::success(serde_json::Value::Null)
183 }
184}
185
186#[cfg(test)]
187#[path = "envelope/envelope_tests.rs"]
188mod envelope_tests;