1use xso::{AsXml, FromXml};
8
9use crate::ns;
10use crate::stanza_error::DefinedCondition;
11
12#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
14#[xml(namespace = ns::SM, name = "a")]
15pub struct A {
16 #[xml(attribute)]
18 pub h: u32,
19}
20
21impl A {
22 pub fn new(h: u32) -> A {
24 A { h }
25 }
26}
27
28generate_attribute!(
29 ResumeAttr,
31 "resume",
32 bool
33);
34
35#[derive(FromXml, AsXml, PartialEq, Debug, Clone, Default)]
37#[xml(namespace = ns::SM, name = "enable")]
38pub struct Enable {
39 #[xml(attribute(default))]
42 pub max: Option<u32>,
43
44 #[xml(attribute(default))]
46 pub resume: ResumeAttr,
47}
48
49impl Enable {
50 pub fn new() -> Self {
52 Enable::default()
53 }
54
55 pub fn with_max(mut self, max: u32) -> Self {
57 self.max = Some(max);
58 self
59 }
60
61 pub fn with_resume(mut self) -> Self {
63 self.resume = ResumeAttr::True;
64 self
65 }
66}
67
68generate_id!(
69 StreamId
71);
72
73#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
75#[xml(namespace = ns::SM, name = "enabled")]
76pub struct Enabled {
77 #[xml(attribute(default))]
79 pub id: Option<StreamId>,
80
81 #[xml(attribute(default))]
84 pub location: Option<String>,
85
86 #[xml(attribute(default))]
89 pub max: Option<u32>,
90
91 #[xml(attribute(default))]
93 pub resume: ResumeAttr,
94}
95
96generate_element!(
97 Failed, "failed", SM,
99 attributes: [
100 h: Option<u32> = "h",
102 ],
103 children: [
104 error: Option<DefinedCondition> = ("*", XMPP_STANZAS) => DefinedCondition
107 ]
108);
109
110#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
112#[xml(namespace = ns::SM, name = "r")]
113pub struct R;
114
115#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
117#[xml(namespace = ns::SM, name = "resume")]
118pub struct Resume {
119 #[xml(attribute)]
121 pub h: u32,
122
123 #[xml(attribute)]
126 pub previd: StreamId,
127}
128
129#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
131#[xml(namespace = ns::SM, name = "resumed")]
132pub struct Resumed {
133 #[xml(attribute)]
135 pub h: u32,
136
137 #[xml(attribute)]
140 pub previd: StreamId,
141}
142
143#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
146#[xml(namespace = ns::SM, name = "sm")]
147pub struct StreamManagement;
148
149#[cfg(test)]
150mod tests {
151 use super::*;
152 use minidom::Element;
153
154 #[cfg(target_pointer_width = "32")]
155 #[test]
156 fn test_size() {
157 assert_size!(A, 4);
158 assert_size!(ResumeAttr, 1);
159 assert_size!(Enable, 12);
160 assert_size!(StreamId, 12);
161 assert_size!(Enabled, 36);
162 assert_size!(Failed, 12);
163 assert_size!(R, 0);
164 assert_size!(Resume, 16);
165 assert_size!(Resumed, 16);
166 assert_size!(StreamManagement, 0);
167 }
168
169 #[cfg(target_pointer_width = "64")]
170 #[test]
171 fn test_size() {
172 assert_size!(A, 4);
173 assert_size!(ResumeAttr, 1);
174 assert_size!(Enable, 12);
175 assert_size!(StreamId, 24);
176 assert_size!(Enabled, 64);
177 assert_size!(Failed, 12);
178 assert_size!(R, 0);
179 assert_size!(Resume, 32);
180 assert_size!(Resumed, 32);
181 assert_size!(StreamManagement, 0);
182 }
183
184 #[test]
185 fn a() {
186 let elem: Element = "<a xmlns='urn:xmpp:sm:3' h='5'/>".parse().unwrap();
187 let a = A::try_from(elem).unwrap();
188 assert_eq!(a.h, 5);
189 }
190
191 #[test]
192 fn stream_feature() {
193 let elem: Element = "<sm xmlns='urn:xmpp:sm:3'/>".parse().unwrap();
194 StreamManagement::try_from(elem).unwrap();
195 }
196
197 #[test]
198 fn resume() {
199 let elem: Element = "<enable xmlns='urn:xmpp:sm:3' resume='true'/>"
200 .parse()
201 .unwrap();
202 let enable = Enable::try_from(elem).unwrap();
203 assert_eq!(enable.max, None);
204 assert_eq!(enable.resume, ResumeAttr::True);
205
206 let elem: Element = "<enabled xmlns='urn:xmpp:sm:3' resume='true' id='coucou' max='600'/>"
207 .parse()
208 .unwrap();
209 let enabled = Enabled::try_from(elem).unwrap();
210 let previd = enabled.id.unwrap();
211 assert_eq!(enabled.resume, ResumeAttr::True);
212 assert_eq!(previd, StreamId(String::from("coucou")));
213 assert_eq!(enabled.max, Some(600));
214 assert_eq!(enabled.location, None);
215
216 let elem: Element = "<resume xmlns='urn:xmpp:sm:3' h='5' previd='coucou'/>"
217 .parse()
218 .unwrap();
219 let resume = Resume::try_from(elem).unwrap();
220 assert_eq!(resume.h, 5);
221 assert_eq!(resume.previd, previd);
222
223 let elem: Element = "<resumed xmlns='urn:xmpp:sm:3' h='5' previd='coucou'/>"
224 .parse()
225 .unwrap();
226 let resumed = Resumed::try_from(elem).unwrap();
227 assert_eq!(resumed.h, 5);
228 assert_eq!(resumed.previd, previd);
229 }
230
231 #[test]
232 fn test_serialize_failed() {
233 let reference: Element = "<failed xmlns='urn:xmpp:sm:3'><unexpected-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></failed>"
234 .parse()
235 .unwrap();
236
237 let elem: Element = "<unexpected-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>"
238 .parse()
239 .unwrap();
240
241 let error = DefinedCondition::try_from(elem).unwrap();
242
243 let failed = Failed {
244 h: None,
245 error: Some(error),
246 };
247 let serialized: Element = failed.into();
248 assert_eq!(serialized, reference);
249 }
250}