parsers: port some elements with children to derive macros

This commit is contained in:
Jonas Schäfer 2024-06-29 16:14:12 +02:00
parent 5bd36eccfc
commit 5d284bbd3a
11 changed files with 106 additions and 117 deletions

View file

@ -33,27 +33,25 @@ pub struct Private;
impl MessagePayload for Private {} impl MessagePayload for Private {}
generate_element!(
/// Wrapper for a message received on another resource. /// Wrapper for a message received on another resource.
Received, "received", CARBONS, #[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
#[xml(namespace = ns::CARBONS, name = "received")]
children: [ pub struct Received {
/// Wrapper for the enclosed message. /// Wrapper for the enclosed message.
forwarded: Required<Forwarded> = ("forwarded", FORWARD) => Forwarded #[xml(child)]
] pub forwarded: Forwarded,
); }
impl MessagePayload for Received {} impl MessagePayload for Received {}
generate_element!(
/// Wrapper for a message sent from another resource. /// Wrapper for a message sent from another resource.
Sent, "sent", CARBONS, #[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
#[xml(namespace = ns::CARBONS, name = "sent")]
children: [ pub struct Sent {
/// Wrapper for the enclosed message. /// Wrapper for the enclosed message.
forwarded: Required<Forwarded> = ("forwarded", FORWARD) => Forwarded #[xml(child)]
] pub forwarded: Forwarded,
); }
impl MessagePayload for Sent {} impl MessagePayload for Sent {}

View file

@ -94,25 +94,25 @@ generate_element!(
impl IqResultPayload for ListCertsResponse {} impl IqResultPayload for ListCertsResponse {}
generate_element!(
/// Client disables an X.509 certificate. /// Client disables an X.509 certificate.
Disable, "disable", SASL_CERT, #[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
children: [ #[xml(namespace = ns::SASL_CERT, name = "disable")]
pub struct Disable {
/// Name of the certificate to disable. /// Name of the certificate to disable.
name: Required<Name> = ("name", SASL_CERT) => Name #[xml(child)]
] pub name: Name,
); }
impl IqSetPayload for Disable {} impl IqSetPayload for Disable {}
generate_element!(
/// Client revokes an X.509 certificate. /// Client revokes an X.509 certificate.
Revoke, "revoke", SASL_CERT, #[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
children: [ #[xml(namespace = ns::SASL_CERT, name = "revoke")]
pub struct Revoke {
/// Name of the certificate to revoke. /// Name of the certificate to revoke.
name: Required<Name> = ("name", SASL_CERT) => Name #[xml(child)]
] pub name: Name,
); }
impl IqSetPayload for Revoke {} impl IqSetPayload for Revoke {}

View file

@ -4,11 +4,12 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this // 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/. // file, You can obtain one at http://mozilla.org/MPL/2.0/.
use xso::error::{Error, FromElementError};
use crate::data_forms_validate::Validate; use crate::data_forms_validate::Validate;
use crate::media_element::MediaElement; use crate::media_element::MediaElement;
use crate::ns; use crate::ns;
use minidom::Element; use minidom::Element;
use xso::error::{Error, FromElementError};
generate_element!( generate_element!(
/// Represents one of the possible values for a list- field. /// Represents one of the possible values for a list- field.

View file

@ -105,16 +105,18 @@ pub struct Get {
pub url: String, pub url: String,
} }
generate_element!(
/// Requesting a slot /// Requesting a slot
SlotResult, "slot", HTTP_UPLOAD, #[derive(FromXml, AsXml, Debug, Clone, PartialEq)]
children: [ #[xml(namespace = ns::HTTP_UPLOAD, name = "slot")]
pub struct SlotResult {
/// Put URL and headers /// Put URL and headers
put: Required<Put> = ("put", HTTP_UPLOAD) => Put, #[xml(child)]
pub put: Put,
/// Get URL /// Get URL
get: Required<Get> = ("get", HTTP_UPLOAD) => Get #[xml(child)]
] pub get: Get,
); }
impl IqResultPayload for SlotResult {} impl IqResultPayload for SlotResult {}

View file

@ -117,22 +117,23 @@ impl From<Query> for Element {
} }
} }
generate_element!(
/// The wrapper around forwarded stanzas. /// The wrapper around forwarded stanzas.
Result_, "result", MAM, #[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
attributes: [ #[xml(namespace = ns::MAM, name = "result")]
pub struct Result_ {
/// The stanza-id under which the archive stored this stanza. /// The stanza-id under which the archive stored this stanza.
id: Required<String> = "id", #[xml(attribute)]
pub id: String,
/// The same queryid as the one requested in the /// The same queryid as the one requested in the
/// [query](struct.Query.html). /// [query](struct.Query.html).
queryid: Option<QueryId> = "queryid", #[xml(attribute(default))]
], pub queryid: Option<QueryId>,
children: [
/// The actual stanza being forwarded. /// The actual stanza being forwarded.
forwarded: Required<Forwarded> = ("forwarded", FORWARD) => Forwarded #[xml(child)]
] pub forwarded: Forwarded,
); }
impl MessagePayload for Result_ {} impl MessagePayload for Result_ {}

View file

@ -567,7 +567,7 @@ mod tests {
FromElementError::Invalid(Error::Other(string)) => string, FromElementError::Invalid(Error::Other(string)) => string,
_ => panic!(), _ => panic!(),
}; };
assert_eq!(message, "Unknown attribute in reason element.".to_owned()); assert_eq!(message, "Unknown attribute in Reason element.".to_owned());
} }
#[cfg(not(feature = "disable-validation"))] #[cfg(not(feature = "disable-validation"))]
@ -583,7 +583,7 @@ mod tests {
FromElementError::Invalid(Error::Other(string)) => string, FromElementError::Invalid(Error::Other(string)) => string,
_ => panic!(), _ => panic!(),
}; };
assert_eq!(message, "Unknown child in reason element.".to_owned()); assert_eq!(message, "Unknown child in Reason element.".to_owned());
} }
#[cfg(not(feature = "disable-validation"))] #[cfg(not(feature = "disable-validation"))]

View file

@ -59,7 +59,7 @@ mod tests {
FromElementError::Invalid(Error::Other(string)) => string, FromElementError::Invalid(Error::Other(string)) => string,
_ => panic!(), _ => panic!(),
}; };
assert_eq!(message, "Unknown child in nick element."); assert_eq!(message, "Unknown child in Nick element.");
} }
#[cfg(not(feature = "disable-validation"))] #[cfg(not(feature = "disable-validation"))]
@ -73,6 +73,6 @@ mod tests {
FromElementError::Invalid(Error::Other(string)) => string, FromElementError::Invalid(Error::Other(string)) => string,
_ => panic!(), _ => panic!(),
}; };
assert_eq!(message, "Unknown attribute in nick element."); assert_eq!(message, "Unknown attribute in Nick element.");
} }
} }

View file

@ -20,18 +20,18 @@ pub struct PubKeyData {
pub data: Vec<u8>, pub data: Vec<u8>,
} }
generate_element!(
/// Pubkey element to be used in PubSub publish payloads. /// Pubkey element to be used in PubSub publish payloads.
PubKey, "pubkey", OX, #[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
attributes: [ #[xml(namespace = ns::OX, name = "pubkey")]
pub struct PubKey {
/// Last updated date /// Last updated date
date: Option<DateTime> = "date" #[xml(attribute(default))]
], pub date: Option<DateTime>,
children: [
/// Public key as base64 data /// Public key as base64 data
data: Required<PubKeyData> = ("data", OX) => PubKeyData #[xml(child)]
] pub data: PubKeyData,
); }
impl PubSubPayload for PubKey {} impl PubSubPayload for PubKey {}

View file

@ -19,20 +19,22 @@
//! This module uses the legacy bookmarks [`bookmarks::Conference`][crate::bookmarks::Conference] //! This module uses the legacy bookmarks [`bookmarks::Conference`][crate::bookmarks::Conference]
//! struct as stored in a legacy [`bookmarks::Storage`][crate::bookmarks::Storage] struct. //! struct as stored in a legacy [`bookmarks::Storage`][crate::bookmarks::Storage] struct.
use xso::{AsXml, FromXml};
use crate::{ use crate::{
bookmarks::Storage, bookmarks::Storage,
iq::{IqGetPayload, IqResultPayload, IqSetPayload}, iq::{IqGetPayload, IqResultPayload, IqSetPayload},
ns,
}; };
generate_element!(
/// A Private XML Storage query. Only supports XEP-0048 bookmarks. /// A Private XML Storage query. Only supports XEP-0048 bookmarks.
Query, "query", PRIVATE, #[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
attributes: [], #[xml(namespace = ns::PRIVATE, name = "query")]
children: [ pub struct Query {
/// XEP-0048 bookmarks in a [`Storage`] element /// XEP-0048 bookmarks in a [`Storage`] element
storage: Required<Storage> = ("storage", BOOKMARKS) => Storage, #[xml(child)]
] pub storage: Storage,
); }
impl IqSetPayload for Query {} impl IqSetPayload for Query {}
impl IqGetPayload for Query {} impl IqGetPayload for Query {}

View file

@ -453,7 +453,7 @@ macro_rules! generate_id {
} }
macro_rules! generate_elem_id { macro_rules! generate_elem_id {
($(#[$meta:meta])* $elem:ident, $name:tt, $ns:ident) => ( ($(#[$meta:meta])* $elem:ident, $name:literal, $ns:ident) => (
generate_elem_id!($(#[$meta])* $elem, $name, $ns, String); generate_elem_id!($(#[$meta])* $elem, $name, $ns, String);
impl ::std::str::FromStr for $elem { impl ::std::str::FromStr for $elem {
type Err = xso::error::Error; type Err = xso::error::Error;
@ -463,27 +463,11 @@ macro_rules! generate_elem_id {
} }
} }
); );
($(#[$meta:meta])* $elem:ident, $name:tt, $ns:ident, $type:ty) => ( ($(#[$meta:meta])* $elem:ident, $name:literal, $ns:ident, $type:ty) => (
$(#[$meta])* $(#[$meta])*
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(xso::FromXml, xso::AsXml, Debug, Clone, PartialEq, Eq, Hash)]
pub struct $elem(pub $type); #[xml(namespace = crate::ns::$ns, name = $name)]
impl ::std::convert::TryFrom<minidom::Element> for $elem { pub struct $elem(#[xml(text)] pub $type);
type Error = xso::error::FromElementError;
fn try_from(elem: minidom::Element) -> Result<$elem, xso::error::FromElementError> {
check_self!(elem, $name, $ns);
check_no_children!(elem, $name);
check_no_attributes!(elem, $name);
// TODO: add a way to parse that differently when needed.
Ok($elem(elem.text().parse().map_err(xso::error::Error::text_parse_error)?))
}
}
impl From<$elem> for minidom::Element {
fn from(elem: $elem) -> minidom::Element {
minidom::Element::builder($name, crate::ns::$ns)
.append(elem.0.to_string())
.build()
}
}
); );
} }

View file

@ -23,17 +23,18 @@ use crate::iq::{IqGetPayload, IqResultPayload, IqSetPayload};
use crate::ns; use crate::ns;
use minidom::Element; use minidom::Element;
generate_element!(
/// A photo element. /// A photo element.
Photo, "PHOTO", VCARD, #[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
attributes: [], #[xml(namespace = ns::VCARD, name = "PHOTO")]
children: [ pub struct Photo {
/// The type of the photo. /// The type of the photo.
type_: Required<Type> = ("TYPE", VCARD) => Type, #[xml(child)]
pub type_: Type,
/// The binary data of the photo. /// The binary data of the photo.
binval: Required<Binval> = ("BINVAL", VCARD) => Binval, #[xml(child)]
] pub binval: Binval,
); }
/// The type of the photo. /// The type of the photo.
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)] #[derive(FromXml, AsXml, PartialEq, Debug, Clone)]