1use custom_debug_derive::Debug as CustomDebug;
4use frame::Frame;
5
6pub mod client;
7mod frame;
8
9pub(crate) type Result<T> = std::result::Result<T, anyhow::Error>;
10
11#[derive(Debug)]
13pub struct Message<T> {
14 pub content: T,
16 pub extra_headers: Vec<(Vec<u8>, Vec<u8>)>,
18}
19
20fn pretty_bytes(b: &Option<Vec<u8>>, f: &mut std::fmt::Formatter) -> std::fmt::Result {
21 if let Some(v) = b {
22 write!(f, "{}", String::from_utf8_lossy(v))
23 } else {
24 write!(f, "None")
25 }
26}
27
28#[derive(CustomDebug, Clone)]
31pub enum FromServer {
32 #[doc(hidden)] Connected {
34 version: String,
35 session: Option<String>,
36 server: Option<String>,
37 heartbeat: Option<String>,
38 },
39 Message {
41 destination: String,
42 message_id: String,
43 subscription: String,
44 headers: Vec<(String, String)>,
45 #[debug(with = "pretty_bytes")]
46 body: Option<Vec<u8>>,
47 },
48 Receipt { receipt_id: String },
51 Error {
53 message: Option<String>,
54 #[debug(with = "pretty_bytes")]
55 body: Option<Vec<u8>>,
56 },
57}
58
59impl Message<FromServer> {
61 fn from_frame(frame: Frame) -> Result<Message<FromServer>> {
67 frame.to_server_msg()
68 }
69}
70
71#[derive(Debug, Clone)]
74pub enum ToServer {
75 #[doc(hidden)] Connect {
77 accept_version: String,
78 host: String,
79 login: Option<String>,
80 passcode: Option<String>,
81 heartbeat: Option<(u32, u32)>,
82 },
83 Send {
85 destination: String,
86 transaction: Option<String>,
87 headers: Option<Vec<(String, String)>>,
88 body: Option<Vec<u8>>,
89 },
90 Subscribe {
92 destination: String,
93 id: String,
94 ack: Option<AckMode>,
95 },
96 Unsubscribe { id: String },
98 Ack {
101 id: String,
103 transaction: Option<String>,
104 },
105 Nack {
107 id: String,
108 transaction: Option<String>,
109 },
110 Begin { transaction: String },
112 Commit { transaction: String },
114 Abort { transaction: String },
116 Disconnect { receipt: Option<String> },
119}
120
121#[derive(Debug, Clone, Copy)]
122pub enum AckMode {
123 Auto,
124 Client,
125 ClientIndividual,
126}
127
128impl Message<ToServer> {
129 fn to_frame(&self) -> Frame {
130 let mut frame = self.content.to_frame();
131 frame.add_extra_headers(&self.extra_headers);
132 frame
133 }
134 #[allow(dead_code)]
135 fn from_frame(frame: Frame) -> Result<Message<ToServer>> {
136 frame.to_client_msg()
137 }
138}
139
140impl From<ToServer> for Message<ToServer> {
141 fn from(content: ToServer) -> Message<ToServer> {
142 Message {
143 content,
144 extra_headers: vec![],
145 }
146 }
147}