1use crate::roles::Roles;
2use serde::de::{SeqAccess, Visitor};
3use serde::{Deserialize, Deserializer, Serialize};
4use serde_json::{json, Value};
5use std::fmt::Formatter;
6use std::marker::PhantomData;
7
8use super::{helpers, MessageDirection, WampMessage};
9
10#[derive(Debug, Clone, PartialEq, Eq)]
11pub struct Event {
70 pub subscription: u64,
71 pub publication: u64,
72 pub details: Value,
73 pub args: Value,
74 pub kwargs: Value,
75}
76
77#[macro_export]
78macro_rules! event {
121 ($subscription:expr, $publication:expr) => {
122 event! {$subscription, $publication, json!({}), serde_json::Value::Null, Value::Null}
123 };
124
125 ($subscription:expr, $publication:expr, $details:expr) => {
126 event! {$subscription, $publication, $details, serde_json::Value::Null, Value::Null}
127 };
128
129 ($subscription:expr, $publication:expr, args:$args:expr) => {
130 event! {$subscription, $publication, json!({}), $args, Value::Null}
131 };
132
133 ($subscription:expr, $publication:expr, kwargs:$kwargs:expr) => {
134 event! {$subscription, $publication, json!({}), serde_json::Value::Null, $kwargs }
135 };
136
137 ($subscription:expr, $publication:expr, args:$args:expr, kwargs:$kwargs:expr) => {
138 event! {$subscription, $publication, json!({}), $args, $kwargs }
139 };
140
141 ($subscription:expr, $publication:expr, $details:expr, args:$args:expr) => {
142 event! {$subscription, $publication, $details, $args, serde_json::Value::Null}
143 };
144
145 ($subscription:expr, $publication:expr, $details:expr, kwargs:$kwargs:expr) => {
146 event! {$subscription, $publication, $details, serde_json::Value::Null, $kwargs}
147 };
148
149 ($subscription:expr, $publication:expr, $details:expr, $args:expr, $kwargs:expr) => {{
150 Event {
151 subscription: $subscription,
152 publication: $publication,
153 details: $details,
154 args: $args,
155 kwargs: $kwargs,
156 }
157 }};
158}
159
160impl WampMessage for Event {
161 const ID: u64 = 36;
162
163 fn direction(role: Roles) -> &'static MessageDirection {
164 match role {
165 Roles::Callee => &MessageDirection {
166 receives: &false,
167 sends: &false,
168 },
169 Roles::Caller => &MessageDirection {
170 receives: &false,
171 sends: &false,
172 },
173 Roles::Publisher => &MessageDirection {
174 receives: &false,
175 sends: &false,
176 },
177 Roles::Subscriber => &MessageDirection {
178 receives: &true,
179 sends: &false,
180 },
181 Roles::Dealer => &MessageDirection {
182 receives: &false,
183 sends: &false,
184 },
185 Roles::Broker => &MessageDirection {
186 receives: &false,
187 sends: &true,
188 },
189 }
190 }
191}
192
193impl Serialize for Event {
194 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
195 where
196 S: serde::Serializer,
197 {
198 let args =
199 helpers::ser_value_is_args::<S, _>(&self.args, "Args must be Array like or Null.")?;
200 let kwargs = helpers::ser_value_is_kwargs::<S, _>(
201 &self.kwargs,
202 "Kwargs must be Object like or Null.",
203 )?;
204
205 if args.is_null() {
206 if kwargs.is_null() {}
207 } else {
208 if kwargs.is_null() {}
209 }
210
211 if args.is_null() {
212 if kwargs.is_null() {
213 (
214 Self::ID,
215 &self.subscription,
216 &self.publication,
217 &self.details,
218 )
219 .serialize(serializer)
220 } else {
221 (
222 Self::ID,
223 &self.subscription,
224 &self.publication,
225 &self.details,
226 json!([]),
227 kwargs,
228 )
229 .serialize(serializer)
230 }
231 } else {
232 if kwargs.is_null() {
233 (
234 Self::ID,
235 &self.subscription,
236 &self.publication,
237 &self.details,
238 args,
239 )
240 .serialize(serializer)
241 } else {
242 (
243 Self::ID,
244 &self.subscription,
245 &self.publication,
246 &self.details,
247 args,
248 kwargs,
249 )
250 .serialize(serializer)
251 }
252 }
253 }
254}
255
256impl<'de> Deserialize<'de> for Event {
257 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
258 where
259 D: Deserializer<'de>,
260 {
261 struct EventVisitor(
262 PhantomData<u8>,
263 PhantomData<u64>,
264 PhantomData<u64>,
265 PhantomData<Value>,
266 PhantomData<Value>,
267 PhantomData<Value>,
268 );
269
270 impl<'vi> Visitor<'vi> for EventVisitor {
271 type Value = Event;
272 fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
273 formatter.write_str("A sequence of Event components.")
274 }
275
276 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
277 where
278 A: SeqAccess<'vi>,
279 {
280 let message_id: u64 = helpers::deser_seq_element(
281 &mut seq,
282 "Message ID must be present and type u8.",
283 )?;
284 helpers::validate_id::<Event, A, _>(&message_id, "Event")?;
285 let subscription: u64 = helpers::deser_seq_element(
286 &mut seq,
287 "Subscription must be present and type u64.",
288 )?;
289 let publication: u64 = helpers::deser_seq_element(
290 &mut seq,
291 "Publication must be present and object like.",
292 )?;
293 let details: Value = helpers::deser_seq_element(
294 &mut seq,
295 "Details must be present and object like.",
296 )?;
297 helpers::deser_value_is_object::<A, _>(&details, "Details must be object like.")?;
298 let args: Value = helpers::deser_args_kwargs_element(
299 &mut seq,
300 "Args must be array like or null.",
301 )?;
302 let kwargs: Value = helpers::deser_args_kwargs_element(
303 &mut seq,
304 "Kwargs must be object like or null.",
305 )?;
306 Ok(Event {
307 subscription,
308 publication,
309 details,
310 args,
311 kwargs,
312 })
313 }
314 }
315
316 deserializer.deserialize_struct(
317 "Event",
318 &["subscription", "publication", "details", "args", "kwargs"],
319 EventVisitor(
320 PhantomData,
321 PhantomData,
322 PhantomData,
323 PhantomData,
324 PhantomData,
325 PhantomData,
326 ),
327 )
328 }
329}
330
331#[cfg(test)]
332mod tests {
333 use serde_json::{from_str, to_string};
334
335 use super::Event;
336
337 #[test]
338 fn test() {
339 let d = r#"[36,5512315355,4429313566,{},[],{"color":"orange","sizes":[23,42,7]}]"#;
340 let mut ed = Event {
341 subscription: 5512315355,
342 publication: 4429313566,
343 details: serde_json::json!({}),
344 args: serde_json::Value::Null,
345 kwargs: serde_json::json!({"color":"orange","sizes":[23,42,7]}),
346 };
347 let ed2: Event = from_str(d).unwrap();
348 let d2 = to_string(&ed).unwrap();
349 assert_ne!(ed, ed2);
350 ed.args = serde_json::json!([]);
351 assert_eq!(ed, ed2);
352 assert_eq!(d, d2);
353 }
354}