diff --git a/src/data_forms.rs b/src/data_forms.rs index a2330a52..15135ef3 100644 --- a/src/data_forms.rs +++ b/src/data_forms.rs @@ -57,6 +57,78 @@ pub struct Field { pub media: Vec, } +impl Field { + fn is_list(&self) -> bool { + self.type_ == FieldType::ListSingle || + self.type_ == FieldType::ListMulti + } +} + +impl TryFrom for Field { + type Err = Error; + + fn try_from(elem: Element) -> Result { + 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 isn’t a value or media element.")); + } + } + Ok(field) + } +} + impl From for Element { fn from(field: Field) -> Element { Element::builder("field") @@ -129,70 +201,8 @@ impl TryFrom for DataForm { } form.instructions = Some(child.text()); } else if child.is("field", ns::DATA_FORMS) { - let var: String = get_attr!(child, "var", required); - let field_type = get_attr!(child, "type", default); - 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 isn’t a value or media element.")); - } - } - if is_form_type { + let field = Field::try_from(child.clone())?; + if field.var == "FORM_TYPE" && field.type_ == FieldType::Hidden { if form.form_type.is_some() { return Err(Error::ParseError("More than one FORM_TYPE in a data form.")); }