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}