wamp_core/messages/
event.rs

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)]
11/// # Event - [wamp-proto](https://wamp-proto.org/wamp_latest_ietf.html#name-event-2)
12///  Represents an Event message in the WAMP protocol.
13/// ## Examples
14/// ```
15/// use wamp_core::messages::Event;
16/// use wamp_core::event;
17/// use serde_json::{json, Value};
18///
19/// let event = Event {
20///     subscription: 1,
21///     publication: 2,
22///     details: json!({}),
23///     args: Value::Null,
24///     kwargs: Value::Null
25/// };
26///
27/// let event2 = event!(1, 2);
28///
29/// assert_eq!(event, event2);
30/// ```
31/// ### Serializer
32/// Serde Serialize trait implementation for event.
33/// ```
34/// use wamp_core::messages::Event;
35/// use serde_json::{json, to_string};
36///
37/// let event = Event {
38///     subscription: 1,
39///     publication: 2,
40///     details: json!({}),
41///     args: json!([1, 2, 3]),
42///     kwargs: json!({"key": "value"})
43/// };
44///
45/// let event2_string = r#"[36,1,2,{},[1,2,3],{"key":"value"}]"#;
46///
47/// let event_string = to_string(&event).unwrap();
48/// assert_eq!(event_string, event2_string);
49/// ```
50/// ### Deserializer
51/// Serde Deserialize trait implementation for event.
52/// ```
53/// use wamp_core::messages::Event;
54/// use serde_json::{json, from_str};
55///
56/// let event = Event {
57///     subscription: 1,
58///     publication: 2,
59///     details: json!({}),
60///     args: json!([1, 2, 3]),
61///     kwargs: json!({"key": "value"})
62/// };
63///
64/// let event2_string = r#"[36,1,2,{},[1,2,3],{"key":"value"}]"#;
65///
66/// let event2 = from_str::<Event>(event2_string).unwrap();
67/// assert_eq!(event, event2);
68/// ```
69pub 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]
78/// ## Event Macro - [wamp-proto](https://wamp-proto.org/wamp_latest_ietf.html#name-event-2)
79///
80/// ### Examples
81/// ```
82/// use wamp_core::event;
83/// use wamp_core::messages::Event;
84/// use serde_json::{json, Value};
85///
86/// // Create a event message with default values
87/// let event = event!(1, 2);
88///
89/// // Which is the same as creating this:
90/// let event2 = Event {
91///     subscription: 1,
92///     publication: 2,
93///     details: json!({}),
94///     args: Value::Null,
95///     kwargs: Value::Null
96/// };
97///
98/// assert_eq!(event, event2);
99///
100/// // Some other ways you can construct it using the macro
101///
102/// // Create a event with custom details but empty args and kwargs
103/// let _ = event!(1, 2, json!( { "key": "value" } ));
104///
105/// // Create a event with custom args or kwargs, but empty details
106/// let _ = event!(1, 2, args: json!( [ 1, 2, 3 ] ));
107/// let _ = event!(1, 2, kwargs: json!( { "key": "value" } ));
108///
109/// // Create a event with custom args and kwargs, but empty details
110/// let _ = event!(1, 2, args: json!([ 1, 2, 3 ]), kwargs: json!({ "key": "value" }));
111///
112/// // Create a event with custom details, and either custom args OR custom kwargs
113/// let _ = event!(1, 2, json!( { "key": "value" } ), args: json!( [ 1, 2, 3 ] ));
114/// let _ = event!(1, 2, json!( { "key": "value" } ), kwargs: json!( { "key": "value" } ));
115///
116/// // Create a event with custom details, and both custom args and kwargs
117/// // Note that when you use all "required" arguments for the struuct, keyword arguments should not be used for args and kwargs
118/// let _ = event!(1, 2, json!({}), json!([]), json!({}));
119/// ```
120macro_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}