xmpp-parsers: Simplify PubSub Item using xso

Now that we can have a single arbitrary payload, we can derive FromXml
and AsXml on the Item.
This commit is contained in:
Emmanuel Gil Peyrot 2024-12-20 19:05:07 +01:00 committed by Jonas Schäfer
commit f63b780089
7 changed files with 55 additions and 115 deletions

View file

@ -4,20 +4,33 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
use xso::{AsXml, FromXml};
use crate::data_forms::DataForm;
use crate::date::DateTime;
use crate::message::MessagePayload;
use crate::ns;
use crate::pubsub::{Item as PubSubItem, ItemId, NodeName, Subscription, SubscriptionId};
use crate::pubsub::{ItemId, NodeName, Subscription, SubscriptionId};
use jid::Jid;
use minidom::Element;
use xso::error::{Error, FromElementError};
/// Event wrapper for a PubSub `<item/>`.
#[derive(Debug, Clone, PartialEq)]
pub struct Item(pub PubSubItem);
/// An event item from a PubSub node.
#[derive(FromXml, AsXml, Debug, Clone, PartialEq)]
#[xml(namespace = ns::PUBSUB_EVENT, name = "item")]
pub struct Item {
/// The identifier for this item, unique per node.
#[xml(attribute(default))]
pub id: Option<ItemId>,
impl_pubsub_item!(Item, PUBSUB_EVENT);
/// The JID of the entity who published this item.
#[xml(attribute(default))]
pub publisher: Option<Jid>,
/// The payload of this item, in an arbitrary namespace.
#[xml(element(default))]
pub payload: Option<Element>,
}
/// Represents an event happening to a PubSub node.
#[derive(Debug, Clone, PartialEq)]

View file

@ -18,7 +18,6 @@ pub use self::event::PubSubEvent;
pub use self::owner::PubSubOwner;
pub use self::pubsub::PubSub;
use jid::Jid;
use minidom::Element;
generate_id!(
@ -77,33 +76,5 @@ generate_attribute!(
}
);
/// An item from a PubSub node.
#[derive(Debug, Clone, PartialEq)]
pub struct Item {
/// The identifier for this item, unique per node.
pub id: Option<ItemId>,
/// The JID of the entity who published this item.
pub publisher: Option<Jid>,
/// The payload of this item, in an arbitrary namespace.
pub payload: Option<Element>,
}
impl Item {
/// Create a new item, accepting only payloads implementing `PubSubPayload`.
pub fn new<P: PubSubPayload>(
id: Option<ItemId>,
publisher: Option<Jid>,
payload: Option<P>,
) -> Item {
Item {
id,
publisher,
payload: payload.map(Into::into),
}
}
}
/// This trait should be implemented on any element which can be included as a PubSub payload.
pub trait PubSubPayload: TryFrom<Element> + Into<Element> {}

View file

@ -14,7 +14,7 @@ use crate::data_forms::DataForm;
use crate::iq::{IqGetPayload, IqResultPayload, IqSetPayload};
use crate::ns;
use crate::pubsub::{
AffiliationAttribute, Item as PubSubItem, NodeName, Subscription, SubscriptionId,
AffiliationAttribute, ItemId, NodeName, PubSubPayload, Subscription, SubscriptionId,
};
use jid::Jid;
use minidom::Element;
@ -111,11 +111,37 @@ impl Items {
}
}
/// Response wrapper for a PubSub `<item/>`.
#[derive(Debug, Clone, PartialEq)]
pub struct Item(pub PubSubItem);
/// A requested item from a PubSub node.
#[derive(FromXml, AsXml, Debug, Clone, PartialEq)]
#[xml(namespace = ns::PUBSUB, name = "item")]
pub struct Item {
/// The identifier for this item, unique per node.
#[xml(attribute(default))]
pub id: Option<ItemId>,
impl_pubsub_item!(Item, PUBSUB);
/// The JID of the entity who published this item.
#[xml(attribute(default))]
pub publisher: Option<Jid>,
/// The payload of this item, in an arbitrary namespace.
#[xml(element(default))]
pub payload: Option<Element>,
}
impl Item {
/// Create a new item, accepting only payloads implementing `PubSubPayload`.
pub fn new<P: PubSubPayload>(
id: Option<ItemId>,
publisher: Option<Jid>,
payload: Option<P>,
) -> Item {
Item {
id,
publisher,
payload: payload.map(Into::into),
}
}
}
/// The options associated to a subscription request.
#[derive(FromXml, AsXml, Debug, PartialEq, Clone)]