diff --git a/parsers/src/bind2.rs b/parsers/src/bind2.rs
index fa72cd8a..4b76d378 100644
--- a/parsers/src/bind2.rs
+++ b/parsers/src/bind2.rs
@@ -4,6 +4,8 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+use xso::{AsXml, FromXml};
+
use crate::mam;
use crate::ns;
use minidom::Element;
@@ -11,70 +13,14 @@ use xso::error::{Error, FromElementError};
/// Represents the `` element, as sent by the server in SASL 2 to advertise which features
/// can be enabled during the binding step.
-#[derive(Debug, Clone, PartialEq)]
+#[derive(FromXml, AsXml, Debug, Clone, PartialEq)]
+#[xml(namespace = ns::BIND2, name = "bind")]
pub struct BindFeature {
/// The features that can be enabled by the client.
+ #[xml(extract(name = "inline", fields(extract(n = .., name = "feature", fields(attribute(name = "var", type_ = String))))))]
pub inline_features: Vec,
}
-impl TryFrom for BindFeature {
- type Error = FromElementError;
-
- fn try_from(root: Element) -> Result {
- check_self!(root, "bind", BIND2);
- check_no_attributes!(root, "bind");
-
- let mut inline = None;
- for child in root.children() {
- if child.is("inline", ns::BIND2) {
- if inline.is_some() {
- return Err(
- Error::Other("Bind must not have more than one inline element.").into(),
- );
- }
- check_no_attributes!(child, "inline");
- inline = Some(child);
- } else {
- return Err(Error::Other("Unknown element in Bind.").into());
- }
- }
-
- let mut inline_features = Vec::new();
- if let Some(inline) = inline {
- for child in inline.children() {
- if child.is("feature", ns::BIND2) {
- check_no_children!(child, "feature");
- check_no_unknown_attributes!(child, "feature", ["var"]);
- let var = get_attr!(child, "var", Required);
- inline_features.push(var);
- } else {
- return Err(Error::Other("Unknown element in Inline.").into());
- }
- }
- }
-
- Ok(BindFeature { inline_features })
- }
-}
-
-impl From for Element {
- fn from(bind: BindFeature) -> Element {
- Element::builder("bind", ns::BIND2)
- .append_all(if bind.inline_features.is_empty() {
- None
- } else {
- Some(
- Element::builder("inline", ns::BIND2).append_all(
- bind.inline_features
- .into_iter()
- .map(|var| Element::builder("feature", ns::BIND2).attr("var", var)),
- ),
- )
- })
- .build()
- }
-}
-
/// Represents a `` element, as sent by the client inline in the `` SASL 2
/// element, to perform the binding at the same time as the authentication.
#[derive(Debug, Clone, PartialEq)]