data_forms: Use the new helper macros to simplify parsing.

This commit is contained in:
Emmanuel Gil Peyrot 2017-10-10 18:26:05 +01:00
commit 9f27f200ca

View file

@ -14,25 +14,35 @@ use ns;
use media_element::MediaElement; use media_element::MediaElement;
generate_attribute!(FieldType, "type", {
Boolean => "boolean",
Fixed => "fixed",
Hidden => "hidden",
JidMulti => "jid-multi",
JidSingle => "jid-single",
ListMulti => "list-multi",
ListSingle => "list-single",
TextMulti => "text-multi",
TextPrivate => "text-private",
TextSingle => "text-single",
}, Default = TextSingle);
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Option_ { pub struct Option_ {
pub label: Option<String>, pub label: Option<String>,
pub value: String, pub value: String,
} }
impl TryFrom<Element> for Option_ {
type Err = Error;
fn try_from(elem: Element) -> Result<Option_, Error> {
check_self!(elem, "option", ns::DATA_FORMS);
check_no_unknown_attributes!(elem, "option", ["label"]);
let mut value = None;
for child in elem.children() {
if !child.is("value", ns::DATA_FORMS) {
return Err(Error::ParseError("Non-value element in option element"));
}
if value.is_some() {
return Err(Error::ParseError("More than one value element in option element"));
}
value = Some(child.text());
}
Ok(Option_ {
label: get_attr!(elem, "label", optional),
value: value.ok_or(Error::ParseError("No value element in option element"))?,
})
}
}
impl From<Option_> for Element { impl From<Option_> for Element {
fn from(option: Option_) -> Element { fn from(option: Option_) -> Element {
Element::builder("option") Element::builder("option")
@ -46,6 +56,19 @@ impl From<Option_> for Element {
} }
} }
generate_attribute!(FieldType, "type", {
Boolean => "boolean",
Fixed => "fixed",
Hidden => "hidden",
JidMulti => "jid-multi",
JidSingle => "jid-single",
ListMulti => "list-multi",
ListSingle => "list-single",
TextMulti => "text-multi",
TextPrivate => "text-private",
TextSingle => "text-single",
}, Default = TextSingle);
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Field { pub struct Field {
pub var: String, pub var: String,
@ -68,6 +91,8 @@ impl TryFrom<Element> for Field {
type Err = Error; type Err = Error;
fn try_from(elem: Element) -> Result<Field, Error> { fn try_from(elem: Element) -> Result<Field, Error> {
check_self!(elem, "field", ns::DATA_FORMS);
check_no_unknown_attributes!(elem, "field", ["label", "type", "var"]);
let mut field = Field { let mut field = Field {
var: get_attr!(elem, "var", required), var: get_attr!(elem, "var", required),
type_: get_attr!(elem, "type", default), type_: get_attr!(elem, "type", default),
@ -79,50 +104,27 @@ impl TryFrom<Element> for Field {
}; };
for element in elem.children() { for element in elem.children() {
if element.is("value", ns::DATA_FORMS) { if element.is("value", ns::DATA_FORMS) {
for _ in element.children() { check_no_children!(element, "value");
return Err(Error::ParseError("Value element must not have any child.")); check_no_unknown_attributes!(element, "value", []);
}
for _ in element.attrs() {
return Err(Error::ParseError("Value element must not have any attribute."));
}
field.values.push(element.text()); field.values.push(element.text());
} else if element.is("required", ns::DATA_FORMS) { } else if element.is("required", ns::DATA_FORMS) {
if field.required { if field.required {
return Err(Error::ParseError("More than one required element.")); return Err(Error::ParseError("More than one required element."));
} }
for _ in element.children() { check_no_children!(element, "required");
return Err(Error::ParseError("Required element must not have any child.")); check_no_unknown_attributes!(element, "required", []);
}
for _ in element.attrs() {
return Err(Error::ParseError("Required element must not have any attribute."));
}
field.required = true; field.required = true;
} else if element.is("option", ns::DATA_FORMS) { } else if element.is("option", ns::DATA_FORMS) {
if !field.is_list() { if !field.is_list() {
return Err(Error::ParseError("Option element found in non-list field.")); return Err(Error::ParseError("Option element found in non-list field."));
} }
let label = get_attr!(element, "label", optional); let option = Option_::try_from(element.clone())?;
let mut value = None; field.options.push(option);
for child2 in element.children() {
if child2.is("value", ns::DATA_FORMS) {
if value.is_some() {
return Err(Error::ParseError("More than one value element in option element"));
}
value = Some(child2.text());
} else {
return Err(Error::ParseError("Non-value element in option element"));
}
}
let value = value.ok_or(Error::ParseError("No value element in option element"))?;
field.options.push(Option_ {
label: label,
value: value,
});
} else if element.is("media", ns::MEDIA_ELEMENT) { } else if element.is("media", ns::MEDIA_ELEMENT) {
let media_element = MediaElement::try_from(element.clone())?; let media_element = MediaElement::try_from(element.clone())?;
field.media.push(media_element); field.media.push(media_element);
} else { } else {
return Err(Error::ParseError("Field child isnt a value or media element.")); return Err(Error::ParseError("Field child isnt a value, option or media element."));
} }
} }
Ok(field) Ok(field)
@ -166,9 +168,8 @@ impl TryFrom<Element> for DataForm {
type Err = Error; type Err = Error;
fn try_from(elem: Element) -> Result<DataForm, Error> { fn try_from(elem: Element) -> Result<DataForm, Error> {
if !elem.is("x", ns::DATA_FORMS) { check_self!(elem, "x", ns::DATA_FORMS);
return Err(Error::ParseError("This is not a data form element.")); check_no_unknown_attributes!(elem, "x", ["type"]);
}
let type_ = get_attr!(elem, "type", required); let type_ = get_attr!(elem, "type", required);
let mut form = DataForm { let mut form = DataForm {
type_: type_, type_: type_,
@ -182,23 +183,15 @@ impl TryFrom<Element> for DataForm {
if form.title.is_some() { if form.title.is_some() {
return Err(Error::ParseError("More than one title in form element.")); return Err(Error::ParseError("More than one title in form element."));
} }
for _ in child.children() { check_no_children!(child, "title");
return Err(Error::ParseError("Title element must not have any child.")); check_no_unknown_attributes!(child, "title", []);
}
for _ in child.attrs() {
return Err(Error::ParseError("Title element must not have any attribute."));
}
form.title = Some(child.text()); form.title = Some(child.text());
} else if child.is("instructions", ns::DATA_FORMS) { } else if child.is("instructions", ns::DATA_FORMS) {
if form.instructions.is_some() { if form.instructions.is_some() {
return Err(Error::ParseError("More than one instructions in form element.")); return Err(Error::ParseError("More than one instructions in form element."));
} }
for _ in child.children() { check_no_children!(child, "instructions");
return Err(Error::ParseError("instructions element must not have any child.")); check_no_unknown_attributes!(child, "instructions", []);
}
for _ in child.attrs() {
return Err(Error::ParseError("instructions element must not have any attribute."));
}
form.instructions = Some(child.text()); form.instructions = Some(child.text());
} else if child.is("field", ns::DATA_FORMS) { } else if child.is("field", ns::DATA_FORMS) {
let field = Field::try_from(child.clone())?; let field = Field::try_from(child.clone())?;