Port everything over to AsXml
This commit is contained in:
parent
4910b01244
commit
ccf38cdf9b
64 changed files with 848 additions and 371 deletions
|
|
@ -3,13 +3,13 @@
|
||||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
// 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::{FromXml, IntoXml};
|
use xso::{AsXml, FromXml};
|
||||||
|
|
||||||
use crate::message::MessagePayload;
|
use crate::message::MessagePayload;
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
|
|
||||||
/// Requests the attention of the recipient.
|
/// Requests the attention of the recipient.
|
||||||
#[derive(FromXml, IntoXml, Debug, Clone, PartialEq)]
|
#[derive(FromXml, AsXml, Debug, Clone, PartialEq)]
|
||||||
#[xml(namespace = ns::ATTENTION, name = "attention")]
|
#[xml(namespace = ns::ATTENTION, name = "attention")]
|
||||||
pub struct Attention;
|
pub struct Attention;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
// 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::{FromXml, IntoXml};
|
use xso::{AsXml, FromXml};
|
||||||
|
|
||||||
use crate::hashes::Sha1HexAttribute;
|
use crate::hashes::Sha1HexAttribute;
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
|
|
@ -23,7 +23,7 @@ generate_element!(
|
||||||
impl PubSubPayload for Metadata {}
|
impl PubSubPayload for Metadata {}
|
||||||
|
|
||||||
/// Communicates avatar metadata.
|
/// Communicates avatar metadata.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::AVATAR_METADATA, name = "info")]
|
#[xml(namespace = ns::AVATAR_METADATA, name = "info")]
|
||||||
pub struct Info {
|
pub struct Info {
|
||||||
/// The size of the image data in bytes.
|
/// The size of the image data in bytes.
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
// 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::{FromXml, IntoXml};
|
use xso::{AsXml, FromXml};
|
||||||
|
|
||||||
use crate::iq::{IqGetPayload, IqResultPayload, IqSetPayload};
|
use crate::iq::{IqGetPayload, IqResultPayload, IqSetPayload};
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
|
|
@ -14,7 +14,7 @@ use xso::error::FromElementError;
|
||||||
|
|
||||||
/// The element requesting the blocklist, the result iq will contain a
|
/// The element requesting the blocklist, the result iq will contain a
|
||||||
/// [BlocklistResult].
|
/// [BlocklistResult].
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::BLOCKING, name = "blocklist")]
|
#[xml(namespace = ns::BLOCKING, name = "blocklist")]
|
||||||
pub struct BlocklistRequest;
|
pub struct BlocklistRequest;
|
||||||
|
|
||||||
|
|
@ -88,7 +88,7 @@ generate_blocking_element!(
|
||||||
impl IqSetPayload for Unblock {}
|
impl IqSetPayload for Unblock {}
|
||||||
|
|
||||||
/// The application-specific error condition when a message is blocked.
|
/// The application-specific error condition when a message is blocked.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::BLOCKING_ERRORS, name = "blocked")]
|
#[xml(namespace = ns::BLOCKING_ERRORS, name = "blocked")]
|
||||||
pub struct Blocked;
|
pub struct Blocked;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,14 @@
|
||||||
// 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, text::Base64, FromXml, FromXmlText, IntoXml, IntoXmlText};
|
use std::borrow::Cow;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
use xso::{error::Error, text::Base64, AsXml, AsXmlText, FromXml, FromXmlText};
|
||||||
|
|
||||||
use crate::hashes::{Algo, Hash};
|
use crate::hashes::{Algo, Hash};
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
use minidom::IntoAttributeValue;
|
use minidom::IntoAttributeValue;
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
/// A Content-ID, as defined in RFC2111.
|
/// A Content-ID, as defined in RFC2111.
|
||||||
///
|
///
|
||||||
|
|
@ -56,14 +58,18 @@ impl FromXmlText for ContentId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IntoXmlText for ContentId {
|
impl AsXmlText for ContentId {
|
||||||
fn into_xml_text(self) -> Result<String, Error> {
|
fn as_xml_text(&self) -> Result<Cow<'_, str>, Error> {
|
||||||
let algo = match self.hash.algo {
|
let algo = match self.hash.algo {
|
||||||
Algo::Sha_1 => "sha1",
|
Algo::Sha_1 => "sha1",
|
||||||
Algo::Sha_256 => "sha256",
|
Algo::Sha_256 => "sha256",
|
||||||
_ => unimplemented!(),
|
_ => unimplemented!(),
|
||||||
};
|
};
|
||||||
Ok(format!("{}+{}@bob.xmpp.org", algo, self.hash.to_hex()))
|
Ok(Cow::Owned(format!(
|
||||||
|
"{}+{}@bob.xmpp.org",
|
||||||
|
algo,
|
||||||
|
self.hash.to_hex()
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -79,7 +85,7 @@ impl IntoAttributeValue for ContentId {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Request for an uncached cid file.
|
/// Request for an uncached cid file.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::BOB, name = "data")]
|
#[xml(namespace = ns::BOB, name = "data")]
|
||||||
pub struct Data {
|
pub struct Data {
|
||||||
/// The cid in question.
|
/// The cid in question.
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
//!
|
//!
|
||||||
//! 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.
|
//! 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 xso::{AsXml, FromXml};
|
||||||
|
|
||||||
use jid::BareJid;
|
use jid::BareJid;
|
||||||
|
|
||||||
|
|
@ -63,7 +63,7 @@ impl Conference {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An URL bookmark.
|
/// An URL bookmark.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::BOOKMARKS, name = "url")]
|
#[xml(namespace = ns::BOOKMARKS, name = "url")]
|
||||||
pub struct Url {
|
pub struct Url {
|
||||||
/// A user-defined name for this URL.
|
/// A user-defined name for this URL.
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
// 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::{FromXml, IntoXml};
|
use xso::{AsXml, FromXml};
|
||||||
|
|
||||||
use crate::forwarding::Forwarded;
|
use crate::forwarding::Forwarded;
|
||||||
use crate::iq::IqSetPayload;
|
use crate::iq::IqSetPayload;
|
||||||
|
|
@ -12,14 +12,14 @@ use crate::message::MessagePayload;
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
|
|
||||||
/// Enable carbons for this session.
|
/// Enable carbons for this session.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::CARBONS, name = "enable")]
|
#[xml(namespace = ns::CARBONS, name = "enable")]
|
||||||
pub struct Enable;
|
pub struct Enable;
|
||||||
|
|
||||||
impl IqSetPayload for Enable {}
|
impl IqSetPayload for Enable {}
|
||||||
|
|
||||||
/// Disable a previously-enabled carbons.
|
/// Disable a previously-enabled carbons.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::CARBONS, name = "disable")]
|
#[xml(namespace = ns::CARBONS, name = "disable")]
|
||||||
pub struct Disable;
|
pub struct Disable;
|
||||||
|
|
||||||
|
|
@ -27,7 +27,7 @@ impl IqSetPayload for Disable {}
|
||||||
|
|
||||||
/// Request the enclosing message to not be copied to other carbons-enabled
|
/// Request the enclosing message to not be copied to other carbons-enabled
|
||||||
/// resources of the user.
|
/// resources of the user.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::CARBONS, name = "private")]
|
#[xml(namespace = ns::CARBONS, name = "private")]
|
||||||
pub struct Private;
|
pub struct Private;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
// 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::{text::Base64, FromXml, IntoXml};
|
use xso::{text::Base64, AsXml, FromXml};
|
||||||
|
|
||||||
use crate::iq::{IqGetPayload, IqResultPayload, IqSetPayload};
|
use crate::iq::{IqGetPayload, IqResultPayload, IqSetPayload};
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
|
|
@ -17,7 +17,7 @@ generate_elem_id!(
|
||||||
);
|
);
|
||||||
|
|
||||||
/// An X.509 certificate.
|
/// An X.509 certificate.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::SASL_CERT, name = "x509cert")]
|
#[xml(namespace = ns::SASL_CERT, name = "x509cert")]
|
||||||
pub struct Cert {
|
pub struct Cert {
|
||||||
/// The BER X.509 data.
|
/// The BER X.509 data.
|
||||||
|
|
@ -43,7 +43,7 @@ generate_element!(
|
||||||
impl IqSetPayload for Append {}
|
impl IqSetPayload for Append {}
|
||||||
|
|
||||||
/// Client requests the current list of X.509 certificates.
|
/// Client requests the current list of X.509 certificates.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::SASL_CERT, name = "items")]
|
#[xml(namespace = ns::SASL_CERT, name = "items")]
|
||||||
pub struct ListCertsQuery;
|
pub struct ListCertsQuery;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,22 +4,22 @@
|
||||||
// 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::{FromXml, IntoXml};
|
use xso::{AsXml, FromXml};
|
||||||
|
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
|
|
||||||
/// Stream:feature sent by the server to advertise it supports CSI.
|
/// Stream:feature sent by the server to advertise it supports CSI.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::CSI, name = "csi")]
|
#[xml(namespace = ns::CSI, name = "csi")]
|
||||||
pub struct Feature;
|
pub struct Feature;
|
||||||
|
|
||||||
/// Client indicates it is inactive.
|
/// Client indicates it is inactive.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::CSI, name = "inactive")]
|
#[xml(namespace = ns::CSI, name = "inactive")]
|
||||||
pub struct Inactive;
|
pub struct Inactive;
|
||||||
|
|
||||||
/// Client indicates it is active again.
|
/// Client indicates it is active again.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::CSI, name = "active")]
|
#[xml(namespace = ns::CSI, name = "active")]
|
||||||
pub struct Active;
|
pub struct Active;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ use std::fmt::{Display, Formatter};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use minidom::{Element, IntoAttributeValue};
|
use minidom::{Element, IntoAttributeValue};
|
||||||
use xso::{error::FromElementError, FromXml, IntoXml};
|
use xso::{error::FromElementError, AsXml, FromXml};
|
||||||
|
|
||||||
use crate::ns::{self, XDATA_VALIDATE};
|
use crate::ns::{self, XDATA_VALIDATE};
|
||||||
use crate::Error;
|
use crate::Error;
|
||||||
|
|
@ -67,7 +67,7 @@ pub enum Method {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Selection Ranges in "list-multi"
|
/// Selection Ranges in "list-multi"
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::XDATA_VALIDATE, name = "list-range")]
|
#[xml(namespace = ns::XDATA_VALIDATE, name = "list-range")]
|
||||||
pub struct ListRange {
|
pub struct ListRange {
|
||||||
/// The 'min' attribute specifies the minimum allowable number of selected/entered values.
|
/// The 'min' attribute specifies the minimum allowable number of selected/entered values.
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,10 @@
|
||||||
// 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 std::borrow::Cow;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use xso::{error::Error, FromXmlText, IntoXmlText};
|
use xso::{error::Error, AsXmlText, FromXmlText};
|
||||||
|
|
||||||
use chrono::{DateTime as ChronoDateTime, FixedOffset};
|
use chrono::{DateTime as ChronoDateTime, FixedOffset};
|
||||||
use minidom::{IntoAttributeValue, Node};
|
use minidom::{IntoAttributeValue, Node};
|
||||||
|
|
@ -48,9 +49,9 @@ impl FromXmlText for DateTime {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IntoXmlText for DateTime {
|
impl AsXmlText for DateTime {
|
||||||
fn into_xml_text(self) -> Result<String, Error> {
|
fn as_xml_text(&self) -> Result<Cow<'_, str>, Error> {
|
||||||
Ok(self.0.to_rfc3339())
|
Ok(Cow::Owned(self.0.to_rfc3339()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
// 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::{text::EmptyAsNone, FromXml, IntoXml};
|
use xso::{text::EmptyAsNone, AsXml, FromXml};
|
||||||
|
|
||||||
use crate::date::DateTime;
|
use crate::date::DateTime;
|
||||||
use crate::message::MessagePayload;
|
use crate::message::MessagePayload;
|
||||||
|
|
@ -13,7 +13,7 @@ use crate::presence::PresencePayload;
|
||||||
use jid::Jid;
|
use jid::Jid;
|
||||||
|
|
||||||
/// Notes when and by whom a message got stored for later delivery.
|
/// Notes when and by whom a message got stored for later delivery.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::DELAY, name = "delay")]
|
#[xml(namespace = ns::DELAY, name = "delay")]
|
||||||
pub struct Delay {
|
pub struct Delay {
|
||||||
/// The entity which delayed this message.
|
/// The entity which delayed this message.
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
use xso::{
|
use xso::{
|
||||||
error::{Error, FromElementError},
|
error::{Error, FromElementError},
|
||||||
FromXml, IntoXml,
|
AsXml, FromXml,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::data_forms::{DataForm, DataFormType};
|
use crate::data_forms::{DataForm, DataFormType};
|
||||||
|
|
@ -20,7 +20,7 @@ use jid::Jid;
|
||||||
///
|
///
|
||||||
/// It should only be used in an `<iq type='get'/>`, as it can only represent
|
/// It should only be used in an `<iq type='get'/>`, as it can only represent
|
||||||
/// the request, and not a result.
|
/// the request, and not a result.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::DISCO_INFO, name = "query")]
|
#[xml(namespace = ns::DISCO_INFO, name = "query")]
|
||||||
pub struct DiscoInfoQuery {
|
pub struct DiscoInfoQuery {
|
||||||
/// Node on which we are doing the discovery.
|
/// Node on which we are doing the discovery.
|
||||||
|
|
@ -31,7 +31,7 @@ pub struct DiscoInfoQuery {
|
||||||
impl IqGetPayload for DiscoInfoQuery {}
|
impl IqGetPayload for DiscoInfoQuery {}
|
||||||
|
|
||||||
/// Structure representing a `<feature xmlns='http://jabber.org/protocol/disco#info'/>` element.
|
/// Structure representing a `<feature xmlns='http://jabber.org/protocol/disco#info'/>` element.
|
||||||
#[derive(FromXml, IntoXml, Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(FromXml, AsXml, Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
#[xml(namespace = ns::DISCO_INFO, name = "feature")]
|
#[xml(namespace = ns::DISCO_INFO, name = "feature")]
|
||||||
pub struct Feature {
|
pub struct Feature {
|
||||||
/// Namespace of the feature we want to represent.
|
/// Namespace of the feature we want to represent.
|
||||||
|
|
@ -203,7 +203,7 @@ children: [
|
||||||
impl IqGetPayload for DiscoItemsQuery {}
|
impl IqGetPayload for DiscoItemsQuery {}
|
||||||
|
|
||||||
/// Structure representing an `<item xmlns='http://jabber.org/protocol/disco#items'/>` element.
|
/// Structure representing an `<item xmlns='http://jabber.org/protocol/disco#items'/>` element.
|
||||||
#[derive(FromXml, IntoXml, Debug, Clone, PartialEq)]
|
#[derive(FromXml, AsXml, Debug, Clone, PartialEq)]
|
||||||
#[xml(namespace = ns::DISCO_ITEMS, name = "item")]
|
#[xml(namespace = ns::DISCO_ITEMS, name = "item")]
|
||||||
pub struct Item {
|
pub struct Item {
|
||||||
/// JID of the entity pointed by this item.
|
/// JID of the entity pointed by this item.
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,13 @@
|
||||||
// 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::{FromXml, IntoXml};
|
use xso::{AsXml, FromXml};
|
||||||
|
|
||||||
use crate::message::MessagePayload;
|
use crate::message::MessagePayload;
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
|
|
||||||
/// Structure representing an `<encryption xmlns='urn:xmpp:eme:0'/>` element.
|
/// Structure representing an `<encryption xmlns='urn:xmpp:eme:0'/>` element.
|
||||||
#[derive(FromXml, IntoXml, Debug, Clone, PartialEq)]
|
#[derive(FromXml, AsXml, Debug, Clone, PartialEq)]
|
||||||
#[xml(namespace = ns::EME, name = "encryption")]
|
#[xml(namespace = ns::EME, name = "encryption")]
|
||||||
pub struct ExplicitMessageEncryption {
|
pub struct ExplicitMessageEncryption {
|
||||||
/// Namespace of the encryption scheme used.
|
/// Namespace of the encryption scheme used.
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
// 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::{FromXml, IntoXml};
|
use xso::{AsXml, FromXml};
|
||||||
|
|
||||||
use crate::data_forms::DataForm;
|
use crate::data_forms::DataForm;
|
||||||
use crate::date::DateTime;
|
use crate::date::DateTime;
|
||||||
|
|
@ -101,7 +101,7 @@ generate_element!(
|
||||||
impl IqGetPayload for Service {}
|
impl IqGetPayload for Service {}
|
||||||
|
|
||||||
/// Structure representing a `<services xmlns='urn:xmpp:extdisco:2'/>` element.
|
/// Structure representing a `<services xmlns='urn:xmpp:extdisco:2'/>` element.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::EXT_DISCO, name = "services")]
|
#[xml(namespace = ns::EXT_DISCO, name = "services")]
|
||||||
pub struct ServicesQuery {
|
pub struct ServicesQuery {
|
||||||
/// TODO
|
/// TODO
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
// 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::{FromXml, IntoXml};
|
use xso::{AsXml, FromXml};
|
||||||
|
|
||||||
use crate::date::DateTime;
|
use crate::date::DateTime;
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
|
|
@ -14,7 +14,7 @@ generate_elem_id!(
|
||||||
Mechanism, "mechanism", FAST
|
Mechanism, "mechanism", FAST
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO: Replace this with a proper bool once we can derive FromXml and IntoXml on FastQuery.
|
// TODO: Replace this with a proper bool once we can derive FromXml and AsXml on FastQuery.
|
||||||
generate_attribute!(
|
generate_attribute!(
|
||||||
/// Whether TLS zero-roundtrip is possible.
|
/// Whether TLS zero-roundtrip is possible.
|
||||||
Tls0Rtt, "tls-0rtt", bool
|
Tls0Rtt, "tls-0rtt", bool
|
||||||
|
|
@ -34,7 +34,7 @@ children: [
|
||||||
);
|
);
|
||||||
|
|
||||||
/// 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, IntoXml, Debug, Clone, PartialEq)]
|
#[derive(FromXml, AsXml, Debug, Clone, PartialEq)]
|
||||||
#[xml(namespace = ns::FAST, name = "fast")]
|
#[xml(namespace = ns::FAST, name = "fast")]
|
||||||
pub struct FastResponse {
|
pub struct FastResponse {
|
||||||
/// Servers MUST reject any authentication requests received via TLS 0-RTT payloads that do not
|
/// Servers MUST reject any authentication requests received via TLS 0-RTT payloads that do not
|
||||||
|
|
@ -51,7 +51,7 @@ pub struct FastResponse {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is the `<request-token/>` element sent by the client in the SASL2 authenticate step.
|
/// This is the `<request-token/>` element sent by the client in the SASL2 authenticate step.
|
||||||
#[derive(FromXml, IntoXml, Debug, Clone, PartialEq)]
|
#[derive(FromXml, AsXml, Debug, Clone, PartialEq)]
|
||||||
#[xml(namespace = ns::FAST, name = "request-token")]
|
#[xml(namespace = ns::FAST, name = "request-token")]
|
||||||
pub struct RequestToken {
|
pub struct RequestToken {
|
||||||
/// This element MUST contain a 'mechanism' attribute, the value of which MUST be one of the
|
/// This element MUST contain a 'mechanism' attribute, the value of which MUST be one of the
|
||||||
|
|
@ -62,7 +62,7 @@ pub struct RequestToken {
|
||||||
|
|
||||||
/// This is the `<token/>` element sent by the server on successful SASL2 authentication containing
|
/// This is the `<token/>` element sent by the server on successful SASL2 authentication containing
|
||||||
/// a `<request-token/>` element.
|
/// a `<request-token/>` element.
|
||||||
#[derive(FromXml, IntoXml, Debug, Clone, PartialEq)]
|
#[derive(FromXml, AsXml, Debug, Clone, PartialEq)]
|
||||||
#[xml(namespace = ns::FAST, name = "token")]
|
#[xml(namespace = ns::FAST, name = "token")]
|
||||||
pub struct Token {
|
pub struct Token {
|
||||||
/// The secret token to be used for subsequent authentications, as generated by the server.
|
/// The secret token to be used for subsequent authentications, as generated by the server.
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,16 @@
|
||||||
// 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, text::Base64, FromXml, FromXmlText, IntoXml, IntoXmlText};
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use base64::{engine::general_purpose::STANDARD as Base64Engine, Engine};
|
|
||||||
use minidom::IntoAttributeValue;
|
|
||||||
use std::num::ParseIntError;
|
use std::num::ParseIntError;
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
use xso::{error::Error, text::Base64, AsXml, AsXmlText, FromXml, FromXmlText};
|
||||||
|
|
||||||
|
use base64::{engine::general_purpose::STANDARD as Base64Engine, Engine};
|
||||||
|
use minidom::IntoAttributeValue;
|
||||||
|
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
|
|
||||||
/// List of the algorithms we support, or Unknown.
|
/// List of the algorithms we support, or Unknown.
|
||||||
|
|
@ -97,9 +99,9 @@ impl FromXmlText for Algo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IntoXmlText for Algo {
|
impl AsXmlText for Algo {
|
||||||
fn into_xml_text(self) -> Result<String, Error> {
|
fn as_xml_text(&self) -> Result<Cow<'_, str>, Error> {
|
||||||
Ok(String::from(match self {
|
Ok(Cow::Borrowed(match self {
|
||||||
Algo::Sha_1 => "sha-1",
|
Algo::Sha_1 => "sha-1",
|
||||||
Algo::Sha_256 => "sha-256",
|
Algo::Sha_256 => "sha-256",
|
||||||
Algo::Sha_512 => "sha-512",
|
Algo::Sha_512 => "sha-512",
|
||||||
|
|
@ -107,7 +109,7 @@ impl IntoXmlText for Algo {
|
||||||
Algo::Sha3_512 => "sha3-512",
|
Algo::Sha3_512 => "sha3-512",
|
||||||
Algo::Blake2b_256 => "blake2b-256",
|
Algo::Blake2b_256 => "blake2b-256",
|
||||||
Algo::Blake2b_512 => "blake2b-512",
|
Algo::Blake2b_512 => "blake2b-512",
|
||||||
Algo::Unknown(text) => return Ok(text),
|
Algo::Unknown(text) => text.as_str(),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -120,7 +122,7 @@ impl IntoAttributeValue for Algo {
|
||||||
|
|
||||||
/// This element represents a hash of some data, defined by the hash
|
/// This element represents a hash of some data, defined by the hash
|
||||||
/// algorithm used and the computed value.
|
/// algorithm used and the computed value.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::HASHES, name = "hash")]
|
#[xml(namespace = ns::HASHES, name = "hash")]
|
||||||
pub struct Hash {
|
pub struct Hash {
|
||||||
/// The algorithm used to create this hash.
|
/// The algorithm used to create this hash.
|
||||||
|
|
@ -213,9 +215,9 @@ impl FromXmlText for Sha1HexAttribute {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IntoXmlText for Sha1HexAttribute {
|
impl AsXmlText for Sha1HexAttribute {
|
||||||
fn into_xml_text(self) -> Result<String, xso::error::Error> {
|
fn as_xml_text(&self) -> Result<Cow<'_, str>, xso::error::Error> {
|
||||||
Ok(self.to_hex())
|
Ok(Cow::Owned(self.to_hex()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
use xso::{
|
use xso::{
|
||||||
error::{Error, FromElementError},
|
error::{Error, FromElementError},
|
||||||
FromXml, IntoXml,
|
AsXml, FromXml,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::iq::{IqGetPayload, IqResultPayload};
|
use crate::iq::{IqGetPayload, IqResultPayload};
|
||||||
|
|
@ -14,7 +14,7 @@ use crate::ns;
|
||||||
use crate::Element;
|
use crate::Element;
|
||||||
|
|
||||||
/// Requesting a slot
|
/// Requesting a slot
|
||||||
#[derive(FromXml, IntoXml, Debug, Clone, PartialEq)]
|
#[derive(FromXml, AsXml, Debug, Clone, PartialEq)]
|
||||||
#[xml(namespace = ns::HTTP_UPLOAD, name = "request")]
|
#[xml(namespace = ns::HTTP_UPLOAD, name = "request")]
|
||||||
pub struct SlotRequest {
|
pub struct SlotRequest {
|
||||||
/// The filename to be uploaded.
|
/// The filename to be uploaded.
|
||||||
|
|
@ -97,7 +97,7 @@ generate_element!(
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Get URL
|
/// Get URL
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::HTTP_UPLOAD, name = "get")]
|
#[xml(namespace = ns::HTTP_UPLOAD, name = "get")]
|
||||||
pub struct Get {
|
pub struct Get {
|
||||||
/// URL
|
/// URL
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
// 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::{text::Base64, FromXml, IntoXml};
|
use xso::{text::Base64, AsXml, FromXml};
|
||||||
|
|
||||||
use crate::iq::IqSetPayload;
|
use crate::iq::IqSetPayload;
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
|
|
@ -44,7 +44,7 @@ attributes: [
|
||||||
impl IqSetPayload for Open {}
|
impl IqSetPayload for Open {}
|
||||||
|
|
||||||
/// Exchange a chunk of data in an open stream.
|
/// Exchange a chunk of data in an open stream.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::IBB, name = "data")]
|
#[xml(namespace = ns::IBB, name = "data")]
|
||||||
pub struct Data {
|
pub struct Data {
|
||||||
/// Sequence number of this chunk, must wraparound after 65535.
|
/// Sequence number of this chunk, must wraparound after 65535.
|
||||||
|
|
@ -63,7 +63,7 @@ pub struct Data {
|
||||||
impl IqSetPayload for Data {}
|
impl IqSetPayload for Data {}
|
||||||
|
|
||||||
/// Close an open stream.
|
/// Close an open stream.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::IBB, name = "close")]
|
#[xml(namespace = ns::IBB, name = "close")]
|
||||||
pub struct Close {
|
pub struct Close {
|
||||||
/// The identifier of the stream to be closed.
|
/// The identifier of the stream to be closed.
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,14 @@
|
||||||
// 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::{FromXml, IntoXml};
|
use xso::{AsXml, FromXml};
|
||||||
|
|
||||||
use crate::date::DateTime;
|
use crate::date::DateTime;
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
use crate::presence::PresencePayload;
|
use crate::presence::PresencePayload;
|
||||||
|
|
||||||
/// Represents the last time the user interacted with their system.
|
/// Represents the last time the user interacted with their system.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::IDLE, name = "idle")]
|
#[xml(namespace = ns::IDLE, name = "idle")]
|
||||||
pub struct Idle {
|
pub struct Idle {
|
||||||
/// The time at which the user stopped interacting.
|
/// The time at which the user stopped interacting.
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
// 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::{FromXml, IntoXml};
|
use xso::{AsXml, FromXml};
|
||||||
|
|
||||||
use jid::Jid;
|
use jid::Jid;
|
||||||
|
|
||||||
|
|
@ -12,7 +12,7 @@ use crate::iq::{IqGetPayload, IqResultPayload};
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
|
|
||||||
/// Request from a client to stringprep/PRECIS a string into a JID.
|
/// Request from a client to stringprep/PRECIS a string into a JID.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::JID_PREP, name = "jid")]
|
#[xml(namespace = ns::JID_PREP, name = "jid")]
|
||||||
pub struct JidPrepQuery {
|
pub struct JidPrepQuery {
|
||||||
/// The potential JID.
|
/// The potential JID.
|
||||||
|
|
@ -30,7 +30,7 @@ impl JidPrepQuery {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Response from the server with the stringprep’d/PRECIS’d JID.
|
/// Response from the server with the stringprep’d/PRECIS’d JID.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::JID_PREP, name = "jid")]
|
#[xml(namespace = ns::JID_PREP, name = "jid")]
|
||||||
pub struct JidPrepResponse {
|
pub struct JidPrepResponse {
|
||||||
/// The JID.
|
/// The JID.
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ use std::collections::BTreeMap;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use xso::{
|
use xso::{
|
||||||
error::{Error, FromElementError},
|
error::{Error, FromElementError},
|
||||||
FromXml, IntoXml,
|
AsXml, FromXml,
|
||||||
};
|
};
|
||||||
|
|
||||||
generate_element!(
|
generate_element!(
|
||||||
|
|
@ -323,7 +323,7 @@ impl From<Checksum> for Element {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A notice that the file transfer has been completed.
|
/// A notice that the file transfer has been completed.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::JINGLE_FT, name = "received")]
|
#[xml(namespace = ns::JINGLE_FT, name = "received")]
|
||||||
pub struct Received {
|
pub struct Received {
|
||||||
/// The content identifier of this Jingle session.
|
/// The content identifier of this Jingle session.
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
// 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::{FromXml, IntoXml};
|
use xso::{AsXml, FromXml};
|
||||||
|
|
||||||
use crate::jingle::ContentId;
|
use crate::jingle::ContentId;
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
|
|
@ -21,7 +21,7 @@ generate_attribute!(
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Describes a content that should be grouped with other ones.
|
/// Describes a content that should be grouped with other ones.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::JINGLE_GROUPING, name = "content")]
|
#[xml(namespace = ns::JINGLE_GROUPING, name = "content")]
|
||||||
pub struct Content {
|
pub struct Content {
|
||||||
/// The name of the matching [`Content`](crate::jingle::Content).
|
/// The name of the matching [`Content`](crate::jingle::Content).
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
use std::net::IpAddr;
|
use std::net::IpAddr;
|
||||||
|
|
||||||
use xso::{FromXml, IntoXml};
|
use xso::{AsXml, FromXml};
|
||||||
|
|
||||||
use crate::jingle_dtls_srtp::Fingerprint;
|
use crate::jingle_dtls_srtp::Fingerprint;
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
|
|
@ -68,7 +68,7 @@ generate_attribute!(
|
||||||
);
|
);
|
||||||
|
|
||||||
/// A candidate for an ICE-UDP session.
|
/// A candidate for an ICE-UDP session.
|
||||||
#[derive(FromXml, IntoXml, Debug, PartialEq, Clone)]
|
#[derive(FromXml, AsXml, Debug, PartialEq, Clone)]
|
||||||
#[xml(namespace = ns::JINGLE_ICE_UDP, name = "candidate")]
|
#[xml(namespace = ns::JINGLE_ICE_UDP, name = "candidate")]
|
||||||
pub struct Candidate {
|
pub struct Candidate {
|
||||||
/// A Component ID as defined in ICE-CORE.
|
/// A Component ID as defined in ICE-CORE.
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
use std::net::IpAddr;
|
use std::net::IpAddr;
|
||||||
|
|
||||||
use xso::{FromXml, IntoXml};
|
use xso::{AsXml, FromXml};
|
||||||
|
|
||||||
use crate::jingle_ice_udp::Type;
|
use crate::jingle_ice_udp::Type;
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
|
|
@ -35,7 +35,7 @@ impl Transport {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A candidate for an ICE-UDP session.
|
/// A candidate for an ICE-UDP session.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::JINGLE_RAW_UDP, name = "candidate")]
|
#[xml(namespace = ns::JINGLE_RAW_UDP, name = "candidate")]
|
||||||
pub struct Candidate {
|
pub struct Candidate {
|
||||||
/// A Component ID as defined in ICE-CORE.
|
/// A Component ID as defined in ICE-CORE.
|
||||||
|
|
|
||||||
|
|
@ -4,12 +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::{FromXml, IntoXml};
|
use xso::{AsXml, FromXml};
|
||||||
|
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
|
|
||||||
/// Wrapper element for a rtcp-fb.
|
/// Wrapper element for a rtcp-fb.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::JINGLE_RTCP_FB, name = "rtcp-fb")]
|
#[xml(namespace = ns::JINGLE_RTCP_FB, name = "rtcp-fb")]
|
||||||
pub struct RtcpFb {
|
pub struct RtcpFb {
|
||||||
/// Type of this rtcp-fb.
|
/// Type of this rtcp-fb.
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
// 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::{FromXml, IntoXml};
|
use xso::{AsXml, FromXml};
|
||||||
|
|
||||||
use crate::jingle_rtcp_fb::RtcpFb;
|
use crate::jingle_rtcp_fb::RtcpFb;
|
||||||
use crate::jingle_rtp_hdrext::RtpHdrext;
|
use crate::jingle_rtp_hdrext::RtpHdrext;
|
||||||
|
|
@ -13,7 +13,7 @@ use crate::ns;
|
||||||
|
|
||||||
/// Specifies the ability to multiplex RTP Data and Control Packets on a single port as
|
/// Specifies the ability to multiplex RTP Data and Control Packets on a single port as
|
||||||
/// described in RFC 5761.
|
/// described in RFC 5761.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::JINGLE_RTP, name = "rtcp-mux")]
|
#[xml(namespace = ns::JINGLE_RTP, name = "rtcp-mux")]
|
||||||
pub struct RtcpMux;
|
pub struct RtcpMux;
|
||||||
|
|
||||||
|
|
@ -138,7 +138,7 @@ impl PayloadType {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parameter related to a payload.
|
/// Parameter related to a payload.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::JINGLE_RTP, name = "parameter")]
|
#[xml(namespace = ns::JINGLE_RTP, name = "parameter")]
|
||||||
pub struct Parameter {
|
pub struct Parameter {
|
||||||
/// The name of the parameter, from the list at
|
/// The name of the parameter, from the list at
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
// 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::{FromXml, IntoXml};
|
use xso::{AsXml, FromXml};
|
||||||
|
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
|
|
||||||
|
|
@ -32,7 +32,7 @@ impl Source {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parameter associated with a ssrc.
|
/// Parameter associated with a ssrc.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::JINGLE_SSMA, name = "parameter")]
|
#[xml(namespace = ns::JINGLE_SSMA, name = "parameter")]
|
||||||
pub struct Parameter {
|
pub struct Parameter {
|
||||||
/// The name of the parameter.
|
/// The name of the parameter.
|
||||||
|
|
|
||||||
|
|
@ -6,12 +6,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::{FromXml, IntoXml};
|
use xso::{AsXml, FromXml};
|
||||||
|
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
|
|
||||||
/// A Jingle thumbnail.
|
/// A Jingle thumbnail.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::JINGLE_THUMBNAILS, name = "thumbnail")]
|
#[xml(namespace = ns::JINGLE_THUMBNAILS, name = "thumbnail")]
|
||||||
pub struct Thumbnail {
|
pub struct Thumbnail {
|
||||||
/// The URI of the thumbnail.
|
/// The URI of the thumbnail.
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,14 @@
|
||||||
// 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::{text::Base64, FromXml, IntoXml};
|
use xso::{text::Base64, AsXml, FromXml};
|
||||||
|
|
||||||
use crate::message::MessagePayload;
|
use crate::message::MessagePayload;
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
use crate::pubsub::PubSubPayload;
|
use crate::pubsub::PubSubPayload;
|
||||||
|
|
||||||
/// Element of the device list
|
/// Element of the device list
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::LEGACY_OMEMO, name = "device")]
|
#[xml(namespace = ns::LEGACY_OMEMO, name = "device")]
|
||||||
pub struct Device {
|
pub struct Device {
|
||||||
/// Device id
|
/// Device id
|
||||||
|
|
@ -33,7 +33,7 @@ impl PubSubPayload for DeviceList {}
|
||||||
|
|
||||||
/// SignedPreKey public key
|
/// SignedPreKey public key
|
||||||
/// Part of a device's bundle
|
/// Part of a device's bundle
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::LEGACY_OMEMO, name = "signedPreKeyPublic")]
|
#[xml(namespace = ns::LEGACY_OMEMO, name = "signedPreKeyPublic")]
|
||||||
pub struct SignedPreKeyPublic {
|
pub struct SignedPreKeyPublic {
|
||||||
/// SignedPreKey id
|
/// SignedPreKey id
|
||||||
|
|
@ -47,7 +47,7 @@ pub struct SignedPreKeyPublic {
|
||||||
|
|
||||||
/// SignedPreKey signature
|
/// SignedPreKey signature
|
||||||
/// Part of a device's bundle
|
/// Part of a device's bundle
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::LEGACY_OMEMO, name = "signedPreKeySignature")]
|
#[xml(namespace = ns::LEGACY_OMEMO, name = "signedPreKeySignature")]
|
||||||
pub struct SignedPreKeySignature {
|
pub struct SignedPreKeySignature {
|
||||||
/// Signature bytes
|
/// Signature bytes
|
||||||
|
|
@ -56,7 +56,7 @@ pub struct SignedPreKeySignature {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Part of a device's bundle
|
/// Part of a device's bundle
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::LEGACY_OMEMO, name = "identityKey")]
|
#[xml(namespace = ns::LEGACY_OMEMO, name = "identityKey")]
|
||||||
pub struct IdentityKey {
|
pub struct IdentityKey {
|
||||||
/// Serialized PublicKey
|
/// Serialized PublicKey
|
||||||
|
|
@ -76,7 +76,7 @@ generate_element!(
|
||||||
|
|
||||||
/// PreKey public key
|
/// PreKey public key
|
||||||
/// Part of a device's bundle
|
/// Part of a device's bundle
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::LEGACY_OMEMO, name = "preKeyPublic")]
|
#[xml(namespace = ns::LEGACY_OMEMO, name = "preKeyPublic")]
|
||||||
pub struct PreKeyPublic {
|
pub struct PreKeyPublic {
|
||||||
/// PreKey id
|
/// PreKey id
|
||||||
|
|
@ -123,7 +123,7 @@ generate_element!(
|
||||||
);
|
);
|
||||||
|
|
||||||
/// IV used for payload encryption
|
/// IV used for payload encryption
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::LEGACY_OMEMO, name = "iv")]
|
#[xml(namespace = ns::LEGACY_OMEMO, name = "iv")]
|
||||||
pub struct IV {
|
pub struct IV {
|
||||||
/// IV bytes
|
/// IV bytes
|
||||||
|
|
@ -139,7 +139,7 @@ generate_attribute!(
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Part of the OMEMO element header
|
/// Part of the OMEMO element header
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::LEGACY_OMEMO, name = "key")]
|
#[xml(namespace = ns::LEGACY_OMEMO, name = "key")]
|
||||||
pub struct Key {
|
pub struct Key {
|
||||||
/// The device id this key is encrypted for.
|
/// The device id this key is encrypted for.
|
||||||
|
|
@ -159,7 +159,7 @@ pub struct Key {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The encrypted message body
|
/// The encrypted message body
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::LEGACY_OMEMO, name = "payload")]
|
#[xml(namespace = ns::LEGACY_OMEMO, name = "payload")]
|
||||||
pub struct Payload {
|
pub struct Payload {
|
||||||
/// Encrypted with AES-128 in Galois/Counter Mode (GCM)
|
/// Encrypted with AES-128 in Galois/Counter Mode (GCM)
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
use xso::{
|
use xso::{
|
||||||
error::{Error, FromElementError},
|
error::{Error, FromElementError},
|
||||||
FromXml, IntoXml,
|
AsXml, FromXml,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::data_forms::DataForm;
|
use crate::data_forms::DataForm;
|
||||||
|
|
@ -165,7 +165,7 @@ generate_element!(
|
||||||
impl IqResultPayload for Fin {}
|
impl IqResultPayload for Fin {}
|
||||||
|
|
||||||
/// Metadata of the first message in the archive.
|
/// Metadata of the first message in the archive.
|
||||||
#[derive(FromXml, IntoXml, Debug, Clone, PartialEq)]
|
#[derive(FromXml, AsXml, Debug, Clone, PartialEq)]
|
||||||
#[xml(namespace = ns::MAM, name = "start")]
|
#[xml(namespace = ns::MAM, name = "start")]
|
||||||
pub struct Start {
|
pub struct Start {
|
||||||
/// The id of the first message in the archive.
|
/// The id of the first message in the archive.
|
||||||
|
|
@ -178,7 +178,7 @@ pub struct Start {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Metadata of the last message in the archive.
|
/// Metadata of the last message in the archive.
|
||||||
#[derive(FromXml, IntoXml, Debug, Clone, PartialEq)]
|
#[derive(FromXml, AsXml, Debug, Clone, PartialEq)]
|
||||||
#[xml(namespace = ns::MAM, name = "end")]
|
#[xml(namespace = ns::MAM, name = "end")]
|
||||||
pub struct End {
|
pub struct End {
|
||||||
/// The id of the last message in the archive.
|
/// The id of the last message in the archive.
|
||||||
|
|
@ -191,7 +191,7 @@ pub struct End {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Request an archive for its metadata.
|
/// Request an archive for its metadata.
|
||||||
#[derive(FromXml, IntoXml, Debug, Clone, PartialEq)]
|
#[derive(FromXml, AsXml, Debug, Clone, PartialEq)]
|
||||||
#[xml(namespace = ns::MAM, name = "metadata")]
|
#[xml(namespace = ns::MAM, name = "metadata")]
|
||||||
pub struct MetadataQuery;
|
pub struct MetadataQuery;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,14 @@
|
||||||
// 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::{FromXml, IntoXml};
|
use xso::{AsXml, FromXml};
|
||||||
|
|
||||||
use crate::message::MessagePayload;
|
use crate::message::MessagePayload;
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
|
|
||||||
/// Defines that the message containing this payload should replace a
|
/// Defines that the message containing this payload should replace a
|
||||||
/// previous message, identified by the id.
|
/// previous message, identified by the id.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::MESSAGE_CORRECT, name = "replace")]
|
#[xml(namespace = ns::MESSAGE_CORRECT, name = "replace")]
|
||||||
pub struct Replace {
|
pub struct Replace {
|
||||||
/// The 'id' attribute of the message getting corrected.
|
/// The 'id' attribute of the message getting corrected.
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
// TODO: validate nicks by applying the “nickname” profile of the PRECIS OpaqueString class, as
|
// TODO: validate nicks by applying the “nickname” profile of the PRECIS OpaqueString class, as
|
||||||
// defined in RFC 7700.
|
// defined in RFC 7700.
|
||||||
|
|
||||||
use xso::{FromXml, IntoXml};
|
use xso::{AsXml, FromXml};
|
||||||
|
|
||||||
use crate::iq::{IqResultPayload, IqSetPayload};
|
use crate::iq::{IqResultPayload, IqSetPayload};
|
||||||
use crate::message::MessagePayload;
|
use crate::message::MessagePayload;
|
||||||
|
|
@ -59,7 +59,7 @@ impl Participant {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A node to subscribe to.
|
/// A node to subscribe to.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::MIX_CORE, name = "subscribe")]
|
#[xml(namespace = ns::MIX_CORE, name = "subscribe")]
|
||||||
pub struct Subscribe {
|
pub struct Subscribe {
|
||||||
/// The PubSub node to subscribe to.
|
/// The PubSub node to subscribe to.
|
||||||
|
|
@ -151,7 +151,7 @@ impl UpdateSubscription {
|
||||||
|
|
||||||
/// Request to leave a given MIX channel. It will automatically unsubscribe the user from all
|
/// Request to leave a given MIX channel. It will automatically unsubscribe the user from all
|
||||||
/// nodes on this channel.
|
/// nodes on this channel.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::MIX_CORE, name = "leave")]
|
#[xml(namespace = ns::MIX_CORE, name = "leave")]
|
||||||
pub struct Leave;
|
pub struct Leave;
|
||||||
|
|
||||||
|
|
@ -204,7 +204,7 @@ impl Mix {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new MIX channel.
|
/// Create a new MIX channel.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Clone, Debug, Default)]
|
#[derive(FromXml, AsXml, PartialEq, Clone, Debug, Default)]
|
||||||
#[xml(namespace = ns::MIX_CORE, name = "create")]
|
#[xml(namespace = ns::MIX_CORE, name = "create")]
|
||||||
pub struct Create {
|
pub struct Create {
|
||||||
/// The requested channel identifier.
|
/// The requested channel identifier.
|
||||||
|
|
@ -230,7 +230,7 @@ impl Create {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Destroy a given MIX channel.
|
/// Destroy a given MIX channel.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::MIX_CORE, name = "destroy")]
|
#[xml(namespace = ns::MIX_CORE, name = "destroy")]
|
||||||
pub struct Destroy {
|
pub struct Destroy {
|
||||||
/// The channel identifier to be destroyed.
|
/// The channel identifier to be destroyed.
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,14 @@
|
||||||
// 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::{FromXml, IntoXml};
|
use xso::{AsXml, FromXml};
|
||||||
|
|
||||||
use crate::date::DateTime;
|
use crate::date::DateTime;
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
use crate::presence::PresencePayload;
|
use crate::presence::PresencePayload;
|
||||||
|
|
||||||
/// Represents the query for messages before our join.
|
/// Represents the query for messages before our join.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone, Default)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone, Default)]
|
||||||
#[xml(namespace = ns::MUC, name = "history")]
|
#[xml(namespace = ns::MUC, name = "history")]
|
||||||
pub struct History {
|
pub struct History {
|
||||||
/// How many characters of history to send, in XML characters.
|
/// How many characters of history to send, in XML characters.
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
use xso::{
|
use xso::{
|
||||||
error::{Error, FromElementError},
|
error::{Error, FromElementError},
|
||||||
FromXml, IntoXml,
|
AsXml, FromXml,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::message::MessagePayload;
|
use crate::message::MessagePayload;
|
||||||
|
|
@ -131,7 +131,7 @@ impl From<Actor> for Element {
|
||||||
|
|
||||||
/// Used to continue a one-to-one discussion in a room, with more than one
|
/// Used to continue a one-to-one discussion in a room, with more than one
|
||||||
/// participant.
|
/// participant.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::MUC_USER, name = "continue")]
|
#[xml(namespace = ns::MUC_USER, name = "continue")]
|
||||||
pub struct Continue {
|
pub struct Continue {
|
||||||
/// The thread to continue in this room.
|
/// The thread to continue in this room.
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
// 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::{FromXml, IntoXml};
|
use xso::{AsXml, FromXml};
|
||||||
|
|
||||||
use crate::message::MessagePayload;
|
use crate::message::MessagePayload;
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
|
|
@ -14,7 +14,7 @@ use crate::presence::PresencePayload;
|
||||||
///
|
///
|
||||||
/// It allows clients to identify a MUC participant across reconnects and
|
/// It allows clients to identify a MUC participant across reconnects and
|
||||||
/// renames. It thus prevents impersonification of anonymous users.
|
/// renames. It thus prevents impersonification of anonymous users.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::OID, name = "occupant-id")]
|
#[xml(namespace = ns::OID, name = "occupant-id")]
|
||||||
pub struct OccupantId {
|
pub struct OccupantId {
|
||||||
/// The id associated to the sending user by the MUC service.
|
/// The id associated to the sending user by the MUC service.
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
// 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::{text::Base64, FromXml, IntoXml};
|
use xso::{text::Base64, AsXml, FromXml};
|
||||||
|
|
||||||
use crate::date::DateTime;
|
use crate::date::DateTime;
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
|
|
@ -12,7 +12,7 @@ use crate::pubsub::PubSubPayload;
|
||||||
|
|
||||||
/// Data contained in the PubKey element
|
/// Data contained in the PubKey element
|
||||||
// TODO: Merge this container with the PubKey struct
|
// TODO: Merge this container with the PubKey struct
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::OX, name = "data")]
|
#[xml(namespace = ns::OX, name = "data")]
|
||||||
pub struct PubKeyData {
|
pub struct PubKeyData {
|
||||||
/// Base64 data
|
/// Base64 data
|
||||||
|
|
@ -36,7 +36,7 @@ generate_element!(
|
||||||
impl PubSubPayload for PubKey {}
|
impl PubSubPayload for PubKey {}
|
||||||
|
|
||||||
/// Public key metadata
|
/// Public key metadata
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::OX, name = "pubkey-metadata")]
|
#[xml(namespace = ns::OX, name = "pubkey-metadata")]
|
||||||
pub struct PubKeyMeta {
|
pub struct PubKeyMeta {
|
||||||
/// OpenPGP v4 fingerprint
|
/// OpenPGP v4 fingerprint
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,14 @@
|
||||||
// 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::{FromXml, IntoXml};
|
use xso::{AsXml, FromXml};
|
||||||
|
|
||||||
use crate::iq::IqGetPayload;
|
use crate::iq::IqGetPayload;
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
|
|
||||||
/// Represents a ping to the recipient, which must be answered with an
|
/// Represents a ping to the recipient, which must be answered with an
|
||||||
/// empty `<iq/>` or with an error.
|
/// empty `<iq/>` or with an error.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::PING, name = "ping")]
|
#[xml(namespace = ns::PING, name = "ping")]
|
||||||
pub struct Ping;
|
pub struct Ping;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
// 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::{FromXml, IntoXml};
|
use xso::{AsXml, FromXml};
|
||||||
|
|
||||||
use crate::data_forms::DataForm;
|
use crate::data_forms::DataForm;
|
||||||
use crate::iq::{IqGetPayload, IqResultPayload, IqSetPayload};
|
use crate::iq::{IqGetPayload, IqResultPayload, IqSetPayload};
|
||||||
|
|
@ -29,7 +29,7 @@ generate_element!(
|
||||||
);
|
);
|
||||||
|
|
||||||
/// An affiliation element.
|
/// An affiliation element.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::PUBSUB_OWNER, name = "affiliation")]
|
#[xml(namespace = ns::PUBSUB_OWNER, name = "affiliation")]
|
||||||
pub struct Affiliation {
|
pub struct Affiliation {
|
||||||
/// The node this affiliation pertains to.
|
/// The node this affiliation pertains to.
|
||||||
|
|
@ -77,7 +77,7 @@ generate_element!(
|
||||||
);
|
);
|
||||||
|
|
||||||
/// A redirect element.
|
/// A redirect element.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::PUBSUB_OWNER, name = "redirect")]
|
#[xml(namespace = ns::PUBSUB_OWNER, name = "redirect")]
|
||||||
pub struct Redirect {
|
pub struct Redirect {
|
||||||
/// The node this node will be redirected to.
|
/// The node this node will be redirected to.
|
||||||
|
|
@ -86,7 +86,7 @@ pub struct Redirect {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Request to clear a node.
|
/// Request to clear a node.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::PUBSUB_OWNER, name = "purge")]
|
#[xml(namespace = ns::PUBSUB_OWNER, name = "purge")]
|
||||||
pub struct Purge {
|
pub struct Purge {
|
||||||
/// The node to be cleared.
|
/// The node to be cleared.
|
||||||
|
|
@ -108,7 +108,7 @@ generate_element!(
|
||||||
);
|
);
|
||||||
|
|
||||||
/// A subscription element, describing the state of a subscription.
|
/// A subscription element, describing the state of a subscription.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::PUBSUB_OWNER, name = "subscription")]
|
#[xml(namespace = ns::PUBSUB_OWNER, name = "subscription")]
|
||||||
pub struct SubscriptionElem {
|
pub struct SubscriptionElem {
|
||||||
/// The JID affected by this subscription.
|
/// The JID affected by this subscription.
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
use xso::{
|
use xso::{
|
||||||
error::{Error, FromElementError},
|
error::{Error, FromElementError},
|
||||||
FromXml, IntoXml,
|
AsXml, FromXml,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::data_forms::DataForm;
|
use crate::data_forms::DataForm;
|
||||||
|
|
@ -34,7 +34,7 @@ generate_element!(
|
||||||
);
|
);
|
||||||
|
|
||||||
/// An affiliation element.
|
/// An affiliation element.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::PUBSUB, name = "affiliation")]
|
#[xml(namespace = ns::PUBSUB, name = "affiliation")]
|
||||||
pub struct Affiliation {
|
pub struct Affiliation {
|
||||||
/// The node this affiliation pertains to.
|
/// The node this affiliation pertains to.
|
||||||
|
|
@ -56,7 +56,7 @@ generate_element!(
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Request to create a new node.
|
/// Request to create a new node.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::PUBSUB, name = "create")]
|
#[xml(namespace = ns::PUBSUB, name = "create")]
|
||||||
pub struct Create {
|
pub struct Create {
|
||||||
/// The node name to create, if `None` the service will generate one.
|
/// The node name to create, if `None` the service will generate one.
|
||||||
|
|
@ -222,7 +222,7 @@ impl From<SubscribeOptions> for Element {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A request to subscribe a JID to a node.
|
/// A request to subscribe a JID to a node.
|
||||||
#[derive(FromXml, IntoXml, Debug, PartialEq, Clone)]
|
#[derive(FromXml, AsXml, Debug, PartialEq, Clone)]
|
||||||
#[xml(namespace = ns::PUBSUB, name = "subscribe")]
|
#[xml(namespace = ns::PUBSUB, name = "subscribe")]
|
||||||
pub struct Subscribe {
|
pub struct Subscribe {
|
||||||
/// The JID being subscribed.
|
/// The JID being subscribed.
|
||||||
|
|
@ -270,7 +270,7 @@ generate_element!(
|
||||||
);
|
);
|
||||||
|
|
||||||
/// An unsubscribe request.
|
/// An unsubscribe request.
|
||||||
#[derive(FromXml, IntoXml, Debug, PartialEq, Clone)]
|
#[derive(FromXml, AsXml, Debug, PartialEq, Clone)]
|
||||||
#[xml(namespace = ns::PUBSUB, name = "unsubscribe")]
|
#[xml(namespace = ns::PUBSUB, name = "unsubscribe")]
|
||||||
pub struct Unsubscribe {
|
pub struct Unsubscribe {
|
||||||
/// The JID affected by this request.
|
/// The JID affected by this request.
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
// 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::{FromXml, IntoXml};
|
use xso::{AsXml, FromXml};
|
||||||
|
|
||||||
use crate::message::MessagePayload;
|
use crate::message::MessagePayload;
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
|
|
@ -25,7 +25,7 @@ generate_element!(
|
||||||
impl MessagePayload for Reactions {}
|
impl MessagePayload for Reactions {}
|
||||||
|
|
||||||
/// One emoji reaction.
|
/// One emoji reaction.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::REACTIONS, name = "reaction")]
|
#[xml(namespace = ns::REACTIONS, name = "reaction")]
|
||||||
pub struct Reaction {
|
pub struct Reaction {
|
||||||
/// The text of this reaction.
|
/// The text of this reaction.
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,14 @@
|
||||||
// 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::{FromXml, IntoXml};
|
use xso::{AsXml, FromXml};
|
||||||
|
|
||||||
use crate::message::MessagePayload;
|
use crate::message::MessagePayload;
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
|
|
||||||
/// Requests that this message is acked by the final recipient once
|
/// Requests that this message is acked by the final recipient once
|
||||||
/// received.
|
/// received.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::RECEIPTS, name = "request")]
|
#[xml(namespace = ns::RECEIPTS, name = "request")]
|
||||||
pub struct Request;
|
pub struct Request;
|
||||||
|
|
||||||
|
|
@ -19,7 +19,7 @@ impl MessagePayload for Request {}
|
||||||
|
|
||||||
/// Notes that a previous message has correctly been received, it is
|
/// Notes that a previous message has correctly been received, it is
|
||||||
/// referenced by its 'id' attribute.
|
/// referenced by its 'id' attribute.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::RECEIPTS, name = "received")]
|
#[xml(namespace = ns::RECEIPTS, name = "received")]
|
||||||
pub struct Received {
|
pub struct Received {
|
||||||
/// The 'id' attribute of the received message.
|
/// The 'id' attribute of the received message.
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
// 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::{text::EmptyAsNone, FromXml, IntoXml};
|
use xso::{text::EmptyAsNone, AsXml, FromXml};
|
||||||
|
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
use crate::Element;
|
use crate::Element;
|
||||||
|
|
@ -31,7 +31,7 @@ generate_attribute!(
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Supports the transmission of text, including key presses, and text block inserts.
|
/// Supports the transmission of text, including key presses, and text block inserts.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::RTT, name = "t")]
|
#[xml(namespace = ns::RTT, name = "t")]
|
||||||
pub struct Insert {
|
pub struct Insert {
|
||||||
/// Position in the message to start inserting from. If None, this means to start from the
|
/// Position in the message to start inserting from. If None, this means to start from the
|
||||||
|
|
@ -113,7 +113,7 @@ impl TryFrom<Action> for Erase {
|
||||||
|
|
||||||
/// Allow for the transmission of intervals, between real-time text actions, to recreate the
|
/// Allow for the transmission of intervals, between real-time text actions, to recreate the
|
||||||
/// pauses between key presses.
|
/// pauses between key presses.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::RTT, name = "w")]
|
#[xml(namespace = ns::RTT, name = "w")]
|
||||||
pub struct Wait {
|
pub struct Wait {
|
||||||
/// Amount of milliseconds to wait before the next action.
|
/// Amount of milliseconds to wait before the next action.
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
use xso::{
|
use xso::{
|
||||||
error::{Error, FromElementError},
|
error::{Error, FromElementError},
|
||||||
text::Base64,
|
text::Base64,
|
||||||
FromXml, IntoXml,
|
AsXml, FromXml,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
|
|
@ -48,7 +48,7 @@ generate_attribute!(
|
||||||
|
|
||||||
/// The first step of the SASL process, selecting the mechanism and sending
|
/// The first step of the SASL process, selecting the mechanism and sending
|
||||||
/// the first part of the handshake.
|
/// the first part of the handshake.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::SASL, name = "auth")]
|
#[xml(namespace = ns::SASL, name = "auth")]
|
||||||
pub struct Auth {
|
pub struct Auth {
|
||||||
/// The mechanism used.
|
/// The mechanism used.
|
||||||
|
|
@ -63,7 +63,7 @@ pub struct Auth {
|
||||||
/// In case the mechanism selected at the [auth](struct.Auth.html) step
|
/// In case the mechanism selected at the [auth](struct.Auth.html) step
|
||||||
/// requires a second step, the server sends this element with additional
|
/// requires a second step, the server sends this element with additional
|
||||||
/// data.
|
/// data.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::SASL, name = "challenge")]
|
#[xml(namespace = ns::SASL, name = "challenge")]
|
||||||
pub struct Challenge {
|
pub struct Challenge {
|
||||||
/// The challenge data.
|
/// The challenge data.
|
||||||
|
|
@ -74,7 +74,7 @@ pub struct Challenge {
|
||||||
/// In case the mechanism selected at the [auth](struct.Auth.html) step
|
/// In case the mechanism selected at the [auth](struct.Auth.html) step
|
||||||
/// requires a second step, this contains the client’s response to the
|
/// requires a second step, this contains the client’s response to the
|
||||||
/// server’s [challenge](struct.Challenge.html).
|
/// server’s [challenge](struct.Challenge.html).
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::SASL, name = "response")]
|
#[xml(namespace = ns::SASL, name = "response")]
|
||||||
pub struct Response {
|
pub struct Response {
|
||||||
/// The response data.
|
/// The response data.
|
||||||
|
|
@ -84,12 +84,12 @@ pub struct Response {
|
||||||
|
|
||||||
/// Sent by the client at any point after [auth](struct.Auth.html) if it
|
/// Sent by the client at any point after [auth](struct.Auth.html) if it
|
||||||
/// wants to cancel the current authentication process.
|
/// wants to cancel the current authentication process.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::SASL, name = "abort")]
|
#[xml(namespace = ns::SASL, name = "abort")]
|
||||||
pub struct Abort;
|
pub struct Abort;
|
||||||
|
|
||||||
/// Sent by the server on SASL success.
|
/// Sent by the server on SASL success.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::SASL, name = "success")]
|
#[xml(namespace = ns::SASL, name = "success")]
|
||||||
pub struct Success {
|
pub struct Success {
|
||||||
/// Possible data sent on success.
|
/// Possible data sent on success.
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,13 @@
|
||||||
// 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::{FromXml, IntoXml};
|
use xso::{AsXml, FromXml};
|
||||||
|
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
use crate::stanza_error::DefinedCondition;
|
use crate::stanza_error::DefinedCondition;
|
||||||
|
|
||||||
/// Acknowledgement of the currently received stanzas.
|
/// Acknowledgement of the currently received stanzas.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::SM, name = "a")]
|
#[xml(namespace = ns::SM, name = "a")]
|
||||||
pub struct A {
|
pub struct A {
|
||||||
/// The last handled stanza.
|
/// The last handled stanza.
|
||||||
|
|
@ -105,12 +105,12 @@ generate_element!(
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Requests the currently received stanzas by the other party.
|
/// Requests the currently received stanzas by the other party.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::SM, name = "r")]
|
#[xml(namespace = ns::SM, name = "r")]
|
||||||
pub struct R;
|
pub struct R;
|
||||||
|
|
||||||
/// Requests a stream resumption.
|
/// Requests a stream resumption.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::SM, name = "resume")]
|
#[xml(namespace = ns::SM, name = "resume")]
|
||||||
pub struct Resume {
|
pub struct Resume {
|
||||||
/// The last handled stanza.
|
/// The last handled stanza.
|
||||||
|
|
@ -124,7 +124,7 @@ pub struct Resume {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The response by the server for a successfully resumed stream.
|
/// The response by the server for a successfully resumed stream.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::SM, name = "resumed")]
|
#[xml(namespace = ns::SM, name = "resumed")]
|
||||||
pub struct Resumed {
|
pub struct Resumed {
|
||||||
/// The last handled stanza.
|
/// The last handled stanza.
|
||||||
|
|
@ -139,7 +139,7 @@ pub struct Resumed {
|
||||||
|
|
||||||
// TODO: add support for optional and required.
|
// TODO: add support for optional and required.
|
||||||
/// Represents availability of Stream Management in `<stream:features/>`.
|
/// Represents availability of Stream Management in `<stream:features/>`.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::SM, name = "sm")]
|
#[xml(namespace = ns::SM, name = "sm")]
|
||||||
pub struct StreamManagement;
|
pub struct StreamManagement;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
// 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::{FromXml, IntoXml};
|
use xso::{AsXml, FromXml};
|
||||||
|
|
||||||
use crate::message::MessagePayload;
|
use crate::message::MessagePayload;
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
|
|
@ -12,7 +12,7 @@ use jid::Jid;
|
||||||
|
|
||||||
/// Gives the identifier a service has stamped on this stanza, often in
|
/// Gives the identifier a service has stamped on this stanza, often in
|
||||||
/// order to identify it inside of [an archive](../mam/index.html).
|
/// order to identify it inside of [an archive](../mam/index.html).
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::SID, name = "stanza-id")]
|
#[xml(namespace = ns::SID, name = "stanza-id")]
|
||||||
pub struct StanzaId {
|
pub struct StanzaId {
|
||||||
/// The id associated to this stanza by another entity.
|
/// The id associated to this stanza by another entity.
|
||||||
|
|
@ -28,7 +28,7 @@ impl MessagePayload for StanzaId {}
|
||||||
|
|
||||||
/// A hack for MUC before version 1.31 to track a message which may have
|
/// A hack for MUC before version 1.31 to track a message which may have
|
||||||
/// its 'id' attribute changed.
|
/// its 'id' attribute changed.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::SID, name = "origin-id")]
|
#[xml(namespace = ns::SID, name = "origin-id")]
|
||||||
pub struct OriginId {
|
pub struct OriginId {
|
||||||
/// The id this client set for this stanza.
|
/// The id this client set for this stanza.
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,14 @@
|
||||||
// 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::{FromXml, IntoXml};
|
use xso::{AsXml, FromXml};
|
||||||
|
|
||||||
use jid::BareJid;
|
use jid::BareJid;
|
||||||
|
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
|
|
||||||
/// The stream opening for client-server communications.
|
/// The stream opening for client-server communications.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::STREAM, name = "stream")]
|
#[xml(namespace = ns::STREAM, name = "stream")]
|
||||||
pub struct Stream {
|
pub struct Stream {
|
||||||
/// The JID of the entity opening this stream.
|
/// The JID of the entity opening this stream.
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
// 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::{FromXml, IntoXml};
|
use xso::{AsXml, FromXml};
|
||||||
|
|
||||||
use crate::date::DateTime;
|
use crate::date::DateTime;
|
||||||
use crate::iq::{IqGetPayload, IqResultPayload};
|
use crate::iq::{IqGetPayload, IqResultPayload};
|
||||||
|
|
@ -15,7 +15,7 @@ use std::str::FromStr;
|
||||||
use xso::error::{Error, FromElementError};
|
use xso::error::{Error, FromElementError};
|
||||||
|
|
||||||
/// An entity time query.
|
/// An entity time query.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::TIME, name = "time")]
|
#[xml(namespace = ns::TIME, name = "time")]
|
||||||
pub struct TimeQuery;
|
pub struct TimeQuery;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,9 +19,9 @@ mod helpers {
|
||||||
// this is to ensure that the macros do not have hidden dependencies on
|
// this is to ensure that the macros do not have hidden dependencies on
|
||||||
// any specific names being imported.
|
// any specific names being imported.
|
||||||
use minidom::Element;
|
use minidom::Element;
|
||||||
use xso::{error::FromElementError, transform, try_from_element, FromXml, IntoXml};
|
use xso::{error::FromElementError, transform, try_from_element, AsXml, FromXml};
|
||||||
|
|
||||||
pub(super) fn roundtrip_full<T: IntoXml + FromXml + PartialEq + std::fmt::Debug + Clone>(
|
pub(super) fn roundtrip_full<T: AsXml + FromXml + PartialEq + std::fmt::Debug + Clone>(
|
||||||
s: &str,
|
s: &str,
|
||||||
) {
|
) {
|
||||||
let initial: Element = s.parse().unwrap();
|
let initial: Element = s.parse().unwrap();
|
||||||
|
|
@ -47,7 +47,7 @@ mod helpers {
|
||||||
|
|
||||||
use self::helpers::{parse_str, roundtrip_full};
|
use self::helpers::{parse_str, roundtrip_full};
|
||||||
|
|
||||||
use xso::{FromXml, IntoXml};
|
use xso::{AsXml, FromXml};
|
||||||
|
|
||||||
// these are adverserial local names in order to trigger any issues with
|
// these are adverserial local names in order to trigger any issues with
|
||||||
// unqualified names in the macro expansions.
|
// unqualified names in the macro expansions.
|
||||||
|
|
@ -81,7 +81,7 @@ static BAR_NAME: &::xso::exports::rxml::strings::NcNameStr = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = NS1, name = "foo")]
|
#[xml(namespace = NS1, name = "foo")]
|
||||||
struct Empty;
|
struct Empty;
|
||||||
|
|
||||||
|
|
@ -164,7 +164,7 @@ fn empty_qname_check_has_precedence_over_attr_check() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = NS1, name = BAR_NAME)]
|
#[xml(namespace = NS1, name = BAR_NAME)]
|
||||||
struct NamePath;
|
struct NamePath;
|
||||||
|
|
||||||
|
|
@ -178,7 +178,7 @@ fn name_path_roundtrip() {
|
||||||
roundtrip_full::<NamePath>("<bar xmlns='urn:example:ns1'/>");
|
roundtrip_full::<NamePath>("<bar xmlns='urn:example:ns1'/>");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = "urn:example:ns2", name = "baz")]
|
#[xml(namespace = "urn:example:ns2", name = "baz")]
|
||||||
struct NamespaceLit;
|
struct NamespaceLit;
|
||||||
|
|
||||||
|
|
@ -192,7 +192,7 @@ fn namespace_lit_roundtrip() {
|
||||||
roundtrip_full::<NamespaceLit>("<baz xmlns='urn:example:ns2'/>");
|
roundtrip_full::<NamespaceLit>("<baz xmlns='urn:example:ns2'/>");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = NS1, name = "attr")]
|
#[xml(namespace = NS1, name = "attr")]
|
||||||
struct RequiredAttribute {
|
struct RequiredAttribute {
|
||||||
#[xml(attribute)]
|
#[xml(attribute)]
|
||||||
|
|
@ -237,7 +237,7 @@ fn required_attribute_missing() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = NS1, name = "attr")]
|
#[xml(namespace = NS1, name = "attr")]
|
||||||
struct RenamedAttribute {
|
struct RenamedAttribute {
|
||||||
#[xml(attribute = "a1")]
|
#[xml(attribute = "a1")]
|
||||||
|
|
@ -256,7 +256,7 @@ fn renamed_attribute_roundtrip() {
|
||||||
roundtrip_full::<RenamedAttribute>("<attr xmlns='urn:example:ns1' a1='bar' bar='baz'/>");
|
roundtrip_full::<RenamedAttribute>("<attr xmlns='urn:example:ns1' a1='bar' bar='baz'/>");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = NS1, name = "attr")]
|
#[xml(namespace = NS1, name = "attr")]
|
||||||
struct NamespacedAttribute {
|
struct NamespacedAttribute {
|
||||||
#[xml(attribute(namespace = "urn:example:ns1", name = FOO_NAME))]
|
#[xml(attribute(namespace = "urn:example:ns1", name = FOO_NAME))]
|
||||||
|
|
@ -297,7 +297,7 @@ fn namespaced_attribute_roundtrip_b() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = NS1, name = "attr")]
|
#[xml(namespace = NS1, name = "attr")]
|
||||||
struct PrefixedAttribute {
|
struct PrefixedAttribute {
|
||||||
#[xml(attribute = "xml:lang")]
|
#[xml(attribute = "xml:lang")]
|
||||||
|
|
@ -314,7 +314,7 @@ fn prefixed_attribute_roundtrip() {
|
||||||
roundtrip_full::<PrefixedAttribute>("<attr xmlns='urn:example:ns1' xml:lang='foo'/>");
|
roundtrip_full::<PrefixedAttribute>("<attr xmlns='urn:example:ns1' xml:lang='foo'/>");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = NS1, name = "attr")]
|
#[xml(namespace = NS1, name = "attr")]
|
||||||
struct RequiredNonStringAttribute {
|
struct RequiredNonStringAttribute {
|
||||||
#[xml(attribute)]
|
#[xml(attribute)]
|
||||||
|
|
@ -331,7 +331,7 @@ fn required_non_string_attribute_roundtrip() {
|
||||||
roundtrip_full::<RequiredNonStringAttribute>("<attr xmlns='urn:example:ns1' foo='-16'/>");
|
roundtrip_full::<RequiredNonStringAttribute>("<attr xmlns='urn:example:ns1' foo='-16'/>");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = NS1, name = "attr")]
|
#[xml(namespace = NS1, name = "attr")]
|
||||||
struct DefaultAttribute {
|
struct DefaultAttribute {
|
||||||
#[xml(attribute(default))]
|
#[xml(attribute(default))]
|
||||||
|
|
@ -381,7 +381,7 @@ fn default_attribute_roundtrip_pp() {
|
||||||
roundtrip_full::<DefaultAttribute>("<attr xmlns='urn:example:ns1' foo='xyz' bar='16'/>");
|
roundtrip_full::<DefaultAttribute>("<attr xmlns='urn:example:ns1' foo='xyz' bar='16'/>");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = NS1, name = "text")]
|
#[xml(namespace = NS1, name = "text")]
|
||||||
struct TextString {
|
struct TextString {
|
||||||
#[xml(text)]
|
#[xml(text)]
|
||||||
|
|
@ -409,7 +409,7 @@ fn text_string_positive_preserves_whitespace() {
|
||||||
assert_eq!(el.text, " \t\n");
|
assert_eq!(el.text, " \t\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = NS1, name = "text")]
|
#[xml(namespace = NS1, name = "text")]
|
||||||
struct TextNonString {
|
struct TextNonString {
|
||||||
#[xml(text)]
|
#[xml(text)]
|
||||||
|
|
@ -426,7 +426,7 @@ fn text_non_string_roundtrip() {
|
||||||
roundtrip_full::<TextNonString>("<text xmlns='urn:example:ns1'>123456</text>");
|
roundtrip_full::<TextNonString>("<text xmlns='urn:example:ns1'>123456</text>");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = NS1, name = "elem")]
|
#[xml(namespace = NS1, name = "elem")]
|
||||||
struct IgnoresWhitespaceWithoutTextConsumer;
|
struct IgnoresWhitespaceWithoutTextConsumer;
|
||||||
|
|
||||||
|
|
@ -443,7 +443,7 @@ fn ignores_whitespace_without_text_consumer_positive() {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = NS1, name = "elem")]
|
#[xml(namespace = NS1, name = "elem")]
|
||||||
struct FailsTextWithoutTextConsumer;
|
struct FailsTextWithoutTextConsumer;
|
||||||
|
|
||||||
|
|
@ -465,7 +465,7 @@ fn fails_text_without_text_consumer_positive() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = NS1, name = "text")]
|
#[xml(namespace = NS1, name = "text")]
|
||||||
struct TextWithCodec {
|
struct TextWithCodec {
|
||||||
#[xml(text(codec = xso::text::EmptyAsNone))]
|
#[xml(text(codec = xso::text::EmptyAsNone))]
|
||||||
|
|
|
||||||
|
|
@ -94,9 +94,13 @@ macro_rules! generate_attribute {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl ::xso::IntoXmlText for $elem {
|
impl ::xso::AsXmlText for $elem {
|
||||||
fn into_xml_text(self) -> Result<String, xso::error::Error> {
|
fn as_xml_text(&self) -> Result<::std::borrow::Cow<'_, str>, xso::error::Error> {
|
||||||
Ok(self.to_string())
|
match self {
|
||||||
|
$(
|
||||||
|
$elem::$a => Ok(::std::borrow::Cow::Borrowed($b))
|
||||||
|
),+
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl ::minidom::IntoAttributeValue for $elem {
|
impl ::minidom::IntoAttributeValue for $elem {
|
||||||
|
|
@ -130,16 +134,16 @@ macro_rules! generate_attribute {
|
||||||
s.parse().map_err(xso::error::Error::text_parse_error)
|
s.parse().map_err(xso::error::Error::text_parse_error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl ::xso::IntoXmlText for $elem {
|
impl ::xso::AsXmlText for $elem {
|
||||||
fn into_xml_text(self) -> Result<String, xso::error::Error> {
|
fn as_xml_text(&self) -> Result<std::borrow::Cow<'_, str>, xso::error::Error> {
|
||||||
Ok(String::from(match self {
|
Ok(std::borrow::Cow::Borrowed(match self {
|
||||||
$($elem::$a => $b),+
|
$($elem::$a => $b),+
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unreachable_patterns)]
|
#[allow(unreachable_patterns)]
|
||||||
fn into_optional_xml_text(self) -> Result<Option<String>, xso::error::Error> {
|
fn as_optional_xml_text(&self) -> Result<Option<std::borrow::Cow<'_, str>>, xso::error::Error> {
|
||||||
Ok(Some(String::from(match self {
|
Ok(Some(std::borrow::Cow::Borrowed(match self {
|
||||||
$elem::$default => return Ok(None),
|
$elem::$default => return Ok(None),
|
||||||
$($elem::$a => $b),+
|
$($elem::$a => $b),+
|
||||||
})))
|
})))
|
||||||
|
|
@ -219,17 +223,17 @@ macro_rules! generate_attribute {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl ::xso::IntoXmlText for $elem {
|
impl ::xso::AsXmlText for $elem {
|
||||||
fn into_xml_text(self) -> Result<String, xso::error::Error> {
|
fn as_xml_text(&self) -> Result<::std::borrow::Cow<'_, str>, xso::error::Error> {
|
||||||
match self {
|
match self {
|
||||||
Self::True => Ok("true".to_owned()),
|
Self::True => Ok(::std::borrow::Cow::Borrowed("true")),
|
||||||
Self::False => Ok("false".to_owned()),
|
Self::False => Ok(::std::borrow::Cow::Borrowed("false")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn into_optional_xml_text(self) -> Result<Option<String>, xso::error::Error> {
|
fn as_optional_xml_text(&self) -> Result<Option<::std::borrow::Cow<'_, str>>, xso::error::Error> {
|
||||||
match self {
|
match self {
|
||||||
Self::True => Ok(Some("true".to_owned())),
|
Self::True => Ok(Some(::std::borrow::Cow::Borrowed("true"))),
|
||||||
Self::False => Ok(None),
|
Self::False => Ok(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -435,9 +439,9 @@ macro_rules! generate_id {
|
||||||
Ok(Self(s))
|
Ok(Self(s))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl ::xso::IntoXmlText for $elem {
|
impl ::xso::AsXmlText for $elem {
|
||||||
fn into_xml_text(self) ->Result<String, xso::error::Error> {
|
fn as_xml_text(&self) ->Result<::std::borrow::Cow<'_, str>, xso::error::Error> {
|
||||||
Ok(self.0)
|
Ok(::std::borrow::Cow::Borrowed(self.0.as_str()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl ::minidom::IntoAttributeValue for $elem {
|
impl ::minidom::IntoAttributeValue for $elem {
|
||||||
|
|
@ -803,11 +807,11 @@ macro_rules! generate_element {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ::xso::IntoXml for $elem {
|
impl ::xso::AsXml for $elem {
|
||||||
type EventIter = ::xso::minidom_compat::IntoEventsViaElement;
|
type ItemIter<'x> = ::xso::minidom_compat::AsItemsViaElement<'x>;
|
||||||
|
|
||||||
fn into_event_iter(self) -> Result<Self::EventIter, ::xso::error::Error> {
|
fn as_xml_iter(&self) -> Result<Self::ItemIter<'_>, ::xso::error::Error> {
|
||||||
Self::EventIter::new(self)
|
::xso::minidom_compat::AsItemsViaElement::new(self.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
//! For vCard updates defined in [XEP-0153](https://xmpp.org/extensions/xep-0153.html),
|
//! For vCard updates defined in [XEP-0153](https://xmpp.org/extensions/xep-0153.html),
|
||||||
//! see [`vcard_update`][crate::vcard_update] module.
|
//! see [`vcard_update`][crate::vcard_update] module.
|
||||||
|
|
||||||
use xso::{FromXml, IntoXml};
|
use xso::{AsXml, FromXml};
|
||||||
|
|
||||||
use crate::iq::{IqGetPayload, IqResultPayload, IqSetPayload};
|
use crate::iq::{IqGetPayload, IqResultPayload, IqSetPayload};
|
||||||
use crate::util::text_node_codecs::{Codec, WhitespaceAwareBase64};
|
use crate::util::text_node_codecs::{Codec, WhitespaceAwareBase64};
|
||||||
|
|
@ -33,7 +33,7 @@ generate_element!(
|
||||||
);
|
);
|
||||||
|
|
||||||
/// The type of the photo.
|
/// The type of the photo.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::VCARD, name = "TYPE")]
|
#[xml(namespace = ns::VCARD, name = "TYPE")]
|
||||||
pub struct Type {
|
pub struct Type {
|
||||||
/// The type as a plain text string; at least "image/jpeg", "image/gif" and "image/png" SHOULD be supported.
|
/// The type as a plain text string; at least "image/jpeg", "image/gif" and "image/png" SHOULD be supported.
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
// 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::{FromXml, IntoXml};
|
use xso::{AsXml, FromXml};
|
||||||
|
|
||||||
use crate::iq::{IqGetPayload, IqResultPayload};
|
use crate::iq::{IqGetPayload, IqResultPayload};
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
|
|
@ -13,7 +13,7 @@ use crate::ns;
|
||||||
///
|
///
|
||||||
/// It should only be used in an `<iq type='get'/>`, as it can only
|
/// It should only be used in an `<iq type='get'/>`, as it can only
|
||||||
/// represent the request, and not a result.
|
/// represent the request, and not a result.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::VERSION, name = "query")]
|
#[xml(namespace = ns::VERSION, name = "query")]
|
||||||
pub struct VersionQuery;
|
pub struct VersionQuery;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,14 @@
|
||||||
// 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::{FromXml, IntoXml};
|
use xso::{AsXml, FromXml};
|
||||||
|
|
||||||
use jid::BareJid;
|
use jid::BareJid;
|
||||||
|
|
||||||
use crate::ns;
|
use crate::ns;
|
||||||
|
|
||||||
/// The stream opening for WebSocket.
|
/// The stream opening for WebSocket.
|
||||||
#[derive(FromXml, IntoXml, PartialEq, Debug, Clone)]
|
#[derive(FromXml, AsXml, PartialEq, Debug, Clone)]
|
||||||
#[xml(namespace = ns::WEBSOCKET, name = "open")]
|
#[xml(namespace = ns::WEBSOCKET, name = "open")]
|
||||||
pub struct Open {
|
pub struct Open {
|
||||||
/// The JID of the entity opening this stream.
|
/// The JID of the entity opening this stream.
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ version = "0.0.2"
|
||||||
authors = [
|
authors = [
|
||||||
"Jonas Schäfer <jonas@zombofant.net>",
|
"Jonas Schäfer <jonas@zombofant.net>",
|
||||||
]
|
]
|
||||||
description = "Macro implementation of #[derive(FromXml, IntoXml)]"
|
description = "Macro implementation of #[derive(FromXml, AsXml)]"
|
||||||
homepage = "https://xmpp.rs"
|
homepage = "https://xmpp.rs"
|
||||||
repository = "https://gitlab.com/xmpp-rs/xmpp-rs"
|
repository = "https://gitlab.com/xmpp-rs/xmpp-rs"
|
||||||
keywords = ["xso", "derive", "serialization"]
|
keywords = ["xso", "derive", "serialization"]
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,9 @@ use syn::{spanned::Spanned, *};
|
||||||
|
|
||||||
use crate::error_message::ParentRef;
|
use crate::error_message::ParentRef;
|
||||||
use crate::field::{FieldBuilderPart, FieldDef, FieldIteratorPart, FieldTempInit};
|
use crate::field::{FieldBuilderPart, FieldDef, FieldIteratorPart, FieldTempInit};
|
||||||
use crate::scope::{mangle_member, FromEventsScope, IntoEventsScope};
|
use crate::scope::{mangle_member, AsItemsScope, FromEventsScope};
|
||||||
use crate::state::{FromEventsSubmachine, IntoEventsSubmachine, State};
|
use crate::state::{AsItemsSubmachine, FromEventsSubmachine, State};
|
||||||
use crate::types::qname_ty;
|
use crate::types::{namespace_ty, ncnamestr_cow_ty, phantom_lifetime_ty};
|
||||||
|
|
||||||
/// A struct or enum variant's contents.
|
/// A struct or enum variant's contents.
|
||||||
pub(crate) struct Compound {
|
pub(crate) struct Compound {
|
||||||
|
|
@ -230,58 +230,86 @@ impl Compound {
|
||||||
/// **Important:** The returned submachine is not in functional state!
|
/// **Important:** The returned submachine is not in functional state!
|
||||||
/// It's `init` must be modified so that a variable called `name` of type
|
/// It's `init` must be modified so that a variable called `name` of type
|
||||||
/// `rxml::QName` is in scope.
|
/// `rxml::QName` is in scope.
|
||||||
pub(crate) fn make_into_event_iter_statemachine(
|
pub(crate) fn make_as_item_iter_statemachine(
|
||||||
&self,
|
&self,
|
||||||
input_name: &Path,
|
input_name: &Path,
|
||||||
state_prefix: &str,
|
state_prefix: &str,
|
||||||
) -> Result<IntoEventsSubmachine> {
|
lifetime: &Lifetime,
|
||||||
let scope = IntoEventsScope::new();
|
) -> Result<AsItemsSubmachine> {
|
||||||
let IntoEventsScope { ref attrs, .. } = scope;
|
let scope = AsItemsScope::new(lifetime);
|
||||||
|
|
||||||
let start_element_state_ident = quote::format_ident!("{}StartElement", state_prefix);
|
let element_head_start_state_ident =
|
||||||
let end_element_state_ident = quote::format_ident!("{}EndElement", state_prefix);
|
quote::format_ident!("{}ElementHeadStart", state_prefix);
|
||||||
|
let element_head_end_state_ident = quote::format_ident!("{}ElementHeadEnd", state_prefix);
|
||||||
|
let element_foot_state_ident = quote::format_ident!("{}ElementFoot", state_prefix);
|
||||||
let name_ident = quote::format_ident!("name");
|
let name_ident = quote::format_ident!("name");
|
||||||
|
let ns_ident = quote::format_ident!("ns");
|
||||||
|
let dummy_ident = quote::format_ident!("dummy");
|
||||||
let mut states = Vec::new();
|
let mut states = Vec::new();
|
||||||
|
|
||||||
let mut init_body = TokenStream::default();
|
|
||||||
let mut destructure = TokenStream::default();
|
let mut destructure = TokenStream::default();
|
||||||
let mut start_init = TokenStream::default();
|
let mut start_init = TokenStream::default();
|
||||||
|
|
||||||
states.push(
|
states.push(
|
||||||
State::new(start_element_state_ident.clone())
|
State::new(element_head_start_state_ident.clone())
|
||||||
.with_field(&name_ident, &qname_ty(Span::call_site())),
|
.with_field(&dummy_ident, &phantom_lifetime_ty(lifetime.clone()))
|
||||||
|
.with_field(&ns_ident, &namespace_ty(Span::call_site()))
|
||||||
|
.with_field(
|
||||||
|
&name_ident,
|
||||||
|
&ncnamestr_cow_ty(Span::call_site(), lifetime.clone()),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut element_head_end_idx = states.len();
|
||||||
|
states.push(
|
||||||
|
State::new(element_head_end_state_ident.clone()).with_impl(quote! {
|
||||||
|
::core::option::Option::Some(::xso::Item::ElementHeadEnd)
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
for (i, field) in self.fields.iter().enumerate() {
|
for (i, field) in self.fields.iter().enumerate() {
|
||||||
let member = field.member();
|
let member = field.member();
|
||||||
let bound_name = mangle_member(member);
|
let bound_name = mangle_member(member);
|
||||||
let part = field.make_iterator_part(&scope, &bound_name)?;
|
let part = field.make_iterator_part(&bound_name)?;
|
||||||
let state_name = quote::format_ident!("{}Field{}", state_prefix, i);
|
let state_name = quote::format_ident!("{}Field{}", state_prefix, i);
|
||||||
|
let ty = scope.borrow(field.ty().clone());
|
||||||
|
|
||||||
match part {
|
match part {
|
||||||
FieldIteratorPart::Header { setter } => {
|
FieldIteratorPart::Header { generator } => {
|
||||||
|
// we have to make sure that we carry our data around in
|
||||||
|
// all the previous states.
|
||||||
|
for state in &mut states[..element_head_end_idx] {
|
||||||
|
state.add_field(&bound_name, &ty);
|
||||||
|
}
|
||||||
|
states.insert(
|
||||||
|
element_head_end_idx,
|
||||||
|
State::new(state_name)
|
||||||
|
.with_field(&bound_name, &ty)
|
||||||
|
.with_impl(quote! {
|
||||||
|
#generator
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
element_head_end_idx += 1;
|
||||||
|
|
||||||
destructure.extend(quote! {
|
destructure.extend(quote! {
|
||||||
#member: #bound_name,
|
#member: ref #bound_name,
|
||||||
});
|
});
|
||||||
init_body.extend(setter);
|
|
||||||
start_init.extend(quote! {
|
start_init.extend(quote! {
|
||||||
#bound_name,
|
#bound_name,
|
||||||
});
|
});
|
||||||
states[0].add_field(&bound_name, field.ty());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FieldIteratorPart::Text { generator } => {
|
FieldIteratorPart::Text { generator } => {
|
||||||
// we have to make sure that we carry our data around in
|
// we have to make sure that we carry our data around in
|
||||||
// all the previous states.
|
// all the previous states.
|
||||||
for state in states.iter_mut() {
|
for state in states.iter_mut() {
|
||||||
state.add_field(&bound_name, field.ty());
|
state.add_field(&bound_name, &ty);
|
||||||
}
|
}
|
||||||
states.push(
|
states.push(
|
||||||
State::new(state_name)
|
State::new(state_name)
|
||||||
.with_field(&bound_name, field.ty())
|
.with_field(&bound_name, &ty)
|
||||||
.with_impl(quote! {
|
.with_impl(quote! {
|
||||||
#generator.map(|value| ::xso::exports::rxml::Event::Text(
|
#generator.map(|value| ::xso::Item::Text(
|
||||||
::xso::exports::rxml::parser::EventMetrics::zero(),
|
|
||||||
value,
|
value,
|
||||||
))
|
))
|
||||||
}),
|
}),
|
||||||
|
|
@ -298,32 +326,27 @@ impl Compound {
|
||||||
|
|
||||||
states[0].set_impl(quote! {
|
states[0].set_impl(quote! {
|
||||||
{
|
{
|
||||||
let mut #attrs = ::xso::exports::rxml::AttrMap::new();
|
::core::option::Option::Some(::xso::Item::ElementHeadStart(
|
||||||
#init_body
|
#ns_ident,
|
||||||
::core::option::Option::Some(::xso::exports::rxml::Event::StartElement(
|
|
||||||
::xso::exports::rxml::parser::EventMetrics::zero(),
|
|
||||||
#name_ident,
|
#name_ident,
|
||||||
#attrs,
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
states.push(
|
states.push(
|
||||||
State::new(end_element_state_ident.clone()).with_impl(quote! {
|
State::new(element_foot_state_ident.clone()).with_impl(quote! {
|
||||||
::core::option::Option::Some(::xso::exports::rxml::Event::EndElement(
|
::core::option::Option::Some(::xso::Item::ElementFoot)
|
||||||
::xso::exports::rxml::parser::EventMetrics::zero(),
|
|
||||||
))
|
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(IntoEventsSubmachine {
|
Ok(AsItemsSubmachine {
|
||||||
defs: TokenStream::default(),
|
defs: TokenStream::default(),
|
||||||
states,
|
states,
|
||||||
destructure: quote! {
|
destructure: quote! {
|
||||||
#input_name { #destructure }
|
#input_name { #destructure }
|
||||||
},
|
},
|
||||||
init: quote! {
|
init: quote! {
|
||||||
Self::#start_element_state_ident { #name_ident, #start_init }
|
Self::#element_head_start_state_ident { #dummy_ident: ::std::marker::PhantomData, #name_ident: name.1, #ns_ident: name.0, #start_init }
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,9 @@ use rxml_validation::NcName;
|
||||||
|
|
||||||
use crate::error_message::{self, ParentRef};
|
use crate::error_message::{self, ParentRef};
|
||||||
use crate::meta::{Flag, NameRef, NamespaceRef, XmlFieldMeta};
|
use crate::meta::{Flag, NameRef, NamespaceRef, XmlFieldMeta};
|
||||||
use crate::scope::{FromEventsScope, IntoEventsScope};
|
use crate::scope::FromEventsScope;
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
default_fn, from_xml_text_fn, into_optional_xml_text_fn, into_xml_text_fn, string_ty,
|
as_optional_xml_text_fn, as_xml_text_fn, default_fn, from_xml_text_fn, string_ty,
|
||||||
text_codec_decode_fn, text_codec_encode_fn,
|
text_codec_decode_fn, text_codec_encode_fn,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -69,13 +69,12 @@ pub(crate) enum FieldBuilderPart {
|
||||||
pub(crate) enum FieldIteratorPart {
|
pub(crate) enum FieldIteratorPart {
|
||||||
/// The field is emitted as part of StartElement.
|
/// The field is emitted as part of StartElement.
|
||||||
Header {
|
Header {
|
||||||
/// A sequence of statements which updates the temporary variables
|
/// An expression which consumes the field's value and returns a
|
||||||
/// during the StartElement event's construction, consuming the
|
/// `Item`.
|
||||||
/// field's value.
|
generator: TokenStream,
|
||||||
setter: TokenStream,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/// The field is emitted as text event.
|
/// The field is emitted as text item.
|
||||||
Text {
|
Text {
|
||||||
/// An expression which consumes the field's value and returns a
|
/// An expression which consumes the field's value and returns a
|
||||||
/// String, which is then emitted as text data.
|
/// String, which is then emitted as text data.
|
||||||
|
|
@ -295,19 +294,13 @@ impl FieldDef {
|
||||||
///
|
///
|
||||||
/// `bound_name` must be the name to which the field's value is bound in
|
/// `bound_name` must be the name to which the field's value is bound in
|
||||||
/// the iterator code.
|
/// the iterator code.
|
||||||
pub(crate) fn make_iterator_part(
|
pub(crate) fn make_iterator_part(&self, bound_name: &Ident) -> Result<FieldIteratorPart> {
|
||||||
&self,
|
|
||||||
scope: &IntoEventsScope,
|
|
||||||
bound_name: &Ident,
|
|
||||||
) -> Result<FieldIteratorPart> {
|
|
||||||
match self.kind {
|
match self.kind {
|
||||||
FieldKind::Attribute {
|
FieldKind::Attribute {
|
||||||
ref xml_name,
|
ref xml_name,
|
||||||
ref xml_namespace,
|
ref xml_namespace,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let IntoEventsScope { ref attrs, .. } = scope;
|
|
||||||
|
|
||||||
let xml_namespace = match xml_namespace {
|
let xml_namespace = match xml_namespace {
|
||||||
Some(v) => quote! { ::xso::exports::rxml::Namespace::from(#v) },
|
Some(v) => quote! { ::xso::exports::rxml::Namespace::from(#v) },
|
||||||
None => quote! {
|
None => quote! {
|
||||||
|
|
@ -315,16 +308,13 @@ impl FieldDef {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let into_optional_xml_text = into_optional_xml_text_fn(self.ty.clone());
|
let as_optional_xml_text = as_optional_xml_text_fn(self.ty.clone());
|
||||||
|
|
||||||
Ok(FieldIteratorPart::Header {
|
Ok(FieldIteratorPart::Header {
|
||||||
// This is a neat little trick:
|
generator: quote! {
|
||||||
// Option::from(x) converts x to an Option<T> *unless* it
|
#as_optional_xml_text(#bound_name)?.map(|#bound_name| ::xso::Item::Attribute(
|
||||||
// already is an Option<_>.
|
|
||||||
setter: quote! {
|
|
||||||
#into_optional_xml_text(#bound_name)?.and_then(|#bound_name| #attrs.insert(
|
|
||||||
#xml_namespace,
|
#xml_namespace,
|
||||||
#xml_name.to_owned(),
|
::std::borrow::Cow::Borrowed(#xml_name),
|
||||||
#bound_name,
|
#bound_name,
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
|
|
@ -338,8 +328,8 @@ impl FieldDef {
|
||||||
quote! { #encode(#bound_name)? }
|
quote! { #encode(#bound_name)? }
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
let into_xml_text = into_xml_text_fn(self.ty.clone());
|
let as_xml_text = as_xml_text_fn(self.ty.clone());
|
||||||
quote! { ::core::option::Option::Some(#into_xml_text(#bound_name)?) }
|
quote! { ::core::option::Option::Some(#as_xml_text(#bound_name)?) }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -111,26 +111,27 @@ pub fn from_xml(input: RawTokenStream) -> RawTokenStream {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate a `xso::IntoXml` implementation for the given item, or fail with
|
/// Generate a `xso::AsXml` implementation for the given item, or fail with
|
||||||
/// a proper compiler error.
|
/// a proper compiler error.
|
||||||
fn into_xml_impl(input: Item) -> Result<TokenStream> {
|
fn as_xml_impl(input: Item) -> Result<TokenStream> {
|
||||||
let (vis, ident, def) = parse_struct(input)?;
|
let (vis, ident, def) = parse_struct(input)?;
|
||||||
|
|
||||||
let structs::IntoXmlParts {
|
let structs::AsXmlParts {
|
||||||
defs,
|
defs,
|
||||||
into_event_iter_body,
|
as_xml_iter_body,
|
||||||
event_iter_ty_ident,
|
item_iter_ty_lifetime,
|
||||||
} = def.make_into_event_iter(&vis)?;
|
item_iter_ty,
|
||||||
|
} = def.make_as_xml_iter(&vis)?;
|
||||||
|
|
||||||
#[cfg_attr(not(feature = "minidom"), allow(unused_mut))]
|
#[cfg_attr(not(feature = "minidom"), allow(unused_mut))]
|
||||||
let mut result = quote! {
|
let mut result = quote! {
|
||||||
#defs
|
#defs
|
||||||
|
|
||||||
impl ::xso::IntoXml for #ident {
|
impl ::xso::AsXml for #ident {
|
||||||
type EventIter = #event_iter_ty_ident;
|
type ItemIter<#item_iter_ty_lifetime> = #item_iter_ty;
|
||||||
|
|
||||||
fn into_event_iter(self) -> ::core::result::Result<Self::EventIter, ::xso::error::Error> {
|
fn as_xml_iter(&self) -> ::core::result::Result<Self::ItemIter<'_>, ::xso::error::Error> {
|
||||||
#into_event_iter_body
|
#as_xml_iter_body
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -162,15 +163,15 @@ fn into_xml_impl(input: Item) -> Result<TokenStream> {
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Macro to derive a `xso::IntoXml` implementation on a type.
|
/// Macro to derive a `xso::AsXml` implementation on a type.
|
||||||
///
|
///
|
||||||
/// The user-facing documentation for this macro lives in the `xso` crate.
|
/// The user-facing documentation for this macro lives in the `xso` crate.
|
||||||
#[proc_macro_derive(IntoXml, attributes(xml))]
|
#[proc_macro_derive(AsXml, attributes(xml))]
|
||||||
pub fn into_xml(input: RawTokenStream) -> RawTokenStream {
|
pub fn as_xml(input: RawTokenStream) -> RawTokenStream {
|
||||||
// Shim wrapper around `into_xml_impl` which converts any errors into
|
// Shim wrapper around `as_xml_impl` which converts any errors into
|
||||||
// actual compiler errors within the resulting token stream.
|
// actual compiler errors within the resulting token stream.
|
||||||
let item = syn::parse_macro_input!(input as Item);
|
let item = syn::parse_macro_input!(input as Item);
|
||||||
match into_xml_impl(item) {
|
match as_xml_impl(item) {
|
||||||
Ok(v) => v.into(),
|
Ok(v) => v.into(),
|
||||||
Err(e) => e.into_compile_error().into(),
|
Err(e) => e.into_compile_error().into(),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@
|
||||||
use proc_macro2::Span;
|
use proc_macro2::Span;
|
||||||
use syn::*;
|
use syn::*;
|
||||||
|
|
||||||
|
use crate::types::ref_ty;
|
||||||
|
|
||||||
/// Container struct for various identifiers used throughout the parser code.
|
/// Container struct for various identifiers used throughout the parser code.
|
||||||
///
|
///
|
||||||
/// This struct is passed around from the [`crate::compound::Compound`]
|
/// This struct is passed around from the [`crate::compound::Compound`]
|
||||||
|
|
@ -80,19 +82,24 @@ impl FromEventsScope {
|
||||||
/// same page about which identifiers are used for what.
|
/// same page about which identifiers are used for what.
|
||||||
///
|
///
|
||||||
/// See [`FromEventsScope`] for recommendations on the usage.
|
/// See [`FromEventsScope`] for recommendations on the usage.
|
||||||
pub(crate) struct IntoEventsScope {
|
pub(crate) struct AsItemsScope {
|
||||||
/// Accesses the `AttrMap` from code in
|
/// Lifetime for data borrowed by the implementation.
|
||||||
/// [`crate::field::FieldIteratorPart::Header`].
|
pub(crate) lifetime: Lifetime,
|
||||||
pub(crate) attrs: Ident,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IntoEventsScope {
|
impl AsItemsScope {
|
||||||
/// Create a fresh scope with all necessary identifiers.
|
/// Create a fresh scope with all necessary identifiers.
|
||||||
pub(crate) fn new() -> Self {
|
pub(crate) fn new(lifetime: &Lifetime) -> Self {
|
||||||
Self {
|
Self {
|
||||||
attrs: Ident::new("attrs", Span::call_site()),
|
lifetime: lifetime.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a reference to `ty`, borrowed for the lifetime of the AsXml
|
||||||
|
/// impl.
|
||||||
|
pub(crate) fn borrow(&self, ty: Type) -> Type {
|
||||||
|
ref_ty(ty, self.lifetime.clone())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn mangle_member(member: &Member) -> Ident {
|
pub(crate) fn mangle_member(member: &Member) -> Ident {
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ impl State {
|
||||||
/// the `advance` implementation of the state machine.
|
/// the `advance` implementation of the state machine.
|
||||||
///
|
///
|
||||||
/// See [`FromEventsStateMachine::advance_match_arms`] and
|
/// See [`FromEventsStateMachine::advance_match_arms`] and
|
||||||
/// [`IntoEventsSubmachine::compile`] for the respective
|
/// [`AsItemsSubmachine::compile`] for the respective
|
||||||
/// requirements on the implementations.
|
/// requirements on the implementations.
|
||||||
pub(crate) fn with_impl(mut self, body: TokenStream) -> Self {
|
pub(crate) fn with_impl(mut self, body: TokenStream) -> Self {
|
||||||
self.advance_body = body;
|
self.advance_body = body;
|
||||||
|
|
@ -171,12 +171,12 @@ impl FromEventsSubmachine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A partial [`IntoEventsStateMachine`] which only covers the builder for a
|
/// A partial [`AsItemsStateMachine`] which only covers the builder for a
|
||||||
/// single compound.
|
/// single compound.
|
||||||
///
|
///
|
||||||
/// See [`IntoEventsStateMachine`] for more information on the state machines
|
/// See [`AsItemsStateMachine`] for more information on the state machines
|
||||||
/// in general.
|
/// in general.
|
||||||
pub(crate) struct IntoEventsSubmachine {
|
pub(crate) struct AsItemsSubmachine {
|
||||||
/// Additional items necessary for the statemachine.
|
/// Additional items necessary for the statemachine.
|
||||||
pub(crate) defs: TokenStream,
|
pub(crate) defs: TokenStream,
|
||||||
|
|
||||||
|
|
@ -194,7 +194,7 @@ pub(crate) struct IntoEventsSubmachine {
|
||||||
pub(crate) init: TokenStream,
|
pub(crate) init: TokenStream,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IntoEventsSubmachine {
|
impl AsItemsSubmachine {
|
||||||
/// Convert a partial state machine into a full state machine.
|
/// Convert a partial state machine into a full state machine.
|
||||||
///
|
///
|
||||||
/// This converts the abstract [`State`] items into token
|
/// This converts the abstract [`State`] items into token
|
||||||
|
|
@ -202,13 +202,13 @@ impl IntoEventsSubmachine {
|
||||||
/// definitions and the match arms), rendering them effectively immutable.
|
/// definitions and the match arms), rendering them effectively immutable.
|
||||||
///
|
///
|
||||||
/// This requires that the [`State::advance_body`] token streams evaluate
|
/// This requires that the [`State::advance_body`] token streams evaluate
|
||||||
/// to an `Option<rxml::Event>`. If it evaluates to `Some(.)`, that is
|
/// to an `Option<Item>`. If it evaluates to `Some(.)`, that is
|
||||||
/// emitted from the iterator. If it evaluates to `None`, the `advance`
|
/// emitted from the iterator. If it evaluates to `None`, the `advance`
|
||||||
/// implementation is called again.
|
/// implementation is called again.
|
||||||
///
|
///
|
||||||
/// Each state implementation is augmented to also enter the next state,
|
/// Each state implementation is augmented to also enter the next state,
|
||||||
/// causing the iterator to terminate eventually.
|
/// causing the iterator to terminate eventually.
|
||||||
pub(crate) fn compile(self) -> IntoEventsStateMachine {
|
pub(crate) fn compile(self) -> AsItemsStateMachine {
|
||||||
let mut state_defs = TokenStream::default();
|
let mut state_defs = TokenStream::default();
|
||||||
let mut advance_match_arms = TokenStream::default();
|
let mut advance_match_arms = TokenStream::default();
|
||||||
|
|
||||||
|
|
@ -227,13 +227,13 @@ impl IntoEventsSubmachine {
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
quote! {
|
quote! {
|
||||||
::core::result::Result::Ok((::core::option::Option::Some(Self::#next_name { #construct_next }), event))
|
::core::result::Result::Ok((::core::option::Option::Some(Self::#next_name { #construct_next }), item))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// final state -> exit the state machine
|
// final state -> exit the state machine
|
||||||
None => {
|
None => {
|
||||||
quote! {
|
quote! {
|
||||||
::core::result::Result::Ok((::core::option::Option::None, event))
|
::core::result::Result::Ok((::core::option::Option::None, item))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -244,17 +244,17 @@ impl IntoEventsSubmachine {
|
||||||
|
|
||||||
advance_match_arms.extend(quote! {
|
advance_match_arms.extend(quote! {
|
||||||
Self::#name { #destructure } => {
|
Self::#name { #destructure } => {
|
||||||
let event = #advance_body;
|
let item = #advance_body;
|
||||||
#footer
|
#footer
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
IntoEventsStateMachine {
|
AsItemsStateMachine {
|
||||||
defs: self.defs,
|
defs: self.defs,
|
||||||
state_defs,
|
state_defs,
|
||||||
advance_match_arms,
|
advance_match_arms,
|
||||||
variants: vec![IntoEventsEntryPoint {
|
variants: vec![AsItemsEntryPoint {
|
||||||
init: self.init,
|
init: self.init,
|
||||||
destructure: self.destructure,
|
destructure: self.destructure,
|
||||||
}],
|
}],
|
||||||
|
|
@ -281,7 +281,7 @@ pub(crate) struct FromEventsEntryPoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A single variant's entrypoint into the event iterator.
|
/// A single variant's entrypoint into the event iterator.
|
||||||
pub(crate) struct IntoEventsEntryPoint {
|
pub(crate) struct AsItemsEntryPoint {
|
||||||
/// A pattern match which destructures the target type into its parts, for
|
/// A pattern match which destructures the target type into its parts, for
|
||||||
/// use by `init`.
|
/// use by `init`.
|
||||||
destructure: TokenStream,
|
destructure: TokenStream,
|
||||||
|
|
@ -468,7 +468,7 @@ impl FromEventsStateMachine {
|
||||||
/// method. That method consumes the enum value and returns either a new enum
|
/// method. That method consumes the enum value and returns either a new enum
|
||||||
/// value, an error, or the output type of the state machine.
|
/// value, an error, or the output type of the state machine.
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub(crate) struct IntoEventsStateMachine {
|
pub(crate) struct AsItemsStateMachine {
|
||||||
/// Extra items which are needed for the state machine implementation.
|
/// Extra items which are needed for the state machine implementation.
|
||||||
defs: TokenStream,
|
defs: TokenStream,
|
||||||
|
|
||||||
|
|
@ -480,7 +480,7 @@ pub(crate) struct IntoEventsStateMachine {
|
||||||
/// enumeration type.
|
/// enumeration type.
|
||||||
///
|
///
|
||||||
/// Each match arm must either diverge or evaluate to a
|
/// Each match arm must either diverge or evaluate to a
|
||||||
/// `Result<(Option<State>, Option<Event>), xso::error::Error>`, where
|
/// `Result<(Option<State>, Option<Item>), xso::error::Error>`, where
|
||||||
/// where `State` is the state enumeration.
|
/// where `State` is the state enumeration.
|
||||||
///
|
///
|
||||||
/// If `Some(.)` is returned for the event, that event is emitted. If
|
/// If `Some(.)` is returned for the event, that event is emitted. If
|
||||||
|
|
@ -489,7 +489,7 @@ pub(crate) struct IntoEventsStateMachine {
|
||||||
/// field.
|
/// field.
|
||||||
///
|
///
|
||||||
/// If `None` is returned for the `Option<State>`, the iterator
|
/// If `None` is returned for the `Option<State>`, the iterator
|
||||||
/// terminates yielding the `Option<Event>` value directly (even if it is
|
/// terminates yielding the `Option<Item>` value directly (even if it is
|
||||||
/// `None`). After the iterator has terminated, it yields `None`
|
/// `None`). After the iterator has terminated, it yields `None`
|
||||||
/// indefinitely.
|
/// indefinitely.
|
||||||
advance_match_arms: TokenStream,
|
advance_match_arms: TokenStream,
|
||||||
|
|
@ -498,10 +498,10 @@ pub(crate) struct IntoEventsStateMachine {
|
||||||
///
|
///
|
||||||
/// This may only contain more than one element if an enumeration is being
|
/// This may only contain more than one element if an enumeration is being
|
||||||
/// serialised by the resulting state machine.
|
/// serialised by the resulting state machine.
|
||||||
variants: Vec<IntoEventsEntryPoint>,
|
variants: Vec<AsItemsEntryPoint>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IntoEventsStateMachine {
|
impl AsItemsStateMachine {
|
||||||
/// Render the state machine as a token stream.
|
/// Render the state machine as a token stream.
|
||||||
///
|
///
|
||||||
/// The token stream contains the following pieces:
|
/// The token stream contains the following pieces:
|
||||||
|
|
@ -515,7 +515,8 @@ impl IntoEventsStateMachine {
|
||||||
vis: &Visibility,
|
vis: &Visibility,
|
||||||
input_ty: &Type,
|
input_ty: &Type,
|
||||||
state_ty_ident: &Ident,
|
state_ty_ident: &Ident,
|
||||||
event_iter_ty_ident: &Ident,
|
item_iter_ty_lifetime: &Lifetime,
|
||||||
|
item_iter_ty: &Type,
|
||||||
) -> Result<TokenStream> {
|
) -> Result<TokenStream> {
|
||||||
let Self {
|
let Self {
|
||||||
defs,
|
defs,
|
||||||
|
|
@ -525,10 +526,10 @@ impl IntoEventsStateMachine {
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
let input_ty_ref = make_ty_ref(input_ty);
|
let input_ty_ref = make_ty_ref(input_ty);
|
||||||
let docstr = format!("Convert a {0} into XML events.\n\nThis type is generated using the [`macro@xso::IntoXml`] derive macro and implements [`std::iter:Iterator`] for {0}.", input_ty_ref);
|
let docstr = format!("Convert a {0} into XML events.\n\nThis type is generated using the [`macro@xso::AsXml`] derive macro and implements [`std::iter:Iterator`] for {0}.", input_ty_ref);
|
||||||
|
|
||||||
let init_body = if variants.len() == 1 {
|
let init_body = if variants.len() == 1 {
|
||||||
let IntoEventsEntryPoint { destructure, init } = variants.remove(0);
|
let AsItemsEntryPoint { destructure, init } = variants.remove(0);
|
||||||
quote! {
|
quote! {
|
||||||
{
|
{
|
||||||
let #destructure = value;
|
let #destructure = value;
|
||||||
|
|
@ -537,7 +538,7 @@ impl IntoEventsStateMachine {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let mut match_arms = TokenStream::default();
|
let mut match_arms = TokenStream::default();
|
||||||
for IntoEventsEntryPoint { destructure, init } in variants {
|
for AsItemsEntryPoint { destructure, init } in variants {
|
||||||
match_arms.extend(quote! {
|
match_arms.extend(quote! {
|
||||||
#destructure => #init,
|
#destructure => #init,
|
||||||
});
|
});
|
||||||
|
|
@ -553,40 +554,40 @@ impl IntoEventsStateMachine {
|
||||||
Ok(quote! {
|
Ok(quote! {
|
||||||
#defs
|
#defs
|
||||||
|
|
||||||
enum #state_ty_ident {
|
enum #state_ty_ident<#item_iter_ty_lifetime> {
|
||||||
#state_defs
|
#state_defs
|
||||||
}
|
}
|
||||||
|
|
||||||
impl #state_ty_ident {
|
impl<#item_iter_ty_lifetime> #state_ty_ident<#item_iter_ty_lifetime> {
|
||||||
fn advance(mut self) -> ::core::result::Result<(::core::option::Option<Self>, ::core::option::Option<::xso::exports::rxml::Event>), ::xso::error::Error> {
|
fn advance(mut self) -> ::core::result::Result<(::core::option::Option<Self>, ::core::option::Option<::xso::Item<#item_iter_ty_lifetime>>), ::xso::error::Error> {
|
||||||
match self {
|
match self {
|
||||||
#advance_match_arms
|
#advance_match_arms
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new(
|
fn new(
|
||||||
value: #input_ty,
|
value: &#item_iter_ty_lifetime #input_ty,
|
||||||
) -> ::core::result::Result<Self, ::xso::error::Error> {
|
) -> ::core::result::Result<Self, ::xso::error::Error> {
|
||||||
::core::result::Result::Ok(#init_body)
|
::core::result::Result::Ok(#init_body)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc = #docstr]
|
#[doc = #docstr]
|
||||||
#vis struct #event_iter_ty_ident(::core::option::Option<#state_ty_ident>);
|
#vis struct #item_iter_ty(::core::option::Option<#state_ty_ident<#item_iter_ty_lifetime>>);
|
||||||
|
|
||||||
impl ::std::iter::Iterator for #event_iter_ty_ident {
|
impl<#item_iter_ty_lifetime> ::std::iter::Iterator for #item_iter_ty {
|
||||||
type Item = ::core::result::Result<::xso::exports::rxml::Event, ::xso::error::Error>;
|
type Item = ::core::result::Result<::xso::Item<#item_iter_ty_lifetime>, ::xso::error::Error>;
|
||||||
|
|
||||||
fn next(&mut self) -> ::core::option::Option<Self::Item> {
|
fn next(&mut self) -> ::core::option::Option<Self::Item> {
|
||||||
let mut state = self.0.take()?;
|
let mut state = self.0.take()?;
|
||||||
loop {
|
loop {
|
||||||
let (next_state, ev) = match state.advance() {
|
let (next_state, item) = match state.advance() {
|
||||||
::core::result::Result::Ok(v) => v,
|
::core::result::Result::Ok(v) => v,
|
||||||
::core::result::Result::Err(e) => return ::core::option::Option::Some(::core::result::Result::Err(e)),
|
::core::result::Result::Err(e) => return ::core::option::Option::Some(::core::result::Result::Err(e)),
|
||||||
};
|
};
|
||||||
if let ::core::option::Option::Some(ev) = ev {
|
if let ::core::option::Option::Some(item) = item {
|
||||||
self.0 = next_state;
|
self.0 = next_state;
|
||||||
return ::core::option::Option::Some(::core::result::Result::Ok(ev));
|
return ::core::option::Option::Some(::core::result::Result::Ok(item));
|
||||||
}
|
}
|
||||||
// no event, do we have a state?
|
// no event, do we have a state?
|
||||||
if let ::core::option::Option::Some(st) = next_state {
|
if let ::core::option::Option::Some(st) = next_state {
|
||||||
|
|
@ -602,8 +603,8 @@ impl IntoEventsStateMachine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl #event_iter_ty_ident {
|
impl<#item_iter_ty_lifetime> #item_iter_ty {
|
||||||
fn new(value: #input_ty) -> ::core::result::Result<Self, ::xso::error::Error> {
|
fn new(value: &#item_iter_ty_lifetime #input_ty) -> ::core::result::Result<Self, ::xso::error::Error> {
|
||||||
#state_ty_ident::new(value).map(|ok| Self(::core::option::Option::Some(ok)))
|
#state_ty_ident::new(value).map(|ok| Self(::core::option::Option::Some(ok)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
//! Handling of structs
|
//! Handling of structs
|
||||||
|
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::{Span, TokenStream};
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
use syn::*;
|
use syn::*;
|
||||||
|
|
||||||
|
|
@ -25,16 +25,19 @@ pub(crate) struct FromXmlParts {
|
||||||
pub(crate) builder_ty_ident: Ident,
|
pub(crate) builder_ty_ident: Ident,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parts necessary to construct a `::xso::IntoXml` implementation.
|
/// Parts necessary to construct a `::xso::AsXml` implementation.
|
||||||
pub(crate) struct IntoXmlParts {
|
pub(crate) struct AsXmlParts {
|
||||||
/// Additional items necessary for the implementation.
|
/// Additional items necessary for the implementation.
|
||||||
pub(crate) defs: TokenStream,
|
pub(crate) defs: TokenStream,
|
||||||
|
|
||||||
/// The body of the `::xso::IntoXml::into_event_iter` function.
|
/// The body of the `::xso::AsXml::as_xml_iter` function.
|
||||||
pub(crate) into_event_iter_body: TokenStream,
|
pub(crate) as_xml_iter_body: TokenStream,
|
||||||
|
|
||||||
/// The name of the type which is the `::xso::IntoXml::EventIter`.
|
/// The type which is the `::xso::AsXml::ItemIter`.
|
||||||
pub(crate) event_iter_ty_ident: Ident,
|
pub(crate) item_iter_ty: Type,
|
||||||
|
|
||||||
|
/// The lifetime name used in `item_iter_ty`.
|
||||||
|
pub(crate) item_iter_ty_lifetime: Lifetime,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Definition of a struct and how to parse it.
|
/// Definition of a struct and how to parse it.
|
||||||
|
|
@ -55,7 +58,7 @@ pub(crate) struct StructDef {
|
||||||
builder_ty_ident: Ident,
|
builder_ty_ident: Ident,
|
||||||
|
|
||||||
/// Name of the iterator type.
|
/// Name of the iterator type.
|
||||||
event_iter_ty_ident: Ident,
|
item_iter_ty_ident: Ident,
|
||||||
|
|
||||||
/// Flag whether debug mode is enabled.
|
/// Flag whether debug mode is enabled.
|
||||||
debug: bool,
|
debug: bool,
|
||||||
|
|
@ -78,7 +81,7 @@ impl StructDef {
|
||||||
inner: Compound::from_fields(fields)?,
|
inner: Compound::from_fields(fields)?,
|
||||||
target_ty_ident: ident.clone(),
|
target_ty_ident: ident.clone(),
|
||||||
builder_ty_ident: quote::format_ident!("{}FromXmlBuilder", ident),
|
builder_ty_ident: quote::format_ident!("{}FromXmlBuilder", ident),
|
||||||
event_iter_ty_ident: quote::format_ident!("{}IntoXmlIterator", ident),
|
item_iter_ty_ident: quote::format_ident!("{}AsXmlIterator", ident),
|
||||||
debug: meta.debug.is_set(),
|
debug: meta.debug.is_set(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -136,22 +139,53 @@ impl StructDef {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn make_into_event_iter(&self, vis: &Visibility) -> Result<IntoXmlParts> {
|
pub(crate) fn make_as_xml_iter(&self, vis: &Visibility) -> Result<AsXmlParts> {
|
||||||
let xml_namespace = &self.namespace;
|
let xml_namespace = &self.namespace;
|
||||||
let xml_name = &self.name;
|
let xml_name = &self.name;
|
||||||
|
|
||||||
let target_ty_ident = &self.target_ty_ident;
|
let target_ty_ident = &self.target_ty_ident;
|
||||||
let event_iter_ty_ident = &self.event_iter_ty_ident;
|
let item_iter_ty_ident = &self.item_iter_ty_ident;
|
||||||
let state_ty_ident = quote::format_ident!("{}State", event_iter_ty_ident);
|
let item_iter_ty_lifetime = Lifetime {
|
||||||
|
apostrophe: Span::call_site(),
|
||||||
|
ident: Ident::new("xso_proc_as_xml_iter_lifetime", Span::call_site()),
|
||||||
|
};
|
||||||
|
let item_iter_ty = Type::Path(TypePath {
|
||||||
|
qself: None,
|
||||||
|
path: Path {
|
||||||
|
leading_colon: None,
|
||||||
|
segments: [PathSegment {
|
||||||
|
ident: item_iter_ty_ident.clone(),
|
||||||
|
arguments: PathArguments::AngleBracketed(AngleBracketedGenericArguments {
|
||||||
|
colon2_token: None,
|
||||||
|
lt_token: token::Lt {
|
||||||
|
spans: [Span::call_site()],
|
||||||
|
},
|
||||||
|
args: [GenericArgument::Lifetime(item_iter_ty_lifetime.clone())]
|
||||||
|
.into_iter()
|
||||||
|
.collect(),
|
||||||
|
gt_token: token::Gt {
|
||||||
|
spans: [Span::call_site()],
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}]
|
||||||
|
.into_iter()
|
||||||
|
.collect(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
let state_ty_ident = quote::format_ident!("{}State", item_iter_ty_ident);
|
||||||
|
|
||||||
let defs = self
|
let defs = self
|
||||||
.inner
|
.inner
|
||||||
.make_into_event_iter_statemachine(&target_ty_ident.clone().into(), "Struct")?
|
.make_as_item_iter_statemachine(
|
||||||
|
&target_ty_ident.clone().into(),
|
||||||
|
"Struct",
|
||||||
|
&item_iter_ty_lifetime,
|
||||||
|
)?
|
||||||
.with_augmented_init(|init| {
|
.with_augmented_init(|init| {
|
||||||
quote! {
|
quote! {
|
||||||
let name = (
|
let name = (
|
||||||
::xso::exports::rxml::Namespace::from(#xml_namespace),
|
::xso::exports::rxml::Namespace::from(#xml_namespace),
|
||||||
#xml_name.into(),
|
::std::borrow::Cow::Borrowed(#xml_name),
|
||||||
);
|
);
|
||||||
#init
|
#init
|
||||||
}
|
}
|
||||||
|
|
@ -165,15 +199,17 @@ impl StructDef {
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
&state_ty_ident,
|
&state_ty_ident,
|
||||||
event_iter_ty_ident,
|
&item_iter_ty_lifetime,
|
||||||
|
&item_iter_ty,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(IntoXmlParts {
|
Ok(AsXmlParts {
|
||||||
defs,
|
defs,
|
||||||
into_event_iter_body: quote! {
|
as_xml_iter_body: quote! {
|
||||||
#event_iter_ty_ident::new(self)
|
#item_iter_ty_ident::new(self)
|
||||||
},
|
},
|
||||||
event_iter_ty_ident: event_iter_ty_ident.clone(),
|
item_iter_ty,
|
||||||
|
item_iter_ty_lifetime,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,8 @@
|
||||||
use proc_macro2::Span;
|
use proc_macro2::Span;
|
||||||
use syn::{spanned::Spanned, *};
|
use syn::{spanned::Spanned, *};
|
||||||
|
|
||||||
/// Construct a [`syn::Type`] referring to `::xso::exports::rxml::QName`.
|
/// Construct a [`syn::Type`] referring to `::xso::exports::rxml::Namespace`.
|
||||||
pub(crate) fn qname_ty(span: Span) -> Type {
|
pub(crate) fn namespace_ty(span: Span) -> Type {
|
||||||
Type::Path(TypePath {
|
Type::Path(TypePath {
|
||||||
qself: None,
|
qself: None,
|
||||||
path: Path {
|
path: Path {
|
||||||
|
|
@ -31,7 +31,7 @@ pub(crate) fn qname_ty(span: Span) -> Type {
|
||||||
arguments: PathArguments::None,
|
arguments: PathArguments::None,
|
||||||
},
|
},
|
||||||
PathSegment {
|
PathSegment {
|
||||||
ident: Ident::new("QName", span),
|
ident: Ident::new("Namespace", span),
|
||||||
arguments: PathArguments::None,
|
arguments: PathArguments::None,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
@ -41,6 +41,83 @@ pub(crate) fn qname_ty(span: Span) -> Type {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Construct a [`syn::Type`] referring to `::xso::exports::rxml::NcNameStr`.
|
||||||
|
pub(crate) fn ncnamestr_ty(span: Span) -> Type {
|
||||||
|
Type::Path(TypePath {
|
||||||
|
qself: None,
|
||||||
|
path: Path {
|
||||||
|
leading_colon: Some(syn::token::PathSep {
|
||||||
|
spans: [span, span],
|
||||||
|
}),
|
||||||
|
segments: [
|
||||||
|
PathSegment {
|
||||||
|
ident: Ident::new("xso", span),
|
||||||
|
arguments: PathArguments::None,
|
||||||
|
},
|
||||||
|
PathSegment {
|
||||||
|
ident: Ident::new("exports", span),
|
||||||
|
arguments: PathArguments::None,
|
||||||
|
},
|
||||||
|
PathSegment {
|
||||||
|
ident: Ident::new("rxml", span),
|
||||||
|
arguments: PathArguments::None,
|
||||||
|
},
|
||||||
|
PathSegment {
|
||||||
|
ident: Ident::new("NcNameStr", span),
|
||||||
|
arguments: PathArguments::None,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
.into_iter()
|
||||||
|
.collect(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct a [`syn::Type`] referring to `Cow<#lifetime, #ty>`.
|
||||||
|
pub(crate) fn cow_ty(ty: Type, lifetime: Lifetime) -> Type {
|
||||||
|
let span = ty.span();
|
||||||
|
Type::Path(TypePath {
|
||||||
|
qself: None,
|
||||||
|
path: Path {
|
||||||
|
leading_colon: Some(syn::token::PathSep {
|
||||||
|
spans: [span, span],
|
||||||
|
}),
|
||||||
|
segments: [
|
||||||
|
PathSegment {
|
||||||
|
ident: Ident::new("std", span),
|
||||||
|
arguments: PathArguments::None,
|
||||||
|
},
|
||||||
|
PathSegment {
|
||||||
|
ident: Ident::new("borrow", span),
|
||||||
|
arguments: PathArguments::None,
|
||||||
|
},
|
||||||
|
PathSegment {
|
||||||
|
ident: Ident::new("Cow", span),
|
||||||
|
arguments: PathArguments::AngleBracketed(AngleBracketedGenericArguments {
|
||||||
|
colon2_token: None,
|
||||||
|
lt_token: token::Lt { spans: [span] },
|
||||||
|
args: [
|
||||||
|
GenericArgument::Lifetime(lifetime),
|
||||||
|
GenericArgument::Type(ty),
|
||||||
|
]
|
||||||
|
.into_iter()
|
||||||
|
.collect(),
|
||||||
|
gt_token: token::Gt { spans: [span] },
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
.into_iter()
|
||||||
|
.collect(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct a [`syn::Type`] referring to
|
||||||
|
/// `Cow<#lifetime, ::rxml::NcNameStr>`.
|
||||||
|
pub(crate) fn ncnamestr_cow_ty(ty_span: Span, lifetime: Lifetime) -> Type {
|
||||||
|
cow_ty(ncnamestr_ty(ty_span), lifetime)
|
||||||
|
}
|
||||||
|
|
||||||
/// Construct a [`syn::Expr`] referring to
|
/// Construct a [`syn::Expr`] referring to
|
||||||
/// `<#ty as ::xso::FromXmlText>::from_xml_text`.
|
/// `<#ty as ::xso::FromXmlText>::from_xml_text`.
|
||||||
pub(crate) fn from_xml_text_fn(ty: Type) -> Expr {
|
pub(crate) fn from_xml_text_fn(ty: Type) -> Expr {
|
||||||
|
|
@ -79,8 +156,8 @@ pub(crate) fn from_xml_text_fn(ty: Type) -> Expr {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a [`syn::Expr`] referring to
|
/// Construct a [`syn::Expr`] referring to
|
||||||
/// `<#ty as ::xso::IntoOptionalXmlText>::into_optional_xml_text`.
|
/// `<#ty as ::xso::AsOptionalXmlText>::as_optional_xml_text`.
|
||||||
pub(crate) fn into_optional_xml_text_fn(ty: Type) -> Expr {
|
pub(crate) fn as_optional_xml_text_fn(ty: Type) -> Expr {
|
||||||
let span = ty.span();
|
let span = ty.span();
|
||||||
Expr::Path(ExprPath {
|
Expr::Path(ExprPath {
|
||||||
attrs: Vec::new(),
|
attrs: Vec::new(),
|
||||||
|
|
@ -101,11 +178,11 @@ pub(crate) fn into_optional_xml_text_fn(ty: Type) -> Expr {
|
||||||
arguments: PathArguments::None,
|
arguments: PathArguments::None,
|
||||||
},
|
},
|
||||||
PathSegment {
|
PathSegment {
|
||||||
ident: Ident::new("IntoOptionalXmlText", span),
|
ident: Ident::new("AsOptionalXmlText", span),
|
||||||
arguments: PathArguments::None,
|
arguments: PathArguments::None,
|
||||||
},
|
},
|
||||||
PathSegment {
|
PathSegment {
|
||||||
ident: Ident::new("into_optional_xml_text", span),
|
ident: Ident::new("as_optional_xml_text", span),
|
||||||
arguments: PathArguments::None,
|
arguments: PathArguments::None,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
@ -185,8 +262,8 @@ pub(crate) fn string_ty(span: Span) -> Type {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a [`syn::Expr`] referring to
|
/// Construct a [`syn::Expr`] referring to
|
||||||
/// `<#ty as ::xso::IntoXmlText>::into_xml_text`.
|
/// `<#ty as ::xso::AsXmlText>::as_xml_text`.
|
||||||
pub(crate) fn into_xml_text_fn(ty: Type) -> Expr {
|
pub(crate) fn as_xml_text_fn(ty: Type) -> Expr {
|
||||||
let span = ty.span();
|
let span = ty.span();
|
||||||
Expr::Path(ExprPath {
|
Expr::Path(ExprPath {
|
||||||
attrs: Vec::new(),
|
attrs: Vec::new(),
|
||||||
|
|
@ -207,11 +284,11 @@ pub(crate) fn into_xml_text_fn(ty: Type) -> Expr {
|
||||||
arguments: PathArguments::None,
|
arguments: PathArguments::None,
|
||||||
},
|
},
|
||||||
PathSegment {
|
PathSegment {
|
||||||
ident: Ident::new("IntoXmlText", span),
|
ident: Ident::new("AsXmlText", span),
|
||||||
arguments: PathArguments::None,
|
arguments: PathArguments::None,
|
||||||
},
|
},
|
||||||
PathSegment {
|
PathSegment {
|
||||||
ident: Ident::new("into_xml_text", span),
|
ident: Ident::new("as_xml_text", span),
|
||||||
arguments: PathArguments::None,
|
arguments: PathArguments::None,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
@ -293,3 +370,55 @@ pub(crate) fn text_codec_decode_fn(codec_ty: Type, for_ty: Type) -> Expr {
|
||||||
path: ty.path,
|
path: ty.path,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Construct a [`syn::Type`] for `&#lifetime #ty`.
|
||||||
|
pub(crate) fn ref_ty(ty: Type, lifetime: Lifetime) -> Type {
|
||||||
|
let span = ty.span();
|
||||||
|
Type::Reference(TypeReference {
|
||||||
|
and_token: token::And { spans: [span] },
|
||||||
|
lifetime: Some(lifetime),
|
||||||
|
mutability: None,
|
||||||
|
elem: Box::new(ty),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct a [`syn::Type`] referring to
|
||||||
|
/// `::std::marker::PhantomData<&#lifetime ()>`.
|
||||||
|
pub(crate) fn phantom_lifetime_ty(lifetime: Lifetime) -> Type {
|
||||||
|
let span = lifetime.span();
|
||||||
|
let dummy = Type::Tuple(TypeTuple {
|
||||||
|
paren_token: token::Paren::default(),
|
||||||
|
elems: punctuated::Punctuated::default(),
|
||||||
|
});
|
||||||
|
Type::Path(TypePath {
|
||||||
|
qself: None,
|
||||||
|
path: Path {
|
||||||
|
leading_colon: Some(syn::token::PathSep {
|
||||||
|
spans: [span, span],
|
||||||
|
}),
|
||||||
|
segments: [
|
||||||
|
PathSegment {
|
||||||
|
ident: Ident::new("std", span),
|
||||||
|
arguments: PathArguments::None,
|
||||||
|
},
|
||||||
|
PathSegment {
|
||||||
|
ident: Ident::new("marker", span),
|
||||||
|
arguments: PathArguments::None,
|
||||||
|
},
|
||||||
|
PathSegment {
|
||||||
|
ident: Ident::new("PhantomData", span),
|
||||||
|
arguments: PathArguments::AngleBracketed(AngleBracketedGenericArguments {
|
||||||
|
colon2_token: None,
|
||||||
|
lt_token: token::Lt { spans: [span] },
|
||||||
|
args: [GenericArgument::Type(ref_ty(dummy, lifetime))]
|
||||||
|
.into_iter()
|
||||||
|
.collect(),
|
||||||
|
gt_token: token::Gt { spans: [span] },
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
.into_iter()
|
||||||
|
.collect(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# Make a struct or enum parseable from XML
|
# Make a struct or enum parseable from XML
|
||||||
|
|
||||||
This derives the [`FromXml`] trait on a struct or enum. It is the counterpart
|
This derives the [`FromXml`] trait on a struct or enum. It is the counterpart
|
||||||
to [`macro@IntoXml`].
|
to [`macro@AsXml`].
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
|
|
@ -75,7 +75,7 @@ The following mapping types are defined:
|
||||||
|
|
||||||
The `attribute` meta causes the field to be mapped to an XML attribute of the
|
The `attribute` meta causes the field to be mapped to an XML attribute of the
|
||||||
same name. For `FromXml`, the field's type must implement [`FromXmlText`] and
|
same name. For `FromXml`, the field's type must implement [`FromXmlText`] and
|
||||||
for `IntoXml`, the field's type must implement [`IntoOptionalXmlText`].
|
for `AsXml`, the field's type must implement [`AsOptionalXmlText`].
|
||||||
|
|
||||||
The following keys can be used inside the `#[xml(attribute(..))]` meta:
|
The following keys can be used inside the `#[xml(attribute(..))]` meta:
|
||||||
|
|
||||||
|
|
@ -99,7 +99,7 @@ otherwise).
|
||||||
If `default` is specified and the attribute is absent in the source, the value
|
If `default` is specified and the attribute is absent in the source, the value
|
||||||
is generated using [`std::default::Default`], requiring the field type to
|
is generated using [`std::default::Default`], requiring the field type to
|
||||||
implement the `Default` trait for a `FromXml` derivation. `default` has no
|
implement the `Default` trait for a `FromXml` derivation. `default` has no
|
||||||
influence on `IntoXml`.
|
influence on `AsXml`.
|
||||||
|
|
||||||
##### Example
|
##### Example
|
||||||
|
|
||||||
|
|
@ -148,14 +148,14 @@ If `codec` is given, the given `codec` must implement
|
||||||
[`TextCodec<T>`][`TextCodec`] where `T` is the type of the field.
|
[`TextCodec<T>`][`TextCodec`] where `T` is the type of the field.
|
||||||
|
|
||||||
If `codec` is *not* given, the field's type must implement [`FromXmlText`] for
|
If `codec` is *not* given, the field's type must implement [`FromXmlText`] for
|
||||||
`FromXml` and for `IntoXml`, the field's type must implement [`IntoXmlText`].
|
`FromXml` and for `AsXml`, the field's type must implement [`AsXmlText`].
|
||||||
|
|
||||||
The `text` meta also supports a shorthand syntax, `#[xml(text = ..)]`, where
|
The `text` meta also supports a shorthand syntax, `#[xml(text = ..)]`, where
|
||||||
the value is treated as the value for the `codec` key (with optional prefix as
|
the value is treated as the value for the `codec` key (with optional prefix as
|
||||||
described above, and unnamespaced otherwise).
|
described above, and unnamespaced otherwise).
|
||||||
|
|
||||||
Only a single field per struct may be annotated with `#[xml(text)]` at a time,
|
Only a single field per struct may be annotated with `#[xml(text)]` at a time,
|
||||||
to avoid parsing ambiguities. This is also true if only `IntoXml` is derived on
|
to avoid parsing ambiguities. This is also true if only `AsXml` is derived on
|
||||||
a field, for consistency.
|
a field, for consistency.
|
||||||
|
|
||||||
##### Example without codec
|
##### Example without codec
|
||||||
|
|
|
||||||
|
|
@ -49,14 +49,14 @@ pub use xso_proc::FromXml;
|
||||||
|
|
||||||
/// # Make a struct or enum serialisable to XML
|
/// # Make a struct or enum serialisable to XML
|
||||||
///
|
///
|
||||||
/// This derives the [`IntoXml`] trait on a struct or enum. It is the
|
/// This derives the [`AsXml`] trait on a struct or enum. It is the
|
||||||
/// counterpart to [`macro@FromXml`].
|
/// counterpart to [`macro@FromXml`].
|
||||||
///
|
///
|
||||||
/// The attributes necessary and available for the derivation to work are
|
/// The attributes necessary and available for the derivation to work are
|
||||||
/// documented on [`macro@FromXml`].
|
/// documented on [`macro@FromXml`].
|
||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
#[cfg(feature = "macros")]
|
#[cfg(feature = "macros")]
|
||||||
pub use xso_proc::IntoXml;
|
pub use xso_proc::AsXml;
|
||||||
|
|
||||||
/// Trait allowing to consume a struct and iterate its contents as
|
/// Trait allowing to consume a struct and iterate its contents as
|
||||||
/// serialisable [`rxml::Event`] items.
|
/// serialisable [`rxml::Event`] items.
|
||||||
|
|
@ -369,10 +369,10 @@ impl<T: AsXmlText> AsOptionalXmlText for Option<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempt to transform a type implementing [`IntoXml`] into another
|
/// Attempt to transform a type implementing [`AsXml`] into another
|
||||||
/// type which implements [`FromXml`].
|
/// type which implements [`FromXml`].
|
||||||
pub fn transform<T: FromXml, F: IntoXml>(from: F) -> Result<T, self::error::Error> {
|
pub fn transform<T: FromXml, F: AsXml>(from: F) -> Result<T, self::error::Error> {
|
||||||
let mut iter = from.into_event_iter()?;
|
let mut iter = self::rxml_util::ItemToEvent::new(from.as_xml_iter()?);
|
||||||
let (qname, attrs) = match iter.next() {
|
let (qname, attrs) = match iter.next() {
|
||||||
Some(Ok(rxml::Event::StartElement(_, qname, attrs))) => (qname, attrs),
|
Some(Ok(rxml::Event::StartElement(_, qname, attrs))) => (qname, attrs),
|
||||||
Some(Err(e)) => return Err(e),
|
Some(Err(e)) => return Err(e),
|
||||||
|
|
@ -418,8 +418,24 @@ pub fn try_from_element<T: FromXml>(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut iter = from.into_event_iter()?;
|
let mut iter = from.as_xml_iter()?;
|
||||||
iter.next().expect("first event from minidom::Element")?;
|
// consume the element header
|
||||||
|
for item in &mut iter {
|
||||||
|
let item = item?;
|
||||||
|
match item {
|
||||||
|
// discard the element header
|
||||||
|
Item::XmlDeclaration(..) => (),
|
||||||
|
Item::ElementHeadStart(..) => (),
|
||||||
|
Item::Attribute(..) => (),
|
||||||
|
Item::ElementHeadEnd => {
|
||||||
|
// now that the element header is over, we break out
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Item::Text(..) => panic!("text before end of element header"),
|
||||||
|
Item::ElementFoot => panic!("element foot before end of element header"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let iter = self::rxml_util::ItemToEvent::new(iter);
|
||||||
for event in iter {
|
for event in iter {
|
||||||
let event = event?;
|
let event = event?;
|
||||||
if let Some(v) = sink.feed(event)? {
|
if let Some(v) = sink.feed(event)? {
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,7 @@
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use rxml::{Namespace, NcNameStr, XmlVersion};
|
use rxml::{parser::EventMetrics, AttrMap, Event, Namespace, NcName, NcNameStr, XmlVersion};
|
||||||
#[cfg(feature = "minidom")]
|
|
||||||
use rxml::Event;
|
|
||||||
|
|
||||||
/// An encodable item.
|
/// An encodable item.
|
||||||
///
|
///
|
||||||
|
|
@ -164,12 +162,130 @@ impl<I: Iterator<Item = Result<Event, crate::error::Error>>> Iterator for EventT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Iterator adapter which converts an iterator over [`Item`] to
|
||||||
|
/// an iterator over [`Event`][`crate::Event`].
|
||||||
|
///
|
||||||
|
/// As `Event` does not support borrowing data, this iterator copies the data
|
||||||
|
/// from the items on the fly.
|
||||||
|
pub(crate) struct ItemToEvent<I> {
|
||||||
|
inner: I,
|
||||||
|
event_buffer: Option<Event>,
|
||||||
|
elem_buffer: Option<(Namespace, NcName, AttrMap)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'x, I: Iterator<Item = Result<Item<'x>, crate::error::Error>>> ItemToEvent<I> {
|
||||||
|
/// Create a new adapter with `inner` as the source iterator.
|
||||||
|
pub(crate) fn new(inner: I) -> Self {
|
||||||
|
Self {
|
||||||
|
inner,
|
||||||
|
event_buffer: None,
|
||||||
|
elem_buffer: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I> ItemToEvent<I> {
|
||||||
|
fn update<'x>(&mut self, item: Item<'x>) -> Result<Option<Event>, crate::error::Error> {
|
||||||
|
assert!(self.event_buffer.is_none());
|
||||||
|
match item {
|
||||||
|
Item::XmlDeclaration(v) => {
|
||||||
|
assert!(self.elem_buffer.is_none());
|
||||||
|
Ok(Some(Event::XmlDeclaration(EventMetrics::zero(), v)))
|
||||||
|
}
|
||||||
|
Item::ElementHeadStart(ns, name) => {
|
||||||
|
if self.elem_buffer.is_some() {
|
||||||
|
// this is only used with AsXml implementations, so
|
||||||
|
// triggering this is always a coding failure instead of a
|
||||||
|
// runtime error.
|
||||||
|
panic!("got a second ElementHeadStart items without ElementHeadEnd inbetween: ns={:?} name={:?} (state={:?})", ns, name, self.elem_buffer);
|
||||||
|
}
|
||||||
|
self.elem_buffer = Some((ns.to_owned(), name.into_owned(), AttrMap::new()));
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
Item::Attribute(ns, name, value) => {
|
||||||
|
let Some((_, _, attrs)) = self.elem_buffer.as_mut() else {
|
||||||
|
// this is only used with AsXml implementations, so
|
||||||
|
// triggering this is always a coding failure instead of a
|
||||||
|
// runtime error.
|
||||||
|
panic!(
|
||||||
|
"got a second Attribute item without ElementHeadStart: ns={:?}, name={:?}",
|
||||||
|
ns, name
|
||||||
|
);
|
||||||
|
};
|
||||||
|
attrs.insert(ns, name.into_owned(), value.into_owned());
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
Item::ElementHeadEnd => {
|
||||||
|
let Some((ns, name, attrs)) = self.elem_buffer.take() else {
|
||||||
|
// this is only used with AsXml implementations, so
|
||||||
|
// triggering this is always a coding failure instead of a
|
||||||
|
// runtime error.
|
||||||
|
panic!(
|
||||||
|
"got ElementHeadEnd item without ElementHeadStart: {:?}",
|
||||||
|
item
|
||||||
|
);
|
||||||
|
};
|
||||||
|
Ok(Some(Event::StartElement(
|
||||||
|
EventMetrics::zero(),
|
||||||
|
(ns, name),
|
||||||
|
attrs,
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
Item::Text(value) => {
|
||||||
|
if let Some(elem_buffer) = self.elem_buffer.as_ref() {
|
||||||
|
// this is only used with AsXml implementations, so
|
||||||
|
// triggering this is always a coding failure instead of a
|
||||||
|
// runtime error.
|
||||||
|
panic!("got Text after ElementHeadStart but before ElementHeadEnd: Text({:?}) (state = {:?})", value, elem_buffer);
|
||||||
|
}
|
||||||
|
Ok(Some(Event::Text(EventMetrics::zero(), value.into_owned())))
|
||||||
|
}
|
||||||
|
Item::ElementFoot => {
|
||||||
|
let end_ev = Event::EndElement(EventMetrics::zero());
|
||||||
|
let result = if let Some((ns, name, attrs)) = self.elem_buffer.take() {
|
||||||
|
// content-less element
|
||||||
|
self.event_buffer = Some(end_ev);
|
||||||
|
Event::StartElement(EventMetrics::zero(), (ns, name), attrs)
|
||||||
|
} else {
|
||||||
|
end_ev
|
||||||
|
};
|
||||||
|
Ok(Some(result))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'x, I: Iterator<Item = Result<Item<'x>, crate::error::Error>>> Iterator for ItemToEvent<I> {
|
||||||
|
type Item = Result<Event, crate::error::Error>;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
if let Some(event) = self.event_buffer.take() {
|
||||||
|
return Some(Ok(event));
|
||||||
|
}
|
||||||
|
loop {
|
||||||
|
let item = match self.inner.next() {
|
||||||
|
Some(Ok(v)) => v,
|
||||||
|
Some(Err(e)) => return Some(Err(e)),
|
||||||
|
None => return None,
|
||||||
|
};
|
||||||
|
match self.update(item).transpose() {
|
||||||
|
Some(v) => return Some(v),
|
||||||
|
None => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
// we may create an indefinte amount of items for a single event,
|
||||||
|
// so we cannot provide a reasonable upper bound.
|
||||||
|
(self.inner.size_hint().0, None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(all(test, feature = "minidom"))]
|
#[cfg(all(test, feature = "minidom"))]
|
||||||
mod tests_minidom {
|
mod tests_minidom {
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
|
|
||||||
use rxml::{parser::EventMetrics, AttrMap};
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
fn events_to_items<I: Iterator<Item = Event>>(events: I) -> Vec<Item<'static>> {
|
fn events_to_items<I: Iterator<Item = Event>>(events: I) -> Vec<Item<'static>> {
|
||||||
|
|
@ -307,3 +423,144 @@ mod tests_minidom {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use std::convert::TryInto;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
fn items_to_events<'x, I: IntoIterator<Item = Item<'x>>>(
|
||||||
|
items: I,
|
||||||
|
) -> Result<Vec<Event>, crate::error::Error> {
|
||||||
|
let iter = ItemToEvent {
|
||||||
|
inner: items.into_iter().map(|x| Ok(x)),
|
||||||
|
event_buffer: None,
|
||||||
|
elem_buffer: None,
|
||||||
|
};
|
||||||
|
let mut result = Vec::new();
|
||||||
|
for ev in iter {
|
||||||
|
let ev = ev?;
|
||||||
|
result.push(ev);
|
||||||
|
}
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn item_to_event_xml_decl() {
|
||||||
|
let items = vec![Item::XmlDeclaration(XmlVersion::V1_0)];
|
||||||
|
let events = items_to_events(items).expect("item conversion");
|
||||||
|
assert_eq!(events.len(), 1);
|
||||||
|
match events[0] {
|
||||||
|
Event::XmlDeclaration(_, XmlVersion::V1_0) => (),
|
||||||
|
ref other => panic!("unexected event in position 0: {:?}", other),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn item_to_event_simple_empty_element() {
|
||||||
|
let items = vec![
|
||||||
|
Item::ElementHeadStart(Namespace::NONE, Cow::Borrowed("elem".try_into().unwrap())),
|
||||||
|
Item::ElementHeadEnd,
|
||||||
|
Item::ElementFoot,
|
||||||
|
];
|
||||||
|
let events = items_to_events(items).expect("item conversion");
|
||||||
|
assert_eq!(events.len(), 2);
|
||||||
|
match events[0] {
|
||||||
|
Event::StartElement(_, (ref ns, ref name), ref attrs) => {
|
||||||
|
assert_eq!(attrs.len(), 0);
|
||||||
|
assert_eq!(ns, Namespace::none());
|
||||||
|
assert_eq!(name, "elem");
|
||||||
|
}
|
||||||
|
ref other => panic!("unexected event in position 0: {:?}", other),
|
||||||
|
};
|
||||||
|
match events[1] {
|
||||||
|
Event::EndElement(_) => (),
|
||||||
|
ref other => panic!("unexected event in position 1: {:?}", other),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn item_to_event_short_empty_element() {
|
||||||
|
let items = vec![
|
||||||
|
Item::ElementHeadStart(Namespace::NONE, Cow::Borrowed("elem".try_into().unwrap())),
|
||||||
|
Item::ElementFoot,
|
||||||
|
];
|
||||||
|
let events = items_to_events(items).expect("item conversion");
|
||||||
|
assert_eq!(events.len(), 2);
|
||||||
|
match events[0] {
|
||||||
|
Event::StartElement(_, (ref ns, ref name), ref attrs) => {
|
||||||
|
assert_eq!(attrs.len(), 0);
|
||||||
|
assert_eq!(ns, Namespace::none());
|
||||||
|
assert_eq!(name, "elem");
|
||||||
|
}
|
||||||
|
ref other => panic!("unexected event in position 0: {:?}", other),
|
||||||
|
};
|
||||||
|
match events[1] {
|
||||||
|
Event::EndElement(_) => (),
|
||||||
|
ref other => panic!("unexected event in position 1: {:?}", other),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn item_to_event_element_with_text_content() {
|
||||||
|
let items = vec![
|
||||||
|
Item::ElementHeadStart(Namespace::NONE, Cow::Borrowed("elem".try_into().unwrap())),
|
||||||
|
Item::ElementHeadEnd,
|
||||||
|
Item::Text(Cow::Borrowed("Hello World!")),
|
||||||
|
Item::ElementFoot,
|
||||||
|
];
|
||||||
|
let events = items_to_events(items).expect("item conversion");
|
||||||
|
assert_eq!(events.len(), 3);
|
||||||
|
match events[0] {
|
||||||
|
Event::StartElement(_, (ref ns, ref name), ref attrs) => {
|
||||||
|
assert_eq!(attrs.len(), 0);
|
||||||
|
assert_eq!(ns, Namespace::none());
|
||||||
|
assert_eq!(name, "elem");
|
||||||
|
}
|
||||||
|
ref other => panic!("unexected event in position 0: {:?}", other),
|
||||||
|
};
|
||||||
|
match events[1] {
|
||||||
|
Event::Text(_, ref value) => {
|
||||||
|
assert_eq!(value, "Hello World!");
|
||||||
|
}
|
||||||
|
ref other => panic!("unexected event in position 1: {:?}", other),
|
||||||
|
};
|
||||||
|
match events[2] {
|
||||||
|
Event::EndElement(_) => (),
|
||||||
|
ref other => panic!("unexected event in position 2: {:?}", other),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn item_to_event_element_with_attributes() {
|
||||||
|
let items = vec![
|
||||||
|
Item::ElementHeadStart(Namespace::NONE, Cow::Borrowed("elem".try_into().unwrap())),
|
||||||
|
Item::Attribute(
|
||||||
|
Namespace::NONE,
|
||||||
|
Cow::Borrowed("attr".try_into().unwrap()),
|
||||||
|
Cow::Borrowed("value"),
|
||||||
|
),
|
||||||
|
Item::ElementHeadEnd,
|
||||||
|
Item::ElementFoot,
|
||||||
|
];
|
||||||
|
let events = items_to_events(items).expect("item conversion");
|
||||||
|
assert_eq!(events.len(), 2);
|
||||||
|
match events[0] {
|
||||||
|
Event::StartElement(_, (ref ns, ref name), ref attrs) => {
|
||||||
|
assert_eq!(ns, Namespace::none());
|
||||||
|
assert_eq!(name, "elem");
|
||||||
|
assert_eq!(attrs.len(), 1);
|
||||||
|
assert_eq!(
|
||||||
|
attrs.get(Namespace::none(), "attr").map(|x| x.as_str()),
|
||||||
|
Some("value")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
ref other => panic!("unexected event in position 0: {:?}", other),
|
||||||
|
};
|
||||||
|
match events[1] {
|
||||||
|
Event::EndElement(_) => (),
|
||||||
|
ref other => panic!("unexected event in position 2: {:?}", other),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ convert_via_fromstr_and_display! {
|
||||||
/// Represent a way to encode/decode text data into a Rust type.
|
/// Represent a way to encode/decode text data into a Rust type.
|
||||||
///
|
///
|
||||||
/// This trait can be used in scenarios where implementing [`FromXmlText`]
|
/// This trait can be used in scenarios where implementing [`FromXmlText`]
|
||||||
/// and/or [`IntoXmlText`] on a type is not feasible or sensible, such as the
|
/// and/or [`AsXmlText`] on a type is not feasible or sensible, such as the
|
||||||
/// following:
|
/// following:
|
||||||
///
|
///
|
||||||
/// 1. The type originates in a foreign crate, preventing the implementation
|
/// 1. The type originates in a foreign crate, preventing the implementation
|
||||||
|
|
@ -143,7 +143,7 @@ convert_via_fromstr_and_display! {
|
||||||
/// 2. There is more than one way to convert a value to/from XML.
|
/// 2. There is more than one way to convert a value to/from XML.
|
||||||
///
|
///
|
||||||
/// The codec to use for a text can be specified in the attributes understood
|
/// The codec to use for a text can be specified in the attributes understood
|
||||||
/// by `FromXml` and `IntoXml` derive macros. See the documentation of the
|
/// by `FromXml` and `AsXml` derive macros. See the documentation of the
|
||||||
/// [`FromXml`][`macro@crate::FromXml`] derive macro for details.
|
/// [`FromXml`][`macro@crate::FromXml`] derive macro for details.
|
||||||
pub trait TextCodec<T> {
|
pub trait TextCodec<T> {
|
||||||
/// Decode a string value into the type.
|
/// Decode a string value into the type.
|
||||||
|
|
@ -152,7 +152,7 @@ pub trait TextCodec<T> {
|
||||||
/// Encode the type as string value.
|
/// Encode the type as string value.
|
||||||
///
|
///
|
||||||
/// If this returns `None`, the string value is not emitted at all.
|
/// If this returns `None`, the string value is not emitted at all.
|
||||||
fn encode(value: T) -> Result<Option<String>, Error>;
|
fn encode(value: &T) -> Result<Option<Cow<'_, str>>, Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Text codec which does no transform.
|
/// Text codec which does no transform.
|
||||||
|
|
@ -163,8 +163,8 @@ impl TextCodec<String> for Plain {
|
||||||
Ok(s)
|
Ok(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode(value: String) -> Result<Option<String>, Error> {
|
fn encode(value: &String) -> Result<Option<Cow<'_, str>>, Error> {
|
||||||
Ok(Some(value))
|
Ok(Some(Cow::Borrowed(value.as_str())))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -180,9 +180,9 @@ impl TextCodec<Option<String>> for EmptyAsNone {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode(value: Option<String>) -> Result<Option<String>, Error> {
|
fn encode(value: &Option<String>) -> Result<Option<Cow<'_, str>>, Error> {
|
||||||
Ok(match value {
|
Ok(match value.as_ref() {
|
||||||
Some(v) if !v.is_empty() => Some(v),
|
Some(v) if !v.is_empty() => Some(Cow::Borrowed(v.as_str())),
|
||||||
Some(_) | None => None,
|
Some(_) | None => None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -237,8 +237,8 @@ impl<Filter: TextFilter> TextCodec<Vec<u8>> for Base64<Filter> {
|
||||||
.map_err(Error::text_parse_error)
|
.map_err(Error::text_parse_error)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode(value: Vec<u8>) -> Result<Option<String>, Error> {
|
fn encode(value: &Vec<u8>) -> Result<Option<Cow<'_, str>>, Error> {
|
||||||
Ok(Some(StandardBase64Engine.encode(&value)))
|
Ok(Some(Cow::Owned(StandardBase64Engine.encode(&value))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -252,7 +252,11 @@ impl<Filter: TextFilter> TextCodec<Option<Vec<u8>>> for Base64<Filter> {
|
||||||
Ok(Some(Self::decode(s)?))
|
Ok(Some(Self::decode(s)?))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode(decoded: Option<Vec<u8>>) -> Result<Option<String>, Error> {
|
fn encode(decoded: &Option<Vec<u8>>) -> Result<Option<Cow<'_, str>>, Error> {
|
||||||
decoded.map(Self::encode).transpose().map(Option::flatten)
|
decoded
|
||||||
|
.as_ref()
|
||||||
|
.map(Self::encode)
|
||||||
|
.transpose()
|
||||||
|
.map(Option::flatten)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue