mirror of
https://gitlab.com/xmpp-rs/xmpp-rs.git
synced 2024-07-12 22:21:53 +00:00
jid: Replace icu with stringprep
This dependency is unmaintained, but it is written in pure Rust unlike ICU, and doesn’t require a roundtrip through UTF-16, improving both performances (perhaps?) and ease of compilation.
This commit is contained in:
parent
a7dee0bef4
commit
d867d8d7a1
2 changed files with 26 additions and 21 deletions
|
@ -19,9 +19,6 @@ edition = "2018"
|
||||||
gitlab = { repository = "xmpp-rs/xmpp-rs" }
|
gitlab = { repository = "xmpp-rs/xmpp-rs" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
icu = { version = "0.1", optional = true }
|
|
||||||
minidom = { version = "0.15", optional = true }
|
minidom = { version = "0.15", optional = true }
|
||||||
serde = { version = "1.0", features = ["derive"], optional = true }
|
serde = { version = "1.0", features = ["derive"], optional = true }
|
||||||
|
stringprep = "0.1.2"
|
||||||
[features]
|
|
||||||
stringprep = ["icu"]
|
|
||||||
|
|
|
@ -18,15 +18,13 @@ use std::convert::{Into, TryFrom};
|
||||||
use std::error::Error as StdError;
|
use std::error::Error as StdError;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
use stringprep::{nameprep, nodeprep, resourceprep};
|
||||||
|
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
|
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
|
||||||
|
|
||||||
#[cfg(feature = "icu")]
|
|
||||||
use icu::{Icu, Strict};
|
|
||||||
|
|
||||||
/// An error that signifies that a `Jid` cannot be parsed from a string.
|
/// An error that signifies that a `Jid` cannot be parsed from a string.
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug)]
|
||||||
pub enum JidParseError {
|
pub enum JidParseError {
|
||||||
/// Happens when there is no domain, that is either the string is empty,
|
/// Happens when there is no domain, that is either the string is empty,
|
||||||
/// starts with a /, or contains the @/ sequence.
|
/// starts with a /, or contains the @/ sequence.
|
||||||
|
@ -41,19 +39,33 @@ pub enum JidParseError {
|
||||||
/// Happens when the resource is empty, that is the string ends with a /.
|
/// Happens when the resource is empty, that is the string ends with a /.
|
||||||
EmptyResource,
|
EmptyResource,
|
||||||
|
|
||||||
#[cfg(feature = "icu")]
|
|
||||||
/// Happens when the JID is invalid according to stringprep. TODO: make errors
|
/// Happens when the JID is invalid according to stringprep. TODO: make errors
|
||||||
/// meaningful.
|
/// meaningful.
|
||||||
Stringprep(icu::Error),
|
Stringprep(stringprep::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "icu")]
|
impl From<stringprep::Error> for JidParseError {
|
||||||
impl From<icu::Error> for JidParseError {
|
fn from(e: stringprep::Error) -> JidParseError {
|
||||||
fn from(e: icu::Error) -> JidParseError {
|
|
||||||
JidParseError::Stringprep(e)
|
JidParseError::Stringprep(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PartialEq for JidParseError {
|
||||||
|
fn eq(&self, other: &JidParseError) -> bool {
|
||||||
|
use JidParseError as E;
|
||||||
|
match (self, other) {
|
||||||
|
(E::NoDomain, E::NoDomain) => true,
|
||||||
|
(E::NoResource, E::NoResource) => true,
|
||||||
|
(E::EmptyNode, E::EmptyNode) => true,
|
||||||
|
(E::EmptyResource, E::EmptyResource) => true,
|
||||||
|
(E::Stringprep(_), E::Stringprep(_)) => false, // TODO: fix that.
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Eq for JidParseError {}
|
||||||
|
|
||||||
impl StdError for JidParseError {}
|
impl StdError for JidParseError {}
|
||||||
|
|
||||||
impl fmt::Display for JidParseError {
|
impl fmt::Display for JidParseError {
|
||||||
|
@ -66,7 +78,6 @@ impl fmt::Display for JidParseError {
|
||||||
JidParseError::NoResource => "no resource found in this full JID",
|
JidParseError::NoResource => "no resource found in this full JID",
|
||||||
JidParseError::EmptyNode => "nodepart empty despite the presence of a @",
|
JidParseError::EmptyNode => "nodepart empty despite the presence of a @",
|
||||||
JidParseError::EmptyResource => "resource empty despite the presence of a /",
|
JidParseError::EmptyResource => "resource empty despite the presence of a /",
|
||||||
#[cfg(feature = "icu")]
|
|
||||||
JidParseError::Stringprep(_err) => "TODO",
|
JidParseError::Stringprep(_err) => "TODO",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -416,17 +427,15 @@ fn _from_str(s: &str) -> Result<StringJid, JidParseError> {
|
||||||
return Err(JidParseError::EmptyResource);
|
return Err(JidParseError::EmptyResource);
|
||||||
}
|
}
|
||||||
let domain = domain.ok_or(JidParseError::NoDomain)?;
|
let domain = domain.ok_or(JidParseError::NoDomain)?;
|
||||||
#[cfg(feature = "icu")]
|
|
||||||
let (node, domain, resource) = {
|
let (node, domain, resource) = {
|
||||||
let icu = Icu::new()?;
|
|
||||||
let node = if let Some(node) = node {
|
let node = if let Some(node) = node {
|
||||||
Some(icu.nodeprep(&node, Strict::AllowUnassigned)?)
|
Some(nodeprep(&node)?.into_owned())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
let domain = icu.idna2008.to_unicode(&domain)?;
|
let domain = nameprep(&domain)?.into_owned();
|
||||||
let resource = if let Some(resource) = resource {
|
let resource = if let Some(resource) = resource {
|
||||||
Some(icu.resourceprep(&resource, Strict::AllowUnassigned)?)
|
Some(resourceprep(&resource)?.into_owned())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
@ -973,9 +982,8 @@ mod tests {
|
||||||
assert_eq!(elem.attr("from"), Some(String::from(bare).as_ref()));
|
assert_eq!(elem.attr("from"), Some(String::from(bare).as_ref()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "icu")]
|
|
||||||
#[test]
|
#[test]
|
||||||
fn icu_jid() {
|
fn stringprep() {
|
||||||
let full = FullJid::from_str("Test@☃.coM/Test™").unwrap();
|
let full = FullJid::from_str("Test@☃.coM/Test™").unwrap();
|
||||||
let equiv = FullJid::new("test", "☃.com", "TestTM");
|
let equiv = FullJid::new("test", "☃.com", "TestTM");
|
||||||
assert_eq!(full, equiv);
|
assert_eq!(full, equiv);
|
||||||
|
|
Loading…
Reference in a new issue