1use crate::{Error, Frame, Message, QoS, Result};
4use bytes::Bytes;
5
6pub fn encode_message(message: &Message) -> Result<Bytes> {
8 let bytes = rmp_serde::to_vec_named(message)?;
9 Ok(Bytes::from(bytes))
10}
11
12pub fn decode_message(bytes: &[u8]) -> Result<Message> {
14 let message = rmp_serde::from_slice(bytes)?;
15 Ok(message)
16}
17
18pub fn encode(message: &Message) -> Result<Bytes> {
20 let payload = encode_message(message)?;
21 let frame = Frame::new(payload).with_qos(message.default_qos());
22 frame.encode()
23}
24
25pub fn encode_with_options(
27 message: &Message,
28 qos: Option<QoS>,
29 timestamp: Option<u64>,
30) -> Result<Bytes> {
31 let payload = encode_message(message)?;
32 let mut frame = Frame::new(payload);
33
34 if let Some(qos) = qos {
35 frame = frame.with_qos(qos);
36 } else {
37 frame = frame.with_qos(message.default_qos());
38 }
39
40 if let Some(ts) = timestamp {
41 frame = frame.with_timestamp(ts);
42 }
43
44 frame.encode()
45}
46
47pub fn decode(bytes: &[u8]) -> Result<(Message, Frame)> {
49 let frame = Frame::decode(bytes)?;
50 let message = decode_message(&frame.payload)?;
51 Ok((message, frame))
52}
53
54pub fn encode_payload(message: &Message) -> Result<Vec<u8>> {
56 let bytes = rmp_serde::to_vec_named(message)?;
57 Ok(bytes)
58}
59
60pub fn decode_payload(bytes: &[u8]) -> Result<Message> {
62 decode_message(bytes)
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68 use crate::types::*;
69
70 #[test]
71 fn test_hello_roundtrip() {
72 let msg = Message::Hello(HelloMessage {
73 version: 2,
74 name: "Test Client".to_string(),
75 features: vec!["param".to_string(), "event".to_string()],
76 capabilities: None,
77 token: None,
78 });
79
80 let encoded = encode(&msg).unwrap();
81 let (decoded, frame) = decode(&encoded).unwrap();
82
83 match decoded {
84 Message::Hello(hello) => {
85 assert_eq!(hello.version, 2);
86 assert_eq!(hello.name, "Test Client");
87 assert_eq!(hello.features.len(), 2);
88 }
89 _ => panic!("Expected Hello message"),
90 }
91
92 assert_eq!(frame.flags.qos, QoS::Fire);
93 }
94
95 #[test]
96 fn test_set_roundtrip() {
97 let msg = Message::Set(SetMessage {
98 address: "/test/value".to_string(),
99 value: Value::Float(0.75),
100 revision: Some(42),
101 lock: false,
102 unlock: false,
103 });
104
105 let encoded = encode(&msg).unwrap();
106 let (decoded, frame) = decode(&encoded).unwrap();
107
108 match decoded {
109 Message::Set(set) => {
110 assert_eq!(set.address, "/test/value");
111 assert_eq!(set.value.as_f64(), Some(0.75));
112 assert_eq!(set.revision, Some(42));
113 }
114 _ => panic!("Expected Set message"),
115 }
116
117 assert_eq!(frame.flags.qos, QoS::Confirm);
118 }
119
120 #[test]
121 fn test_bundle_roundtrip() {
122 let msg = Message::Bundle(BundleMessage {
123 timestamp: Some(1000000),
124 messages: vec![
125 Message::Set(SetMessage {
126 address: "/light/1".to_string(),
127 value: Value::Float(1.0),
128 revision: None,
129 lock: false,
130 unlock: false,
131 }),
132 Message::Set(SetMessage {
133 address: "/light/2".to_string(),
134 value: Value::Float(0.0),
135 revision: None,
136 lock: false,
137 unlock: false,
138 }),
139 ],
140 });
141
142 let encoded = encode(&msg).unwrap();
143 let (decoded, _) = decode(&encoded).unwrap();
144
145 match decoded {
146 Message::Bundle(bundle) => {
147 assert_eq!(bundle.timestamp, Some(1000000));
148 assert_eq!(bundle.messages.len(), 2);
149 }
150 _ => panic!("Expected Bundle message"),
151 }
152 }
153
154 #[test]
155 fn test_value_types() {
156 let values = vec![
158 Value::Null,
159 Value::Bool(true),
160 Value::Int(42),
161 Value::Float(3.14),
162 Value::String("hello".to_string()),
163 Value::Array(vec![Value::Int(1), Value::Int(2), Value::Int(3)]),
164 ];
165
166 for value in values {
167 let msg = Message::Set(SetMessage {
168 address: "/test".to_string(),
169 value: value.clone(),
170 revision: None,
171 lock: false,
172 unlock: false,
173 });
174
175 let encoded = encode(&msg).unwrap();
176 let (decoded, _) = decode(&encoded).unwrap();
177
178 match decoded {
179 Message::Set(set) => {
180 assert_eq!(set.value, value);
181 }
182 _ => panic!("Expected Set message"),
183 }
184 }
185 }
186}