diff --git a/jid/src/error.rs b/jid/src/error.rs index bcb3ad8af9c01b0901785a242c48f8335c6b405e..535d1223d2b38825da093b767b24005c19340fff 100644 --- a/jid/src/error.rs +++ b/jid/src/error.rs @@ -16,19 +16,12 @@ pub enum Error { /// Happens when the node is empty, that is the string starts with a @. NodeEmpty, - /// Happens when there is no domain, that is either the string is empty, - /// starts with a /, or contains the @/ sequence. - DomainEmpty, - /// Happens when the resource is empty, that is the string ends with a /. ResourceEmpty, /// Happens when the localpart is longer than 1023 bytes. NodeTooLong, - /// Happens when the domain is longer than 1023 bytes. - DomainTooLong, - /// Happens when the resource is longer than 1023 bytes. ResourceTooLong, @@ -60,10 +53,8 @@ impl fmt::Display for Error { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.write_str(match self { Error::NodeEmpty => "nodepart empty despite the presence of a @", - Error::DomainEmpty => "no domain found in this JID", Error::ResourceEmpty => "resource empty despite the presence of a /", Error::NodeTooLong => "localpart longer than 1023 bytes", - Error::DomainTooLong => "domain longer than 1023 bytes", Error::ResourceTooLong => "resource longer than 1023 bytes", Error::NodePrep => "localpart doesn’t pass nodeprep validation", Error::NamePrep => "domain doesn’t pass nameprep validation", diff --git a/jid/src/parts.rs b/jid/src/parts.rs index 35259be4310ca88489a083d1c50a840e6c0715b0..c64ea790f5798862e1169baa65e59888383112a6 100644 --- a/jid/src/parts.rs +++ b/jid/src/parts.rs @@ -8,20 +8,10 @@ use core::str::FromStr; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; -use stringprep::{nameprep, nodeprep, resourceprep}; +use crate::{domain_check, node_check, resource_check}; use crate::{BareJid, Error, Jid}; -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(()) - } -} - macro_rules! def_part_parse_doc { ($name:ident, $other:ident, $more:expr) => { concat!( @@ -57,7 +47,7 @@ macro_rules! def_part_into_inner_doc { macro_rules! def_part_types { ( $(#[$mainmeta:meta])* - pub struct $name:ident(String) use $prepfn:ident(err = $preperr:path, empty = $emptyerr:path, long = $longerr:path); + pub struct $name:ident(String) use $check_fn:ident(); $(#[$refmeta:meta])* pub struct ref $borrowed:ident(str); @@ -70,9 +60,8 @@ macro_rules! def_part_types { impl $name { #[doc = def_part_parse_doc!($name, str, "Depending on whether the contents are changed by normalisation operations, this function either returns a copy or a reference to the original data.")] pub fn new(s: &str) -> Result, Error> { - let node = $prepfn(s).map_err(|_| $preperr)?; - length_check(node.len(), $emptyerr, $longerr)?; - match node { + let part = $check_fn(s)?; + match part { Cow::Borrowed(v) => Ok(Cow::Borrowed($borrowed::from_str_unchecked(v))), Cow::Owned(v) => Ok(Cow::Owned(Self(v))), } @@ -213,7 +202,7 @@ def_part_types! { /// /// The corresponding slice type is [`NodeRef`]. #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] - pub struct NodePart(String) use nodeprep(err = Error::NodePrep, empty = Error::NodeEmpty, long = Error::NodeTooLong); + pub struct NodePart(String) use node_check(); /// `str`-like type which conforms to the requirements of [`NodePart`]. /// @@ -227,7 +216,7 @@ def_part_types! { /// (optional) `/` in any [`Jid`][crate::Jid], whether /// [`BareJid`][crate::BareJid] or [`FullJid`][crate::FullJid]. #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] - pub struct DomainPart(String) use nameprep(err = Error::NamePrep, empty = Error::DomainEmpty, long = Error::DomainTooLong); + pub struct DomainPart(String) use domain_check(); /// `str`-like type which conforms to the requirements of [`DomainPart`]. /// @@ -240,7 +229,7 @@ def_part_types! { /// The [`ResourcePart`] is the optional part after the `/` in a /// [`Jid`][crate::Jid]. It is mandatory in [`FullJid`][crate::FullJid]. #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] - pub struct ResourcePart(String) use resourceprep(err = Error::ResourcePrep, empty = Error::ResourceEmpty, long = Error::ResourceTooLong); + pub struct ResourcePart(String) use resource_check(); /// `str`-like type which conforms to the requirements of /// [`ResourcePart`].