xmpp-parsers: Convert some more elements to xso

This commit is contained in:
Emmanuel Gil Peyrot 2024-08-03 14:41:33 +02:00 committed by Link Mauve
parent 1e0bccc504
commit 48855843d4
9 changed files with 132 additions and 114 deletions

View file

@ -75,18 +75,18 @@ pub struct Url {
pub url: String, pub url: String,
} }
generate_element!(
/// Container element for multiple bookmarks. /// Container element for multiple bookmarks.
#[derive(Default)] #[derive(FromXml, AsXml, PartialEq, Debug, Clone, Default)]
Storage, "storage", BOOKMARKS, #[xml(namespace = ns::BOOKMARKS, name = "storage")]
children: [ pub struct Storage {
/// Conferences the user has expressed an interest in. /// Conferences the user has expressed an interest in.
conferences: Vec<Conference> = ("conference", BOOKMARKS) => Conference, #[xml(child(n = ..))]
pub conferences: Vec<Conference>,
/// URLs the user is interested in. /// URLs the user is interested in.
urls: Vec<Url> = ("url", BOOKMARKS) => Url #[xml(child(n = ..))]
] pub urls: Vec<Url>,
); }
impl Storage { impl Storage {
/// Create an empty bookmarks storage. /// Create an empty bookmarks storage.

View file

@ -20,18 +20,18 @@ generate_attribute!(
Tls0Rtt, "tls-0rtt", bool Tls0Rtt, "tls-0rtt", bool
); );
generate_element!(
/// This is the `<fast/>` element sent by the server as a SASL2 inline feature. /// This is the `<fast/>` element sent by the server as a SASL2 inline feature.
FastQuery, "fast", FAST, #[derive(FromXml, AsXml, Debug, Clone, PartialEq)]
attributes: [ #[xml(namespace = ns::FAST, name = "fast")]
pub struct FastQuery {
/// Whether TLS zero-roundtrip is possible. /// Whether TLS zero-roundtrip is possible.
tls_0rtt: Default<Tls0Rtt> = "tls-0rtt", #[xml(attribute(default, name = "tls-0rtt"))]
], pub tls_0rtt: Tls0Rtt,
children: [
/// A list of `<mechanism/>` elements, listing all server allowed mechanisms. /// A list of `<mechanism/>` elements, listing all server allowed mechanisms.
mechanisms: Vec<Mechanism> = ("mechanism", FAST) => Mechanism #[xml(child(n = ..))]
] pub mechanisms: Vec<Mechanism>,
); }
/// This is the `<fast/>` element the client MUST include within its SASL2 authentication request. /// This is the `<fast/>` element the client MUST include within its SASL2 authentication request.
#[derive(FromXml, AsXml, Debug, Clone, PartialEq)] #[derive(FromXml, AsXml, Debug, Clone, PartialEq)]

View file

@ -16,23 +16,23 @@ use xso::{
AsXml, FromXml, AsXml, FromXml,
}; };
generate_element!(
/// Represents a range in a file. /// Represents a range in a file.
#[derive(Default)] #[derive(FromXml, AsXml, PartialEq, Debug, Clone, Default)]
Range, "range", JINGLE_FT, #[xml(namespace = ns::JINGLE_FT, name = "range")]
attributes: [ pub struct Range {
/// The offset in bytes from the beginning of the file. /// The offset in bytes from the beginning of the file.
offset: Default<u64> = "offset", #[xml(attribute(default))]
pub offset: u64,
/// The length in bytes of the range, or None to be the entire /// The length in bytes of the range, or None to be the entire
/// remaining of the file. /// remaining of the file.
length: Option<u64> = "length" #[xml(attribute(default))]
], pub length: Option<u64>,
children: [
/// List of hashes for this range. /// List of hashes for this range.
hashes: Vec<Hash> = ("hash", HASHES) => Hash #[xml(child(n = ..))]
] pub hashes: Vec<Hash>,
); }
impl Range { impl Range {
/// Creates a new range. /// Creates a new range.
@ -632,6 +632,6 @@ mod tests {
FromElementError::Invalid(Error::Other(string)) => string, FromElementError::Invalid(Error::Other(string)) => string,
_ => panic!(), _ => panic!(),
}; };
assert_eq!(message, "Unknown attribute in range element."); assert_eq!(message, "Unknown attribute in Range element.");
} }
} }

View file

@ -11,15 +11,14 @@ use xso::{AsXml, FromXml};
use crate::jingle_ice_udp::Type; use crate::jingle_ice_udp::Type;
use crate::ns; use crate::ns;
generate_element!(
/// Wrapper element for an raw UDP transport. /// Wrapper element for an raw UDP transport.
#[derive(Default)] #[derive(FromXml, AsXml, PartialEq, Debug, Clone, Default)]
Transport, "transport", JINGLE_RAW_UDP, #[xml(namespace = ns::JINGLE_RAW_UDP, name = "transport")]
children: [ pub struct Transport {
/// List of candidates for this raw UDP session. /// List of candidates for this raw UDP session.
candidates: Vec<Candidate> = ("candidate", JINGLE_RAW_UDP) => Candidate #[xml(child(n = ..))]
] pub candidates: Vec<Candidate>,
); }
impl Transport { impl Transport {
/// Create a new ICE-UDP transport. /// Create a new ICE-UDP transport.

View file

@ -144,14 +144,14 @@ generate_attribute!(
bool bool
); );
generate_element!(
/// Notes the end of a page in a query. /// Notes the end of a page in a query.
Fin, "fin", MAM, #[derive(FromXml, AsXml, Debug, Clone, PartialEq)]
attributes: [ #[xml(namespace = ns::MAM, name = "fin")]
pub struct Fin {
/// True when the end of a MAM query has been reached. /// True when the end of a MAM query has been reached.
complete: Default<Complete> = "complete", #[xml(attribute(default))]
], pub complete: Complete,
children: [
/// Describes the current page, it should contain at least [first] /// Describes the current page, it should contain at least [first]
/// (with an [index]) and [last], and generally [count]. /// (with an [index]) and [last], and generally [count].
/// ///
@ -159,9 +159,9 @@ generate_element!(
/// [index]: ../rsm/struct.SetResult.html#structfield.first_index /// [index]: ../rsm/struct.SetResult.html#structfield.first_index
/// [last]: ../rsm/struct.SetResult.html#structfield.last /// [last]: ../rsm/struct.SetResult.html#structfield.last
/// [count]: ../rsm/struct.SetResult.html#structfield.count /// [count]: ../rsm/struct.SetResult.html#structfield.count
set: Required<SetResult> = ("set", RSM) => SetResult #[xml(child)]
] pub set: SetResult,
); }
impl IqResultPayload for Fin {} impl IqResultPayload for Fin {}

View file

@ -219,31 +219,31 @@ generate_attribute!(
pub struct Item { pub struct Item {
/// The affiliation of this user with the room. /// The affiliation of this user with the room.
#[xml(attribute)] #[xml(attribute)]
affiliation: Affiliation, pub affiliation: Affiliation,
/// The real JID of this user, if you are allowed to see it. /// The real JID of this user, if you are allowed to see it.
#[xml(attribute(default))] #[xml(attribute(default))]
jid: Option<FullJid>, pub jid: Option<FullJid>,
/// The current nickname of this user. /// The current nickname of this user.
#[xml(attribute(default))] #[xml(attribute(default))]
nick: Option<String>, pub nick: Option<String>,
/// The current role of this user. /// The current role of this user.
#[xml(attribute)] #[xml(attribute)]
role: Role, pub role: Role,
/// The actor affected by this item. /// The actor affected by this item.
#[xml(child(default))] #[xml(child(default))]
actor: Option<Actor>, pub actor: Option<Actor>,
/// Whether this continues a one-to-one discussion. /// Whether this continues a one-to-one discussion.
#[xml(child(default))] #[xml(child(default))]
continue_: Option<Continue>, pub continue_: Option<Continue>,
/// A reason for this item. /// A reason for this item.
#[xml(child(default))] #[xml(child(default))]
reason: Option<Reason>, pub reason: Option<Reason>,
} }
impl Item { impl Item {
@ -293,16 +293,18 @@ impl Item {
} }
} }
generate_element!(
/// The main muc#user element. /// The main muc#user element.
MucUser, "x", MUC_USER, children: [ #[derive(FromXml, AsXml, Debug, PartialEq, Clone)]
#[xml(namespace = ns::MUC_USER, name = "x")]
pub struct MucUser {
/// List of statuses applying to this item. /// List of statuses applying to this item.
status: Vec<Status> = ("status", MUC_USER) => Status, #[xml(child(n = ..))]
pub status: Vec<Status>,
/// List of items. /// List of items.
items: Vec<Item> = ("item", MUC_USER) => Item #[xml(child(n = ..))]
] pub items: Vec<Item>,
); }
impl Default for MucUser { impl Default for MucUser {
fn default() -> Self { fn default() -> Self {
@ -380,7 +382,7 @@ mod tests {
FromElementError::Invalid(Error::Other(string)) => string, FromElementError::Invalid(Error::Other(string)) => string,
_ => panic!(), _ => panic!(),
}; };
assert_eq!(message, "Unknown child in x element."); assert_eq!(message, "Unknown child in MucUser element.");
} }
#[test] #[test]
@ -407,7 +409,7 @@ mod tests {
FromElementError::Invalid(Error::Other(string)) => string, FromElementError::Invalid(Error::Other(string)) => string,
_ => panic!(), _ => panic!(),
}; };
assert_eq!(message, "Unknown attribute in x element."); assert_eq!(message, "Unknown attribute in MucUser element.");
} }
#[test] #[test]

View file

@ -167,21 +167,22 @@ generate_attribute!(
bool bool
); );
generate_element!(
/// A request to retract some items from a node. /// A request to retract some items from a node.
Retract, "retract", PUBSUB, #[derive(FromXml, AsXml, Debug, PartialEq, Clone)]
attributes: [ #[xml(namespace = ns::PUBSUB, name = "retract")]
pub struct Retract {
/// The node affected by this request. /// The node affected by this request.
node: Required<NodeName> = "node", #[xml(attribute)]
pub node: NodeName,
/// Whether a retract request should notify subscribers or not. /// Whether a retract request should notify subscribers or not.
notify: Default<Notify> = "notify", #[xml(attribute(default))]
], pub notify: Notify,
children: [
/// The items affected by this request. /// The items affected by this request.
items: Vec<Item> = ("item", PUBSUB) => Item #[xml(child(n = ..))]
] pub items: Vec<Item>,
); }
/// Indicate that the subscription can be configured. /// Indicate that the subscription can be configured.
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]

View file

@ -45,24 +45,14 @@ pub struct RequiredStartTls;
#[xml(namespace = ns::BIND, name = "bind")] #[xml(namespace = ns::BIND, name = "bind")]
pub struct Bind; pub struct Bind;
generate_element!(
/// List of supported SASL mechanisms /// List of supported SASL mechanisms
#[derive(Default)] #[derive(FromXml, AsXml, PartialEq, Debug, Clone, Default)]
SaslMechanisms, "mechanisms", SASL, #[xml(namespace = ns::SASL, name = "mechanisms")]
children: [ pub struct SaslMechanisms {
/// List of information elements describing this avatar. /// List of information elements describing this avatar.
mechanisms: Vec<SaslMechanism> = ("mechanism", SASL) => SaslMechanism, #[xml(child(n = ..))]
] pub mechanisms: Vec<SaslMechanism>,
); }
// TODO: Uncomment me when xso supports collections, see
// https://gitlab.com/xmpp-rs/xmpp-rs/-/issues/136
// #[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
// #[xml(namespace = ns::SASL, name = "mechanisms")]
// pub struct SaslMechanisms {
// #[xml(child(default))]
// mechanisms: Vec<SaslMechanism>,
// }
/// The name of a SASL mechanism. /// The name of a SASL mechanism.
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)] #[derive(FromXml, AsXml, PartialEq, Debug, Clone)]

View file

@ -300,6 +300,24 @@ macro_rules! generate_attribute_enum {
}) })
} }
} }
impl ::xso::FromXml for $elem {
type Builder = ::xso::minidom_compat::FromEventsViaElement<$elem>;
fn from_events(
qname: ::xso::exports::rxml::QName,
attrs: ::xso::exports::rxml::AttrMap,
) -> Result<Self::Builder, ::xso::error::FromEventsError> {
if qname.0 != crate::ns::$ns || qname.1 != $name {
return Err(::xso::error::FromEventsError::Mismatch {
name: qname,
attrs,
})
}
Self::Builder::new(qname, attrs)
}
}
impl From<$elem> for minidom::Element { impl From<$elem> for minidom::Element {
fn from(elem: $elem) -> minidom::Element { fn from(elem: $elem) -> minidom::Element {
minidom::Element::builder($name, crate::ns::$ns) minidom::Element::builder($name, crate::ns::$ns)
@ -309,6 +327,14 @@ macro_rules! generate_attribute_enum {
.build() .build()
} }
} }
impl ::xso::AsXml for $elem {
type ItemIter<'x> = ::xso::minidom_compat::AsItemsViaElement<'x>;
fn as_xml_iter(&self) -> Result<Self::ItemIter<'_>, ::xso::error::Error> {
::xso::minidom_compat::AsItemsViaElement::new(self.clone())
}
}
); );
} }