1mod frame_outbox;
2
3use bytes::Bytes;
4use serde::{Deserialize, Serialize};
5use tower::BoxError;
6
7pub use frame_outbox::FrameOutbox;
8
9#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
11pub struct MessageFrame {
12 pub uri: String,
14 pub data: Bytes,
16 pub meta: Bytes,
18}
19
20#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
22pub enum Frame {
23 #[default]
25 Unit,
26 Error(Bytes),
28 Anonymous(Bytes),
30 Message(MessageFrame),
32}
33
34impl Frame {
35 pub fn new(bytes: impl Into<Bytes>) -> Self {
37 let bytes = bytes.into();
38
39 if bytes.is_empty() {
40 Frame::Unit
41 } else {
42 Frame::Anonymous(bytes)
43 }
44 }
45
46 pub fn message(uri: impl AsRef<str>, data: impl Into<Frame>, meta: impl Into<Frame>) -> Self {
48 Frame::Message(MessageFrame {
49 uri: uri.as_ref().into(),
50 data: data.into().into_bytes(),
51 meta: meta.into().into_bytes(),
52 })
53 }
54
55 pub fn len(&self) -> usize {
58 match self {
59 Frame::Unit => 0,
60 Frame::Error(data)
61 | Frame::Anonymous(data)
62 | Frame::Message(MessageFrame { data, .. }) => data.len(),
63 }
64 }
65
66 pub fn is_empty(&self) -> bool {
68 self.len() == 0
69 }
70
71 pub fn as_bytes(&self) -> &[u8] {
73 match self {
74 Frame::Unit => &[],
75 Frame::Error(data)
76 | Frame::Anonymous(data)
77 | Frame::Message(MessageFrame { data, .. }) => data.as_ref(),
78 }
79 }
80
81 pub fn into_bytes(self) -> Bytes {
84 match self {
85 Frame::Unit => Bytes::new(),
86 Frame::Error(data)
87 | Frame::Anonymous(data)
88 | Frame::Message(MessageFrame { data, .. }) => data,
89 }
90 }
91}
92
93impl AsRef<[u8]> for Frame {
94 fn as_ref(&self) -> &[u8] {
95 self.as_bytes()
96 }
97}
98
99impl From<Vec<u8>> for Frame {
100 fn from(value: Vec<u8>) -> Self {
101 Bytes::from(value).into()
102 }
103}
104
105impl<T> From<Vec<T>> for Frame
106where
107 T: Into<Frame>,
108{
109 fn from(value: Vec<T>) -> Self {
110 let mut bytes: Vec<u8> = vec![];
111
112 for value in value {
113 bytes.extend_from_slice(value.into().as_ref());
114 }
115
116 Bytes::from(bytes).into()
117 }
118}
119
120impl From<()> for Frame {
121 fn from(_: ()) -> Self {
122 Frame::default()
123 }
124}
125
126impl From<Bytes> for Frame {
127 fn from(bytes: Bytes) -> Self {
128 Frame::new(bytes)
129 }
130}
131
132impl From<Frame> for Bytes {
133 fn from(frame: Frame) -> Bytes {
134 frame.into_bytes()
135 }
136}
137
138impl From<Frame> for String {
139 fn from(value: Frame) -> Self {
140 String::from_utf8_lossy(value.as_ref()).into_owned()
141 }
142}
143
144impl From<String> for Frame {
145 fn from(value: String) -> Self {
146 Frame::new(value)
147 }
148}
149
150impl<T> From<Option<T>> for Frame
151where
152 T: Into<Frame>,
153{
154 fn from(option: Option<T>) -> Self {
155 match option {
156 Some(value) => value.into(),
157 None => Frame::default(),
158 }
159 }
160}
161
162impl<T, E> From<Result<T, E>> for Frame
163where
164 T: Into<Frame>,
165 E: Into<Frame>,
166{
167 fn from(result: Result<T, E>) -> Self {
168 match result {
169 Ok(value) => value.into(),
170 Err(error) => error.into(),
171 }
172 }
173}
174
175impl From<BoxError> for Frame {
176 fn from(error: BoxError) -> Self {
177 error.to_string().into()
178 }
179}