data_forms: Split field parsing into its own TryFrom impl.

This commit is contained in:
Emmanuel Gil Peyrot 2017-07-29 04:19:58 +01:00
parent 37d1ae64ad
commit 58760fc28d

View file

@ -57,6 +57,78 @@ pub struct Field {
pub media: Vec<MediaElement>, pub media: Vec<MediaElement>,
} }
impl Field {
fn is_list(&self) -> bool {
self.type_ == FieldType::ListSingle ||
self.type_ == FieldType::ListMulti
}
}
impl TryFrom<Element> for Field {
type Err = Error;
fn try_from(elem: Element) -> Result<Field, Error> {
let mut field = Field {
var: get_attr!(elem, "var", required),
type_: get_attr!(elem, "type", default),
label: get_attr!(elem, "label", optional),
required: false,
options: vec!(),
values: vec!(),
media: vec!(),
};
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."));
}
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."));
}
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,
});
} 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."));
}
}
Ok(field)
}
}
impl From<Field> for Element { impl From<Field> for Element {
fn from(field: Field) -> Element { fn from(field: Field) -> Element {
Element::builder("field") Element::builder("field")
@ -129,70 +201,8 @@ impl TryFrom<Element> for DataForm {
} }
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 var: String = get_attr!(child, "var", required); let field = Field::try_from(child.clone())?;
let field_type = get_attr!(child, "type", default); if field.var == "FORM_TYPE" && field.type_ == FieldType::Hidden {
let label = get_attr!(child, "label", optional);
let is_form_type = var == "FORM_TYPE" && field_type == FieldType::Hidden;
let is_list = field_type == FieldType::ListSingle || field_type == FieldType::ListMulti;
let mut field = Field {
var: var,
type_: field_type,
label: label,
required: false,
options: vec!(),
values: vec!(),
media: vec!(),
};
for element in child.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."));
}
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."));
}
field.required = true;
} else if element.is("option", ns::DATA_FORMS) {
if !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,
});
} 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."));
}
}
if is_form_type {
if form.form_type.is_some() { if form.form_type.is_some() {
return Err(Error::ParseError("More than one FORM_TYPE in a data form.")); return Err(Error::ParseError("More than one FORM_TYPE in a data form."));
} }