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;
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)]
pub struct Option_ {
pub label: Option<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 {
fn from(option: Option_) -> Element {
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)]
pub struct Field {
pub var: String,
@ -68,6 +91,8 @@ impl TryFrom<Element> for Field {
type Err = 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 {
var: get_attr!(elem, "var", required),
type_: get_attr!(elem, "type", default),
@ -79,50 +104,27 @@ impl TryFrom<Element> for Field {
};
for element in elem.children() {
if element.is("value", ns::DATA_FORMS) {
for _ in element.children() {
return Err(Error::ParseError("Value element must not have any child."));
}
for _ in element.attrs() {
return Err(Error::ParseError("Value element must not have any attribute."));
}
check_no_children!(element, "value");
check_no_unknown_attributes!(element, "value", []);
field.values.push(element.text());
} else if element.is("required", ns::DATA_FORMS) {
if field.required {
return Err(Error::ParseError("More than one required element."));
}
for _ in element.children() {
return Err(Error::ParseError("Required element must not have any child."));
}
for _ in element.attrs() {
return Err(Error::ParseError("Required element must not have any attribute."));
}
check_no_children!(element, "required");
check_no_unknown_attributes!(element, "required", []);
field.required = true;
} else if element.is("option", ns::DATA_FORMS) {
if !field.is_list() {
return Err(Error::ParseError("Option element found in non-list field."));
}
let label = get_attr!(element, "label", optional);
let mut value = None;
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,
});
let option = Option_::try_from(element.clone())?;
field.options.push(option);
} else if element.is("media", ns::MEDIA_ELEMENT) {
let media_element = MediaElement::try_from(element.clone())?;
field.media.push(media_element);
} 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)
@ -166,9 +168,8 @@ impl TryFrom<Element> for DataForm {
type Err = Error;
fn try_from(elem: Element) -> Result<DataForm, Error> {
if !elem.is("x", ns::DATA_FORMS) {
return Err(Error::ParseError("This is not a data form element."));
}
check_self!(elem, "x", ns::DATA_FORMS);
check_no_unknown_attributes!(elem, "x", ["type"]);
let type_ = get_attr!(elem, "type", required);
let mut form = DataForm {
type_: type_,
@ -182,23 +183,15 @@ impl TryFrom<Element> for DataForm {
if form.title.is_some() {
return Err(Error::ParseError("More than one title in form element."));
}
for _ in child.children() {
return Err(Error::ParseError("Title element must not have any child."));
}
for _ in child.attrs() {
return Err(Error::ParseError("Title element must not have any attribute."));
}
check_no_children!(child, "title");
check_no_unknown_attributes!(child, "title", []);
form.title = Some(child.text());
} else if child.is("instructions", ns::DATA_FORMS) {
if form.instructions.is_some() {
return Err(Error::ParseError("More than one instructions in form element."));
}
for _ in child.children() {
return Err(Error::ParseError("instructions element must not have any child."));
}
for _ in child.attrs() {
return Err(Error::ParseError("instructions element must not have any attribute."));
}
check_no_children!(child, "instructions");
check_no_unknown_attributes!(child, "instructions", []);
form.instructions = Some(child.text());
} else if child.is("field", ns::DATA_FORMS) {
let field = Field::try_from(child.clone())?;