disco: Split Feature and Identity parsing out of DiscoQueryResult.

This commit is contained in:
Emmanuel Gil Peyrot 2017-07-29 04:35:15 +01:00
parent 5ece20a029
commit 4d3717d170

View file

@ -54,6 +54,27 @@ pub struct Feature {
pub var: String, pub var: String,
} }
impl TryFrom<Element> for Feature {
type Err = Error;
fn try_from(elem: Element) -> Result<Feature, Error> {
if !elem.is("feature", ns::DISCO_INFO) {
return Err(Error::ParseError("This is not a disco#info feature element."));
}
for _ in elem.children() {
return Err(Error::ParseError("Unknown child in disco#info feature element."));
}
for (attr, _) in elem.attrs() {
if attr != "var" {
return Err(Error::ParseError("Unknown attribute in disco#info feature element."));
}
}
Ok(Feature {
var: get_attr!(elem, "var", required)
})
}
}
impl From<Feature> for Element { impl From<Feature> for Element {
fn from(feature: Feature) -> Element { fn from(feature: Feature) -> Element {
Element::builder("feature") Element::builder("feature")
@ -71,6 +92,33 @@ pub struct Identity {
pub name: Option<String>, pub name: Option<String>,
} }
impl TryFrom<Element> for Identity {
type Err = Error;
fn try_from(elem: Element) -> Result<Identity, Error> {
if !elem.is("identity", ns::DISCO_INFO) {
return Err(Error::ParseError("This is not a disco#info identity element."));
}
let category = get_attr!(elem, "category", required);
if category == "" {
return Err(Error::ParseError("Identity must have a non-empty 'category' attribute."))
}
let type_ = get_attr!(elem, "type", required);
if type_ == "" {
return Err(Error::ParseError("Identity must have a non-empty 'type' attribute."))
}
Ok(Identity {
category: category,
type_: type_,
lang: get_attr!(elem, "xml:lang", optional),
name: get_attr!(elem, "name", optional),
})
}
}
impl From<Identity> for Element { impl From<Identity> for Element {
fn from(identity: Identity) -> Element { fn from(identity: Identity) -> Element {
Element::builder("identity") Element::builder("identity")
@ -108,29 +156,11 @@ impl TryFrom<Element> for DiscoInfoResult {
for child in elem.children() { for child in elem.children() {
if child.is("feature", ns::DISCO_INFO) { if child.is("feature", ns::DISCO_INFO) {
let feature = get_attr!(child, "var", required); let feature = Feature::try_from(child.clone())?;
result.features.push(Feature { result.features.push(feature);
var: feature,
});
} else if child.is("identity", ns::DISCO_INFO) { } else if child.is("identity", ns::DISCO_INFO) {
let category = get_attr!(child, "category", required); let identity = Identity::try_from(child.clone())?;
if category == "" { result.identities.push(identity);
return Err(Error::ParseError("Identity must have a non-empty 'category' attribute."))
}
let type_ = get_attr!(child, "type", required);
if type_ == "" {
return Err(Error::ParseError("Identity must have a non-empty 'type' attribute."))
}
let lang = get_attr!(child, "xml:lang", optional);
let name = get_attr!(child, "name", optional);
result.identities.push(Identity {
category: category,
type_: type_,
lang: lang,
name: name,
});
} else if child.is("x", ns::DATA_FORMS) { } else if child.is("x", ns::DATA_FORMS) {
let data_form = DataForm::try_from(child.clone())?; let data_form = DataForm::try_from(child.clone())?;
if data_form.type_ != DataFormType::Result_ { if data_form.type_ != DataFormType::Result_ {