diff --git a/parsers/ChangeLog b/parsers/ChangeLog index 726841e8dcd0f5160763dc2291ba0b9b3555f049..2783a2a4552002680d93356cb2446a3180131dcd 100644 --- a/parsers/ChangeLog +++ b/parsers/ChangeLog @@ -1,6 +1,9 @@ Version NEXT: XXXX-YY-ZZ RELEASER * Breaking + - MIX (XEP-0369) has been removed, it has failed to gain any traction in + the XMPP ecosystem and is actively being replaced with better + alternatives based on MUC. - The `alternate_address` field of `xmpp_parsers::stanza_error::StanzaError` has been moved into the corresponding enum variants of the diff --git a/parsers/doap.xml b/parsers/doap.xml index dca2e434b6a103a4b65ca82b6c6d0e0878906810..ad48dbcd89d42b79112d852be1455d0938f84304 100644 --- a/parsers/doap.xml +++ b/parsers/doap.xml @@ -565,7 +565,7 @@ - complete + removed 0.14.3 0.18.0 diff --git a/parsers/src/lib.rs b/parsers/src/lib.rs index 8b1607d3419c764e82d8da68ded45f246aff41d5..76d3b54c49b252cef85b152e5daf67bd71ef20a8 100644 --- a/parsers/src/lib.rs +++ b/parsers/src/lib.rs @@ -251,9 +251,6 @@ pub mod stanza_id; /// XEP-0363: HTTP File Upload pub mod http_upload; -/// XEP-0369: Mediated Information eXchange (MIX) -pub mod mix; - /// XEP-0373: OpenPGP for XMPP pub mod openpgp; diff --git a/parsers/src/mix.rs b/parsers/src/mix.rs deleted file mode 100644 index 7f40f9fbd82e9f0a44598cf551e5a3c4d2e627c9..0000000000000000000000000000000000000000 --- a/parsers/src/mix.rs +++ /dev/null @@ -1,391 +0,0 @@ -// Copyright (c) 2020 Emmanuel Gil Peyrot -// -// 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 -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -// TODO: validate nicks by applying the “nickname” profile of the PRECIS OpaqueString class, as -// defined in RFC 7700. - -use xso::{AsXml, FromXml}; - -use crate::iq::{IqResultPayload, IqSetPayload}; -use crate::message::MessagePayload; -use crate::ns; -use crate::pubsub::{NodeName, PubSubPayload}; -use jid::BareJid; - -generate_id!( - /// The identifier a participant receives when joining a channel. - ParticipantId -); - -impl ParticipantId { - /// Create a new ParticipantId. - pub fn new>(participant: P) -> ParticipantId { - ParticipantId(participant.into()) - } -} - -generate_id!( - /// A MIX channel identifier. - ChannelId -); - -/// Represents a participant in a MIX channel, usually returned on the -/// urn:xmpp:mix:nodes:participants PubSub node. -#[derive(FromXml, AsXml, PartialEq, Debug, Clone)] -#[xml(namespace = ns::MIX_CORE, name = "participant")] -pub struct Participant { - /// The nick of this participant. - #[xml(extract(fields(text)))] - pub nick: String, - - /// The bare JID of this participant. - #[xml(extract(fields(text)))] - pub jid: BareJid, -} - -impl PubSubPayload for Participant {} - -impl Participant { - /// Create a new MIX participant. - pub fn new, N: Into>(jid: J, nick: N) -> Participant { - Participant { - nick: nick.into(), - jid: jid.into(), - } - } -} - -/// A node to subscribe to. -#[derive(FromXml, AsXml, PartialEq, Debug, Clone)] -#[xml(namespace = ns::MIX_CORE, name = "subscribe")] -pub struct Subscribe { - /// The PubSub node to subscribe to. - #[xml(attribute)] - pub node: NodeName, -} - -impl Subscribe { - /// Create a new Subscribe element. - pub fn new>(node: N) -> Subscribe { - Subscribe { - node: NodeName(node.into()), - } - } -} - -/// A request from a user’s server to join a MIX channel. -#[derive(FromXml, AsXml, PartialEq, Debug, Clone)] -#[xml(namespace = ns::MIX_CORE, name = "join")] -pub struct Join { - /// The participant identifier returned by the MIX service on successful join. - #[xml(attribute(default))] - pub id: Option, - - /// The nick requested by the user or set by the service. - #[xml(extract(fields(text)))] - pub nick: String, - - /// Which MIX nodes to subscribe to. - #[xml(child(n = ..))] - pub subscribes: Vec, -} - -impl IqSetPayload for Join {} -impl IqResultPayload for Join {} - -impl Join { - /// Create a new Join element. - pub fn from_nick_and_nodes>(nick: N, nodes: &[&str]) -> Join { - let subscribes = nodes.iter().cloned().map(Subscribe::new).collect(); - Join { - id: None, - nick: nick.into(), - subscribes, - } - } - - /// Sets the JID on this update-subscription. - pub fn with_id>(mut self, id: I) -> Self { - self.id = Some(ParticipantId(id.into())); - self - } -} - -/// Update a given subscription. -#[derive(FromXml, AsXml, PartialEq, Debug, Clone)] -#[xml(namespace = ns::MIX_CORE, name = "update-subscription")] -pub struct UpdateSubscription { - /// The JID of the user to be affected. - // TODO: why is it not a participant id instead? - #[xml(attribute(default))] - pub jid: Option, - - /// The list of additional nodes to subscribe to. - // TODO: what happens when we are already subscribed? Also, how do we unsubscribe from - // just one? - #[xml(child(n = ..))] - pub subscribes: Vec, -} - -impl IqSetPayload for UpdateSubscription {} -impl IqResultPayload for UpdateSubscription {} - -impl UpdateSubscription { - /// Create a new UpdateSubscription element. - pub fn from_nodes(nodes: &[&str]) -> UpdateSubscription { - let subscribes = nodes.iter().cloned().map(Subscribe::new).collect(); - UpdateSubscription { - jid: None, - subscribes, - } - } - - /// Sets the JID on this update-subscription. - pub fn with_jid(mut self, jid: BareJid) -> Self { - self.jid = Some(jid); - self - } -} - -/// Request to leave a given MIX channel. It will automatically unsubscribe the user from all -/// nodes on this channel. -#[derive(FromXml, AsXml, PartialEq, Debug, Clone)] -#[xml(namespace = ns::MIX_CORE, name = "leave")] -pub struct Leave; - -impl IqSetPayload for Leave {} -impl IqResultPayload for Leave {} - -/// A request to change the user’s nick. -#[derive(FromXml, AsXml, PartialEq, Debug, Clone)] -#[xml(namespace = ns::MIX_CORE, name = "setnick")] -pub struct SetNick { - /// The new requested nick. - #[xml(extract(fields(text)))] - pub nick: String, -} - -impl IqSetPayload for SetNick {} -impl IqResultPayload for SetNick {} - -impl SetNick { - /// Create a new SetNick element. - pub fn new>(nick: N) -> SetNick { - SetNick { nick: nick.into() } - } -} - -/// Message payload describing who actually sent the message, since unlike in MUC, all messages -/// are sent from the channel’s JID. -#[derive(FromXml, AsXml, PartialEq, Debug, Clone)] -#[xml(namespace = ns::MIX_CORE, name = "mix")] -pub struct Mix { - /// The nick of the user who said something. - #[xml(extract(fields(text)))] - pub nick: String, - - /// The JID of the user who said something. - #[xml(extract(fields(text)))] - pub jid: BareJid, -} - -impl MessagePayload for Mix {} - -impl Mix { - /// Create a new Mix element. - pub fn new, J: Into>(nick: N, jid: J) -> Mix { - Mix { - nick: nick.into(), - jid: jid.into(), - } - } -} - -/// Create a new MIX channel. -#[derive(FromXml, AsXml, PartialEq, Clone, Debug, Default)] -#[xml(namespace = ns::MIX_CORE, name = "create")] -pub struct Create { - /// The requested channel identifier. - #[xml(attribute(default))] - pub channel: Option, -} - -impl IqSetPayload for Create {} -impl IqResultPayload for Create {} - -impl Create { - /// Create a new ad-hoc Create element. - pub fn new() -> Create { - Create::default() - } - - /// Create a new Create element with a channel identifier. - pub fn from_channel_id>(channel: C) -> Create { - Create { - channel: Some(ChannelId(channel.into())), - } - } -} - -/// Destroy a given MIX channel. -#[derive(FromXml, AsXml, PartialEq, Debug, Clone)] -#[xml(namespace = ns::MIX_CORE, name = "destroy")] -pub struct Destroy { - /// The channel identifier to be destroyed. - #[xml(attribute)] - pub channel: ChannelId, -} - -// TODO: section 7.3.4, example 33, doesn’t mirror the in the iq result unlike every -// other section so far. -impl IqSetPayload for Destroy {} - -impl Destroy { - /// Create a new Destroy element. - pub fn new>(channel: C) -> Destroy { - Destroy { - channel: ChannelId(channel.into()), - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use minidom::Element; - - #[test] - fn participant() { - let elem: Element = "foo@barcoucou" - .parse() - .unwrap(); - let participant = Participant::try_from(elem).unwrap(); - assert_eq!(participant.nick, "coucou"); - assert_eq!(participant.jid.as_str(), "foo@bar"); - } - - #[test] - fn join() { - let elem: Element = "coucou" - .parse() - .unwrap(); - let join = Join::try_from(elem).unwrap(); - assert_eq!(join.nick, "coucou"); - assert_eq!(join.id, None); - assert_eq!(join.subscribes.len(), 2); - assert_eq!(join.subscribes[0].node.0, "urn:xmpp:mix:nodes:messages"); - assert_eq!(join.subscribes[1].node.0, "urn:xmpp:mix:nodes:info"); - } - - #[test] - fn update_subscription() { - let elem: Element = "" - .parse() - .unwrap(); - let update_subscription = UpdateSubscription::try_from(elem).unwrap(); - assert_eq!(update_subscription.jid, None); - assert_eq!(update_subscription.subscribes.len(), 1); - assert_eq!( - update_subscription.subscribes[0].node.0, - "urn:xmpp:mix:nodes:participants" - ); - } - - #[test] - fn leave() { - let elem: Element = "".parse().unwrap(); - Leave::try_from(elem).unwrap(); - } - - #[test] - fn setnick() { - let elem: Element = "coucou" - .parse() - .unwrap(); - let setnick = SetNick::try_from(elem).unwrap(); - assert_eq!(setnick.nick, "coucou"); - } - - #[test] - fn message_mix() { - let elem: Element = - "foo@barcoucou" - .parse() - .unwrap(); - let mix = Mix::try_from(elem).unwrap(); - assert_eq!(mix.nick, "coucou"); - assert_eq!(mix.jid.as_str(), "foo@bar"); - } - - #[test] - fn create() { - let elem: Element = "" - .parse() - .unwrap(); - let create = Create::try_from(elem).unwrap(); - assert_eq!(create.channel.unwrap().0, "coucou"); - - let elem: Element = "".parse().unwrap(); - let create = Create::try_from(elem).unwrap(); - assert_eq!(create.channel, None); - } - - #[test] - fn destroy() { - let elem: Element = "" - .parse() - .unwrap(); - let destroy = Destroy::try_from(elem).unwrap(); - assert_eq!(destroy.channel.0, "coucou"); - } - - #[test] - fn serialise() { - let elem: Element = Join::from_nick_and_nodes("coucou", &["foo", "bar"]).into(); - let xml = String::from(&elem); - assert_eq!(xml, "coucou"); - - let elem: Element = UpdateSubscription::from_nodes(&["foo", "bar"]).into(); - let xml = String::from(&elem); - assert_eq!(xml, ""); - - let elem: Element = Leave.into(); - let xml = String::from(&elem); - assert_eq!(xml, ""); - - let elem: Element = SetNick::new("coucou").into(); - let xml = String::from(&elem); - assert_eq!( - xml, - "coucou" - ); - - let elem: Element = Mix::new("coucou", "coucou@example".parse::().unwrap()).into(); - let xml = String::from(&elem); - assert_eq!( - xml, - "coucoucoucou@example" - ); - - let elem: Element = Create::new().into(); - let xml = String::from(&elem); - assert_eq!(xml, ""); - - let elem: Element = Create::from_channel_id("coucou").into(); - let xml = String::from(&elem); - assert_eq!( - xml, - "" - ); - - let elem: Element = Destroy::new("coucou").into(); - let xml = String::from(&elem); - assert_eq!( - xml, - "" - ); - } -} diff --git a/parsers/src/ns.rs b/parsers/src/ns.rs index ba5552a5b98a57ddb6c8810cc013b740011bba52..64ba8b7992292818bd9fbc6e6b5c4c983619aad3 100644 --- a/parsers/src/ns.rs +++ b/parsers/src/ns.rs @@ -243,23 +243,6 @@ pub const SID: &str = "urn:xmpp:sid:0"; /// XEP-0363: HTTP File Upload pub const HTTP_UPLOAD: &str = "urn:xmpp:http:upload:0"; -/// XEP-0369: Mediated Information eXchange (MIX) -pub const MIX_CORE: &str = "urn:xmpp:mix:core:1"; -/// XEP-0369: Mediated Information eXchange (MIX) -pub const MIX_CORE_SEARCHABLE: &str = "urn:xmpp:mix:core:1#searchable"; -/// XEP-0369: Mediated Information eXchange (MIX) -pub const MIX_CORE_CREATE_CHANNEL: &str = "urn:xmpp:mix:core:1#create-channel"; -/// XEP-0369: Mediated Information eXchange (MIX) -pub const MIX_NODES_PRESENCE: &str = "urn:xmpp:mix:nodes:presence"; -/// XEP-0369: Mediated Information eXchange (MIX) -pub const MIX_NODES_PARTICIPANTS: &str = "urn:xmpp:mix:nodes:participants"; -/// XEP-0369: Mediated Information eXchange (MIX) -pub const MIX_NODES_MESSAGES: &str = "urn:xmpp:mix:nodes:messages"; -/// XEP-0369: Mediated Information eXchange (MIX) -pub const MIX_NODES_CONFIG: &str = "urn:xmpp:mix:nodes:config"; -/// XEP-0369: Mediated Information eXchange (MIX) -pub const MIX_NODES_INFO: &str = "urn:xmpp:mix:nodes:info"; - /// XEP-0373: OpenPGP for XMPP pub const OX: &str = "urn:xmpp:openpgp:0"; /// XEP-0373: OpenPGP for XMPP