mirror of https://gitlab.com/xmpp-rs/xmpp-rs.git
Compare commits
7 Commits
23229ba716
...
4e668f18fb
Author | SHA1 | Date |
---|---|---|
Marc Bauer | 4e668f18fb | |
Jonas Schäfer | 1293e9a3eb | |
Jonas Schäfer | 054447d147 | |
Jonas Schäfer | c08946aa7c | |
Jonas Schäfer | c895cb1009 | |
Jonas Schäfer | 2e9c9411a3 | |
mb | b46fccd9f9 |
180
jid/src/inner.rs
180
jid/src/inner.rs
|
@ -1,180 +0,0 @@
|
|||
// Copyright (c) 2023 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/.
|
||||
|
||||
#![deny(missing_docs)]
|
||||
|
||||
//! Provides a type for Jabber IDs.
|
||||
//!
|
||||
//! For usage, check the documentation on the `Jid` struct.
|
||||
|
||||
use crate::Error;
|
||||
use core::num::NonZeroU16;
|
||||
use memchr::memchr;
|
||||
use std::borrow::Cow;
|
||||
use std::str::FromStr;
|
||||
use stringprep::{nameprep, nodeprep, resourceprep};
|
||||
|
||||
use crate::parts::{DomainRef, NodeRef, ResourceRef};
|
||||
|
||||
fn length_check(len: usize, error_empty: Error, error_too_long: Error) -> Result<(), Error> {
|
||||
if len == 0 {
|
||||
Err(error_empty)
|
||||
} else if len > 1023 {
|
||||
Err(error_too_long)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub(crate) struct InnerJid {
|
||||
pub(crate) normalized: String,
|
||||
pub(crate) at: Option<NonZeroU16>,
|
||||
pub(crate) slash: Option<NonZeroU16>,
|
||||
}
|
||||
|
||||
impl InnerJid {
|
||||
pub(crate) fn new(unnormalized: &str) -> Result<InnerJid, Error> {
|
||||
let bytes = unnormalized.as_bytes();
|
||||
let mut orig_at = memchr(b'@', bytes);
|
||||
let mut orig_slash = memchr(b'/', bytes);
|
||||
if orig_at.is_some() && orig_slash.is_some() && orig_at > orig_slash {
|
||||
// This is part of the resource, not a node@domain separator.
|
||||
orig_at = None;
|
||||
}
|
||||
|
||||
let normalized = match (orig_at, orig_slash) {
|
||||
(Some(at), Some(slash)) => {
|
||||
let node = nodeprep(&unnormalized[..at]).map_err(|_| Error::NodePrep)?;
|
||||
length_check(node.len(), Error::NodeEmpty, Error::NodeTooLong)?;
|
||||
|
||||
let domain = nameprep(&unnormalized[at + 1..slash]).map_err(|_| Error::NamePrep)?;
|
||||
length_check(domain.len(), Error::DomainEmpty, Error::DomainTooLong)?;
|
||||
|
||||
let resource =
|
||||
resourceprep(&unnormalized[slash + 1..]).map_err(|_| Error::ResourcePrep)?;
|
||||
length_check(resource.len(), Error::ResourceEmpty, Error::ResourceTooLong)?;
|
||||
|
||||
orig_at = Some(node.len());
|
||||
orig_slash = Some(node.len() + domain.len() + 1);
|
||||
match (node, domain, resource) {
|
||||
(Cow::Borrowed(_), Cow::Borrowed(_), Cow::Borrowed(_)) => {
|
||||
unnormalized.to_string()
|
||||
}
|
||||
(node, domain, resource) => format!("{node}@{domain}/{resource}"),
|
||||
}
|
||||
}
|
||||
(Some(at), None) => {
|
||||
let node = nodeprep(&unnormalized[..at]).map_err(|_| Error::NodePrep)?;
|
||||
length_check(node.len(), Error::NodeEmpty, Error::NodeTooLong)?;
|
||||
|
||||
let domain = nameprep(&unnormalized[at + 1..]).map_err(|_| Error::NamePrep)?;
|
||||
length_check(domain.len(), Error::DomainEmpty, Error::DomainTooLong)?;
|
||||
|
||||
orig_at = Some(node.len());
|
||||
match (node, domain) {
|
||||
(Cow::Borrowed(_), Cow::Borrowed(_)) => unnormalized.to_string(),
|
||||
(node, domain) => format!("{node}@{domain}"),
|
||||
}
|
||||
}
|
||||
(None, Some(slash)) => {
|
||||
let domain = nameprep(&unnormalized[..slash]).map_err(|_| Error::NamePrep)?;
|
||||
length_check(domain.len(), Error::DomainEmpty, Error::DomainTooLong)?;
|
||||
|
||||
let resource =
|
||||
resourceprep(&unnormalized[slash + 1..]).map_err(|_| Error::ResourcePrep)?;
|
||||
length_check(resource.len(), Error::ResourceEmpty, Error::ResourceTooLong)?;
|
||||
|
||||
orig_slash = Some(domain.len());
|
||||
match (domain, resource) {
|
||||
(Cow::Borrowed(_), Cow::Borrowed(_)) => unnormalized.to_string(),
|
||||
(domain, resource) => format!("{domain}/{resource}"),
|
||||
}
|
||||
}
|
||||
(None, None) => {
|
||||
let domain = nameprep(unnormalized).map_err(|_| Error::NamePrep)?;
|
||||
length_check(domain.len(), Error::DomainEmpty, Error::DomainTooLong)?;
|
||||
|
||||
domain.into_owned()
|
||||
}
|
||||
};
|
||||
|
||||
Ok(InnerJid {
|
||||
normalized,
|
||||
at: orig_at.and_then(|x| NonZeroU16::new(x as u16)),
|
||||
slash: orig_slash.and_then(|x| NonZeroU16::new(x as u16)),
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn node(&self) -> Option<&NodeRef> {
|
||||
self.at.map(|at| {
|
||||
let at = u16::from(at) as usize;
|
||||
NodeRef::from_str_unchecked(&self.normalized[..at])
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn domain(&self) -> &DomainRef {
|
||||
match (self.at, self.slash) {
|
||||
(Some(at), Some(slash)) => {
|
||||
let at = u16::from(at) as usize;
|
||||
let slash = u16::from(slash) as usize;
|
||||
DomainRef::from_str_unchecked(&self.normalized[at + 1..slash])
|
||||
}
|
||||
(Some(at), None) => {
|
||||
let at = u16::from(at) as usize;
|
||||
DomainRef::from_str_unchecked(&self.normalized[at + 1..])
|
||||
}
|
||||
(None, Some(slash)) => {
|
||||
let slash = u16::from(slash) as usize;
|
||||
DomainRef::from_str_unchecked(&self.normalized[..slash])
|
||||
}
|
||||
(None, None) => DomainRef::from_str_unchecked(&self.normalized),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn resource(&self) -> Option<&ResourceRef> {
|
||||
self.slash.map(|slash| {
|
||||
let slash = u16::from(slash) as usize;
|
||||
ResourceRef::from_str_unchecked(&self.normalized[slash + 1..])
|
||||
})
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn as_str(&self) -> &str {
|
||||
self.normalized.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for InnerJid {
|
||||
type Err = Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
InnerJid::new(s)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
macro_rules! assert_size (
|
||||
($t:ty, $sz:expr) => (
|
||||
assert_eq!(::std::mem::size_of::<$t>(), $sz);
|
||||
);
|
||||
);
|
||||
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
#[test]
|
||||
fn test_size() {
|
||||
assert_size!(InnerJid, 16);
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
#[test]
|
||||
fn test_size() {
|
||||
assert_size!(InnerJid, 32);
|
||||
}
|
||||
}
|
831
jid/src/lib.rs
831
jid/src/lib.rs
File diff suppressed because it is too large
Load Diff
|
@ -5,7 +5,7 @@ use std::str::FromStr;
|
|||
|
||||
use stringprep::{nameprep, nodeprep, resourceprep};
|
||||
|
||||
use crate::{BareJid, Error, InnerJid, Jid};
|
||||
use crate::{BareJid, Error, Jid};
|
||||
|
||||
fn length_check(len: usize, error_empty: Error, error_too_long: Error) -> Result<(), Error> {
|
||||
if len == 0 {
|
||||
|
@ -250,18 +250,18 @@ impl DomainRef {
|
|||
impl From<DomainPart> for BareJid {
|
||||
fn from(other: DomainPart) -> Self {
|
||||
BareJid {
|
||||
inner: InnerJid {
|
||||
normalized: other.0,
|
||||
at: None,
|
||||
slash: None,
|
||||
},
|
||||
inner: other.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<DomainPart> for Jid {
|
||||
fn from(other: DomainPart) -> Self {
|
||||
Jid::Bare(other.into())
|
||||
Jid {
|
||||
normalized: other.0,
|
||||
at: None,
|
||||
slash: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ impl From<BindResponse> for FullJid {
|
|||
|
||||
impl From<BindResponse> for Jid {
|
||||
fn from(bind: BindResponse) -> Jid {
|
||||
Jid::Full(bind.jid)
|
||||
Jid::from(bind.jid)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -127,10 +127,12 @@ fn compute_extensions(extensions: &[DataForm]) -> Vec<u8> {
|
|||
}
|
||||
bytes.push(b'<');
|
||||
for field in extension.fields.clone() {
|
||||
if field.var == "FORM_TYPE" {
|
||||
if field.var.as_deref() == Some("FORM_TYPE") {
|
||||
continue;
|
||||
}
|
||||
bytes.append(&mut compute_item(&field.var));
|
||||
if let Some(var) = &field.var {
|
||||
bytes.append(&mut compute_item(var));
|
||||
}
|
||||
bytes.append(&mut compute_items(&field.values, |value| {
|
||||
compute_item(value)
|
||||
}));
|
||||
|
|
|
@ -71,8 +71,8 @@ mod tests {
|
|||
assert_size!(Enable, 0);
|
||||
assert_size!(Disable, 0);
|
||||
assert_size!(Private, 0);
|
||||
assert_size!(Received, 152);
|
||||
assert_size!(Sent, 152);
|
||||
assert_size!(Received, 140);
|
||||
assert_size!(Sent, 140);
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
|
@ -81,8 +81,8 @@ mod tests {
|
|||
assert_size!(Enable, 0);
|
||||
assert_size!(Disable, 0);
|
||||
assert_size!(Private, 0);
|
||||
assert_size!(Received, 288);
|
||||
assert_size!(Sent, 288);
|
||||
assert_size!(Received, 264);
|
||||
assert_size!(Sent, 264);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -71,7 +71,7 @@ generate_attribute!(
|
|||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct Field {
|
||||
/// The unique identifier for this field, in the form.
|
||||
pub var: String,
|
||||
pub var: Option<String>,
|
||||
|
||||
/// The type of this field.
|
||||
pub type_: FieldType,
|
||||
|
@ -96,7 +96,7 @@ impl Field {
|
|||
/// Create a new Field, of the given var and type.
|
||||
pub fn new(var: &str, type_: FieldType) -> Field {
|
||||
Field {
|
||||
var: String::from(var),
|
||||
var: Some(String::from(var)),
|
||||
type_,
|
||||
label: None,
|
||||
required: false,
|
||||
|
@ -129,7 +129,7 @@ impl TryFrom<Element> for Field {
|
|||
check_self!(elem, "field", DATA_FORMS);
|
||||
check_no_unknown_attributes!(elem, "field", ["label", "type", "var"]);
|
||||
let mut field = Field {
|
||||
var: get_attr!(elem, "var", Required),
|
||||
var: get_attr!(elem, "var", Option),
|
||||
type_: get_attr!(elem, "type", Default),
|
||||
label: get_attr!(elem, "label", Option),
|
||||
required: false,
|
||||
|
@ -137,6 +137,11 @@ impl TryFrom<Element> for Field {
|
|||
values: vec![],
|
||||
media: vec![],
|
||||
};
|
||||
|
||||
if field.type_ != FieldType::Fixed && field.var.is_none() {
|
||||
return Err(Error::ParseError("Required attribute 'var' missing."));
|
||||
}
|
||||
|
||||
for element in elem.children() {
|
||||
if element.is("value", ns::DATA_FORMS) {
|
||||
check_no_children!(element, "value");
|
||||
|
@ -276,7 +281,7 @@ impl TryFrom<Element> for DataForm {
|
|||
form.instructions = Some(child.text());
|
||||
} else if child.is("field", ns::DATA_FORMS) {
|
||||
let field = Field::try_from(child.clone())?;
|
||||
if field.var == "FORM_TYPE" {
|
||||
if field.var.as_deref() == Some("FORM_TYPE") {
|
||||
let mut field = field;
|
||||
if form.form_type.is_some() {
|
||||
return Err(Error::ParseError("More than one FORM_TYPE in a data form."));
|
||||
|
@ -355,6 +360,43 @@ mod tests {
|
|||
assert!(form.fields.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_missing_var() {
|
||||
let elem: Element =
|
||||
"<x xmlns='jabber:x:data' type='form'><field type='text-single' label='The name of your bot'/></x>"
|
||||
.parse()
|
||||
.unwrap();
|
||||
let error = DataForm::try_from(elem).unwrap_err();
|
||||
let message = match error {
|
||||
Error::ParseError(string) => string,
|
||||
_ => panic!(),
|
||||
};
|
||||
assert_eq!(message, "Required attribute 'var' missing.");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fixed_field() {
|
||||
let elem: Element =
|
||||
"<x xmlns='jabber:x:data' type='form'><field type='fixed'><value>Section 1: Bot Info</value></field></x>"
|
||||
.parse()
|
||||
.unwrap();
|
||||
let form = DataForm::try_from(elem).unwrap();
|
||||
assert_eq!(form.type_, DataFormType::Form);
|
||||
assert!(form.form_type.is_none());
|
||||
assert_eq!(
|
||||
form.fields,
|
||||
vec![Field {
|
||||
var: None,
|
||||
type_: FieldType::Fixed,
|
||||
label: None,
|
||||
required: false,
|
||||
options: vec![],
|
||||
values: vec!["Section 1: Bot Info".to_string()],
|
||||
media: vec![],
|
||||
}]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid() {
|
||||
let elem: Element = "<x xmlns='jabber:x:data'/>".parse().unwrap();
|
||||
|
|
|
@ -40,13 +40,13 @@ mod tests {
|
|||
#[cfg(target_pointer_width = "32")]
|
||||
#[test]
|
||||
fn test_size() {
|
||||
assert_size!(Delay, 48);
|
||||
assert_size!(Delay, 44);
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
#[test]
|
||||
fn test_size() {
|
||||
assert_size!(Delay, 80);
|
||||
assert_size!(Delay, 72);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -248,7 +248,7 @@ mod tests {
|
|||
assert_size!(DiscoInfoQuery, 12);
|
||||
assert_size!(DiscoInfoResult, 48);
|
||||
|
||||
assert_size!(Item, 44);
|
||||
assert_size!(Item, 40);
|
||||
assert_size!(DiscoItemsQuery, 52);
|
||||
assert_size!(DiscoItemsResult, 64);
|
||||
}
|
||||
|
@ -261,7 +261,7 @@ mod tests {
|
|||
assert_size!(DiscoInfoQuery, 24);
|
||||
assert_size!(DiscoInfoResult, 96);
|
||||
|
||||
assert_size!(Item, 88);
|
||||
assert_size!(Item, 80);
|
||||
assert_size!(DiscoItemsQuery, 104);
|
||||
assert_size!(DiscoItemsResult, 128);
|
||||
}
|
||||
|
|
|
@ -94,7 +94,10 @@ fn compute_extensions(extensions: &[DataForm]) -> Result<Vec<u8>, Error> {
|
|||
));
|
||||
bytes.push(0x1e);
|
||||
bytes.append(&mut compute_items(&extension.fields, 0x1d, |field| {
|
||||
let mut bytes = compute_item(&field.var);
|
||||
let mut bytes = vec![];
|
||||
if let Some(var) = &field.var {
|
||||
bytes.append(&mut compute_item(var));
|
||||
}
|
||||
bytes.append(&mut compute_items(&field.values, 0x1e, |value| {
|
||||
compute_item(value)
|
||||
}));
|
||||
|
|
|
@ -32,13 +32,13 @@ mod tests {
|
|||
#[cfg(target_pointer_width = "32")]
|
||||
#[test]
|
||||
fn test_size() {
|
||||
assert_size!(Forwarded, 152);
|
||||
assert_size!(Forwarded, 140);
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
#[test]
|
||||
fn test_size() {
|
||||
assert_size!(Forwarded, 288);
|
||||
assert_size!(Forwarded, 264);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -232,15 +232,15 @@ mod tests {
|
|||
#[cfg(target_pointer_width = "32")]
|
||||
#[test]
|
||||
fn test_size() {
|
||||
assert_size!(IqType, 96);
|
||||
assert_size!(Iq, 148);
|
||||
assert_size!(IqType, 92);
|
||||
assert_size!(Iq, 156);
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
#[test]
|
||||
fn test_size() {
|
||||
assert_size!(IqType, 192);
|
||||
assert_size!(Iq, 296);
|
||||
assert_size!(IqType, 184);
|
||||
assert_size!(Iq, 272);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -46,14 +46,14 @@ mod tests {
|
|||
#[test]
|
||||
fn test_size() {
|
||||
assert_size!(JidPrepQuery, 12);
|
||||
assert_size!(JidPrepResponse, 20);
|
||||
assert_size!(JidPrepResponse, 16);
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
#[test]
|
||||
fn test_size() {
|
||||
assert_size!(JidPrepQuery, 24);
|
||||
assert_size!(JidPrepResponse, 40);
|
||||
assert_size!(JidPrepResponse, 32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -692,7 +692,7 @@ mod tests {
|
|||
assert_size!(Reason, 1);
|
||||
assert_size!(ReasonElement, 16);
|
||||
assert_size!(SessionId, 12);
|
||||
assert_size!(Jingle, 112);
|
||||
assert_size!(Jingle, 104);
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
|
@ -711,7 +711,7 @@ mod tests {
|
|||
assert_size!(Reason, 1);
|
||||
assert_size!(ReasonElement, 32);
|
||||
assert_size!(SessionId, 24);
|
||||
assert_size!(Jingle, 224);
|
||||
assert_size!(Jingle, 208);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -284,7 +284,7 @@ mod tests {
|
|||
assert_size!(Mode, 1);
|
||||
assert_size!(CandidateId, 12);
|
||||
assert_size!(StreamId, 12);
|
||||
assert_size!(Candidate, 60);
|
||||
assert_size!(Candidate, 56);
|
||||
assert_size!(TransportPayload, 16);
|
||||
assert_size!(Transport, 44);
|
||||
}
|
||||
|
@ -296,7 +296,7 @@ mod tests {
|
|||
assert_size!(Mode, 1);
|
||||
assert_size!(CandidateId, 24);
|
||||
assert_size!(StreamId, 24);
|
||||
assert_size!(Candidate, 96);
|
||||
assert_size!(Candidate, 88);
|
||||
assert_size!(TransportPayload, 32);
|
||||
assert_size!(Transport, 88);
|
||||
}
|
||||
|
|
|
@ -166,7 +166,7 @@ mod tests {
|
|||
fn test_size() {
|
||||
assert_size!(QueryId, 12);
|
||||
assert_size!(Query, 120);
|
||||
assert_size!(Result_, 176);
|
||||
assert_size!(Result_, 164);
|
||||
assert_size!(Complete, 1);
|
||||
assert_size!(Fin, 44);
|
||||
}
|
||||
|
@ -176,7 +176,7 @@ mod tests {
|
|||
fn test_size() {
|
||||
assert_size!(QueryId, 24);
|
||||
assert_size!(Query, 240);
|
||||
assert_size!(Result_, 336);
|
||||
assert_size!(Result_, 312);
|
||||
assert_size!(Complete, 1);
|
||||
assert_size!(Fin, 88);
|
||||
}
|
||||
|
|
|
@ -232,7 +232,7 @@ mod tests {
|
|||
.unwrap();
|
||||
let form = DataForm::try_from(elem).unwrap();
|
||||
assert_eq!(form.fields.len(), 1);
|
||||
assert_eq!(form.fields[0].var, "ocr");
|
||||
assert_eq!(form.fields[0].var.as_deref(), Some("ocr"));
|
||||
assert_eq!(form.fields[0].media[0].width, Some(290));
|
||||
assert_eq!(form.fields[0].media[0].height, Some(80));
|
||||
assert_eq!(form.fields[0].media[0].uris[0].type_, "image/jpeg");
|
||||
|
|
|
@ -307,7 +307,7 @@ mod tests {
|
|||
assert_size!(Body, 12);
|
||||
assert_size!(Subject, 12);
|
||||
assert_size!(Thread, 12);
|
||||
assert_size!(Message, 104);
|
||||
assert_size!(Message, 96);
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
|
@ -317,7 +317,7 @@ mod tests {
|
|||
assert_size!(Body, 24);
|
||||
assert_size!(Subject, 24);
|
||||
assert_size!(Thread, 24);
|
||||
assert_size!(Message, 208);
|
||||
assert_size!(Message, 192);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -379,7 +379,7 @@ mod tests {
|
|||
fn test_size() {
|
||||
assert_size!(Show, 1);
|
||||
assert_size!(Type, 1);
|
||||
assert_size!(Presence, 80);
|
||||
assert_size!(Presence, 72);
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
|
@ -387,7 +387,7 @@ mod tests {
|
|||
fn test_size() {
|
||||
assert_size!(Show, 1);
|
||||
assert_size!(Type, 1);
|
||||
assert_size!(Presence, 160);
|
||||
assert_size!(Presence, 144);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -200,11 +200,11 @@ mod tests {
|
|||
node: NodeName(String::from("foo")),
|
||||
affiliations: vec![
|
||||
Affiliation {
|
||||
jid: Jid::Bare(BareJid::from_str("hamlet@denmark.lit").unwrap()),
|
||||
jid: Jid::from(BareJid::from_str("hamlet@denmark.lit").unwrap()),
|
||||
affiliation: AffiliationAttribute::Owner,
|
||||
},
|
||||
Affiliation {
|
||||
jid: Jid::Bare(BareJid::from_str("polonius@denmark.lit").unwrap()),
|
||||
jid: Jid::from(BareJid::from_str("polonius@denmark.lit").unwrap()),
|
||||
affiliation: AffiliationAttribute::Outcast,
|
||||
},
|
||||
],
|
||||
|
@ -229,7 +229,7 @@ mod tests {
|
|||
title: None,
|
||||
instructions: None,
|
||||
fields: vec![Field {
|
||||
var: String::from("pubsub#access_model"),
|
||||
var: Some(String::from("pubsub#access_model")),
|
||||
type_: FieldType::ListSingle,
|
||||
label: None,
|
||||
required: false,
|
||||
|
@ -276,7 +276,7 @@ mod tests {
|
|||
title: None,
|
||||
instructions: None,
|
||||
fields: vec![Field {
|
||||
var: String::from("pubsub#access_model"),
|
||||
var: Some(String::from("pubsub#access_model")),
|
||||
type_: FieldType::ListSingle,
|
||||
label: None,
|
||||
required: false,
|
||||
|
@ -335,22 +335,22 @@ mod tests {
|
|||
node: NodeName(String::from("foo")),
|
||||
subscriptions: vec![
|
||||
SubscriptionElem {
|
||||
jid: Jid::Bare(BareJid::from_str("hamlet@denmark.lit").unwrap()),
|
||||
jid: Jid::from(BareJid::from_str("hamlet@denmark.lit").unwrap()),
|
||||
subscription: Subscription::Subscribed,
|
||||
subid: None,
|
||||
},
|
||||
SubscriptionElem {
|
||||
jid: Jid::Bare(BareJid::from_str("polonius@denmark.lit").unwrap()),
|
||||
jid: Jid::from(BareJid::from_str("polonius@denmark.lit").unwrap()),
|
||||
subscription: Subscription::Unconfigured,
|
||||
subid: None,
|
||||
},
|
||||
SubscriptionElem {
|
||||
jid: Jid::Bare(BareJid::from_str("bernardo@denmark.lit").unwrap()),
|
||||
jid: Jid::from(BareJid::from_str("bernardo@denmark.lit").unwrap()),
|
||||
subscription: Subscription::Subscribed,
|
||||
subid: Some(String::from("123-abc")),
|
||||
},
|
||||
SubscriptionElem {
|
||||
jid: Jid::Bare(BareJid::from_str("bernardo@denmark.lit").unwrap()),
|
||||
jid: Jid::from(BareJid::from_str("bernardo@denmark.lit").unwrap()),
|
||||
subscription: Subscription::Subscribed,
|
||||
subid: Some(String::from("004-yyy")),
|
||||
},
|
||||
|
|
|
@ -621,7 +621,7 @@ mod tests {
|
|||
title: None,
|
||||
instructions: None,
|
||||
fields: vec![Field {
|
||||
var: String::from("pubsub#access_model"),
|
||||
var: Some(String::from("pubsub#access_model")),
|
||||
type_: FieldType::ListSingle,
|
||||
label: None,
|
||||
required: false,
|
||||
|
|
|
@ -44,17 +44,17 @@ impl TryFrom<DataForm> for ServerInfo {
|
|||
if field.type_ != FieldType::ListMulti {
|
||||
return Err(Error::ParseError("Field is not of the required type."));
|
||||
}
|
||||
if field.var == "abuse-addresses" {
|
||||
if field.var.as_deref() == Some("abuse-addresses") {
|
||||
server_info.abuse = field.values;
|
||||
} else if field.var == "admin-addresses" {
|
||||
} else if field.var.as_deref() == Some("admin-addresses") {
|
||||
server_info.admin = field.values;
|
||||
} else if field.var == "feedback-addresses" {
|
||||
} else if field.var.as_deref() == Some("feedback-addresses") {
|
||||
server_info.feedback = field.values;
|
||||
} else if field.var == "sales-addresses" {
|
||||
} else if field.var.as_deref() == Some("sales-addresses") {
|
||||
server_info.sales = field.values;
|
||||
} else if field.var == "security-addresses" {
|
||||
} else if field.var.as_deref() == Some("security-addresses") {
|
||||
server_info.security = field.values;
|
||||
} else if field.var == "support-addresses" {
|
||||
} else if field.var.as_deref() == Some("support-addresses") {
|
||||
server_info.support = field.values;
|
||||
} else {
|
||||
return Err(Error::ParseError("Unknown form field var."));
|
||||
|
@ -87,7 +87,7 @@ impl From<ServerInfo> for DataForm {
|
|||
/// Generate `Field` for addresses
|
||||
pub fn generate_address_field<S: Into<String>>(var: S, values: Vec<String>) -> Field {
|
||||
Field {
|
||||
var: var.into(),
|
||||
var: Some(var.into()),
|
||||
type_: FieldType::ListMulti,
|
||||
label: None,
|
||||
required: false,
|
||||
|
@ -122,7 +122,7 @@ mod tests {
|
|||
instructions: None,
|
||||
fields: vec![
|
||||
Field {
|
||||
var: String::from("abuse-addresses"),
|
||||
var: Some(String::from("abuse-addresses")),
|
||||
type_: FieldType::ListMulti,
|
||||
label: None,
|
||||
required: false,
|
||||
|
@ -131,7 +131,7 @@ mod tests {
|
|||
media: vec![],
|
||||
},
|
||||
Field {
|
||||
var: String::from("admin-addresses"),
|
||||
var: Some(String::from("admin-addresses")),
|
||||
type_: FieldType::ListMulti,
|
||||
label: None,
|
||||
required: false,
|
||||
|
@ -144,7 +144,7 @@ mod tests {
|
|||
media: vec![],
|
||||
},
|
||||
Field {
|
||||
var: String::from("feedback-addresses"),
|
||||
var: Some(String::from("feedback-addresses")),
|
||||
type_: FieldType::ListMulti,
|
||||
label: None,
|
||||
required: false,
|
||||
|
@ -153,7 +153,7 @@ mod tests {
|
|||
media: vec![],
|
||||
},
|
||||
Field {
|
||||
var: String::from("sales-addresses"),
|
||||
var: Some(String::from("sales-addresses")),
|
||||
type_: FieldType::ListMulti,
|
||||
label: None,
|
||||
required: false,
|
||||
|
@ -162,7 +162,7 @@ mod tests {
|
|||
media: vec![],
|
||||
},
|
||||
Field {
|
||||
var: String::from("security-addresses"),
|
||||
var: Some(String::from("security-addresses")),
|
||||
type_: FieldType::ListMulti,
|
||||
label: None,
|
||||
required: false,
|
||||
|
@ -174,7 +174,7 @@ mod tests {
|
|||
media: vec![],
|
||||
},
|
||||
Field {
|
||||
var: String::from("support-addresses"),
|
||||
var: Some(String::from("support-addresses")),
|
||||
type_: FieldType::ListMulti,
|
||||
label: None,
|
||||
required: false,
|
||||
|
|
|
@ -319,7 +319,7 @@ mod tests {
|
|||
fn test_size() {
|
||||
assert_size!(ErrorType, 1);
|
||||
assert_size!(DefinedCondition, 1);
|
||||
assert_size!(StanzaError, 96);
|
||||
assert_size!(StanzaError, 92);
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
|
@ -327,7 +327,7 @@ mod tests {
|
|||
fn test_size() {
|
||||
assert_size!(ErrorType, 1);
|
||||
assert_size!(DefinedCondition, 1);
|
||||
assert_size!(StanzaError, 192);
|
||||
assert_size!(StanzaError, 184);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -44,14 +44,14 @@ mod tests {
|
|||
#[cfg(target_pointer_width = "32")]
|
||||
#[test]
|
||||
fn test_size() {
|
||||
assert_size!(StanzaId, 32);
|
||||
assert_size!(StanzaId, 24);
|
||||
assert_size!(OriginId, 12);
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
#[test]
|
||||
fn test_size() {
|
||||
assert_size!(StanzaId, 64);
|
||||
assert_size!(StanzaId, 56);
|
||||
assert_size!(OriginId, 24);
|
||||
}
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ async fn main() -> Result<(), Option<()>> {
|
|||
Event::RoomJoined(jid) => {
|
||||
println!("Joined room {}.", jid);
|
||||
client
|
||||
.send_message(Jid::Bare(jid), MessageType::Groupchat, "en", "Hello world!")
|
||||
.send_message(Jid::from(jid), MessageType::Groupchat, "en", "Hello world!")
|
||||
.await;
|
||||
}
|
||||
Event::RoomLeft(jid) => {
|
||||
|
|
|
@ -25,8 +25,8 @@ pub async fn handle_message_chat<C: ServerConnector>(
|
|||
|
||||
for payload in &message.payloads {
|
||||
if let Ok(_) = MucUser::try_from(payload.clone()) {
|
||||
let event = match from.clone() {
|
||||
Jid::Bare(bare) => {
|
||||
let event = match from.clone().try_into_full() {
|
||||
Err(bare) => {
|
||||
// TODO: Can a service message be of type Chat/Normal and not Groupchat?
|
||||
warn!("Received misformed MessageType::Chat in muc#user namespace from a bare JID.");
|
||||
Event::ServiceMessage(
|
||||
|
@ -36,7 +36,7 @@ pub async fn handle_message_chat<C: ServerConnector>(
|
|||
time_info.clone(),
|
||||
)
|
||||
}
|
||||
Jid::Full(full) => Event::RoomPrivateMessage(
|
||||
Ok(full) => Event::RoomPrivateMessage(
|
||||
message.id.clone(),
|
||||
full.to_bare(),
|
||||
full.resource().to_string(),
|
||||
|
|
|
@ -28,17 +28,15 @@ pub async fn handle_message_group_chat<C: ServerConnector>(
|
|||
}
|
||||
|
||||
if let Some((_lang, body)) = message.get_best_body(langs) {
|
||||
let event = match from.clone() {
|
||||
Jid::Full(full) => Event::RoomMessage(
|
||||
let event = match from.clone().try_into_full() {
|
||||
Ok(full) => Event::RoomMessage(
|
||||
message.id.clone(),
|
||||
from.to_bare(),
|
||||
full.resource().to_string(),
|
||||
body.clone(),
|
||||
time_info,
|
||||
),
|
||||
Jid::Bare(bare) => {
|
||||
Event::ServiceMessage(message.id.clone(), bare, body.clone(), time_info)
|
||||
}
|
||||
Err(bare) => Event::ServiceMessage(message.id.clone(), bare, body.clone(), time_info),
|
||||
};
|
||||
events.push(event)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue