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