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