mirror of
https://gitlab.com/xmpp-rs/xmpp-rs.git
synced 2024-06-16 12:56:54 +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::util::error::Error;
|
||||||
use crate::Element;
|
use crate::Element;
|
||||||
use jid::Jid;
|
use jid::Jid;
|
||||||
use std::collections::BTreeMap;
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
@ -461,8 +460,6 @@ impl From<Reason> for Element {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Lang = String;
|
|
||||||
|
|
||||||
/// Informs the recipient of something.
|
/// Informs the recipient of something.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct ReasonElement {
|
pub struct ReasonElement {
|
||||||
|
@ -470,15 +467,13 @@ pub struct ReasonElement {
|
||||||
pub reason: Reason,
|
pub reason: Reason,
|
||||||
|
|
||||||
/// A human-readable description of this reason.
|
/// A human-readable description of this reason.
|
||||||
pub texts: BTreeMap<Lang, String>,
|
pub text: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for ReasonElement {
|
impl fmt::Display for ReasonElement {
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(fmt, "{}", Element::from(self.reason.clone()).name())?;
|
write!(fmt, "{}", Element::from(self.reason.clone()).name())?;
|
||||||
if let Some(text) = self.texts.get("en") {
|
if let Some(text) = self.text.as_ref() {
|
||||||
write!(fmt, ": {}", text)?;
|
|
||||||
} else if let Some(text) = self.texts.get("") {
|
|
||||||
write!(fmt, ": {}", text)?;
|
write!(fmt, ": {}", text)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -492,17 +487,15 @@ impl TryFrom<Element> for ReasonElement {
|
||||||
check_self!(elem, "reason", JINGLE);
|
check_self!(elem, "reason", JINGLE);
|
||||||
check_no_attributes!(elem, "reason");
|
check_no_attributes!(elem, "reason");
|
||||||
let mut reason = None;
|
let mut reason = None;
|
||||||
let mut texts = BTreeMap::new();
|
let mut text = None;
|
||||||
for child in elem.children() {
|
for child in elem.children() {
|
||||||
if child.is("text", ns::JINGLE) {
|
if child.is("text", ns::JINGLE) {
|
||||||
check_no_children!(child, "text");
|
check_no_children!(child, "text");
|
||||||
check_no_unknown_attributes!(child, "text", ["xml:lang"]);
|
check_no_unknown_attributes!(child, "text", ["xml:lang"]);
|
||||||
let lang = get_attr!(elem, "xml:lang", Default);
|
if text.is_some() {
|
||||||
if texts.insert(lang, child.text()).is_some() {
|
return Err(Error::ParseError("Multiple reason texts."));
|
||||||
return Err(Error::ParseError(
|
|
||||||
"Text element present twice for the same xml:lang.",
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
text = Some(child.text());
|
||||||
} else if child.has_ns(ns::JINGLE) {
|
} else if child.has_ns(ns::JINGLE) {
|
||||||
if reason.is_some() {
|
if reason.is_some() {
|
||||||
return Err(Error::ParseError(
|
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."))?;
|
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 {
|
fn from(reason: ReasonElement) -> Element {
|
||||||
Element::builder("reason", ns::JINGLE)
|
Element::builder("reason", ns::JINGLE)
|
||||||
.append(Element::from(reason.reason))
|
.append(Element::from(reason.reason))
|
||||||
.append_all(reason.texts.into_iter().map(|(lang, text)| {
|
.append_all(
|
||||||
Element::builder("text", ns::JINGLE)
|
reason
|
||||||
.attr("xml:lang", lang)
|
.text
|
||||||
.append(text)
|
.into_iter()
|
||||||
}))
|
.map(|text| Element::builder("text", ns::JINGLE).append(text)),
|
||||||
|
)
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -823,13 +817,13 @@ mod tests {
|
||||||
let jingle = Jingle::try_from(elem).unwrap();
|
let jingle = Jingle::try_from(elem).unwrap();
|
||||||
let reason = jingle.reason.unwrap();
|
let reason = jingle.reason.unwrap();
|
||||||
assert_eq!(reason.reason, Reason::Success);
|
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 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 jingle = Jingle::try_from(elem).unwrap();
|
||||||
let reason = jingle.reason.unwrap();
|
let reason = jingle.reason.unwrap();
|
||||||
assert_eq!(reason.reason, Reason::Success);
|
assert_eq!(reason.reason, Reason::Success);
|
||||||
assert_eq!(reason.texts.get(""), Some(&String::from("coucou")));
|
assert_eq!(reason.text, Some(String::from("coucou")));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -872,7 +866,7 @@ mod tests {
|
||||||
Error::ParseError(string) => string,
|
Error::ParseError(string) => string,
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
};
|
};
|
||||||
assert_eq!(message, "Text element present twice for the same xml:lang.");
|
assert_eq!(message, "Multiple reason texts.");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Reference in New Issue
Block a user