diff --git a/parsers/src/avatar.rs b/parsers/src/avatar.rs index 6c10dec2708b26bd9799ed0fa838121b8b19e0a8..4fd873e272c9f8eae3a95c89841217dbb7e3d9c3 100644 --- a/parsers/src/avatar.rs +++ b/parsers/src/avatar.rs @@ -4,7 +4,10 @@ // 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::{FromXml, IntoXml}; + use crate::hashes::Sha1HexAttribute; +use crate::ns; use crate::pubsub::PubSubPayload; use crate::util::text_node_codecs::{Codec, WhitespaceAwareBase64}; @@ -19,29 +22,34 @@ generate_element!( impl PubSubPayload for Metadata {} -generate_element!( - /// Communicates avatar metadata. - Info, "info", AVATAR_METADATA, - attributes: [ - /// The size of the image data in bytes. - bytes: Required = "bytes", - - /// The width of the image in pixels. - width: Option = "width", - - /// The height of the image in pixels. - height: Option = "height", - - /// The SHA-1 hash of the image data for the specified content-type. - id: Required = "id", - - /// The IANA-registered content type of the image data. - type_: Required = "type", - - /// The http: or https: URL at which the image data file is hosted. - url: Option = "url", - ] -); +/// Communicates avatar metadata. +#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)] +#[xml(namespace = ns::AVATAR_METADATA, name = "info")] +pub struct Info { + /// The size of the image data in bytes. + #[xml(attribute)] + pub bytes: u32, + + /// The width of the image in pixels. + #[xml(attribute(default))] + pub width: Option, + + /// The height of the image in pixels. + #[xml(attribute(default))] + pub height: Option, + + /// The SHA-1 hash of the image data for the specified content-type. + #[xml(attribute)] + pub id: Sha1HexAttribute, + + /// The IANA-registered content type of the image data. + #[xml(attribute = "type")] + pub type_: String, + + /// The http: or https: URL at which the image data file is hosted. + #[xml(attribute(default))] + pub url: Option, +} generate_element!( /// The actual avatar data. diff --git a/parsers/src/bookmarks.rs b/parsers/src/bookmarks.rs index e32a20c43993e38c4cdf19a5ff386d2b5dbf07c7..a814e574090cb562575109cb887e59217d2263a7 100644 --- a/parsers/src/bookmarks.rs +++ b/parsers/src/bookmarks.rs @@ -16,9 +16,12 @@ //! //! The [`Conference`][crate::bookmarks::Conference] struct used in [`private::Query`][`crate::private::Query`] is the one from this module. Only the querying mechanism changes from a legacy PubSub implementation here, to a legacy Private XML Query implementation in that other module. The [`Conference`][crate::bookmarks2::Conference] element from the [`bookmarks2`][crate::bookmarks2] module is a different structure, but conversion is possible from [`bookmarks::Conference`][crate::bookmarks::Conference] to [`bookmarks2::Conference`][crate::bookmarks2::Conference] via the [`Conference::into_bookmarks2`][crate::bookmarks::Conference::into_bookmarks2] method. +use xso::{FromXml, IntoXml}; + use jid::BareJid; pub use crate::bookmarks2::Autojoin; +use crate::ns; generate_element!( /// A conference bookmark. @@ -59,17 +62,18 @@ impl Conference { } } -generate_element!( - /// An URL bookmark. - Url, "url", BOOKMARKS, - attributes: [ - /// A user-defined name for this URL. - name: Option = "name", - - /// The URL of this bookmark. - url: Required = "url", - ] -); +/// An URL bookmark. +#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)] +#[xml(namespace = ns::BOOKMARKS, name = "url")] +pub struct Url { + /// A user-defined name for this URL. + #[xml(attribute(default))] + pub name: Option, + + /// The URL of this bookmark. + #[xml(attribute)] + pub url: String, +} generate_element!( /// Container element for multiple bookmarks. diff --git a/parsers/src/disco.rs b/parsers/src/disco.rs index 4daf3e6b78346aef75c78d0edab5bc7133e50621..eb2191cf1af31eb19f75ec3a29818e491b1163d9 100644 --- a/parsers/src/disco.rs +++ b/parsers/src/disco.rs @@ -4,24 +4,29 @@ // 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::{ + error::{Error, FromElementError}, + FromXml, IntoXml, +}; + use crate::data_forms::{DataForm, DataFormType}; use crate::iq::{IqGetPayload, IqResultPayload}; use crate::ns; use crate::rsm::{SetQuery, SetResult}; use crate::Element; use jid::Jid; -use xso::error::{Error, FromElementError}; -generate_element!( /// Structure representing a `` element. /// /// It should only be used in an ``, as it can only represent /// the request, and not a result. -DiscoInfoQuery, "query", DISCO_INFO, -attributes: [ +#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)] +#[xml(namespace = ns::DISCO_INFO, name = "query")] +pub struct DiscoInfoQuery { /// Node on which we are doing the discovery. - node: Option = "node", -]); + #[xml(attribute(default))] + pub node: Option, +} impl IqGetPayload for DiscoInfoQuery {} @@ -197,17 +202,22 @@ children: [ impl IqGetPayload for DiscoItemsQuery {} -generate_element!( /// Structure representing an `` element. -Item, "item", DISCO_ITEMS, -attributes: [ +#[derive(FromXml, IntoXml, Debug, Clone, PartialEq)] +#[xml(namespace = ns::DISCO_ITEMS, name = "item")] +pub struct Item { /// JID of the entity pointed by this item. - jid: Required = "jid", + #[xml(attribute)] + pub jid: Jid, + /// Node of the entity pointed by this item. - node: Option = "node", + #[xml(attribute(default))] + pub node: Option, + /// Name of the entity pointed by this item. - name: Option = "name", -]); + #[xml(attribute(default))] + pub name: Option, +} generate_element!( /// Structure representing a `` element. - ExplicitMessageEncryption, "encryption", EME, - attributes: [ - /// Namespace of the encryption scheme used. - namespace: Required = "namespace", +/// Structure representing an `` element. +#[derive(FromXml, IntoXml, Debug, Clone, PartialEq)] +#[xml(namespace = ns::EME, name = "encryption")] +pub struct ExplicitMessageEncryption { + /// Namespace of the encryption scheme used. + #[xml(attribute)] + pub namespace: String, - /// User-friendly name for the encryption scheme, should be `None` for OTR, - /// legacy OpenPGP and OX. - name: Option = "name", - ] -); + /// User-friendly name for the encryption scheme, should be `None` for OTR, + /// legacy OpenPGP and OX. + #[xml(attribute(default))] + pub name: Option, +} impl MessagePayload for ExplicitMessageEncryption {} @@ -69,15 +73,19 @@ mod tests { #[test] fn test_invalid_child() { - let elem: Element = "" - .parse() - .unwrap(); + let elem: Element = + "" + .parse() + .unwrap(); let error = ExplicitMessageEncryption::try_from(elem).unwrap_err(); let message = match error { FromElementError::Invalid(Error::Other(string)) => string, _ => panic!(), }; - assert_eq!(message, "Unknown child in encryption element."); + assert_eq!( + message, + "Unknown child in ExplicitMessageEncryption element." + ); } #[test] diff --git a/parsers/src/hashes.rs b/parsers/src/hashes.rs index 7ead2af161d14260c612a44804d6cb93260d310a..16ff927de3e27ffc94aa1da857cca4cac1e730f3 100644 --- a/parsers/src/hashes.rs +++ b/parsers/src/hashes.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::{FromXmlText, IntoXmlText}; + use crate::util::text_node_codecs::{Base64, Codec}; use base64::{engine::general_purpose::STANDARD as Base64Engine, Engine}; use minidom::IntoAttributeValue; @@ -184,6 +186,18 @@ impl FromStr for Sha1HexAttribute { } } +impl FromXmlText for Sha1HexAttribute { + fn from_xml_text(s: String) -> Result { + Self::from_str(&s).map_err(xso::error::Error::text_parse_error) + } +} + +impl IntoXmlText for Sha1HexAttribute { + fn into_xml_text(self) -> Result { + Ok(self.to_hex()) + } +} + impl IntoAttributeValue for Sha1HexAttribute { fn into_attribute_value(self) -> Option { Some(self.to_hex()) diff --git a/parsers/src/http_upload.rs b/parsers/src/http_upload.rs index eacd08775bc240fc3cd0189aaa51cb71cdd7a4d2..6e0d3d95a48fe594d95ccf80a9d3b36906fb0d88 100644 --- a/parsers/src/http_upload.rs +++ b/parsers/src/http_upload.rs @@ -4,27 +4,31 @@ // 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::{FromXml, IntoXml}; +use xso::{ + error::{Error, FromElementError}, + FromXml, IntoXml, +}; use crate::iq::{IqGetPayload, IqResultPayload}; use crate::ns; use crate::Element; -use xso::error::{Error, FromElementError}; -generate_element!( - /// Requesting a slot - SlotRequest, "request", HTTP_UPLOAD, - attributes: [ - /// The filename to be uploaded. - filename: Required = "filename", +/// Requesting a slot +#[derive(FromXml, IntoXml, Debug, Clone, PartialEq)] +#[xml(namespace = ns::HTTP_UPLOAD, name = "request")] +pub struct SlotRequest { + /// The filename to be uploaded. + #[xml(attribute)] + pub filename: String, - /// Size of the file to be uploaded. - size: Required = "size", + /// Size of the file to be uploaded. + #[xml(attribute)] + pub size: u64, - /// Content-Type of the file. - content_type: Option = "content-type", - ] -); + /// Content-Type of the file. + #[xml(attribute(name = "content-type"))] + pub content_type: Option, +} impl IqGetPayload for SlotRequest {} diff --git a/parsers/src/ibb.rs b/parsers/src/ibb.rs index d74aed3657d7ab2c1d594ba47360622e029075c1..afcb2883fc8055f355bcbed7f199f3fb9993f085 100644 --- a/parsers/src/ibb.rs +++ b/parsers/src/ibb.rs @@ -4,7 +4,10 @@ // 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::{FromXml, IntoXml}; + use crate::iq::IqSetPayload; +use crate::ns; use crate::util::text_node_codecs::{Base64, Codec}; generate_id!( @@ -59,13 +62,14 @@ Data, "data", IBB, impl IqSetPayload for Data {} -generate_element!( /// Close an open stream. -Close, "close", IBB, -attributes: [ +#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)] +#[xml(namespace = ns::IBB, name = "close")] +pub struct Close { /// The identifier of the stream to be closed. - sid: Required = "sid", -]); + #[xml(attribute)] + pub sid: StreamId, +} impl IqSetPayload for Close {} diff --git a/parsers/src/jingle_ice_udp.rs b/parsers/src/jingle_ice_udp.rs index 683107f182a8cbc5bfdeec7796a2b4d131241a2f..bc1182bfd9f6a132d5dfbf6caa8828f346c38482 100644 --- a/parsers/src/jingle_ice_udp.rs +++ b/parsers/src/jingle_ice_udp.rs @@ -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::jingle_dtls_srtp::Fingerprint; use std::net::IpAddr; +use xso::{FromXml, IntoXml}; + +use crate::jingle_dtls_srtp::Fingerprint; +use crate::ns; + generate_element!( /// Wrapper element for an ICE-UDP transport. #[derive(Default)] @@ -63,50 +67,61 @@ generate_attribute!( } ); -generate_element!( - /// A candidate for an ICE-UDP session. - Candidate, "candidate", JINGLE_ICE_UDP, - attributes: [ - /// A Component ID as defined in ICE-CORE. - component: Required = "component", - - /// A Foundation as defined in ICE-CORE. - foundation: Required = "foundation", - - /// An index, starting at 0, that enables the parties to keep track of updates to the - /// candidate throughout the life of the session. - generation: Required = "generation", - - /// A unique identifier for the candidate. - id: Required = "id", - - /// The Internet Protocol (IP) address for the candidate transport mechanism; this can be - /// either an IPv4 address or an IPv6 address. - ip: Required = "ip", +/// A candidate for an ICE-UDP session. +#[derive(FromXml, IntoXml, Debug, PartialEq, Clone)] +#[xml(namespace = ns::JINGLE_ICE_UDP, name = "candidate")] +pub struct Candidate { + /// A Component ID as defined in ICE-CORE. + #[xml(attribute)] + pub component: u8, + + /// A Foundation as defined in ICE-CORE. + #[xml(attribute)] + pub foundation: String, + + /// An index, starting at 0, that enables the parties to keep track of updates to the + /// candidate throughout the life of the session. + #[xml(attribute)] + pub generation: u8, + + /// A unique identifier for the candidate. + #[xml(attribute)] + pub id: String, + + /// The Internet Protocol (IP) address for the candidate transport mechanism; this can be + /// either an IPv4 address or an IPv6 address. + #[xml(attribute)] + pub ip: IpAddr, + + /// The port at the candidate IP address. + #[xml(attribute)] + pub port: u16, + + /// A Priority as defined in ICE-CORE. + #[xml(attribute)] + pub priority: u32, + + /// The protocol to be used. The only value defined by this specification is "udp". + #[xml(attribute)] + pub protocol: String, + + /// A related address as defined in ICE-CORE. + #[xml(attribute(default, name = "rel-addr"))] + pub rel_addr: Option, + + /// A related port as defined in ICE-CORE. + #[xml(attribute(default, name = "rel-port"))] + pub rel_port: Option, + + /// An index, starting at 0, referencing which network this candidate is on for a given + /// peer. + #[xml(attribute(default))] + pub network: Option, - /// The port at the candidate IP address. - port: Required = "port", - - /// A Priority as defined in ICE-CORE. - priority: Required = "priority", - - /// The protocol to be used. The only value defined by this specification is "udp". - protocol: Required = "protocol", - - /// A related address as defined in ICE-CORE. - rel_addr: Option = "rel-addr", - - /// A related port as defined in ICE-CORE. - rel_port: Option = "rel-port", - - /// An index, starting at 0, referencing which network this candidate is on for a given - /// peer. - network: Option = "network", - - /// A Candidate Type as defined in ICE-CORE. - type_: Required = "type", - ] -); + /// A Candidate Type as defined in ICE-CORE. + #[xml(attribute(name = "type"))] + pub type_: Type, +} #[cfg(test)] mod tests { diff --git a/parsers/src/jingle_raw_udp.rs b/parsers/src/jingle_raw_udp.rs index 3063dca1c36594815f080aa7d059305e76746e1e..c7e36a30a6125d2f123104c131a4211c262375de 100644 --- a/parsers/src/jingle_raw_udp.rs +++ b/parsers/src/jingle_raw_udp.rs @@ -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::jingle_ice_udp::Type; use std::net::IpAddr; +use xso::{FromXml, IntoXml}; + +use crate::jingle_ice_udp::Type; +use crate::ns; + generate_element!( /// Wrapper element for an raw UDP transport. #[derive(Default)] @@ -30,31 +34,36 @@ impl Transport { } } -generate_element!( - /// A candidate for an ICE-UDP session. - Candidate, "candidate", JINGLE_RAW_UDP, - attributes: [ - /// A Component ID as defined in ICE-CORE. - component: Required = "component", +/// A candidate for an ICE-UDP session. +#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)] +#[xml(namespace = ns::JINGLE_RAW_UDP, name = "candidate")] +pub struct Candidate { + /// A Component ID as defined in ICE-CORE. + #[xml(attribute)] + pub component: u8, - /// An index, starting at 0, that enables the parties to keep track of updates to the - /// candidate throughout the life of the session. - generation: Required = "generation", + /// An index, starting at 0, that enables the parties to keep track of updates to the + /// candidate throughout the life of the session. + #[xml(attribute)] + pub generation: u8, - /// A unique identifier for the candidate. - id: Required = "id", + /// A unique identifier for the candidate. + #[xml(attribute)] + pub id: String, - /// The Internet Protocol (IP) address for the candidate transport mechanism; this can be - /// either an IPv4 address or an IPv6 address. - ip: Required = "ip", + /// The Internet Protocol (IP) address for the candidate transport mechanism; this can be + /// either an IPv4 address or an IPv6 address. + #[xml(attribute)] + pub ip: IpAddr, - /// The port at the candidate IP address. - port: Required = "port", + /// The port at the candidate IP address. + #[xml(attribute)] + pub port: u16, - /// A Candidate Type as defined in ICE-CORE. - type_: Option = "type", - ] -); + /// A Candidate Type as defined in ICE-CORE. + #[xml(attribute(default, name = "type"))] + pub type_: Option, +} #[cfg(test)] mod tests { diff --git a/parsers/src/jingle_rtcp_fb.rs b/parsers/src/jingle_rtcp_fb.rs index ee64aee6f75860bd8ae8aad3d350675856dd6fef..052fc3451c8cdd3f9e6e9b79a4c7f1a8346a812d 100644 --- a/parsers/src/jingle_rtcp_fb.rs +++ b/parsers/src/jingle_rtcp_fb.rs @@ -4,17 +4,22 @@ // 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/. -generate_element!( - /// Wrapper element for a rtcp-fb. - RtcpFb, "rtcp-fb", JINGLE_RTCP_FB, - attributes: [ - /// Type of this rtcp-fb. - type_: Required = "type", - - /// Subtype of this rtcp-fb, if relevant. - subtype: Option = "subtype", - ] -); +use xso::{FromXml, IntoXml}; + +use crate::ns; + +/// Wrapper element for a rtcp-fb. +#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)] +#[xml(namespace = ns::JINGLE_RTCP_FB, name = "rtcp-fb")] +pub struct RtcpFb { + /// Type of this rtcp-fb. + #[xml(attribute = "type")] + pub type_: String, + + /// Subtype of this rtcp-fb, if relevant. + #[xml(attribute(default))] + pub subtype: Option, +} #[cfg(test)] mod tests { diff --git a/parsers/src/jingle_rtp.rs b/parsers/src/jingle_rtp.rs index 858dc281d762b9a1ca247c8143fe2529a1052712..b35d91f8b1b4e123bf0b1e124a6a9fadb1293593 100644 --- a/parsers/src/jingle_rtp.rs +++ b/parsers/src/jingle_rtp.rs @@ -137,18 +137,19 @@ impl PayloadType { } } -generate_element!( - /// Parameter related to a payload. - Parameter, "parameter", JINGLE_RTP, - attributes: [ - /// The name of the parameter, from the list at - /// - name: Required = "name", - - /// The value of this parameter. - value: Required = "value", - ] -); +/// Parameter related to a payload. +#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)] +#[xml(namespace = ns::JINGLE_RTP, name = "parameter")] +pub struct Parameter { + /// The name of the parameter, from the list at + /// + #[xml(attribute)] + pub name: String, + + /// The value of this parameter. + #[xml(attribute)] + pub value: String, +} #[cfg(test)] mod tests { diff --git a/parsers/src/jingle_ssma.rs b/parsers/src/jingle_ssma.rs index 2ca6f713a0938664a00202cceca531ef9f8bc96b..f221f6b1140699edcfe40c481aa8061806a9c181 100644 --- a/parsers/src/jingle_ssma.rs +++ b/parsers/src/jingle_ssma.rs @@ -4,6 +4,10 @@ // 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::{FromXml, IntoXml}; + +use crate::ns; + generate_element!( /// Source element for the ssrc SDP attribute. Source, "source", JINGLE_SSMA, @@ -27,17 +31,18 @@ impl Source { } } -generate_element!( - /// Parameter associated with a ssrc. - Parameter, "parameter", JINGLE_SSMA, - attributes: [ - /// The name of the parameter. - name: Required = "name", - - /// The optional value of the parameter. - value: Option = "value", - ] -); +/// Parameter associated with a ssrc. +#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)] +#[xml(namespace = ns::JINGLE_SSMA, name = "parameter")] +pub struct Parameter { + /// The name of the parameter. + #[xml(attribute)] + pub name: String, + + /// The optional value of the parameter. + #[xml(attribute(default))] + pub value: Option, +} generate_attribute!( /// From RFC5888, the list of allowed semantics. diff --git a/parsers/src/pubsub/owner.rs b/parsers/src/pubsub/owner.rs index a7d699a09059b84783c04188c90ffcb79ec35129..a144ff09cb4c9a09aaf1439b3f898566f1bfbd51 100644 --- a/parsers/src/pubsub/owner.rs +++ b/parsers/src/pubsub/owner.rs @@ -107,20 +107,22 @@ generate_element!( ] ); -generate_element!( - /// A subscription element, describing the state of a subscription. - SubscriptionElem, "subscription", PUBSUB_OWNER, - attributes: [ - /// The JID affected by this subscription. - jid: Required = "jid", +/// A subscription element, describing the state of a subscription. +#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)] +#[xml(namespace = ns::PUBSUB_OWNER, name = "subscription")] +pub struct SubscriptionElem { + /// The JID affected by this subscription. + #[xml(attribute)] + pub jid: Jid, - /// The state of the subscription. - subscription: Required = "subscription", + /// The state of the subscription. + #[xml(attribute)] + pub subscription: Subscription, - /// Subscription unique id. - subid: Option = "subid", - ] -); + /// Subscription unique id. + #[xml(attribute(default))] + pub subid: Option, +} /// Main payload used to communicate with a PubSubOwner service. /// diff --git a/parsers/src/pubsub/pubsub.rs b/parsers/src/pubsub/pubsub.rs index 5046da816f292c7afaf3bfdad18450f836f101ca..9d32cab098bd371efc917568441e9b3da381d3f2 100644 --- a/parsers/src/pubsub/pubsub.rs +++ b/parsers/src/pubsub/pubsub.rs @@ -4,6 +4,11 @@ // 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::{ + error::{Error, FromElementError}, + FromXml, IntoXml, +}; + use crate::data_forms::DataForm; use crate::iq::{IqGetPayload, IqResultPayload, IqSetPayload}; use crate::ns; @@ -12,10 +17,6 @@ use crate::pubsub::{ }; use crate::Element; use jid::Jid; -use xso::{ - error::{Error, FromElementError}, - FromXml, IntoXml, -}; // TODO: a better solution would be to split this into a query and a result elements, like for // XEP-0030. @@ -220,17 +221,18 @@ impl From for Element { } } -generate_element!( - /// A request to subscribe a JID to a node. - Subscribe, "subscribe", PUBSUB, - attributes: [ - /// The JID being subscribed. - jid: Required = "jid", +/// A request to subscribe a JID to a node. +#[derive(FromXml, IntoXml, Debug, PartialEq, Clone)] +#[xml(namespace = ns::PUBSUB, name = "subscribe")] +pub struct Subscribe { + /// The JID being subscribed. + #[xml(attribute)] + pub jid: Jid, - /// The node to subscribe to. - node: Option = "node", - ] -); + /// The node to subscribe to. + #[xml(attribute)] + pub node: Option, +} generate_element!( /// A request for current subscriptions. @@ -267,20 +269,22 @@ generate_element!( ] ); -generate_element!( - /// An unsubscribe request. - Unsubscribe, "unsubscribe", PUBSUB, - attributes: [ - /// The JID affected by this request. - jid: Required = "jid", +/// An unsubscribe request. +#[derive(FromXml, IntoXml, Debug, PartialEq, Clone)] +#[xml(namespace = ns::PUBSUB, name = "unsubscribe")] +pub struct Unsubscribe { + /// The JID affected by this request. + #[xml(attribute)] + jid: Jid, - /// The node affected by this request. - node: Option = "node", + /// The node affected by this request. + #[xml(attribute)] + node: Option, - /// The subscription identifier for this subscription. - subid: Option = "subid", - ] -); + /// The subscription identifier for this subscription. + #[xml(attribute)] + subid: Option, +} /// Main payload used to communicate with a PubSub service. /// diff --git a/parsers/src/sm.rs b/parsers/src/sm.rs index 56001e20b52ecb55f066b8fb50f46e7d8b552eb0..d7b3f25f2de217096dc91a3696b22f9d2adaee0f 100644 --- a/parsers/src/sm.rs +++ b/parsers/src/sm.rs @@ -109,31 +109,33 @@ generate_element!( #[xml(namespace = ns::SM, name = "r")] pub struct R; -generate_element!( - /// Requests a stream resumption. - Resume, "resume", SM, - attributes: [ - /// The last handled stanza. - h: Required = "h", +/// Requests a stream resumption. +#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)] +#[xml(namespace = ns::SM, name = "resume")] +pub struct Resume { + /// The last handled stanza. + #[xml(attribute)] + pub h: u32, - /// The previous id given by the server on - /// [enabled](struct.Enabled.html). - previd: Required = "previd", - ] -); + /// The previous id given by the server on + /// [enabled](struct.Enabled.html). + #[xml(attribute)] + pub previd: StreamId, +} -generate_element!( - /// The response by the server for a successfully resumed stream. - Resumed, "resumed", SM, - attributes: [ - /// The last handled stanza. - h: Required = "h", +/// The response by the server for a successfully resumed stream. +#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)] +#[xml(namespace = ns::SM, name = "resumed")] +pub struct Resumed { + /// The last handled stanza. + #[xml(attribute)] + pub h: u32, - /// The previous id given by the server on - /// [enabled](struct.Enabled.html). - previd: Required = "previd", - ] -); + /// The previous id given by the server on + /// [enabled](struct.Enabled.html). + #[xml(attribute)] + pub previd: StreamId, +} // TODO: add support for optional and required. /// Represents availability of Stream Management in ``. diff --git a/parsers/src/stream.rs b/parsers/src/stream.rs index c5edb98f5d64466e88747e7e607c32343f6d9fdf..0b790305b4a181f2e20335e6d4e68a084f27ced6 100644 --- a/parsers/src/stream.rs +++ b/parsers/src/stream.rs @@ -4,29 +4,37 @@ // 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::{FromXml, IntoXml}; + use jid::BareJid; -generate_element!( - /// The stream opening for client-server communications. - Stream, "stream", STREAM, - attributes: [ - /// The JID of the entity opening this stream. - from: Option = "from", +use crate::ns; + +/// The stream opening for client-server communications. +#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)] +#[xml(namespace = ns::STREAM, name = "stream")] +pub struct Stream { + /// The JID of the entity opening this stream. + #[xml(attribute(default))] + pub from: Option, - /// The JID of the entity receiving this stream opening. - to: Option = "to", + /// The JID of the entity receiving this stream opening. + #[xml(attribute(default))] + to: Option, - /// The id of the stream, used for authentication challenges. - id: Option = "id", + /// The id of the stream, used for authentication challenges. + #[xml(attribute(default))] + id: Option, - /// The XMPP version used during this stream. - version: Option = "version", + /// The XMPP version used during this stream. + #[xml(attribute(default))] + version: Option, - /// The default human language for all subsequent stanzas, which will - /// be transmitted to other entities for better localisation. - xml_lang: Option = "xml:lang", - ] -); + /// The default human language for all subsequent stanzas, which will + /// be transmitted to other entities for better localisation. + #[xml(attribute(default, name = "xml:lang"))] + xml_lang: Option, +} impl Stream { /// Creates a simple client→server `` element. diff --git a/parsers/src/util/macros.rs b/parsers/src/util/macros.rs index 6103e4b4efa3a349c47456eb8142d2589b9160ee..8aed09df8c3dca6f011e83276e5cf09a12338c77 100644 --- a/parsers/src/util/macros.rs +++ b/parsers/src/util/macros.rs @@ -125,6 +125,26 @@ macro_rules! generate_attribute { }) } } + impl ::xso::FromXmlText for $elem { + fn from_xml_text(s: String) -> Result<$elem, xso::error::Error> { + s.parse().map_err(xso::error::Error::text_parse_error) + } + } + impl ::xso::IntoXmlText for $elem { + fn into_xml_text(self) -> Result { + Ok(String::from(match self { + $($elem::$a => $b),+ + })) + } + + #[allow(unreachable_patterns)] + fn into_optional_xml_text(self) -> Result, xso::error::Error> { + Ok(Some(String::from(match self { + $elem::$default => return Ok(None), + $($elem::$a => $b),+ + }))) + } + } impl ::minidom::IntoAttributeValue for $elem { #[allow(unreachable_patterns)] fn into_attribute_value(self) -> Option { diff --git a/parsers/src/websocket.rs b/parsers/src/websocket.rs index 3c234056a1737471038d2488a2b5254ef034a917..b2b84e1d256751fc3fcb15a98554517271c8de76 100644 --- a/parsers/src/websocket.rs +++ b/parsers/src/websocket.rs @@ -4,29 +4,37 @@ // 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::{FromXml, IntoXml}; + use jid::BareJid; -generate_element!( - /// The stream opening for WebSocket. - Open, "open", WEBSOCKET, - attributes: [ - /// The JID of the entity opening this stream. - from: Option = "from", +use crate::ns; + +/// The stream opening for WebSocket. +#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)] +#[xml(namespace = ns::WEBSOCKET, name = "open")] +pub struct Open { + /// The JID of the entity opening this stream. + #[xml(attribute(default))] + pub from: Option, - /// The JID of the entity receiving this stream opening. - to: Option = "to", + /// The JID of the entity receiving this stream opening. + #[xml(attribute(default))] + pub to: Option, - /// The id of the stream, used for authentication challenges. - id: Option = "id", + /// The id of the stream, used for authentication challenges. + #[xml(attribute(default))] + pub id: Option, - /// The XMPP version used during this stream. - version: Option = "version", + /// The XMPP version used during this stream. + #[xml(attribute(default))] + pub version: Option, - /// The default human language for all subsequent stanzas, which will - /// be transmitted to other entities for better localisation. - xml_lang: Option = "xml:lang", - ] -); + /// The default human language for all subsequent stanzas, which will + /// be transmitted to other entities for better localisation. + #[xml(attribute(default, name = "xml:lang"))] + pub xml_lang: Option, +} impl Open { /// Creates a simple client→server `` element.