Add pubsub#owner initial support (only configure)
This commit is contained in:
parent
521bf6e7d7
commit
e6d4047160
2 changed files with 143 additions and 0 deletions
|
@ -7,10 +7,14 @@
|
|||
/// The `http://jabber.org/protocol/pubsub#event` protocol.
|
||||
pub mod event;
|
||||
|
||||
/// The `http://jabber.org/protocol/pubsub#owner` protocol.
|
||||
pub mod owner;
|
||||
|
||||
/// The `http://jabber.org/protocol/pubsub` protocol.
|
||||
pub mod pubsub;
|
||||
|
||||
pub use self::event::PubSubEvent;
|
||||
pub use self::owner::PubSubOwner;
|
||||
pub use self::pubsub::PubSub;
|
||||
|
||||
use crate::{Element, Jid};
|
||||
|
|
139
xmpp-parsers/src/pubsub/owner.rs
Normal file
139
xmpp-parsers/src/pubsub/owner.rs
Normal file
|
@ -0,0 +1,139 @@
|
|||
// Copyright (c) ???
|
||||
//
|
||||
// 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/.
|
||||
|
||||
use crate::data_forms::DataForm;
|
||||
use crate::iq::{IqGetPayload, IqResultPayload, IqSetPayload};
|
||||
use crate::ns;
|
||||
use crate::pubsub::NodeName;
|
||||
use crate::util::error::Error;
|
||||
use crate::Element;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
generate_element!(
|
||||
/// Request to configure a node.
|
||||
Configure, "configure", PUBSUB_OWNER,
|
||||
attributes: [
|
||||
/// The node to be configured.
|
||||
node: Option<NodeName> = "node",
|
||||
],
|
||||
children: [
|
||||
/// The form to configure it.
|
||||
form: Option<DataForm> = ("x", DATA_FORMS) => DataForm
|
||||
]
|
||||
);
|
||||
|
||||
/// Main payload used to communicate with a PubSubOwner service.
|
||||
///
|
||||
/// `<pubsub xmlns="http://jabber.org/protocol/pubsub#owner"/>`
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum PubSubOwner {
|
||||
/// Request to configure a node, with optional suggested name and suggested configuration.
|
||||
Configure {
|
||||
/// The configure request for the new node.
|
||||
configure: Configure,
|
||||
},
|
||||
}
|
||||
|
||||
impl IqGetPayload for PubSubOwner {}
|
||||
impl IqSetPayload for PubSubOwner {}
|
||||
impl IqResultPayload for PubSubOwner {}
|
||||
|
||||
impl TryFrom<Element> for PubSubOwner {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(elem: Element) -> Result<PubSubOwner, Error> {
|
||||
check_self!(elem, "pubsub", PUBSUB_OWNER);
|
||||
check_no_attributes!(elem, "pubsub");
|
||||
|
||||
let mut payload = None;
|
||||
for child in elem.children() {
|
||||
if child.is("configure", ns::PUBSUB_OWNER) {
|
||||
if payload.is_some() {
|
||||
return Err(Error::ParseError(
|
||||
"Payload is already defined in pubsub owner element.",
|
||||
));
|
||||
}
|
||||
let configure = Configure::try_from(child.clone())?;
|
||||
payload = Some(PubSubOwner::Configure {
|
||||
configure: configure,
|
||||
});
|
||||
} else {
|
||||
return Err(Error::ParseError("Unknown child in pubsub element."));
|
||||
}
|
||||
}
|
||||
Ok(payload.ok_or(Error::ParseError("No payload in pubsub element."))?)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PubSubOwner> for Element {
|
||||
fn from(pubsub: PubSubOwner) -> Element {
|
||||
Element::builder("pubsub", ns::PUBSUB_OWNER)
|
||||
.append_all(match pubsub {
|
||||
PubSubOwner::Configure { configure } => vec![Element::from(configure)],
|
||||
})
|
||||
.build()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::data_forms::{DataForm, DataFormType, Field, FieldType};
|
||||
use std::str::FromStr;
|
||||
|
||||
#[test]
|
||||
fn configure() {
|
||||
// XXX: Do we want xmpp-parsers to always specify the field type in the output Element?
|
||||
let elem: Element = "<pubsub xmlns='http://jabber.org/protocol/pubsub#owner'><configure node='foo'><x xmlns='jabber:x:data' type='submit'><field var='FORM_TYPE' type='hidden'><value>http://jabber.org/protocol/pubsub#node_config</value></field><field var='pubsub#access_model' type='list-single'><value>whitelist</value></field></x></configure></pubsub>"
|
||||
.parse()
|
||||
.unwrap();
|
||||
let elem1 = elem.clone();
|
||||
|
||||
let pubsub = PubSubOwner::Configure {
|
||||
configure: Configure {
|
||||
node: Some(NodeName(String::from("foo"))),
|
||||
form: Some(DataForm {
|
||||
type_: DataFormType::Submit,
|
||||
form_type: Some(String::from(ns::PUBSUB_CONFIGURE)),
|
||||
title: None,
|
||||
instructions: None,
|
||||
fields: vec![Field {
|
||||
var: String::from("pubsub#access_model"),
|
||||
type_: FieldType::ListSingle,
|
||||
label: None,
|
||||
required: false,
|
||||
options: vec![],
|
||||
values: vec![String::from("whitelist")],
|
||||
media: vec![],
|
||||
}],
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
||||
let elem2 = Element::from(pubsub);
|
||||
assert_eq!(elem1, elem2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_serialize_configure() {
|
||||
let reference: Element = "<pubsub xmlns='http://jabber.org/protocol/pubsub#owner'><configure node='foo'><x xmlns='jabber:x:data' type='submit'/></configure></pubsub>"
|
||||
.parse()
|
||||
.unwrap();
|
||||
|
||||
let elem: Element = "<x xmlns='jabber:x:data' type='submit'/>".parse().unwrap();
|
||||
|
||||
let form = DataForm::try_from(elem).unwrap();
|
||||
|
||||
let configure = PubSubOwner::Configure {
|
||||
configure: Configure {
|
||||
node: Some(NodeName(String::from("foo"))),
|
||||
form: Some(form),
|
||||
},
|
||||
};
|
||||
let serialized: Element = configure.into();
|
||||
assert_eq!(serialized, reference);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue