mirror of
https://gitlab.com/xmpp-rs/xmpp-rs.git
synced 2024-07-12 22:21:53 +00:00
data_forms: Split field parsing into its own TryFrom impl.
This commit is contained in:
parent
37d1ae64ad
commit
58760fc28d
1 changed files with 74 additions and 64 deletions
|
@ -57,6 +57,78 @@ pub struct Field {
|
|||
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 isn’t a value or media element."));
|
||||
}
|
||||
}
|
||||
Ok(field)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Field> for Element {
|
||||
fn from(field: Field) -> Element {
|
||||
Element::builder("field")
|
||||
|
@ -129,70 +201,8 @@ impl TryFrom<Element> 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."));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue