2019-06-10 21:09:20 +00:00
|
|
|
|
// Copyright (c) 2017, 2018 lumi <lumi@pew.im>
|
|
|
|
|
// Copyright (c) 2017, 2018, 2019 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
|
|
|
|
|
// Copyright (c) 2017, 2018, 2019 Maxime “pep” Buquet <pep@bouah.net>
|
|
|
|
|
// Copyright (c) 2017, 2018 Astro <astro@spaceboyz.net>
|
|
|
|
|
// Copyright (c) 2017 Bastien Orivel <eijebong@bananium.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/.
|
|
|
|
|
|
2017-02-28 11:38:00 +00:00
|
|
|
|
#![deny(missing_docs)]
|
|
|
|
|
|
2017-02-27 14:35:57 +00:00
|
|
|
|
//! Provides a type for Jabber IDs.
|
2017-02-27 15:42:09 +00:00
|
|
|
|
//!
|
|
|
|
|
//! For usage, check the documentation on the `Jid` struct.
|
2017-02-27 14:35:57 +00:00
|
|
|
|
|
2019-09-08 20:09:25 +00:00
|
|
|
|
use std::convert::{Into, TryFrom};
|
2019-09-07 14:08:53 +00:00
|
|
|
|
use std::error::Error as StdError;
|
2018-12-18 15:40:44 +00:00
|
|
|
|
use std::fmt;
|
2017-02-27 14:35:57 +00:00
|
|
|
|
use std::str::FromStr;
|
|
|
|
|
|
2020-04-30 21:19:06 +00:00
|
|
|
|
#[cfg(feature = "serde")]
|
2020-05-01 00:26:58 +00:00
|
|
|
|
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
|
2020-04-30 21:19:06 +00:00
|
|
|
|
|
2017-02-27 14:35:57 +00:00
|
|
|
|
/// An error that signifies that a `Jid` cannot be parsed from a string.
|
2019-09-05 16:42:22 +00:00
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
2017-02-27 14:35:57 +00:00
|
|
|
|
pub enum JidParseError {
|
2018-02-18 20:36:36 +00:00
|
|
|
|
/// Happens when there is no domain, that is either the string is empty,
|
|
|
|
|
/// starts with a /, or contains the @/ sequence.
|
2017-02-27 14:35:57 +00:00
|
|
|
|
NoDomain,
|
2018-03-01 15:25:59 +00:00
|
|
|
|
|
2019-04-21 22:52:02 +00:00
|
|
|
|
/// Happens when there is no resource, that is string contains no /.
|
|
|
|
|
NoResource,
|
|
|
|
|
|
2018-02-18 20:36:36 +00:00
|
|
|
|
/// Happens when the node is empty, that is the string starts with a @.
|
|
|
|
|
EmptyNode,
|
2018-03-01 15:25:59 +00:00
|
|
|
|
|
2018-02-18 20:36:36 +00:00
|
|
|
|
/// Happens when the resource is empty, that is the string ends with a /.
|
|
|
|
|
EmptyResource,
|
2017-02-27 14:35:57 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-09-07 14:08:53 +00:00
|
|
|
|
impl StdError for JidParseError {}
|
|
|
|
|
|
2019-09-05 16:42:22 +00:00
|
|
|
|
impl fmt::Display for JidParseError {
|
|
|
|
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
2019-10-22 23:32:41 +00:00
|
|
|
|
write!(
|
|
|
|
|
fmt,
|
|
|
|
|
"{}",
|
|
|
|
|
match self {
|
|
|
|
|
JidParseError::NoDomain => "no domain found in this JID",
|
|
|
|
|
JidParseError::NoResource => "no resource found in this full JID",
|
|
|
|
|
JidParseError::EmptyNode => "nodepart empty despite the presence of a @",
|
|
|
|
|
JidParseError::EmptyResource => "resource empty despite the presence of a /",
|
|
|
|
|
}
|
|
|
|
|
)
|
2019-09-05 16:42:22 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-21 22:52:02 +00:00
|
|
|
|
/// An enum representing a Jabber ID. It can be either a `FullJid` or a `BareJid`.
|
2020-04-30 21:19:06 +00:00
|
|
|
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
2019-10-15 23:23:21 +00:00
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
2019-04-21 22:52:02 +00:00
|
|
|
|
pub enum Jid {
|
|
|
|
|
/// Bare Jid
|
|
|
|
|
Bare(BareJid),
|
|
|
|
|
|
|
|
|
|
/// Full Jid
|
|
|
|
|
Full(FullJid),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl FromStr for Jid {
|
|
|
|
|
type Err = JidParseError;
|
|
|
|
|
|
|
|
|
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
|
|
|
let (ns, ds, rs): StringJid = _from_str(s)?;
|
|
|
|
|
Ok(match rs {
|
|
|
|
|
Some(rs) => Jid::Full(FullJid {
|
|
|
|
|
node: ns,
|
|
|
|
|
domain: ds,
|
|
|
|
|
resource: rs,
|
|
|
|
|
}),
|
|
|
|
|
None => Jid::Bare(BareJid {
|
|
|
|
|
node: ns,
|
|
|
|
|
domain: ds,
|
2019-06-10 20:04:03 +00:00
|
|
|
|
}),
|
2019-04-21 22:52:02 +00:00
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl From<Jid> for String {
|
|
|
|
|
fn from(jid: Jid) -> String {
|
|
|
|
|
match jid {
|
|
|
|
|
Jid::Bare(bare) => String::from(bare),
|
|
|
|
|
Jid::Full(full) => String::from(full),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-06 12:55:19 +00:00
|
|
|
|
impl From<BareJid> for Jid {
|
|
|
|
|
fn from(bare_jid: BareJid) -> Jid {
|
|
|
|
|
Jid::Bare(bare_jid)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl From<FullJid> for Jid {
|
|
|
|
|
fn from(full_jid: FullJid) -> Jid {
|
|
|
|
|
Jid::Full(full_jid)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-31 13:17:51 +00:00
|
|
|
|
impl fmt::Display for Jid {
|
|
|
|
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
|
|
|
|
fmt.write_str(String::from(self.clone()).as_ref())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-20 17:01:25 +00:00
|
|
|
|
impl Jid {
|
|
|
|
|
/// The node part of the Jabber ID, if it exists, else None.
|
|
|
|
|
pub fn node(self) -> Option<String> {
|
|
|
|
|
match self {
|
|
|
|
|
Jid::Bare(BareJid { node, .. }) | Jid::Full(FullJid { node, .. }) => node,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// The domain of the Jabber ID.
|
|
|
|
|
pub fn domain(self) -> String {
|
|
|
|
|
match self {
|
|
|
|
|
Jid::Bare(BareJid { domain, .. }) | Jid::Full(FullJid { domain, .. }) => domain,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-08 20:09:25 +00:00
|
|
|
|
impl From<Jid> for BareJid {
|
|
|
|
|
fn from(jid: Jid) -> BareJid {
|
|
|
|
|
match jid {
|
|
|
|
|
Jid::Full(full) => full.into(),
|
|
|
|
|
Jid::Bare(bare) => bare,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl TryFrom<Jid> for FullJid {
|
|
|
|
|
type Error = JidParseError;
|
|
|
|
|
|
|
|
|
|
fn try_from(jid: Jid) -> Result<Self, Self::Error> {
|
|
|
|
|
match jid {
|
|
|
|
|
Jid::Full(full) => Ok(full),
|
|
|
|
|
Jid::Bare(_) => Err(JidParseError::NoResource),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-10 19:28:32 +00:00
|
|
|
|
impl PartialEq<Jid> for FullJid {
|
|
|
|
|
fn eq(&self, other: &Jid) -> bool {
|
|
|
|
|
match other {
|
|
|
|
|
Jid::Full(full) => self == full,
|
|
|
|
|
Jid::Bare(_) => false,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl PartialEq<Jid> for BareJid {
|
|
|
|
|
fn eq(&self, other: &Jid) -> bool {
|
|
|
|
|
match other {
|
|
|
|
|
Jid::Full(_) => false,
|
|
|
|
|
Jid::Bare(bare) => self == bare,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl PartialEq<FullJid> for Jid {
|
|
|
|
|
fn eq(&self, other: &FullJid) -> bool {
|
|
|
|
|
match self {
|
|
|
|
|
Jid::Full(full) => full == other,
|
|
|
|
|
Jid::Bare(_) => false,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl PartialEq<BareJid> for Jid {
|
|
|
|
|
fn eq(&self, other: &BareJid) -> bool {
|
|
|
|
|
match self {
|
|
|
|
|
Jid::Full(_) => false,
|
|
|
|
|
Jid::Bare(bare) => bare == other,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-10 20:54:52 +00:00
|
|
|
|
/// A struct representing a full Jabber ID.
|
2017-02-27 14:35:57 +00:00
|
|
|
|
///
|
2019-06-10 20:54:52 +00:00
|
|
|
|
/// A full Jabber ID is composed of 3 components, of which one is optional:
|
2017-02-27 14:35:57 +00:00
|
|
|
|
///
|
|
|
|
|
/// - A node/name, `node`, which is the optional part before the @.
|
|
|
|
|
/// - A domain, `domain`, which is the mandatory part after the @ but before the /.
|
2019-04-21 22:52:02 +00:00
|
|
|
|
/// - A resource, `resource`, which is the part after the /.
|
2019-06-10 20:55:15 +00:00
|
|
|
|
///
|
|
|
|
|
/// Unlike a `BareJid`, it always contains a resource, and should only be used when you are certain
|
|
|
|
|
/// there is no case where a resource can be missing. Otherwise, use a `Jid` enum.
|
2017-05-27 19:45:00 +00:00
|
|
|
|
#[derive(Clone, PartialEq, Eq, Hash)]
|
2019-04-21 22:52:02 +00:00
|
|
|
|
pub struct FullJid {
|
2017-02-27 14:35:57 +00:00
|
|
|
|
/// The node part of the Jabber ID, if it exists, else None.
|
|
|
|
|
pub node: Option<String>,
|
|
|
|
|
/// The domain of the Jabber ID.
|
|
|
|
|
pub domain: String,
|
2019-04-21 22:52:02 +00:00
|
|
|
|
/// The resource of the Jabber ID.
|
|
|
|
|
pub resource: String,
|
2017-02-27 14:35:57 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-06-10 20:54:52 +00:00
|
|
|
|
/// A struct representing a bare Jabber ID.
|
2019-04-21 22:52:02 +00:00
|
|
|
|
///
|
2019-06-10 20:54:52 +00:00
|
|
|
|
/// A bare Jabber ID is composed of 2 components, of which one is optional:
|
2019-04-21 22:52:02 +00:00
|
|
|
|
///
|
|
|
|
|
/// - A node/name, `node`, which is the optional part before the @.
|
2019-06-10 20:55:15 +00:00
|
|
|
|
/// - A domain, `domain`, which is the mandatory part after the @.
|
|
|
|
|
///
|
|
|
|
|
/// Unlike a `FullJid`, it can’t contain a resource, and should only be used when you are certain
|
|
|
|
|
/// there is no case where a resource can be set. Otherwise, use a `Jid` enum.
|
2019-04-21 22:52:02 +00:00
|
|
|
|
#[derive(Clone, PartialEq, Eq, Hash)]
|
|
|
|
|
pub struct BareJid {
|
|
|
|
|
/// The node part of the Jabber ID, if it exists, else None.
|
|
|
|
|
pub node: Option<String>,
|
|
|
|
|
/// The domain of the Jabber ID.
|
|
|
|
|
pub domain: String,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl From<FullJid> for String {
|
|
|
|
|
fn from(jid: FullJid) -> String {
|
2020-05-01 00:25:30 +00:00
|
|
|
|
String::from(&jid)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl From<&FullJid> for String {
|
|
|
|
|
fn from(jid: &FullJid) -> String {
|
2017-04-23 13:49:00 +00:00
|
|
|
|
let mut string = String::new();
|
|
|
|
|
if let Some(ref node) = jid.node {
|
|
|
|
|
string.push_str(node);
|
|
|
|
|
string.push('@');
|
|
|
|
|
}
|
|
|
|
|
string.push_str(&jid.domain);
|
2019-04-21 22:52:02 +00:00
|
|
|
|
string.push('/');
|
|
|
|
|
string.push_str(&jid.resource);
|
|
|
|
|
string
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl From<BareJid> for String {
|
|
|
|
|
fn from(jid: BareJid) -> String {
|
2020-05-01 00:25:30 +00:00
|
|
|
|
String::from(&jid)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl From<&BareJid> for String {
|
|
|
|
|
fn from(jid: &BareJid) -> String {
|
2019-04-21 22:52:02 +00:00
|
|
|
|
let mut string = String::new();
|
|
|
|
|
if let Some(ref node) = jid.node {
|
|
|
|
|
string.push_str(node);
|
|
|
|
|
string.push('@');
|
2017-04-23 13:49:00 +00:00
|
|
|
|
}
|
2019-04-21 22:52:02 +00:00
|
|
|
|
string.push_str(&jid.domain);
|
2017-04-23 13:49:00 +00:00
|
|
|
|
string
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-11 13:35:27 +00:00
|
|
|
|
impl From<FullJid> for BareJid {
|
|
|
|
|
fn from(full: FullJid) -> BareJid {
|
2019-04-21 22:52:02 +00:00
|
|
|
|
BareJid {
|
2021-10-11 13:35:27 +00:00
|
|
|
|
node: full.node,
|
|
|
|
|
domain: full.domain,
|
2019-04-21 22:52:02 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl fmt::Debug for FullJid {
|
2017-04-30 20:44:17 +00:00
|
|
|
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
2019-04-21 22:52:02 +00:00
|
|
|
|
write!(fmt, "FullJID({})", self)
|
2017-04-30 20:44:17 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-21 22:52:02 +00:00
|
|
|
|
impl fmt::Debug for BareJid {
|
|
|
|
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
|
|
|
|
write!(fmt, "BareJID({})", self)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl fmt::Display for FullJid {
|
|
|
|
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
|
|
|
|
fmt.write_str(String::from(self.clone()).as_ref())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl fmt::Display for BareJid {
|
2017-02-27 14:35:57 +00:00
|
|
|
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
2018-03-01 15:24:53 +00:00
|
|
|
|
fmt.write_str(String::from(self.clone()).as_ref())
|
2017-02-27 14:35:57 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-01 00:26:58 +00:00
|
|
|
|
#[cfg(feature = "serde")]
|
|
|
|
|
impl Serialize for FullJid {
|
|
|
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
|
|
|
where
|
|
|
|
|
S: Serializer,
|
|
|
|
|
{
|
|
|
|
|
serializer.serialize_str(String::from(self).as_str())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "serde")]
|
|
|
|
|
impl Serialize for BareJid {
|
|
|
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
|
|
|
where
|
|
|
|
|
S: Serializer,
|
|
|
|
|
{
|
|
|
|
|
serializer.serialize_str(String::from(self).as_str())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-27 14:35:57 +00:00
|
|
|
|
enum ParserState {
|
|
|
|
|
Node,
|
|
|
|
|
Domain,
|
2018-12-18 15:40:44 +00:00
|
|
|
|
Resource,
|
2017-02-27 14:35:57 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-04-21 22:52:02 +00:00
|
|
|
|
type StringJid = (Option<String>, String, Option<String>);
|
|
|
|
|
fn _from_str(s: &str) -> Result<StringJid, JidParseError> {
|
|
|
|
|
// TODO: very naive, may need to do it differently
|
|
|
|
|
let iter = s.chars();
|
|
|
|
|
let mut buf = String::with_capacity(s.len());
|
|
|
|
|
let mut state = ParserState::Node;
|
|
|
|
|
let mut node = None;
|
|
|
|
|
let mut domain = None;
|
|
|
|
|
let mut resource = None;
|
|
|
|
|
for c in iter {
|
|
|
|
|
match state {
|
|
|
|
|
ParserState::Node => {
|
|
|
|
|
match c {
|
|
|
|
|
'@' => {
|
2021-10-11 13:35:27 +00:00
|
|
|
|
if buf.is_empty() {
|
2019-04-21 22:52:02 +00:00
|
|
|
|
return Err(JidParseError::EmptyNode);
|
2018-12-18 15:40:44 +00:00
|
|
|
|
}
|
2019-04-21 22:52:02 +00:00
|
|
|
|
state = ParserState::Domain;
|
|
|
|
|
node = Some(buf.clone()); // TODO: performance tweaks, do not need to copy it
|
|
|
|
|
buf.clear();
|
|
|
|
|
}
|
|
|
|
|
'/' => {
|
2021-10-11 13:35:27 +00:00
|
|
|
|
if buf.is_empty() {
|
2019-04-21 22:52:02 +00:00
|
|
|
|
return Err(JidParseError::NoDomain);
|
2018-12-18 15:40:44 +00:00
|
|
|
|
}
|
2019-04-21 22:52:02 +00:00
|
|
|
|
state = ParserState::Resource;
|
|
|
|
|
domain = Some(buf.clone()); // TODO: performance tweaks
|
|
|
|
|
buf.clear();
|
|
|
|
|
}
|
|
|
|
|
c => {
|
|
|
|
|
buf.push(c);
|
2017-02-27 14:35:57 +00:00
|
|
|
|
}
|
2018-12-18 15:40:44 +00:00
|
|
|
|
}
|
2019-04-21 22:52:02 +00:00
|
|
|
|
}
|
|
|
|
|
ParserState::Domain => {
|
|
|
|
|
match c {
|
|
|
|
|
'/' => {
|
2021-10-11 13:35:27 +00:00
|
|
|
|
if buf.is_empty() {
|
2019-04-21 22:52:02 +00:00
|
|
|
|
return Err(JidParseError::NoDomain);
|
2018-12-18 15:40:44 +00:00
|
|
|
|
}
|
2019-04-21 22:52:02 +00:00
|
|
|
|
state = ParserState::Resource;
|
|
|
|
|
domain = Some(buf.clone()); // TODO: performance tweaks
|
|
|
|
|
buf.clear();
|
|
|
|
|
}
|
|
|
|
|
c => {
|
|
|
|
|
buf.push(c);
|
2017-02-27 14:35:57 +00:00
|
|
|
|
}
|
2018-12-18 15:40:44 +00:00
|
|
|
|
}
|
2019-04-21 22:52:02 +00:00
|
|
|
|
}
|
|
|
|
|
ParserState::Resource => {
|
|
|
|
|
buf.push(c);
|
2017-02-27 14:35:57 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-21 22:52:02 +00:00
|
|
|
|
}
|
|
|
|
|
if !buf.is_empty() {
|
|
|
|
|
match state {
|
|
|
|
|
ParserState::Node => {
|
|
|
|
|
domain = Some(buf);
|
|
|
|
|
}
|
|
|
|
|
ParserState::Domain => {
|
|
|
|
|
domain = Some(buf);
|
|
|
|
|
}
|
|
|
|
|
ParserState::Resource => {
|
|
|
|
|
resource = Some(buf);
|
2017-02-27 14:35:57 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-21 22:52:02 +00:00
|
|
|
|
} else if let ParserState::Resource = state {
|
|
|
|
|
return Err(JidParseError::EmptyResource);
|
|
|
|
|
}
|
2019-06-10 20:04:03 +00:00
|
|
|
|
Ok((node, domain.ok_or(JidParseError::NoDomain)?, resource))
|
2019-04-21 22:52:02 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl FromStr for FullJid {
|
|
|
|
|
type Err = JidParseError;
|
|
|
|
|
|
|
|
|
|
fn from_str(s: &str) -> Result<FullJid, JidParseError> {
|
|
|
|
|
let (ns, ds, rs): StringJid = _from_str(s)?;
|
|
|
|
|
Ok(FullJid {
|
|
|
|
|
node: ns,
|
|
|
|
|
domain: ds,
|
|
|
|
|
resource: rs.ok_or(JidParseError::NoResource)?,
|
2017-02-27 14:35:57 +00:00
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-01 00:26:58 +00:00
|
|
|
|
#[cfg(feature = "serde")]
|
|
|
|
|
impl<'de> Deserialize<'de> for FullJid {
|
|
|
|
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
|
|
|
where
|
|
|
|
|
D: Deserializer<'de>,
|
|
|
|
|
{
|
|
|
|
|
let s = String::deserialize(deserializer)?;
|
|
|
|
|
FullJid::from_str(&s).map_err(de::Error::custom)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "serde")]
|
|
|
|
|
impl<'de> Deserialize<'de> for BareJid {
|
|
|
|
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
|
|
|
where
|
|
|
|
|
D: Deserializer<'de>,
|
|
|
|
|
{
|
|
|
|
|
let s = String::deserialize(deserializer)?;
|
|
|
|
|
BareJid::from_str(&s).map_err(de::Error::custom)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-21 22:52:02 +00:00
|
|
|
|
impl FullJid {
|
2019-06-10 20:54:52 +00:00
|
|
|
|
/// Constructs a full Jabber ID containing all three components.
|
2017-02-27 14:35:57 +00:00
|
|
|
|
///
|
|
|
|
|
/// This is of the form `node`@`domain`/`resource`.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
2019-04-21 22:52:02 +00:00
|
|
|
|
/// use jid::FullJid;
|
2017-02-27 14:35:57 +00:00
|
|
|
|
///
|
2019-04-21 22:52:02 +00:00
|
|
|
|
/// let jid = FullJid::new("node", "domain", "resource");
|
2017-02-27 14:35:57 +00:00
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(jid.node, Some("node".to_owned()));
|
|
|
|
|
/// assert_eq!(jid.domain, "domain".to_owned());
|
2019-04-21 22:52:02 +00:00
|
|
|
|
/// assert_eq!(jid.resource, "resource".to_owned());
|
2017-02-27 14:35:57 +00:00
|
|
|
|
/// ```
|
2019-04-21 22:52:02 +00:00
|
|
|
|
pub fn new<NS, DS, RS>(node: NS, domain: DS, resource: RS) -> FullJid
|
2018-12-18 15:40:44 +00:00
|
|
|
|
where
|
|
|
|
|
NS: Into<String>,
|
|
|
|
|
DS: Into<String>,
|
|
|
|
|
RS: Into<String>,
|
|
|
|
|
{
|
2019-04-21 22:52:02 +00:00
|
|
|
|
FullJid {
|
2017-02-27 14:35:57 +00:00
|
|
|
|
node: Some(node.into()),
|
|
|
|
|
domain: domain.into(),
|
2019-06-10 20:04:03 +00:00
|
|
|
|
resource: resource.into(),
|
2017-02-27 14:35:57 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-21 22:52:02 +00:00
|
|
|
|
/// Constructs a new Jabber ID from an existing one, with the node swapped out with a new one.
|
2017-02-27 14:35:57 +00:00
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
2019-04-21 22:52:02 +00:00
|
|
|
|
/// use jid::FullJid;
|
2017-02-27 14:35:57 +00:00
|
|
|
|
///
|
2019-04-21 22:52:02 +00:00
|
|
|
|
/// let jid = FullJid::new("node", "domain", "resource");
|
2017-02-27 14:35:57 +00:00
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(jid.node, Some("node".to_owned()));
|
2019-04-21 22:52:02 +00:00
|
|
|
|
///
|
|
|
|
|
/// let new_jid = jid.with_node("new_node");
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(new_jid.node, Some("new_node".to_owned()));
|
2017-02-27 14:35:57 +00:00
|
|
|
|
/// ```
|
2019-04-21 22:52:02 +00:00
|
|
|
|
pub fn with_node<NS>(&self, node: NS) -> FullJid
|
2018-12-18 15:40:44 +00:00
|
|
|
|
where
|
|
|
|
|
NS: Into<String>,
|
|
|
|
|
{
|
2019-04-21 22:52:02 +00:00
|
|
|
|
FullJid {
|
2017-02-27 14:35:57 +00:00
|
|
|
|
node: Some(node.into()),
|
2019-04-21 22:52:02 +00:00
|
|
|
|
domain: self.domain.clone(),
|
|
|
|
|
resource: self.resource.clone(),
|
2017-02-27 14:35:57 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-21 22:52:02 +00:00
|
|
|
|
/// Constructs a new Jabber ID from an existing one, with the domain swapped out with a new one.
|
2017-06-12 16:40:39 +00:00
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
2019-04-21 22:52:02 +00:00
|
|
|
|
/// use jid::FullJid;
|
2017-06-12 16:40:39 +00:00
|
|
|
|
///
|
2019-04-21 22:52:02 +00:00
|
|
|
|
/// let jid = FullJid::new("node", "domain", "resource");
|
2017-06-12 16:40:39 +00:00
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(jid.domain, "domain".to_owned());
|
2019-04-21 22:52:02 +00:00
|
|
|
|
///
|
|
|
|
|
/// let new_jid = jid.with_domain("new_domain");
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(new_jid.domain, "new_domain");
|
2017-06-12 17:20:42 +00:00
|
|
|
|
/// ```
|
2019-04-21 22:52:02 +00:00
|
|
|
|
pub fn with_domain<DS>(&self, domain: DS) -> FullJid
|
|
|
|
|
where
|
|
|
|
|
DS: Into<String>,
|
|
|
|
|
{
|
|
|
|
|
FullJid {
|
|
|
|
|
node: self.node.clone(),
|
|
|
|
|
domain: domain.into(),
|
|
|
|
|
resource: self.resource.clone(),
|
2017-06-12 16:40:39 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-10 20:54:52 +00:00
|
|
|
|
/// Constructs a full Jabber ID from a bare Jabber ID, specifying a `resource`.
|
2017-02-27 14:35:57 +00:00
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
2019-04-21 22:52:02 +00:00
|
|
|
|
/// use jid::FullJid;
|
2017-02-27 14:35:57 +00:00
|
|
|
|
///
|
2019-04-21 22:52:02 +00:00
|
|
|
|
/// let jid = FullJid::new("node", "domain", "resource");
|
2017-02-27 14:35:57 +00:00
|
|
|
|
///
|
2019-04-21 22:52:02 +00:00
|
|
|
|
/// assert_eq!(jid.resource, "resource".to_owned());
|
|
|
|
|
///
|
|
|
|
|
/// let new_jid = jid.with_resource("new_resource");
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(new_jid.resource, "new_resource");
|
2017-02-27 14:35:57 +00:00
|
|
|
|
/// ```
|
2019-04-21 22:52:02 +00:00
|
|
|
|
pub fn with_resource<RS>(&self, resource: RS) -> FullJid
|
2018-12-18 15:40:44 +00:00
|
|
|
|
where
|
2019-04-21 22:52:02 +00:00
|
|
|
|
RS: Into<String>,
|
2018-12-18 15:40:44 +00:00
|
|
|
|
{
|
2019-04-21 22:52:02 +00:00
|
|
|
|
FullJid {
|
|
|
|
|
node: self.node.clone(),
|
|
|
|
|
domain: self.domain.clone(),
|
|
|
|
|
resource: resource.into(),
|
2017-02-27 14:35:57 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-21 22:52:02 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl FromStr for BareJid {
|
|
|
|
|
type Err = JidParseError;
|
|
|
|
|
|
|
|
|
|
fn from_str(s: &str) -> Result<BareJid, JidParseError> {
|
|
|
|
|
let (ns, ds, _rs): StringJid = _from_str(s)?;
|
|
|
|
|
Ok(BareJid {
|
|
|
|
|
node: ns,
|
|
|
|
|
domain: ds,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-02-27 14:35:57 +00:00
|
|
|
|
|
2019-04-21 22:52:02 +00:00
|
|
|
|
impl BareJid {
|
2019-06-10 20:54:52 +00:00
|
|
|
|
/// Constructs a bare Jabber ID, containing two components.
|
2017-06-12 16:40:39 +00:00
|
|
|
|
///
|
2019-04-21 22:52:02 +00:00
|
|
|
|
/// This is of the form `node`@`domain`.
|
2017-06-12 16:40:39 +00:00
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
2019-04-21 22:52:02 +00:00
|
|
|
|
/// use jid::BareJid;
|
2017-06-12 16:40:39 +00:00
|
|
|
|
///
|
2019-04-21 22:52:02 +00:00
|
|
|
|
/// let jid = BareJid::new("node", "domain");
|
2017-06-12 16:40:39 +00:00
|
|
|
|
///
|
2019-04-21 22:52:02 +00:00
|
|
|
|
/// assert_eq!(jid.node, Some("node".to_owned()));
|
2017-06-12 16:40:39 +00:00
|
|
|
|
/// assert_eq!(jid.domain, "domain".to_owned());
|
2017-06-12 17:20:42 +00:00
|
|
|
|
/// ```
|
2019-04-21 22:52:02 +00:00
|
|
|
|
pub fn new<NS, DS>(node: NS, domain: DS) -> BareJid
|
|
|
|
|
where
|
|
|
|
|
NS: Into<String>,
|
|
|
|
|
DS: Into<String>,
|
|
|
|
|
{
|
|
|
|
|
BareJid {
|
|
|
|
|
node: Some(node.into()),
|
|
|
|
|
domain: domain.into(),
|
2017-06-12 16:40:39 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-10 20:54:52 +00:00
|
|
|
|
/// Constructs a bare Jabber ID containing only a `domain`.
|
2017-02-27 14:35:57 +00:00
|
|
|
|
///
|
2019-04-21 22:52:02 +00:00
|
|
|
|
/// This is of the form `domain`.
|
2017-02-27 14:35:57 +00:00
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
2019-04-21 22:52:02 +00:00
|
|
|
|
/// use jid::BareJid;
|
2017-02-27 14:35:57 +00:00
|
|
|
|
///
|
2019-04-21 22:52:02 +00:00
|
|
|
|
/// let jid = BareJid::domain("domain");
|
2017-02-27 14:35:57 +00:00
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(jid.node, None);
|
|
|
|
|
/// assert_eq!(jid.domain, "domain".to_owned());
|
|
|
|
|
/// ```
|
2019-04-21 22:52:02 +00:00
|
|
|
|
pub fn domain<DS>(domain: DS) -> BareJid
|
2018-12-18 15:40:44 +00:00
|
|
|
|
where
|
|
|
|
|
DS: Into<String>,
|
|
|
|
|
{
|
2019-04-21 22:52:02 +00:00
|
|
|
|
BareJid {
|
2017-02-27 14:35:57 +00:00
|
|
|
|
node: None,
|
|
|
|
|
domain: domain.into(),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Constructs a new Jabber ID from an existing one, with the node swapped out with a new one.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
2019-04-21 22:52:02 +00:00
|
|
|
|
/// use jid::BareJid;
|
2017-02-27 14:35:57 +00:00
|
|
|
|
///
|
2019-04-21 22:52:02 +00:00
|
|
|
|
/// let jid = BareJid::domain("domain");
|
2017-02-27 14:35:57 +00:00
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(jid.node, None);
|
|
|
|
|
///
|
|
|
|
|
/// let new_jid = jid.with_node("node");
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(new_jid.node, Some("node".to_owned()));
|
|
|
|
|
/// ```
|
2019-04-21 22:52:02 +00:00
|
|
|
|
pub fn with_node<NS>(&self, node: NS) -> BareJid
|
2018-12-18 15:40:44 +00:00
|
|
|
|
where
|
2019-04-21 22:52:02 +00:00
|
|
|
|
NS: Into<String>,
|
2018-12-18 15:40:44 +00:00
|
|
|
|
{
|
2019-04-21 22:52:02 +00:00
|
|
|
|
BareJid {
|
2017-02-27 14:35:57 +00:00
|
|
|
|
node: Some(node.into()),
|
|
|
|
|
domain: self.domain.clone(),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Constructs a new Jabber ID from an existing one, with the domain swapped out with a new one.
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
2019-04-21 22:52:02 +00:00
|
|
|
|
/// use jid::BareJid;
|
2017-02-27 14:35:57 +00:00
|
|
|
|
///
|
2019-04-21 22:52:02 +00:00
|
|
|
|
/// let jid = BareJid::domain("domain");
|
2017-02-27 14:35:57 +00:00
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(jid.domain, "domain");
|
|
|
|
|
///
|
|
|
|
|
/// let new_jid = jid.with_domain("new_domain");
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(new_jid.domain, "new_domain");
|
|
|
|
|
/// ```
|
2019-04-21 22:52:02 +00:00
|
|
|
|
pub fn with_domain<DS>(&self, domain: DS) -> BareJid
|
2018-12-18 15:40:44 +00:00
|
|
|
|
where
|
2019-04-21 22:52:02 +00:00
|
|
|
|
DS: Into<String>,
|
2018-12-18 15:40:44 +00:00
|
|
|
|
{
|
2019-04-21 22:52:02 +00:00
|
|
|
|
BareJid {
|
2017-02-27 14:35:57 +00:00
|
|
|
|
node: self.node.clone(),
|
|
|
|
|
domain: domain.into(),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-10 20:54:52 +00:00
|
|
|
|
/// Constructs a full Jabber ID from a bare Jabber ID, specifying a `resource`.
|
2017-02-27 14:35:57 +00:00
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
2019-04-21 22:52:02 +00:00
|
|
|
|
/// use jid::BareJid;
|
2017-02-27 14:35:57 +00:00
|
|
|
|
///
|
2019-04-21 22:52:02 +00:00
|
|
|
|
/// let bare = BareJid::new("node", "domain");
|
|
|
|
|
/// let full = bare.with_resource("resource");
|
2017-02-27 14:35:57 +00:00
|
|
|
|
///
|
2019-04-21 22:52:02 +00:00
|
|
|
|
/// assert_eq!(full.node, Some("node".to_owned()));
|
|
|
|
|
/// assert_eq!(full.domain, "domain".to_owned());
|
|
|
|
|
/// assert_eq!(full.resource, "resource".to_owned());
|
2017-02-27 14:35:57 +00:00
|
|
|
|
/// ```
|
2019-04-21 22:52:02 +00:00
|
|
|
|
pub fn with_resource<RS>(self, resource: RS) -> FullJid
|
2018-12-18 15:40:44 +00:00
|
|
|
|
where
|
2019-04-21 22:52:02 +00:00
|
|
|
|
RS: Into<String>,
|
2018-12-18 15:40:44 +00:00
|
|
|
|
{
|
2019-04-21 22:52:02 +00:00
|
|
|
|
FullJid {
|
|
|
|
|
node: self.node,
|
|
|
|
|
domain: self.domain,
|
|
|
|
|
resource: resource.into(),
|
2017-02-27 14:35:57 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-29 04:11:30 +00:00
|
|
|
|
#[cfg(feature = "minidom")]
|
2019-07-20 17:45:06 +00:00
|
|
|
|
use minidom::{IntoAttributeValue, Node};
|
2017-07-29 04:11:30 +00:00
|
|
|
|
|
|
|
|
|
#[cfg(feature = "minidom")]
|
|
|
|
|
impl IntoAttributeValue for Jid {
|
|
|
|
|
fn into_attribute_value(self) -> Option<String> {
|
|
|
|
|
Some(String::from(self))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-31 20:24:41 +00:00
|
|
|
|
#[cfg(feature = "minidom")]
|
2021-10-11 13:35:27 +00:00
|
|
|
|
impl From<Jid> for Node {
|
|
|
|
|
fn from(jid: Jid) -> Node {
|
|
|
|
|
Node::Text(String::from(jid))
|
2017-10-31 20:24:41 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-21 22:52:02 +00:00
|
|
|
|
#[cfg(feature = "minidom")]
|
|
|
|
|
impl IntoAttributeValue for FullJid {
|
|
|
|
|
fn into_attribute_value(self) -> Option<String> {
|
|
|
|
|
Some(String::from(self))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "minidom")]
|
2021-10-11 13:35:27 +00:00
|
|
|
|
impl From<FullJid> for Node {
|
|
|
|
|
fn from(jid: FullJid) -> Node {
|
|
|
|
|
Node::Text(String::from(jid))
|
2019-04-21 22:52:02 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "minidom")]
|
|
|
|
|
impl IntoAttributeValue for BareJid {
|
|
|
|
|
fn into_attribute_value(self) -> Option<String> {
|
|
|
|
|
Some(String::from(self))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "minidom")]
|
2021-10-11 13:35:27 +00:00
|
|
|
|
impl From<BareJid> for Node {
|
|
|
|
|
fn from(jid: BareJid) -> Node {
|
|
|
|
|
Node::Text(String::from(jid))
|
2019-04-21 22:52:02 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-27 14:35:57 +00:00
|
|
|
|
#[cfg(test)]
|
|
|
|
|
mod tests {
|
|
|
|
|
use super::*;
|
|
|
|
|
|
2019-10-15 23:23:21 +00:00
|
|
|
|
use std::collections::HashMap;
|
2019-10-22 23:32:41 +00:00
|
|
|
|
use std::str::FromStr;
|
2017-02-27 14:35:57 +00:00
|
|
|
|
|
|
|
|
|
#[test]
|
2019-04-21 22:52:02 +00:00
|
|
|
|
fn can_parse_full_jids() {
|
2019-06-10 20:04:03 +00:00
|
|
|
|
assert_eq!(
|
|
|
|
|
FullJid::from_str("a@b.c/d"),
|
|
|
|
|
Ok(FullJid::new("a", "b.c", "d"))
|
|
|
|
|
);
|
2019-04-21 22:52:02 +00:00
|
|
|
|
assert_eq!(
|
|
|
|
|
FullJid::from_str("b.c/d"),
|
|
|
|
|
Ok(FullJid {
|
|
|
|
|
node: None,
|
|
|
|
|
domain: "b.c".to_owned(),
|
|
|
|
|
resource: "d".to_owned(),
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
assert_eq!(FullJid::from_str("a@b.c"), Err(JidParseError::NoResource));
|
|
|
|
|
assert_eq!(FullJid::from_str("b.c"), Err(JidParseError::NoResource));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn can_parse_bare_jids() {
|
|
|
|
|
assert_eq!(BareJid::from_str("a@b.c/d"), Ok(BareJid::new("a", "b.c")));
|
|
|
|
|
assert_eq!(
|
|
|
|
|
BareJid::from_str("b.c/d"),
|
|
|
|
|
Ok(BareJid {
|
|
|
|
|
node: None,
|
|
|
|
|
domain: "b.c".to_owned(),
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
assert_eq!(BareJid::from_str("a@b.c"), Ok(BareJid::new("a", "b.c")));
|
2018-12-18 15:40:44 +00:00
|
|
|
|
assert_eq!(
|
2019-04-21 22:52:02 +00:00
|
|
|
|
BareJid::from_str("b.c"),
|
|
|
|
|
Ok(BareJid {
|
|
|
|
|
node: None,
|
|
|
|
|
domain: "b.c".to_owned(),
|
|
|
|
|
})
|
2018-12-18 15:40:44 +00:00
|
|
|
|
);
|
2017-02-27 14:35:57 +00:00
|
|
|
|
}
|
2017-04-23 13:49:00 +00:00
|
|
|
|
|
2019-04-21 22:52:02 +00:00
|
|
|
|
#[test]
|
|
|
|
|
fn can_parse_jids() {
|
|
|
|
|
let full = FullJid::from_str("a@b.c/d").unwrap();
|
|
|
|
|
let bare = BareJid::from_str("e@f.g").unwrap();
|
|
|
|
|
|
|
|
|
|
assert_eq!(Jid::from_str("a@b.c/d"), Ok(Jid::Full(full)));
|
|
|
|
|
assert_eq!(Jid::from_str("e@f.g"), Ok(Jid::Bare(bare)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn full_to_bare_jid() {
|
|
|
|
|
let bare: BareJid = FullJid::new("a", "b.c", "d").into();
|
|
|
|
|
assert_eq!(bare, BareJid::new("a", "b.c"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn bare_to_full_jid() {
|
2019-06-10 20:04:03 +00:00
|
|
|
|
assert_eq!(
|
|
|
|
|
BareJid::new("a", "b.c").with_resource("d"),
|
|
|
|
|
FullJid::new("a", "b.c", "d")
|
|
|
|
|
);
|
2019-04-21 22:52:02 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-07-20 17:01:25 +00:00
|
|
|
|
#[test]
|
|
|
|
|
fn node_from_jid() {
|
|
|
|
|
assert_eq!(
|
|
|
|
|
Jid::Full(FullJid::new("a", "b.c", "d")).node(),
|
|
|
|
|
Some(String::from("a")),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn domain_from_jid() {
|
|
|
|
|
assert_eq!(
|
|
|
|
|
Jid::Bare(BareJid::new("a", "b.c")).domain(),
|
|
|
|
|
String::from("b.c"),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-08 20:09:25 +00:00
|
|
|
|
#[test]
|
|
|
|
|
fn jid_to_full_bare() {
|
|
|
|
|
let full = FullJid::new("a", "b.c", "d");
|
|
|
|
|
let bare = BareJid::new("a", "b.c");
|
|
|
|
|
|
2019-10-22 23:32:41 +00:00
|
|
|
|
assert_eq!(FullJid::try_from(Jid::Full(full.clone())), Ok(full.clone()),);
|
2019-09-08 20:09:25 +00:00
|
|
|
|
assert_eq!(
|
|
|
|
|
FullJid::try_from(Jid::Bare(bare.clone())),
|
|
|
|
|
Err(JidParseError::NoResource),
|
|
|
|
|
);
|
2019-10-22 23:32:41 +00:00
|
|
|
|
assert_eq!(BareJid::from(Jid::Full(full.clone())), bare.clone(),);
|
|
|
|
|
assert_eq!(BareJid::from(Jid::Bare(bare.clone())), bare,);
|
2019-09-08 20:09:25 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-04-23 13:49:00 +00:00
|
|
|
|
#[test]
|
|
|
|
|
fn serialise() {
|
2018-12-18 15:40:44 +00:00
|
|
|
|
assert_eq!(
|
2019-04-21 22:52:02 +00:00
|
|
|
|
String::from(FullJid::new("a", "b", "c")),
|
2018-12-18 15:40:44 +00:00
|
|
|
|
String::from("a@b/c")
|
|
|
|
|
);
|
2019-06-10 20:04:03 +00:00
|
|
|
|
assert_eq!(String::from(BareJid::new("a", "b")), String::from("a@b"));
|
2017-04-23 13:49:00 +00:00
|
|
|
|
}
|
2017-07-29 04:11:30 +00:00
|
|
|
|
|
2019-10-15 23:23:21 +00:00
|
|
|
|
#[test]
|
|
|
|
|
fn hash() {
|
|
|
|
|
let _map: HashMap<Jid, String> = HashMap::new();
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-18 20:36:36 +00:00
|
|
|
|
#[test]
|
2018-03-01 15:26:44 +00:00
|
|
|
|
fn invalid_jids() {
|
2019-04-21 22:52:02 +00:00
|
|
|
|
assert_eq!(BareJid::from_str(""), Err(JidParseError::NoDomain));
|
|
|
|
|
assert_eq!(BareJid::from_str("/c"), Err(JidParseError::NoDomain));
|
|
|
|
|
assert_eq!(BareJid::from_str("a@/c"), Err(JidParseError::NoDomain));
|
|
|
|
|
assert_eq!(BareJid::from_str("@b"), Err(JidParseError::EmptyNode));
|
|
|
|
|
assert_eq!(BareJid::from_str("b/"), Err(JidParseError::EmptyResource));
|
|
|
|
|
|
|
|
|
|
assert_eq!(FullJid::from_str(""), Err(JidParseError::NoDomain));
|
|
|
|
|
assert_eq!(FullJid::from_str("/c"), Err(JidParseError::NoDomain));
|
|
|
|
|
assert_eq!(FullJid::from_str("a@/c"), Err(JidParseError::NoDomain));
|
|
|
|
|
assert_eq!(FullJid::from_str("@b"), Err(JidParseError::EmptyNode));
|
|
|
|
|
assert_eq!(FullJid::from_str("b/"), Err(JidParseError::EmptyResource));
|
|
|
|
|
assert_eq!(FullJid::from_str("a@b"), Err(JidParseError::NoResource));
|
2018-02-18 20:36:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-08-31 13:17:51 +00:00
|
|
|
|
#[test]
|
|
|
|
|
fn display_jids() {
|
2019-10-22 23:32:41 +00:00
|
|
|
|
assert_eq!(
|
|
|
|
|
format!("{}", FullJid::new("a", "b", "c")),
|
|
|
|
|
String::from("a@b/c")
|
|
|
|
|
);
|
|
|
|
|
assert_eq!(format!("{}", BareJid::new("a", "b")), String::from("a@b"));
|
|
|
|
|
assert_eq!(
|
|
|
|
|
format!("{}", Jid::Full(FullJid::new("a", "b", "c"))),
|
|
|
|
|
String::from("a@b/c")
|
|
|
|
|
);
|
|
|
|
|
assert_eq!(
|
|
|
|
|
format!("{}", Jid::Bare(BareJid::new("a", "b"))),
|
|
|
|
|
String::from("a@b")
|
|
|
|
|
);
|
2019-08-31 13:17:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-07-29 04:11:30 +00:00
|
|
|
|
#[cfg(feature = "minidom")]
|
|
|
|
|
#[test]
|
|
|
|
|
fn minidom() {
|
2020-04-02 21:11:58 +00:00
|
|
|
|
let elem: minidom::Element = "<message xmlns='ns1' from='a@b/c'/>".parse().unwrap();
|
2017-07-29 04:11:30 +00:00
|
|
|
|
let to: Jid = elem.attr("from").unwrap().parse().unwrap();
|
2019-04-21 22:52:02 +00:00
|
|
|
|
assert_eq!(to, Jid::Full(FullJid::new("a", "b", "c")));
|
|
|
|
|
|
2020-04-02 21:11:58 +00:00
|
|
|
|
let elem: minidom::Element = "<message xmlns='ns1' from='a@b'/>".parse().unwrap();
|
2019-04-21 22:52:02 +00:00
|
|
|
|
let to: Jid = elem.attr("from").unwrap().parse().unwrap();
|
|
|
|
|
assert_eq!(to, Jid::Bare(BareJid::new("a", "b")));
|
|
|
|
|
|
2020-04-02 21:11:58 +00:00
|
|
|
|
let elem: minidom::Element = "<message xmlns='ns1' from='a@b/c'/>".parse().unwrap();
|
2019-04-21 22:52:02 +00:00
|
|
|
|
let to: FullJid = elem.attr("from").unwrap().parse().unwrap();
|
|
|
|
|
assert_eq!(to, FullJid::new("a", "b", "c"));
|
|
|
|
|
|
2020-04-02 21:11:58 +00:00
|
|
|
|
let elem: minidom::Element = "<message xmlns='ns1' from='a@b'/>".parse().unwrap();
|
2019-04-21 22:52:02 +00:00
|
|
|
|
let to: BareJid = elem.attr("from").unwrap().parse().unwrap();
|
|
|
|
|
assert_eq!(to, BareJid::new("a", "b"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(feature = "minidom")]
|
|
|
|
|
#[test]
|
|
|
|
|
fn minidom_into_attr() {
|
|
|
|
|
let full = FullJid::new("a", "b", "c");
|
2020-04-02 21:11:58 +00:00
|
|
|
|
let elem = minidom::Element::builder("message", "jabber:client")
|
2019-04-21 22:52:02 +00:00
|
|
|
|
.attr("from", full.clone())
|
|
|
|
|
.build();
|
|
|
|
|
assert_eq!(elem.attr("from"), Some(String::from(full).as_ref()));
|
|
|
|
|
|
|
|
|
|
let bare = BareJid::new("a", "b");
|
2020-04-02 21:11:58 +00:00
|
|
|
|
let elem = minidom::Element::builder("message", "jabber:client")
|
2019-04-21 22:52:02 +00:00
|
|
|
|
.attr("from", bare.clone())
|
|
|
|
|
.build();
|
|
|
|
|
assert_eq!(elem.attr("from"), Some(String::from(bare.clone()).as_ref()));
|
|
|
|
|
|
|
|
|
|
let jid = Jid::Bare(bare.clone());
|
2020-04-02 21:11:58 +00:00
|
|
|
|
let _elem = minidom::Element::builder("message", "jabber:client")
|
2019-04-21 22:52:02 +00:00
|
|
|
|
.attr("from", jid)
|
|
|
|
|
.build();
|
|
|
|
|
assert_eq!(elem.attr("from"), Some(String::from(bare).as_ref()));
|
2017-07-29 04:11:30 +00:00
|
|
|
|
}
|
2017-02-27 14:35:57 +00:00
|
|
|
|
}
|