From 56a66f8c4b1e7f1d2efdd227b04aaab9f33860b1 Mon Sep 17 00:00:00 2001 From: Emmanuel Gil Peyrot Date: Sat, 29 Jul 2017 06:11:48 +0100 Subject: [PATCH] message: Enforce more type safety on Body, Subject and Thread. --- src/message.rs | 51 +++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/src/message.rs b/src/message.rs index 759b7d23..80a0e044 100644 --- a/src/message.rs +++ b/src/message.rs @@ -115,9 +115,10 @@ generate_attribute!(MessageType, "type", { }, Default = Normal); type Lang = String; -type Body = String; -type Subject = String; -type Thread = String; + +generate_elem_id!(Body, "body", ns::JABBER_CLIENT); +generate_elem_id!(Subject, "subject", ns::JABBER_CLIENT); +generate_elem_id!(Thread, "thread", ns::JABBER_CLIENT); /// The main structure representing the `` stanza. #[derive(Debug, Clone)] @@ -168,7 +169,8 @@ impl TryFrom for Message { return Err(Error::ParseError("Unknown child in body element.")); } let lang = get_attr!(root, "xml:lang", default); - if bodies.insert(lang, elem.text()).is_some() { + let body = Body(elem.text()); + if bodies.insert(lang, body).is_some() { return Err(Error::ParseError("Body element present twice for the same xml:lang.")); } } else if elem.is("subject", ns::JABBER_CLIENT) { @@ -176,7 +178,8 @@ impl TryFrom for Message { return Err(Error::ParseError("Unknown child in subject element.")); } let lang = get_attr!(root, "xml:lang", default); - if subjects.insert(lang, elem.text()).is_some() { + let subject = Subject(elem.text()); + if subjects.insert(lang, subject).is_some() { return Err(Error::ParseError("Subject element present twice for the same xml:lang.")); } } else if elem.is("thread", ns::JABBER_CLIENT) { @@ -186,7 +189,7 @@ impl TryFrom for Message { for _ in elem.children() { return Err(Error::ParseError("Unknown child in thread element.")); } - thread = Some(elem.text()); + thread = Some(Thread(elem.text())); } else { payloads.push(elem.clone()) } @@ -214,25 +217,23 @@ impl From for Element { .attr("type", message.type_) .append(message.subjects.into_iter() .map(|(lang, subject)| { - Element::builder("subject") - .ns(ns::JABBER_CLIENT) - .attr("xml:lang", match lang.as_ref() { - "" => None, - lang => Some(lang), - }) - .append(subject) - .build() }) + let mut subject = Element::from(subject); + subject.set_attr("xml:lang", match lang.as_ref() { + "" => None, + lang => Some(lang), + }); + subject + }) .collect::>()) .append(message.bodies.into_iter() .map(|(lang, body)| { - Element::builder("body") - .ns(ns::JABBER_CLIENT) - .attr("xml:lang", match lang.as_ref() { - "" => None, - lang => Some(lang), - }) - .append(body) - .build() }) + let mut body = Element::from(body); + body.set_attr("xml:lang", match lang.as_ref() { + "" => None, + lang => Some(lang), + }); + body + }) .collect::>()) .append(message.payloads) .build() @@ -268,7 +269,7 @@ mod tests { let elem: Element = "Hello world!".parse().unwrap(); let elem1 = elem.clone(); let message = Message::try_from(elem).unwrap(); - assert_eq!(message.bodies[""], "Hello world!"); + assert_eq!(message.bodies[""], Body::from_str("Hello world!").unwrap()); let elem2 = message.into(); assert_eq!(elem1, elem2); @@ -278,7 +279,7 @@ mod tests { fn test_serialise_body() { let elem: Element = "Hello world!".parse().unwrap(); let mut message = Message::new(Some(Jid::from_str("coucou@example.org").unwrap())); - message.bodies.insert(String::from(""), String::from("Hello world!")); + message.bodies.insert(String::from(""), Body::from_str("Hello world!").unwrap()); let elem2 = message.into(); assert_eq!(elem, elem2); } @@ -288,7 +289,7 @@ mod tests { let elem: Element = "Hello world!".parse().unwrap(); let elem1 = elem.clone(); let message = Message::try_from(elem).unwrap(); - assert_eq!(message.subjects[""], "Hello world!"); + assert_eq!(message.subjects[""], Subject::from_str("Hello world!").unwrap()); let elem2 = message.into(); assert_eq!(elem1, elem2);