wamp_core/messages/
published.rs

1use crate::roles::Roles;
2use serde::de::{SeqAccess, Visitor};
3use serde::{Deserialize, Deserializer, Serialize};
4use std::fmt::Formatter;
5use std::marker::PhantomData;
6
7use super::{helpers, MessageDirection, WampMessage};
8
9#[derive(Debug, Clone, PartialEq, Eq)]
10/// # Published - [wamp-proto](https://wamp-proto.org/wamp_latest_ietf.html#name-published-2)
11/// Represents an published message in the WAMP protocol.
12/// ## Examples
13/// ```
14/// use wamp_core::messages::Published;
15/// use wamp_core::published;
16/// use serde_json::json;
17///
18/// # let mut published_message2 = published!(1, 2);
19///
20/// let published_message = Published {
21///     request_id: 1,
22///     publication: 2
23/// };
24///
25/// # assert_eq!(published_message, published_message2);
26/// ```
27/// ### Serializer
28/// Implements serde Serialize trait for published
29/// ```
30/// use wamp_core::messages::Published;
31/// use serde_json::{json, to_string};
32///
33/// // Create an published message
34/// let published = Published {
35///     request_id: 1,
36///     publication: 2
37/// };
38///
39/// // Establish raw json data string
40/// let data = r#"[17,1,2]"#;
41///
42/// // Here we convert it from an `published` frame, to a string representation.
43/// let published = to_string(&published).unwrap();
44///
45/// // Confirm that our published frame strings are equal to each other
46/// assert_eq!(published, data);
47/// ```
48/// ### Deserializer
49/// Implements serde Deserialize trait for published
50/// ```
51/// use wamp_core::messages::Published;
52/// use serde_json::from_str;
53///
54/// // Here is our raw json data string
55/// let data = r#"[17,1,2]"#;
56///
57/// // Here we convert it to an `published` frame
58/// let published = from_str::<Published>(data).unwrap();
59///
60/// // Confirm that our request_id and publication deserialized
61/// assert_eq!(published.request_id, 1);
62/// assert_eq!(published.publication, 2);
63/// ```
64pub struct Published {
65    pub request_id: u64,
66    pub publication: u64,
67}
68
69#[macro_export]
70/// # Published Macro - [wamp-proto](https://wamp-proto.org/wamp_latest_ietf.html#name-published-2)
71/// Macro that allows for default empty implementation of publication object on Published.
72/// ## Examples
73/// ```
74/// use wamp_core::messages::{self, Published};
75/// use wamp_core::published;
76/// use serde_json::json;
77///
78/// let mut published_message = published!(1, 2);
79/// let published_message2 = published!(1, 3);
80///
81/// assert_ne!(published_message, published_message2);
82///
83/// // These macro invocations are the same as the following:
84/// let published_message3 = Published {
85///     request_id: 1,
86///     publication: 2
87/// };
88///
89/// assert_eq!(published_message, published_message3);
90/// assert_ne!(published_message2, published_message3);
91/// ```
92macro_rules! published {
93    ($request_id:expr, $publication:expr) => {
94        Published {
95            request_id: $request_id,
96            publication: $publication,
97        }
98    };
99}
100
101impl WampMessage for Published {
102    const ID: u64 = 17;
103
104    fn direction(role: Roles) -> &'static MessageDirection {
105        match role {
106            Roles::Callee => &MessageDirection {
107                receives: &true,
108                sends: &false,
109            },
110            Roles::Caller => &MessageDirection {
111                receives: &false,
112                sends: &false,
113            },
114            Roles::Publisher => &MessageDirection {
115                receives: &true,
116                sends: &false,
117            },
118            Roles::Subscriber => &MessageDirection {
119                receives: &false,
120                sends: &false,
121            },
122            Roles::Dealer => &MessageDirection {
123                receives: &false,
124                sends: &false,
125            },
126            Roles::Broker => &MessageDirection {
127                receives: &false,
128                sends: &true,
129            },
130        }
131    }
132}
133
134impl Serialize for Published {
135    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
136    where
137        S: serde::Serializer,
138    {
139        (Self::ID, &self.request_id, &self.publication).serialize(serializer)
140    }
141}
142
143impl<'de> Deserialize<'de> for Published {
144    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
145    where
146        D: Deserializer<'de>,
147    {
148        struct PublishedVisitor(PhantomData<u64>, PhantomData<u64>, PhantomData<u64>);
149
150        impl<'vi> Visitor<'vi> for PublishedVisitor {
151            type Value = Published;
152            fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
153                formatter.write_str("A sequence of Published components.")
154            }
155
156            fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
157            where
158                A: SeqAccess<'vi>,
159            {
160                let message_id: u64 = helpers::deser_seq_element(
161                    &mut seq,
162                    "Message ID must be present and type u8.",
163                )?;
164                helpers::validate_id::<Published, A, _>(&message_id, "Published")?;
165                let request_id: u64 = helpers::deser_seq_element(
166                    &mut seq,
167                    "request_id must be present and type u64.",
168                )?;
169                let publication: u64 = helpers::deser_seq_element(
170                    &mut seq,
171                    "publication must be present and object like.",
172                )?;
173                Ok(Published {
174                    request_id,
175                    publication,
176                })
177            }
178        }
179
180        deserializer.deserialize_struct(
181            "Published",
182            &["request_id", "publication"],
183            PublishedVisitor(PhantomData, PhantomData, PhantomData),
184        )
185    }
186}
187
188#[cfg(test)]
189mod tests {
190    use serde_json::{from_str, to_string};
191
192    use super::Published;
193
194    #[test]
195    fn test() {
196        let d1 = r#"[17,239714735,4429313566]"#;
197        let p1 = Published {
198            request_id: 239714735,
199            publication: 4429313566,
200        };
201        assert_eq!(d1, to_string(&p1).unwrap());
202        assert_eq!(from_str::<Published>(d1).unwrap(), p1);
203    }
204}