mam.rs

  1use minidom::Element;
  2use jid::Jid;
  3
  4use error::Error;
  5
  6use data_forms;
  7use data_forms::DataForm;
  8use rsm;
  9use rsm::Set;
 10use forwarding;
 11use forwarding::Forwarded;
 12
 13use ns;
 14
 15#[derive(Debug, Clone)]
 16pub struct Query {
 17    pub queryid: Option<String>,
 18    pub node: Option<String>,
 19    pub form: Option<DataForm>,
 20    pub set: Option<Set>,
 21}
 22
 23#[derive(Debug, Clone)]
 24pub struct Result_ {
 25    pub queryid: String,
 26    pub id: String,
 27    pub forwarded: Forwarded,
 28}
 29
 30#[derive(Debug, Clone)]
 31pub struct Fin {
 32    pub complete: bool,
 33    pub set: Set,
 34}
 35
 36#[derive(Debug, Clone)]
 37pub enum DefaultPrefs {
 38    Always,
 39    Never,
 40    Roster,
 41}
 42
 43#[derive(Debug, Clone)]
 44pub struct Prefs {
 45    pub default_: Option<DefaultPrefs>,
 46    pub always: Vec<Jid>,
 47    pub never: Vec<Jid>,
 48}
 49
 50pub fn parse_query(root: &Element) -> Result<Query, Error> {
 51    if !root.is("query", ns::MAM) {
 52        return Err(Error::ParseError("This is not a query element."));
 53    }
 54    let mut form = None;
 55    let mut set = None;
 56    for child in root.children() {
 57        if child.is("x", ns::DATA_FORMS) {
 58            form = Some(data_forms::parse_data_form(child)?);
 59        } else if child.is("set", ns::RSM) {
 60            set = Some(rsm::parse_rsm(child)?);
 61        } else {
 62            return Err(Error::ParseError("Unknown child in query element."));
 63        }
 64    }
 65    let queryid = match root.attr("queryid") {
 66        Some(queryid) => Some(queryid.to_owned()),
 67        None => None,
 68    };
 69    let node = match root.attr("node") {
 70        Some(node) => Some(node.to_owned()),
 71        None => None,
 72    };
 73    Ok(Query { queryid, node, form, set })
 74}
 75
 76pub fn parse_result(root: &Element) -> Result<Result_, Error> {
 77    if !root.is("result", ns::MAM) {
 78        return Err(Error::ParseError("This is not a result element."));
 79    }
 80    let mut forwarded = None;
 81    for child in root.children() {
 82        if child.is("forwarded", ns::FORWARD) {
 83            forwarded = Some(forwarding::parse_forwarded(child)?);
 84        } else {
 85            return Err(Error::ParseError("Unknown child in result element."));
 86        }
 87    }
 88    let queryid = match root.attr("queryid") {
 89        Some(queryid) => queryid.to_owned(),
 90        None => return Err(Error::ParseError("No 'queryid' attribute present in result.")),
 91    };
 92    let id = match root.attr("id") {
 93        Some(id) => id.to_owned(),
 94        None => return Err(Error::ParseError("No 'id' attribute present in result.")),
 95    };
 96    if forwarded.is_none() {
 97        return Err(Error::ParseError("Mandatory forwarded element missing in result."));
 98    }
 99    let forwarded = forwarded.unwrap();
100    Ok(Result_ {
101        queryid,
102        id,
103        forwarded,
104    })
105}
106
107pub fn parse_fin(root: &Element) -> Result<Fin, Error> {
108    if !root.is("fin", ns::MAM) {
109        return Err(Error::ParseError("This is not a fin element."));
110    }
111    let mut set = None;
112    for child in root.children() {
113        if child.is("set", ns::RSM) {
114            set = Some(rsm::parse_rsm(child)?);
115        } else {
116            return Err(Error::ParseError("Unknown child in fin element."));
117        }
118    }
119    let complete = match root.attr("complete") {
120        Some(complete) => complete == "true",
121        None => false,
122    };
123    if set.is_none() {
124        return Err(Error::ParseError("Mandatory set element missing in fin."));
125    }
126    let set = set.unwrap();
127    Ok(Fin { complete, set })
128}
129
130pub fn parse_prefs(root: &Element) -> Result<Prefs, Error> {
131    if !root.is("prefs", ns::MAM) {
132        return Err(Error::ParseError("This is not a prefs element."));
133    }
134    let mut always = vec!();
135    let mut never = vec!();
136    for child in root.children() {
137        if child.is("always", ns::MAM) {
138            for jid_elem in child.children() {
139                if !jid_elem.is("jid", ns::MAM) {
140                    return Err(Error::ParseError("Invalid jid element in always."));
141                }
142                always.push(jid_elem.text().parse()?);
143            }
144        } else if child.is("never", ns::MAM) {
145            for jid_elem in child.children() {
146                if !jid_elem.is("jid", ns::MAM) {
147                    return Err(Error::ParseError("Invalid jid element in never."));
148                }
149                never.push(jid_elem.text().parse()?);
150            }
151        } else {
152            return Err(Error::ParseError("Unknown child in prefs element."));
153        }
154    }
155    let default_ = match root.attr("default") {
156        Some("always") => Some(DefaultPrefs::Always),
157        Some("never") => Some(DefaultPrefs::Never),
158        Some("roster") => Some(DefaultPrefs::Roster),
159        None => None,
160
161        _ => return Err(Error::ParseError("Invalid 'default' attribute present in prefs.")),
162    };
163    Ok(Prefs { default_, always, never })
164}
165
166pub fn serialise_query(query: &Query) -> Element {
167    let mut elem = Element::builder("query")
168                           .ns(ns::MAM)
169                           .attr("queryid", query.queryid.clone())
170                           .attr("node", query.node.clone())
171                           .build();
172    //if let Some(form) = query.form {
173    //    elem.append_child(data_forms::serialise(&form));
174    //}
175    if let Some(ref set) = query.set {
176        elem.append_child(rsm::serialise(&set));
177    }
178    elem
179}
180
181pub fn serialise_result(result: &Result_) -> Element {
182    let mut elem = Element::builder("result")
183                           .ns(ns::MAM)
184                           .attr("queryid", result.queryid.clone())
185                           .attr("id", result.id.clone())
186                           .build();
187    elem.append_child(forwarding::serialise(&result.forwarded));
188    elem
189}
190
191pub fn serialise_fin(fin: &Fin) -> Element {
192    let mut elem = Element::builder("fin")
193                           .ns(ns::MAM)
194                           .attr("complete", match fin.complete {
195                                true => Some("true"),
196                                false => None,
197                            })
198                           .build();
199    elem.append_child(rsm::serialise(&fin.set));
200    elem
201}
202
203pub fn serialise_prefs(prefs: &Prefs) -> Element {
204    let mut elem = Element::builder("prefs")
205                           .ns(ns::MAM)
206                           .attr("default", match prefs.default_ {
207                                Some(DefaultPrefs::Always) => Some("always"),
208                                Some(DefaultPrefs::Never) => Some("never"),
209                                Some(DefaultPrefs::Roster) => Some("roster"),
210                                None => None,
211                            })
212                           .build();
213    if !prefs.always.is_empty() {
214        let mut always = Element::builder("always")
215                                 .ns(ns::RSM)
216                                 .build();
217        for jid in prefs.always.clone() {
218            always.append_child(Element::builder("jid")
219                                        .ns(ns::RSM)
220                                        .append(String::from(jid))
221                                        .build());
222        }
223        elem.append_child(always);
224    }
225    if !prefs.never.is_empty() {
226        let mut never = Element::builder("never")
227                                 .ns(ns::RSM)
228                                 .build();
229        for jid in prefs.never.clone() {
230            never.append_child(Element::builder("jid")
231                                        .ns(ns::RSM)
232                                        .append(String::from(jid))
233                                        .build());
234        }
235        elem.append_child(never);
236    }
237    elem
238}
239
240#[cfg(test)]
241mod tests {
242    use minidom::Element;
243    use error::Error;
244    use mam;
245
246    #[test]
247    fn test_query() {
248        let elem: Element = "<query xmlns='urn:xmpp:mam:2'/>".parse().unwrap();
249        mam::parse_query(&elem).unwrap();
250    }
251
252    #[test]
253    fn test_result() {
254        let elem: Element = r#"
255<result xmlns='urn:xmpp:mam:2' queryid='f27' id='28482-98726-73623'>
256  <forwarded xmlns='urn:xmpp:forward:0'>
257    <delay xmlns='urn:xmpp:delay' stamp='2010-07-10T23:08:25Z'/>
258    <message xmlns='jabber:client' from="witch@shakespeare.lit" to="macbeth@shakespeare.lit">
259      <body>Hail to thee</body>
260    </message>
261  </forwarded>
262</result>
263"#.parse().unwrap();
264        mam::parse_result(&elem).unwrap();
265    }
266
267    #[test]
268    fn test_fin() {
269        let elem: Element = r#"
270<fin xmlns='urn:xmpp:mam:2'>
271  <set xmlns='http://jabber.org/protocol/rsm'>
272    <first index='0'>28482-98726-73623</first>
273    <last>09af3-cc343-b409f</last>
274  </set>
275</fin>
276"#.parse().unwrap();
277        mam::parse_fin(&elem).unwrap();
278    }
279
280    #[test]
281    fn test_query_x() {
282        let elem: Element = r#"
283<query xmlns='urn:xmpp:mam:2'>
284  <x xmlns='jabber:x:data' type='submit'>
285    <field var='FORM_TYPE' type='hidden'>
286      <value>urn:xmpp:mam:2</value>
287    </field>
288    <field var='with'>
289      <value>juliet@capulet.lit</value>
290    </field>
291  </x>
292</query>
293"#.parse().unwrap();
294        mam::parse_query(&elem).unwrap();
295    }
296
297    #[test]
298    fn test_query_x_set() {
299        let elem: Element = r#"
300<query xmlns='urn:xmpp:mam:2'>
301  <x xmlns='jabber:x:data' type='submit'>
302    <field var='FORM_TYPE' type='hidden'>
303      <value>urn:xmpp:mam:2</value>
304    </field>
305    <field var='start'>
306      <value>2010-08-07T00:00:00Z</value>
307    </field>
308  </x>
309  <set xmlns='http://jabber.org/protocol/rsm'>
310    <max>10</max>
311  </set>
312</query>
313"#.parse().unwrap();
314        mam::parse_query(&elem).unwrap();
315    }
316
317    #[test]
318    fn test_prefs_get() {
319        let elem: Element = "<prefs xmlns='urn:xmpp:mam:2'/>".parse().unwrap();
320        mam::parse_prefs(&elem).unwrap();
321
322        let elem: Element = r#"
323<prefs xmlns='urn:xmpp:mam:2' default='roster'>
324  <always/>
325  <never/>
326</prefs>
327"#.parse().unwrap();
328        mam::parse_prefs(&elem).unwrap();
329    }
330
331    #[test]
332    fn test_prefs_result() {
333        let elem: Element = r#"
334<prefs xmlns='urn:xmpp:mam:2' default='roster'>
335  <always>
336    <jid>romeo@montague.lit</jid>
337  </always>
338  <never>
339    <jid>montague@montague.lit</jid>
340  </never>
341</prefs>
342"#.parse().unwrap();
343        mam::parse_prefs(&elem).unwrap();
344    }
345
346    #[test]
347    fn test_invalid_child() {
348        let elem: Element = "<query xmlns='urn:xmpp:mam:2'><coucou/></query>".parse().unwrap();
349        let error = mam::parse_query(&elem).unwrap_err();
350        let message = match error {
351            Error::ParseError(string) => string,
352            _ => panic!(),
353        };
354        assert_eq!(message, "Unknown child in query element.");
355    }
356
357    #[test]
358    fn test_serialise() {
359        let elem: Element = "<query xmlns='urn:xmpp:mam:2'/>".parse().unwrap();
360        let replace = mam::Query { queryid: None, node: None, form: None, set: None };
361        let elem2 = mam::serialise_query(&replace);
362        assert_eq!(elem, elem2);
363    }
364}