mirror of
https://gitlab.com/xmpp-rs/xmpp-rs.git
synced 2024-07-12 22:21:53 +00:00
parsers: Add support for XEP-0215: External Service Discovery
This commit is contained in:
parent
9891cc48ac
commit
3a6cd23166
4 changed files with 218 additions and 0 deletions
|
@ -296,6 +296,14 @@
|
||||||
<xmpp:since>0.1.0</xmpp:since>
|
<xmpp:since>0.1.0</xmpp:since>
|
||||||
</xmpp:SupportedXep>
|
</xmpp:SupportedXep>
|
||||||
</implements>
|
</implements>
|
||||||
|
<implements>
|
||||||
|
<xmpp:SupportedXep>
|
||||||
|
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0215.html"/>
|
||||||
|
<xmpp:status>complete</xmpp:status>
|
||||||
|
<xmpp:version>0.7.1</xmpp:version>
|
||||||
|
<xmpp:since>NEXT</xmpp:since>
|
||||||
|
</xmpp:SupportedXep>
|
||||||
|
</implements>
|
||||||
<implements>
|
<implements>
|
||||||
<xmpp:SupportedXep>
|
<xmpp:SupportedXep>
|
||||||
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0221.html"/>
|
<xmpp:xep rdf:resource="https://xmpp.org/extensions/xep-0221.html"/>
|
||||||
|
|
204
parsers/src/extdisco.rs
Normal file
204
parsers/src/extdisco.rs
Normal file
|
@ -0,0 +1,204 @@
|
||||||
|
// Copyright (c) 2021 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
|
||||||
|
//
|
||||||
|
// 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::date::DateTime;
|
||||||
|
use crate::iq::{IqGetPayload, IqResultPayload, IqSetPayload};
|
||||||
|
|
||||||
|
generate_attribute!(
|
||||||
|
/// When sending a push update, the action value indicates if the service is being added or
|
||||||
|
/// deleted from the set of known services (or simply being modified).
|
||||||
|
Action, "action", {
|
||||||
|
/// The service is being added from the set of known services.
|
||||||
|
Add => "add",
|
||||||
|
|
||||||
|
/// The service is being removed from the set of known services.
|
||||||
|
Remove => "remove",
|
||||||
|
|
||||||
|
/// The service is being modified.
|
||||||
|
Modify => "modify",
|
||||||
|
}, Default = Add
|
||||||
|
);
|
||||||
|
|
||||||
|
generate_attribute!(
|
||||||
|
/// TODO
|
||||||
|
Transport, "transport", {
|
||||||
|
/// TODO
|
||||||
|
Tcp => "tcp",
|
||||||
|
|
||||||
|
/// TODO
|
||||||
|
Udp => "udp",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
generate_attribute!(
|
||||||
|
/// TODO
|
||||||
|
Type, "type", {
|
||||||
|
/// A server that provides Session Traversal Utilities for NAT (STUN).
|
||||||
|
Stun => "stun",
|
||||||
|
|
||||||
|
/// A server that provides Traversal Using Relays around NAT (TURN).
|
||||||
|
Turn => "turn",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
generate_attribute!(
|
||||||
|
/// TODO
|
||||||
|
Restricted,
|
||||||
|
"restricted",
|
||||||
|
bool
|
||||||
|
);
|
||||||
|
|
||||||
|
generate_element!(
|
||||||
|
/// Structure representing a `<service xmlns='urn:xmpp:extdisco:2'/>` element.
|
||||||
|
Service, "service", EXT_DISCO,
|
||||||
|
attributes: [
|
||||||
|
/// When sending a push update, the action value indicates if the service is being added or
|
||||||
|
/// deleted from the set of known services (or simply being modified).
|
||||||
|
action: Default<Action> = "action",
|
||||||
|
|
||||||
|
/// A timestamp indicating when the provided username and password credentials will expire.
|
||||||
|
expires: Option<DateTime> = "expires",
|
||||||
|
|
||||||
|
/// Either a fully qualified domain name (FQDN) or an IP address (IPv4 or IPv6).
|
||||||
|
host: Required<String> = "host",
|
||||||
|
|
||||||
|
/// A friendly (human-readable) name or label for the service.
|
||||||
|
name: Option<String> = "name",
|
||||||
|
|
||||||
|
/// A service- or server-generated password for use at the service.
|
||||||
|
password: Option<String> = "password",
|
||||||
|
|
||||||
|
/// The communications port to be used at the host.
|
||||||
|
port: Option<u16> = "port",
|
||||||
|
|
||||||
|
/// A boolean value indicating that username and password credentials are required and will
|
||||||
|
/// need to be requested if not already provided.
|
||||||
|
restricted: Default<Restricted> = "restricted",
|
||||||
|
|
||||||
|
/// The underlying transport protocol to be used when communicating with the service (typically
|
||||||
|
/// either TCP or UDP).
|
||||||
|
transport: Option<Transport> = "transport",
|
||||||
|
|
||||||
|
/// The service type as registered with the XMPP Registrar.
|
||||||
|
type_: Required<Type> = "type",
|
||||||
|
|
||||||
|
/// A service- or server-generated username for use at the service.
|
||||||
|
username: Option<String> = "username",
|
||||||
|
], children: [
|
||||||
|
/// Extended information
|
||||||
|
ext_info: Vec<DataForm> = ("x", DATA_FORMS) => DataForm
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
impl IqGetPayload for Service {}
|
||||||
|
|
||||||
|
generate_element!(
|
||||||
|
/// Structure representing a `<services xmlns='urn:xmpp:extdisco:2'/>` element.
|
||||||
|
ServicesQuery, "services", EXT_DISCO,
|
||||||
|
attributes: [
|
||||||
|
/// TODO
|
||||||
|
type_: Option<Type> = "type",
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
impl IqGetPayload for ServicesQuery {}
|
||||||
|
|
||||||
|
generate_element!(
|
||||||
|
/// Structure representing a `<services xmlns='urn:xmpp:extdisco:2'/>` element.
|
||||||
|
ServicesResult, "services", EXT_DISCO,
|
||||||
|
attributes: [
|
||||||
|
/// TODO
|
||||||
|
type_: Option<Type> = "type",
|
||||||
|
],
|
||||||
|
children: [
|
||||||
|
/// List of services.
|
||||||
|
services: Vec<Service> = ("service", EXT_DISCO) => Service
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
impl IqResultPayload for ServicesResult {}
|
||||||
|
impl IqSetPayload for ServicesResult {}
|
||||||
|
|
||||||
|
generate_element!(
|
||||||
|
/// Structure representing a `<credentials xmlns='urn:xmpp:extdisco:2'/>` element.
|
||||||
|
Credentials, "credentials", EXT_DISCO,
|
||||||
|
children: [
|
||||||
|
/// List of services.
|
||||||
|
services: Vec<Service> = ("service", EXT_DISCO) => Service
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
impl IqGetPayload for Credentials {}
|
||||||
|
impl IqResultPayload for Credentials {}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use crate::ns;
|
||||||
|
use crate::Element;
|
||||||
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
|
#[cfg(target_pointer_width = "32")]
|
||||||
|
#[test]
|
||||||
|
fn test_size() {
|
||||||
|
assert_size!(Action, 1);
|
||||||
|
assert_size!(Transport, 1);
|
||||||
|
assert_size!(Restricted, 1);
|
||||||
|
assert_size!(Type, 1);
|
||||||
|
assert_size!(Service, 100); // XXX
|
||||||
|
assert_size!(ServicesQuery, 1);
|
||||||
|
assert_size!(ServicesResult, 16);
|
||||||
|
assert_size!(Credentials, 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_pointer_width = "64")]
|
||||||
|
#[test]
|
||||||
|
fn test_size() {
|
||||||
|
assert_size!(Action, 1);
|
||||||
|
assert_size!(Transport, 1);
|
||||||
|
assert_size!(Restricted, 1);
|
||||||
|
assert_size!(Type, 1);
|
||||||
|
assert_size!(Service, 152);
|
||||||
|
assert_size!(ServicesQuery, 1);
|
||||||
|
assert_size!(ServicesResult, 32);
|
||||||
|
assert_size!(Credentials, 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_simple() {
|
||||||
|
let elem: Element = "<service xmlns='urn:xmpp:extdisco:2' host='stun.shakespeare.lit' port='9998' transport='udp' type='stun'/>".parse().unwrap();
|
||||||
|
let service = Service::try_from(elem).unwrap();
|
||||||
|
assert_eq!(service.action, Action::Add);
|
||||||
|
assert!(service.expires.is_none());
|
||||||
|
assert_eq!(service.host, "stun.shakespeare.lit");
|
||||||
|
assert!(service.name.is_none());
|
||||||
|
assert!(service.password.is_none());
|
||||||
|
assert_eq!(service.port.unwrap(), 9998);
|
||||||
|
assert_eq!(service.restricted, Restricted::False);
|
||||||
|
assert_eq!(service.transport.unwrap(), Transport::Udp);
|
||||||
|
assert_eq!(service.type_, Type::Stun);
|
||||||
|
assert!(service.username.is_none());
|
||||||
|
assert!(service.ext_info.is_empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_service_query() {
|
||||||
|
let query = ServicesQuery { type_: None };
|
||||||
|
let elem = Element::from(query);
|
||||||
|
assert!(elem.is("services", ns::EXT_DISCO));
|
||||||
|
assert_eq!(elem.attrs().next(), None);
|
||||||
|
assert_eq!(elem.nodes().next(), None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_service_result() {
|
||||||
|
let elem: Element = "<services xmlns='urn:xmpp:extdisco:2' type='stun'><service host='stun.shakespeare.lit' port='9998' transport='udp' type='stun'/></services>".parse().unwrap();
|
||||||
|
let services = ServicesResult::try_from(elem).unwrap();
|
||||||
|
assert_eq!(services.type_, Some(Type::Stun));
|
||||||
|
assert_eq!(services.services.len(), 1);
|
||||||
|
}
|
||||||
|
}
|
|
@ -141,6 +141,9 @@ pub mod time;
|
||||||
/// XEP-0203: Delayed Delivery
|
/// XEP-0203: Delayed Delivery
|
||||||
pub mod delay;
|
pub mod delay;
|
||||||
|
|
||||||
|
/// XEP-0215: External Service Discovery
|
||||||
|
pub mod extdisco;
|
||||||
|
|
||||||
/// XEP-0221: Data Forms Media Element
|
/// XEP-0221: Data Forms Media Element
|
||||||
pub mod media_element;
|
pub mod media_element;
|
||||||
|
|
||||||
|
|
|
@ -133,6 +133,9 @@ pub const TIME: &str = "urn:xmpp:time";
|
||||||
/// XEP-0203: Delayed Delivery
|
/// XEP-0203: Delayed Delivery
|
||||||
pub const DELAY: &str = "urn:xmpp:delay";
|
pub const DELAY: &str = "urn:xmpp:delay";
|
||||||
|
|
||||||
|
/// XEP-0215: External Service Discovery
|
||||||
|
pub const EXT_DISCO: &str = "urn:xmpp:extdisco:2";
|
||||||
|
|
||||||
/// XEP-0221: Data Forms Media Element
|
/// XEP-0221: Data Forms Media Element
|
||||||
pub const MEDIA_ELEMENT: &str = "urn:xmpp:media-element";
|
pub const MEDIA_ELEMENT: &str = "urn:xmpp:media-element";
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue