pubsub: Make Item common to both pubsub and pubsub#event namespaces.
This commit is contained in:
parent
d60feffc22
commit
d811c10ed3
4 changed files with 85 additions and 92 deletions
|
@ -8,66 +8,16 @@ use crate::data_forms::DataForm;
|
|||
use crate::date::DateTime;
|
||||
use crate::util::error::Error;
|
||||
use crate::ns;
|
||||
use crate::pubsub::{ItemId, NodeName, Subscription, SubscriptionId, PubSubPayload};
|
||||
use crate::pubsub::{ItemId, NodeName, Subscription, SubscriptionId, Item as PubSubItem};
|
||||
use jid::Jid;
|
||||
use minidom::Element;
|
||||
use try_from::TryFrom;
|
||||
|
||||
/// One PubSub item from a node.
|
||||
/// Event wrapper for a PubSub `<item/>`.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Item {
|
||||
/// The identifier for this item, unique per node.
|
||||
pub id: Option<ItemId>,
|
||||
pub struct Item(pub PubSubItem);
|
||||
|
||||
/// The JID of the entity who published this item.
|
||||
pub publisher: Option<Jid>,
|
||||
|
||||
/// The actual content of this item.
|
||||
pub payload: Option<Element>,
|
||||
}
|
||||
|
||||
impl TryFrom<Element> for Item {
|
||||
type Err = Error;
|
||||
|
||||
fn try_from(elem: Element) -> Result<Item, Error> {
|
||||
check_self!(elem, "item", PUBSUB_EVENT);
|
||||
check_no_unknown_attributes!(elem, "item", ["id", "publisher"]);
|
||||
let mut payloads = elem.children().cloned().collect::<Vec<_>>();
|
||||
let payload = payloads.pop();
|
||||
if !payloads.is_empty() {
|
||||
return Err(Error::ParseError(
|
||||
"More than a single payload in item element.",
|
||||
));
|
||||
}
|
||||
Ok(Item {
|
||||
payload,
|
||||
id: get_attr!(elem, "id", optional),
|
||||
publisher: get_attr!(elem, "publisher", optional),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Item> for Element {
|
||||
fn from(item: Item) -> Element {
|
||||
Element::builder("item")
|
||||
.ns(ns::PUBSUB_EVENT)
|
||||
.attr("id", item.id)
|
||||
.attr("publisher", item.publisher)
|
||||
.append(item.payload)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
impl Item {
|
||||
/// Create a new item event, 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(|payload| payload.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl_pubsub_item!(Item, PUBSUB_EVENT);
|
||||
|
||||
/// Represents an event happening to a PubSub node.
|
||||
#[derive(Debug, Clone)]
|
||||
|
|
|
@ -13,6 +13,8 @@ pub mod pubsub;
|
|||
pub use self::event::PubSubEvent;
|
||||
pub use self::pubsub::PubSub;
|
||||
|
||||
use crate::{Jid, Element};
|
||||
|
||||
generate_id!(
|
||||
/// The name of a PubSub node, used to identify it on a JID.
|
||||
NodeName
|
||||
|
@ -46,5 +48,29 @@ generate_attribute!(
|
|||
}, Default = None
|
||||
);
|
||||
|
||||
/// An item from a PubSub node.
|
||||
#[derive(Debug, Clone)]
|
||||
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(|payload| payload.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// This trait should be implemented on any element which can be included as a PubSub payload.
|
||||
pub trait PubSubPayload: crate::TryFrom<crate::Element> + Into<crate::Element> {}
|
||||
|
|
|
@ -8,7 +8,7 @@ use crate::data_forms::DataForm;
|
|||
use crate::util::error::Error;
|
||||
use crate::iq::{IqGetPayload, IqResultPayload, IqSetPayload};
|
||||
use crate::ns;
|
||||
use crate::pubsub::{ItemId, NodeName, Subscription, SubscriptionId};
|
||||
use crate::pubsub::{NodeName, Subscription, SubscriptionId, Item as PubSubItem};
|
||||
use jid::Jid;
|
||||
use minidom::Element;
|
||||
use try_from::TryFrom;
|
||||
|
@ -113,45 +113,11 @@ generate_element!(
|
|||
]
|
||||
);
|
||||
|
||||
/// An item from a PubSub node.
|
||||
/// Response wrapper for a PubSub `<item/>`.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Item {
|
||||
/// The payload of this item, in an arbitrary namespace.
|
||||
pub payload: Option<Element>,
|
||||
pub struct Item(pub PubSubItem);
|
||||
|
||||
/// The 'id' attribute of this item.
|
||||
pub id: Option<ItemId>,
|
||||
}
|
||||
|
||||
impl TryFrom<Element> for Item {
|
||||
type Err = Error;
|
||||
|
||||
fn try_from(elem: Element) -> Result<Item, Error> {
|
||||
check_self!(elem, "item", PUBSUB);
|
||||
check_no_unknown_attributes!(elem, "item", ["id"]);
|
||||
let mut payloads = elem.children().cloned().collect::<Vec<_>>();
|
||||
let payload = payloads.pop();
|
||||
if !payloads.is_empty() {
|
||||
return Err(Error::ParseError(
|
||||
"More than a single payload in item element.",
|
||||
));
|
||||
}
|
||||
Ok(Item {
|
||||
payload,
|
||||
id: get_attr!(elem, "id", optional),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Item> for Element {
|
||||
fn from(item: Item) -> Element {
|
||||
Element::builder("item")
|
||||
.ns(ns::PUBSUB)
|
||||
.attr("id", item.id)
|
||||
.append(item.payload)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
impl_pubsub_item!(Item, PUBSUB);
|
||||
|
||||
generate_element!(
|
||||
/// The options associated to a subscription request.
|
||||
|
|
|
@ -596,3 +596,54 @@ macro_rules! assert_size (
|
|||
assert_eq!(::std::mem::size_of::<$t>(), $sz);
|
||||
);
|
||||
);
|
||||
|
||||
// TODO: move that to src/pubsub/mod.rs, once we figure out how to use macros from there.
|
||||
macro_rules! impl_pubsub_item {
|
||||
($item:ident, $ns:ident) => {
|
||||
impl crate::TryFrom<crate::Element> for $item {
|
||||
type Err = Error;
|
||||
|
||||
fn try_from(elem: crate::Element) -> Result<$item, Error> {
|
||||
check_self!(elem, "item", $ns);
|
||||
check_no_unknown_attributes!(elem, "item", ["id", "publisher"]);
|
||||
let mut payloads = elem.children().cloned().collect::<Vec<_>>();
|
||||
let payload = payloads.pop();
|
||||
if !payloads.is_empty() {
|
||||
return Err(Error::ParseError(
|
||||
"More than a single payload in item element.",
|
||||
));
|
||||
}
|
||||
Ok($item(crate::pubsub::Item {
|
||||
id: get_attr!(elem, "id", optional),
|
||||
publisher: get_attr!(elem, "publisher", optional),
|
||||
payload,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<$item> for crate::Element {
|
||||
fn from(item: $item) -> crate::Element {
|
||||
crate::Element::builder("item")
|
||||
.ns(ns::$ns)
|
||||
.attr("id", item.0.id)
|
||||
.attr("publisher", item.0.publisher)
|
||||
.append(item.0.payload)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::ops::Deref for $item {
|
||||
type Target = crate::pubsub::Item;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::ops::DerefMut for $item {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue