mirror of
https://gitlab.com/xmpp-rs/xmpp-rs.git
synced 2024-06-18 05:35:57 +02:00
xmpp_parsers::jingle: make ReasonElement::texts into an Option
The Jingle XEP says [1]: > The <reason/> element MAY contain a <text/> element that provides > human-readable information about the reason for the action. It says nowhere that there may be more than one `<text/>` element in there, or that they may be qualified by xml:lang. The schema [2] also agrees with that: > ``` > <xs:complexType name='reasonElementType'> > <xs:sequence> > <xs:choice> > <!-- … omitted … --> > </xs:choice> > <xs:element name='text' type='xs:string' minOccurs='0' maxOccurs='1'/> > <!-- … omitted … --> > </xs:sequence> > </xs:complexType> > ``` [1]: https://xmpp.org/extensions/xep-0166.html#def-reason [2]: https://xmpp.org/extensions/xep-0166.html#schema-jingle
This commit is contained in:
parent
1293e9a3eb
commit
ed0a1cd8cf
|
@ -14,7 +14,6 @@ use crate::ns;
|
|||
use crate::util::error::Error;
|
||||
use crate::Element;
|
||||
use jid::Jid;
|
||||
use std::collections::BTreeMap;
|
||||
use std::fmt;
|
||||
use std::str::FromStr;
|
||||
|
||||
|
@ -461,8 +460,6 @@ impl From<Reason> for Element {
|
|||
}
|
||||
}
|
||||
|
||||
type Lang = String;
|
||||
|
||||
/// Informs the recipient of something.
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct ReasonElement {
|
||||
|
@ -470,15 +467,13 @@ pub struct ReasonElement {
|
|||
pub reason: Reason,
|
||||
|
||||
/// A human-readable description of this reason.
|
||||
pub texts: BTreeMap<Lang, String>,
|
||||
pub text: Option<String>,
|
||||
}
|
||||
|
||||
impl fmt::Display for ReasonElement {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(fmt, "{}", Element::from(self.reason.clone()).name())?;
|
||||
if let Some(text) = self.texts.get("en") {
|
||||
write!(fmt, ": {}", text)?;
|
||||
} else if let Some(text) = self.texts.get("") {
|
||||
if let Some(text) = self.text.as_ref() {
|
||||
write!(fmt, ": {}", text)?;
|
||||
}
|
||||
Ok(())
|
||||
|
@ -492,17 +487,15 @@ impl TryFrom<Element> for ReasonElement {
|
|||
check_self!(elem, "reason", JINGLE);
|
||||
check_no_attributes!(elem, "reason");
|
||||
let mut reason = None;
|
||||
let mut texts = BTreeMap::new();
|
||||
let mut text = None;
|
||||
for child in elem.children() {
|
||||
if child.is("text", ns::JINGLE) {
|
||||
check_no_children!(child, "text");
|
||||
check_no_unknown_attributes!(child, "text", ["xml:lang"]);
|
||||
let lang = get_attr!(elem, "xml:lang", Default);
|
||||
if texts.insert(lang, child.text()).is_some() {
|
||||
return Err(Error::ParseError(
|
||||
"Text element present twice for the same xml:lang.",
|
||||
));
|
||||
if text.is_some() {
|
||||
return Err(Error::ParseError("Multiple reason texts."));
|
||||
}
|
||||
text = Some(child.text());
|
||||
} else if child.has_ns(ns::JINGLE) {
|
||||
if reason.is_some() {
|
||||
return Err(Error::ParseError(
|
||||
|
@ -517,7 +510,7 @@ impl TryFrom<Element> for ReasonElement {
|
|||
}
|
||||
}
|
||||
let reason = reason.ok_or(Error::ParseError("Reason doesn’t contain a valid reason."))?;
|
||||
Ok(ReasonElement { reason, texts })
|
||||
Ok(ReasonElement { reason, text })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -525,11 +518,12 @@ impl From<ReasonElement> for Element {
|
|||
fn from(reason: ReasonElement) -> Element {
|
||||
Element::builder("reason", ns::JINGLE)
|
||||
.append(Element::from(reason.reason))
|
||||
.append_all(reason.texts.into_iter().map(|(lang, text)| {
|
||||
Element::builder("text", ns::JINGLE)
|
||||
.attr("xml:lang", lang)
|
||||
.append(text)
|
||||
}))
|
||||
.append_all(
|
||||
reason
|
||||
.text
|
||||
.into_iter()
|
||||
.map(|text| Element::builder("text", ns::JINGLE).append(text)),
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
@ -823,13 +817,13 @@ mod tests {
|
|||
let jingle = Jingle::try_from(elem).unwrap();
|
||||
let reason = jingle.reason.unwrap();
|
||||
assert_eq!(reason.reason, Reason::Success);
|
||||
assert_eq!(reason.texts, BTreeMap::new());
|
||||
assert_eq!(reason.text, None);
|
||||
|
||||
let elem: Element = "<jingle xmlns='urn:xmpp:jingle:1' action='session-initiate' sid='coucou'><reason><success/><text>coucou</text></reason></jingle>".parse().unwrap();
|
||||
let jingle = Jingle::try_from(elem).unwrap();
|
||||
let reason = jingle.reason.unwrap();
|
||||
assert_eq!(reason.reason, Reason::Success);
|
||||
assert_eq!(reason.texts.get(""), Some(&String::from("coucou")));
|
||||
assert_eq!(reason.text, Some(String::from("coucou")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -872,7 +866,7 @@ mod tests {
|
|||
Error::ParseError(string) => string,
|
||||
_ => panic!(),
|
||||
};
|
||||
assert_eq!(message, "Text element present twice for the same xml:lang.");
|
||||
assert_eq!(message, "Multiple reason texts.");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Reference in New Issue
Block a user