Detailed changes
@@ -13,14 +13,14 @@ use crate::hashes::Sha1HexAttribute;
use crate::ns;
use crate::pubsub::PubSubPayload;
-generate_element!(
- /// Communicates information about an avatar.
- Metadata, "metadata", AVATAR_METADATA,
- children: [
- /// List of information elements describing this avatar.
- infos: Vec<Info> = ("info", AVATAR_METADATA) => Info
- ]
-);
+/// Communicates information about an avatar.
+#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
+#[xml(namespace = ns::AVATAR_METADATA, name = "metadata")]
+pub struct Metadata {
+ /// List of information elements describing this avatar.
+ #[xml(child(n = ..))]
+ pub infos: Vec<Info>,
+}
impl PubSubPayload for Metadata {}
@@ -56,14 +56,14 @@ generate_elem_id!(
SASL_CERT
);
-generate_element!(
- /// A list of resources currently using this certificate.
- Users, "users", SASL_CERT,
- children: [
- /// Resources currently using this certificate.
- resources: Vec<Resource> = ("resource", SASL_CERT) => Resource
- ]
-);
+/// A list of resources currently using this certificate.
+#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
+#[xml(namespace = ns::SASL_CERT, name = "users")]
+pub struct Users {
+ /// Resources currently using this certificate.
+ #[xml(child(n = ..))]
+ pub resources: Vec<Resource>,
+}
generate_element!(
/// An X.509 certificate being set for this user.
@@ -83,14 +83,14 @@ generate_element!(
]
);
-generate_element!(
- /// Server answers with the current list of X.509 certificates.
- ListCertsResponse, "items", SASL_CERT,
- children: [
- /// List of certificates.
- items: Vec<Item> = ("item", SASL_CERT) => Item
- ]
-);
+/// Server answers with the current list of X.509 certificates.
+#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
+#[xml(namespace = ns::SASL_CERT, name = "items")]
+pub struct ListCertsResponse {
+ /// List of certificates.
+ #[xml(child(n = ..))]
+ pub items: Vec<Item>,
+}
impl IqResultPayload for ListCertsResponse {}
@@ -220,25 +220,26 @@ pub struct Item {
pub name: Option<String>,
}
-generate_element!(
- /// Structure representing a `<query
- /// xmlns='http://jabber.org/protocol/disco#items'/>` element.
- ///
- /// It should only be used in an `<iq type='result'/>`, as it can only
- /// represent the result, and not a request.
- DiscoItemsResult, "query", DISCO_ITEMS,
- attributes: [
- /// Node on which we have done this discovery.
- node: Option<String> = "node"
- ],
- children: [
- /// List of items pointed by this entity.
- items: Vec<Item> = ("item", DISCO_ITEMS) => Item,
-
- /// Optional paging via Result Set Management
- rsm: Option<crate::rsm::SetResult> = ("set", RSM) => SetResult,
- ]
-);
+/// Structure representing a `<query
+/// xmlns='http://jabber.org/protocol/disco#items'/>` element.
+///
+/// It should only be used in an `<iq type='result'/>`, as it can only
+/// represent the result, and not a request.
+#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
+#[xml(namespace = ns::DISCO_ITEMS, name = "query")]
+pub struct DiscoItemsResult {
+ /// Node on which we have done this discovery.
+ #[xml(attribute(default))]
+ pub node: Option<String>,
+
+ /// List of items pointed by this entity.
+ #[xml(child(n = ..))]
+ pub items: Vec<Item>,
+
+ /// Optional paging via Result Set Management
+ #[xml(child(default))]
+ pub rsm: Option<SetResult>,
+}
impl IqResultPayload for DiscoItemsResult {}
@@ -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::data_forms::DataForm;
use crate::disco::{DiscoInfoQuery, DiscoInfoResult, Feature, Identity};
use crate::hashes::{Algo, Hash};
@@ -16,16 +18,16 @@ use sha2::{Sha256, Sha512};
use sha3::{Sha3_256, Sha3_512};
use xso::error::Error;
-generate_element!(
- /// Represents a set of capability hashes, all of them must correspond to
- /// the same input [disco#info](../disco/struct.DiscoInfoResult.html),
- /// using different [algorithms](../hashes/enum.Algo.html).
- ECaps2, "c", ECAPS2,
- children: [
- /// Hashes of the [disco#info](../disco/struct.DiscoInfoResult.html).
- hashes: Vec<Hash> = ("hash", HASHES) => Hash
- ]
-);
+/// Represents a set of capability hashes, all of them must correspond to
+/// the same input [disco#info](../disco/struct.DiscoInfoResult.html),
+/// using different [algorithms](../hashes/enum.Algo.html).
+#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
+#[xml(namespace = ns::ECAPS2, name = "c")]
+pub struct ECaps2 {
+ /// Hashes of the [disco#info](../disco/struct.DiscoInfoResult.html).
+ #[xml(child(n = ..))]
+ pub hashes: Vec<Hash>,
+}
impl PresencePayload for ECaps2 {}
@@ -230,7 +232,7 @@ mod tests {
FromElementError::Invalid(Error::Other(string)) => string,
_ => panic!(),
};
- assert_eq!(message, "Unknown child in c element.");
+ assert_eq!(message, "Unknown child in ECaps2 element.");
}
#[test]
@@ -104,37 +104,37 @@ impl IqGetPayload for Service {}
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
#[xml(namespace = ns::EXT_DISCO, name = "services")]
pub struct ServicesQuery {
- /// TODO
+ /// The type of service to filter for.
#[xml(attribute(default, name = "type"))]
pub type_: Option<Type>,
}
impl IqGetPayload for ServicesQuery {}
-generate_element!(
- /// Structure representing a `<services xmlns='urn:xmpp:extdisco:2'/>` element.
- ServicesResult, "services", EXT_DISCO,
- attributes: [
- /// TODO
- type_: Option<Type> = "type",
- ],
- children: [
- /// List of services.
- services: Vec<Service> = ("service", EXT_DISCO) => Service
- ]
-);
+/// Structure representing a `<services xmlns='urn:xmpp:extdisco:2'/>` element.
+#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
+#[xml(namespace = ns::EXT_DISCO, name = "services")]
+pub struct ServicesResult {
+ /// The service type which was requested.
+ #[xml(attribute(name = "type", default))]
+ pub type_: Option<Type>,
+
+ /// List of services.
+ #[xml(child(n = ..))]
+ pub services: Vec<Service>,
+}
impl IqResultPayload for ServicesResult {}
impl IqSetPayload for ServicesResult {}
-generate_element!(
- /// Structure representing a `<credentials xmlns='urn:xmpp:extdisco:2'/>` element.
- Credentials, "credentials", EXT_DISCO,
- children: [
- /// List of services.
- services: Vec<Service> = ("service", EXT_DISCO) => Service
- ]
-);
+/// Structure representing a `<credentials xmlns='urn:xmpp:extdisco:2'/>` element.
+#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
+#[xml(namespace = ns::EXT_DISCO, name = "credentials")]
+pub struct Credentials {
+ /// List of services.
+ #[xml(child(n = ..))]
+ pub services: Vec<Service>,
+}
impl IqGetPayload for Credentials {}
impl IqResultPayload for Credentials {}
@@ -5,8 +5,9 @@
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
use xso::{
- error::{Error, FromElementError},
- AsXml, FromXml,
+ error::{Error, FromElementError, FromEventsError},
+ exports::rxml,
+ minidom_compat, AsXml, FromXml,
};
use crate::iq::{IqGetPayload, IqResultPayload};
@@ -68,6 +69,20 @@ impl TryFrom<Element> for Header {
}
}
+impl FromXml for Header {
+ type Builder = minidom_compat::FromEventsViaElement<Header>;
+
+ fn from_events(
+ qname: rxml::QName,
+ attrs: rxml::AttrMap,
+ ) -> Result<Self::Builder, FromEventsError> {
+ if qname.0 != ns::HTTP_UPLOAD || qname.1 != "header" {
+ return Err(FromEventsError::Mismatch { name: qname, attrs });
+ }
+ Self::Builder::new(qname, attrs)
+ }
+}
+
impl From<Header> for Element {
fn from(elem: Header) -> Element {
let (attr, val) = match elem {
@@ -83,18 +98,26 @@ impl From<Header> for Element {
}
}
-generate_element!(
- /// Put URL
- Put, "put", HTTP_UPLOAD,
- attributes: [
- /// URL
- url: Required<String> = "url",
- ],
- children: [
- /// Header list
- headers: Vec<Header> = ("header", HTTP_UPLOAD) => Header
- ]
-);
+impl AsXml for Header {
+ type ItemIter<'x> = minidom_compat::AsItemsViaElement<'x>;
+
+ fn as_xml_iter(&self) -> Result<Self::ItemIter<'_>, Error> {
+ minidom_compat::AsItemsViaElement::new(self.clone())
+ }
+}
+
+/// Put URL
+#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
+#[xml(namespace = ns::HTTP_UPLOAD, name = "put")]
+pub struct Put {
+ /// URL
+ #[xml(attribute)]
+ pub url: String,
+
+ /// Header list
+ #[xml(child(n = ..))]
+ pub headers: Vec<Header>,
+}
/// Get URL
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
@@ -38,18 +38,18 @@ impl Content {
}
}
-generate_element!(
- /// A semantic group of contents.
- Group, "group", JINGLE_GROUPING,
- attributes: [
- /// Semantics of the grouping.
- semantics: Required<Semantics> = "semantics",
- ],
- children: [
- /// List of contents that should be grouped with each other.
- contents: Vec<Content> = ("content", JINGLE_GROUPING) => Content
- ]
-);
+/// A semantic group of contents.
+#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
+#[xml(namespace = ns::JINGLE_GROUPING, name = "group")]
+pub struct Group {
+ /// Semantics of the grouping.
+ #[xml(attribute)]
+ pub semantics: Semantics,
+
+ /// List of contents that should be grouped with each other.
+ #[xml(child(n = ..))]
+ pub contents: Vec<Content>,
+}
#[cfg(test)]
mod tests {
@@ -8,18 +8,18 @@ use xso::{AsXml, FromXml};
use crate::ns;
-generate_element!(
- /// Source element for the ssrc SDP attribute.
- Source, "source", JINGLE_SSMA,
- attributes: [
- /// Maps to the ssrc-id parameter.
- id: Required<u32> = "ssrc",
- ],
- children: [
- /// List of attributes for this source.
- parameters: Vec<Parameter> = ("parameter", JINGLE_SSMA) => Parameter
- ]
-);
+/// Source element for the ssrc SDP attribute.
+#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
+#[xml(namespace = ns::JINGLE_SSMA, name = "source")]
+pub struct Source {
+ /// Maps to the ssrc-id parameter.
+ #[xml(attribute = "ssrc")]
+ pub id: u32,
+
+ /// List of attributes for this source.
+ #[xml(child(n = ..))]
+ pub parameters: Vec<Parameter>,
+}
impl Source {
/// Create a new SSMA Source element.
@@ -67,18 +67,18 @@ generate_attribute!(
}
);
-generate_element!(
- /// Element grouping multiple ssrc.
- Group, "ssrc-group", JINGLE_SSMA,
- attributes: [
- /// The semantics of this group.
- semantics: Required<Semantics> = "semantics",
- ],
- children: [
- /// The various ssrc concerned by this group.
- sources: Vec<Source> = ("source", JINGLE_SSMA) => Source
- ]
-);
+/// Element grouping multiple ssrc.
+#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
+#[xml(namespace = ns::JINGLE_SSMA, name = "ssrc-group")]
+pub struct Group {
+ /// The semantics of this group.
+ #[xml(attribute)]
+ pub semantics: Semantics,
+
+ /// The various ssrc concerned by this group.
+ #[xml(child(n = ..))]
+ pub sources: Vec<Source>,
+}
#[cfg(test)]
mod tests {
@@ -19,15 +19,15 @@ pub struct Device {
pub id: u32,
}
-generate_element!(
- /// A user's device list contains the OMEMO device ids of all the user's
- /// devicse. These can be used to look up bundles and build a session.
- DeviceList, "list", LEGACY_OMEMO,
- children: [
- /// List of devices
- devices: Vec<Device> = ("device", LEGACY_OMEMO) => Device
- ]
-);
+/// A user's device list contains the OMEMO device ids of all the user's
+/// devicse. These can be used to look up bundles and build a session.
+#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
+#[xml(namespace = ns::LEGACY_OMEMO, name = "list")]
+pub struct DeviceList {
+ /// List of devices
+ #[xml(child(n = ..))]
+ pub devices: Vec<Device>,
+}
impl PubSubPayload for DeviceList {}
@@ -64,15 +64,15 @@ pub struct IdentityKey {
pub data: Vec<u8>,
}
-generate_element!(
+/// List of (single use) PreKeys
+/// Part of a device's bundle
+#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
+#[xml(namespace = ns::LEGACY_OMEMO, name = "prekeys")]
+pub struct Prekeys {
/// List of (single use) PreKeys
- /// Part of a device's bundle
- Prekeys, "prekeys", LEGACY_OMEMO,
- children: [
- /// List of (single use) PreKeys
- keys: Vec<PreKeyPublic> = ("preKeyPublic", LEGACY_OMEMO) => PreKeyPublic,
- ]
-);
+ #[xml(child(n = ..))]
+ pub keys: Vec<PreKeyPublic>,
+}
/// PreKey public key
/// Part of a device's bundle
@@ -113,22 +113,23 @@ pub struct Bundle {
impl PubSubPayload for Bundle {}
-generate_element!(
- /// The header contains encrypted keys for a message
- Header, "header", LEGACY_OMEMO,
- attributes: [
- /// The device id of the sender
- sid: Required<u32> = "sid",
- ],
- children: [
- /// The key that the payload message is encrypted with, separately
- /// encrypted for each recipient device.
- keys: Vec<Key> = ("key", LEGACY_OMEMO) => Key,
+/// The header contains encrypted keys for a message
+#[derive(FromXml, AsXml, Debug, PartialEq, Clone)]
+#[xml(namespace = ns::LEGACY_OMEMO, name = "header")]
+pub struct Header {
+ /// The device id of the sender
+ #[xml(attribute)]
+ pub sid: u32,
- /// IV used for payload encryption
- iv: Required<IV> = ("iv", LEGACY_OMEMO) => IV
- ]
-);
+ /// The key that the payload message is encrypted with, separately
+ /// encrypted for each recipient device.
+ #[xml(child(n = ..))]
+ pub keys: Vec<Key>,
+
+ /// IV used for payload encryption
+ #[xml(child)]
+ pub iv: IV,
+}
/// IV used for payload encryption
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
@@ -27,22 +27,23 @@ pub struct Uri {
pub uri: String,
}
-generate_element!(
- /// References a media element, to be used in [data
- /// forms](../data_forms/index.html).
- MediaElement, "media", MEDIA_ELEMENT,
- attributes: [
- /// The recommended display width in pixels.
- width: Option<usize> = "width",
+/// References a media element, to be used in [data
+/// forms](../data_forms/index.html).
+#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
+#[xml(namespace = ns::MEDIA_ELEMENT, name = "media")]
+pub struct MediaElement {
+ /// The recommended display width in pixels.
+ #[xml(attribute(default))]
+ pub width: Option<usize>,
+
+ /// The recommended display height in pixels.
+ #[xml(attribute(default))]
+ pub height: Option<usize>,
- /// The recommended display height in pixels.
- height: Option<usize> = "height"
- ],
- children: [
- /// A list of URIs referencing this media.
- uris: Vec<Uri> = ("uri", MEDIA_ELEMENT) => Uri
- ]
-);
+ /// A list of URIs referencing this media.
+ #[xml(child(n = ..))]
+ pub uris: Vec<Uri>,
+}
#[cfg(test)]
mod tests {
@@ -162,7 +163,7 @@ mod tests {
FromElementError::Invalid(Error::Other(string)) => string,
_ => panic!(),
};
- assert_eq!(message, "Unknown child in media element.");
+ assert_eq!(message, "Unknown child in MediaElement element.");
}
#[test]
@@ -113,21 +113,21 @@ impl Join {
}
}
-generate_element!(
- /// Update a given subscription.
- UpdateSubscription, "update-subscription", MIX_CORE,
- attributes: [
- /// The JID of the user to be affected.
- // TODO: why is it not a participant id instead?
- jid: Option<BareJid> = "jid",
- ],
- children: [
- /// The list of additional nodes to subscribe to.
- // TODO: what happens when we are already subscribed? Also, how do we unsubscribe from
- // just one?
- subscribes: Vec<Subscribe> = ("subscribe", MIX_CORE) => Subscribe
- ]
-);
+/// Update a given subscription.
+#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
+#[xml(namespace = ns::MIX_CORE, name = "update-subscription")]
+pub struct UpdateSubscription {
+ /// The JID of the user to be affected.
+ // TODO: why is it not a participant id instead?
+ #[xml(attribute(default))]
+ pub jid: Option<BareJid>,
+
+ /// The list of additional nodes to subscribe to.
+ // TODO: what happens when we are already subscribed? Also, how do we unsubscribe from
+ // just one?
+ #[xml(child(n = ..))]
+ pub subscribes: Vec<Subscribe>,
+}
impl IqSetPayload for UpdateSubscription {}
impl IqResultPayload for UpdateSubscription {}
@@ -48,14 +48,14 @@ pub struct PubKeyMeta {
pub date: DateTime,
}
-generate_element!(
- /// List of public key metadata
- PubKeysMeta, "public-key-list", OX,
- children: [
- /// Public keys
- pubkeys: Vec<PubKeyMeta> = ("pubkey-metadata", OX) => PubKeyMeta
- ]
-);
+/// List of public key metadata
+#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
+#[xml(namespace = ns::OX, name = "public-key-list")]
+pub struct PubKeysMeta {
+ /// Public keys
+ #[xml(child(n = ..))]
+ pub pubkeys: Vec<PubKeyMeta>,
+}
impl PubSubPayload for PubKeysMeta {}
@@ -15,18 +15,18 @@ use jid::Jid;
use minidom::Element;
use xso::error::{Error, FromElementError};
-generate_element!(
- /// A list of affiliations you have on a service, or on a node.
- Affiliations, "affiliations", PUBSUB_OWNER,
- attributes: [
- /// The node name this request pertains to.
- node: Required<NodeName> = "node",
- ],
- children: [
- /// The actual list of affiliation elements.
- affiliations: Vec<Affiliation> = ("affiliation", PUBSUB_OWNER) => Affiliation
- ]
-);
+/// A list of affiliations you have on a service, or on a node.
+#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
+#[xml(namespace = ns::PUBSUB_OWNER, name = "affiliations")]
+pub struct Affiliations {
+ /// The node name this request pertains to.
+ #[xml(attribute)]
+ pub node: NodeName,
+
+ /// The actual list of affiliation elements.
+ #[xml(child(n = ..))]
+ pub affiliations: Vec<Affiliation>,
+}
/// An affiliation element.
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
@@ -94,18 +94,18 @@ pub struct Purge {
pub node: NodeName,
}
-generate_element!(
- /// A request for current subscriptions.
- Subscriptions, "subscriptions", PUBSUB_OWNER,
- attributes: [
- /// The node to query.
- node: Required<NodeName> = "node",
- ],
- children: [
- /// The list of subscription elements returned.
- subscriptions: Vec<SubscriptionElem> = ("subscription", PUBSUB_OWNER) => SubscriptionElem
- ]
-);
+/// A request for current subscriptions.
+#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
+#[xml(namespace = ns::PUBSUB_OWNER, name = "subscriptions")]
+pub struct Subscriptions {
+ /// The node to query.
+ #[xml(attribute)]
+ pub node: NodeName,
+
+ /// The list of subscription elements returned.
+ #[xml(child(n = ..))]
+ pub subscriptions: Vec<SubscriptionElem>,
+}
/// A subscription element, describing the state of a subscription.
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
@@ -21,18 +21,18 @@ use minidom::Element;
// TODO: a better solution would be to split this into a query and a result elements, like for
// XEP-0030.
-generate_element!(
- /// A list of affiliations you have on a service, or on a node.
- Affiliations, "affiliations", PUBSUB,
- attributes: [
- /// The optional node name this request pertains to.
- node: Option<NodeName> = "node",
- ],
- children: [
- /// The actual list of affiliation elements.
- affiliations: Vec<Affiliation> = ("affiliation", PUBSUB) => Affiliation
- ]
-);
+/// A list of affiliations you have on a service, or on a node.
+#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
+#[xml(namespace = ns::PUBSUB, name = "affiliations")]
+pub struct Affiliations {
+ /// The optional node name this request pertains to.
+ #[xml(attribute(default))]
+ pub node: Option<NodeName>,
+
+ /// The actual list of affiliation elements.
+ #[xml(child(n = ..))]
+ pub affiliations: Vec<Affiliation>,
+}
/// An affiliation element.
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
@@ -77,25 +77,27 @@ pub struct Default {
// type_: Option<String>,
}
-generate_element!(
- /// A request for a list of items.
- Items, "items", PUBSUB,
- attributes: [
- // TODO: should be an xs:positiveInteger, that is, an unbounded int β₯ 1.
- /// Maximum number of items returned.
- max_items: Option<u32> = "max_items",
+/// A request for a list of items.
+#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
+#[xml(namespace = ns::PUBSUB, name = "items")]
+pub struct Items {
+ // TODO: should be an xs:positiveInteger, that is, an unbounded int β₯ 1.
+ /// Maximum number of items returned.
+ #[xml(attribute(name = "max_items" /*sic!*/, default))]
+ pub max_items: Option<u32>,
+
+ /// The node queried by this request.
+ #[xml(attribute)]
+ pub node: NodeName,
- /// The node queried by this request.
- node: Required<NodeName> = "node",
+ /// The subscription identifier related to this request.
+ #[xml(attribute(default))]
+ pub subid: Option<SubscriptionId>,
- /// The subscription identifier related to this request.
- subid: Option<SubscriptionId> = "subid",
- ],
- children: [
- /// The actual list of items returned.
- items: Vec<Item> = ("item", PUBSUB) => Item
- ]
-);
+ /// The actual list of items returned.
+ #[xml(child(n = ..))]
+ pub items: Vec<Item>,
+}
impl Items {
/// Create a new items request.
@@ -136,18 +138,18 @@ pub struct Options {
pub form: Option<DataForm>,
}
-generate_element!(
- /// Request to publish items to a node.
- Publish, "publish", PUBSUB,
- attributes: [
- /// The target node for this operation.
- node: Required<NodeName> = "node",
- ],
- children: [
- /// The items you want to publish.
- items: Vec<Item> = ("item", PUBSUB) => Item
- ]
-);
+/// Request to publish items to a node.
+#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
+#[xml(namespace = ns::PUBSUB, name = "publish")]
+pub struct Publish {
+ /// The target node for this operation.
+ #[xml(attribute)]
+ pub node: NodeName,
+
+ /// The items you want to publish.
+ #[xml(child(n = ..))]
+ pub items: Vec<Item>,
+}
/// The options associated to a publish request.
#[derive(FromXml, AsXml, Debug, PartialEq, Clone)]
@@ -259,18 +261,18 @@ pub struct Subscribe {
pub node: Option<NodeName>,
}
-generate_element!(
- /// A request for current subscriptions.
- Subscriptions, "subscriptions", PUBSUB,
- attributes: [
- /// The node to query.
- node: Option<NodeName> = "node",
- ],
- children: [
- /// The list of subscription elements returned.
- subscription: Vec<SubscriptionElem> = ("subscription", PUBSUB) => SubscriptionElem
- ]
-);
+/// A request for current subscriptions.
+#[derive(FromXml, AsXml, Debug, PartialEq, Clone)]
+#[xml(namespace = ns::PUBSUB, name = "subscriptions")]
+pub struct Subscriptions {
+ /// The node to query.
+ #[xml(attribute(default))]
+ pub node: Option<NodeName>,
+
+ /// The list of subscription elements returned.
+ #[xml(child(n = ..))]
+ pub subscription: Vec<SubscriptionElem>,
+}
/// A subscription element, describing the state of a subscription.
#[derive(FromXml, AsXml, Debug, PartialEq, Clone)]
@@ -9,18 +9,18 @@ use xso::{AsXml, FromXml};
use crate::message::MessagePayload;
use crate::ns;
-generate_element!(
- /// Container for a set of reactions.
- Reactions, "reactions", REACTIONS,
- attributes: [
- /// The id of the message these reactions apply to.
- id: Required<String> = "id",
- ],
- children: [
- /// The list of reactions.
- reactions: Vec<Reaction> = ("reaction", REACTIONS) => Reaction,
- ]
-);
+/// Container for a set of reactions.
+#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
+#[xml(namespace = ns::REACTIONS, name = "reactions")]
+pub struct Reactions {
+ /// The id of the message these reactions apply to.
+ #[xml(attribute)]
+ pub id: String,
+
+ /// The list of reactions.
+ #[xml(child(n = ..))]
+ pub reactions: Vec<Reaction>,
+}
impl MessagePayload for Reactions {}
@@ -4,9 +4,13 @@
// 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 crate::iq::{IqGetPayload, IqResultPayload, IqSetPayload};
+use xso::{AsXml, FromXml};
+
use jid::BareJid;
+use crate::iq::{IqGetPayload, IqResultPayload, IqSetPayload};
+use crate::ns;
+
generate_elem_id!(
/// Represents a group a contact is part of.
Group,
@@ -67,22 +71,22 @@ generate_element!(
]
);
-generate_element!(
- /// The contact list of the user.
- Roster, "query", ROSTER,
- attributes: [
- /// Version of the contact list.
- ///
- /// This is an opaque string that should only be sent back to the server on
- /// a new connection, if this client is storing the contact list between
- /// connections.
- ver: Option<String> = "ver"
- ],
- children: [
- /// List of the contacts of the user.
- items: Vec<Item> = ("item", ROSTER) => Item
- ]
-);
+/// The contact list of the user.
+#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
+#[xml(namespace = ns::ROSTER, name = "query")]
+pub struct Roster {
+ /// Version of the contact list.
+ ///
+ /// This is an opaque string that should only be sent back to the server on
+ /// a new connection, if this client is storing the contact list between
+ /// connections.
+ #[xml(attribute(default))]
+ pub ver: Option<String>,
+
+ /// List of the contacts of the user.
+ #[xml(child(n = ..))]
+ pub items: Vec<Item>,
+}
impl IqGetPayload for Roster {}
impl IqSetPayload for Roster {}
@@ -273,7 +277,7 @@ mod tests {
FromElementError::Invalid(Error::Other(string)) => string,
_ => panic!(),
};
- assert_eq!(message, "Unknown child in query element.");
+ assert_eq!(message, "Unknown child in Roster element.");
let elem: Element = "<query xmlns='jabber:iq:roster' coucou=''/>"
.parse()
@@ -283,7 +287,7 @@ mod tests {
FromElementError::Invalid(Error::Other(string)) => string,
_ => panic!(),
};
- assert_eq!(message, "Unknown attribute in query element.");
+ assert_eq!(message, "Unknown attribute in Roster element.");
}
#[test]
@@ -172,6 +172,20 @@ impl TryFrom<Element> for SetResult {
}
}
+impl FromXml for SetResult {
+ type Builder = minidom_compat::FromEventsViaElement<SetResult>;
+
+ fn from_events(
+ qname: rxml::QName,
+ attrs: rxml::AttrMap,
+ ) -> Result<Self::Builder, FromEventsError> {
+ if qname.0 != crate::ns::RSM || qname.1 != "set" {
+ return Err(FromEventsError::Mismatch { name: qname, attrs });
+ }
+ Self::Builder::new(qname, attrs)
+ }
+}
+
impl From<SetResult> for Element {
fn from(set: SetResult) -> Element {
let first = set.first.clone().map(|first| {
@@ -193,6 +207,14 @@ impl From<SetResult> for Element {
}
}
+impl AsXml for SetResult {
+ type ItemIter<'x> = minidom_compat::AsItemsViaElement<'x>;
+
+ fn as_xml_iter(&self) -> Result<Self::ItemIter<'_>, Error> {
+ minidom_compat::AsItemsViaElement::new(self.clone())
+ }
+}
+
#[cfg(test)]
mod tests {
use super::*;
@@ -762,6 +762,20 @@ macro_rules! impl_pubsub_item {
}
}
+ impl ::xso::FromXml for $item {
+ type Builder = ::xso::minidom_compat::FromEventsViaElement<$item>;
+
+ 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 != "item" {
+ return Err(::xso::error::FromEventsError::Mismatch { name: qname, attrs });
+ }
+ Self::Builder::new(qname, attrs)
+ }
+ }
+
impl From<$item> for minidom::Element {
fn from(item: $item) -> minidom::Element {
minidom::Element::builder("item", ns::$ns)
@@ -772,6 +786,14 @@ macro_rules! impl_pubsub_item {
}
}
+ impl ::xso::AsXml for $item {
+ 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())
+ }
+ }
+
impl ::std::ops::Deref for $item {
type Target = crate::pubsub::Item;