jid: Rename errors to make them more consistent

This commit is contained in:
Emmanuel Gil Peyrot 2023-06-20 17:58:16 +02:00
parent 1904f0af6c
commit ccf41fc1e8
3 changed files with 45 additions and 36 deletions

View file

@ -14,18 +14,15 @@ use std::fmt;
/// 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, PartialEq, Eq)]
pub enum Error { 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, /// 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.
NoDomain, DomainEmpty,
/// Happens when there is no resource, that is string contains no /.
NoResource,
/// Happens when the node is empty, that is the string starts with a @.
EmptyNode,
/// 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, ResourceEmpty,
/// Happens when the localpart is longer than 1023 bytes. /// Happens when the localpart is longer than 1023 bytes.
NodeTooLong, NodeTooLong,
@ -45,6 +42,9 @@ pub enum Error {
/// Happens when the resource is invalid according to resourceprep. /// Happens when the resource is invalid according to resourceprep.
ResourcePrep, ResourcePrep,
/// Happens when there is no resource, that is string contains no /.
ResourceMissingInFullJid,
/// Happens when parsing a bare JID and there is a resource. /// Happens when parsing a bare JID and there is a resource.
ResourceInBareJid, ResourceInBareJid,
} }
@ -54,16 +54,16 @@ impl StdError for Error {}
impl fmt::Display for Error { impl fmt::Display for Error {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.write_str(match self { fmt.write_str(match self {
Error::NoDomain => "no domain found in this JID", Error::NodeEmpty => "nodepart empty despite the presence of a @",
Error::NoResource => "no resource found in this full JID", Error::DomainEmpty => "no domain found in this JID",
Error::EmptyNode => "nodepart empty despite the presence of a @", Error::ResourceEmpty => "resource empty despite the presence of a /",
Error::EmptyResource => "resource empty despite the presence of a /",
Error::NodeTooLong => "localpart longer than 1023 bytes", Error::NodeTooLong => "localpart longer than 1023 bytes",
Error::DomainTooLong => "domain longer than 1023 bytes", Error::DomainTooLong => "domain longer than 1023 bytes",
Error::ResourceTooLong => "resource longer than 1023 bytes", Error::ResourceTooLong => "resource longer than 1023 bytes",
Error::NodePrep => "localpart doesnt pass nodeprep validation", Error::NodePrep => "localpart doesnt pass nodeprep validation",
Error::NamePrep => "domain doesnt pass nameprep validation", Error::NamePrep => "domain doesnt pass nameprep validation",
Error::ResourcePrep => "resource doesnt pass resourceprep validation", Error::ResourcePrep => "resource doesnt pass resourceprep validation",
Error::ResourceMissingInFullJid => "no resource found in this full JID",
Error::ResourceInBareJid => "resource found while parsing a bare JID", Error::ResourceInBareJid => "resource found while parsing a bare JID",
}) })
} }

View file

@ -46,14 +46,14 @@ impl InnerJid {
let normalized = match (orig_at, orig_slash) { let normalized = match (orig_at, orig_slash) {
(Some(at), Some(slash)) => { (Some(at), Some(slash)) => {
let node = nodeprep(&unnormalized[..at]).map_err(|_| Error::NodePrep)?; let node = nodeprep(&unnormalized[..at]).map_err(|_| Error::NodePrep)?;
length_check(node.len(), Error::EmptyNode, Error::NodeTooLong)?; length_check(node.len(), Error::NodeEmpty, Error::NodeTooLong)?;
let domain = nameprep(&unnormalized[at + 1..slash]).map_err(|_| Error::NamePrep)?; let domain = nameprep(&unnormalized[at + 1..slash]).map_err(|_| Error::NamePrep)?;
length_check(domain.len(), Error::NoDomain, Error::DomainTooLong)?; length_check(domain.len(), Error::DomainEmpty, Error::DomainTooLong)?;
let resource = let resource =
resourceprep(&unnormalized[slash + 1..]).map_err(|_| Error::ResourcePrep)?; resourceprep(&unnormalized[slash + 1..]).map_err(|_| Error::ResourcePrep)?;
length_check(resource.len(), Error::EmptyResource, Error::ResourceTooLong)?; length_check(resource.len(), Error::ResourceEmpty, Error::ResourceTooLong)?;
orig_at = Some(node.len()); orig_at = Some(node.len());
orig_slash = Some(node.len() + domain.len() + 1); orig_slash = Some(node.len() + domain.len() + 1);
@ -61,28 +61,28 @@ impl InnerJid {
} }
(Some(at), None) => { (Some(at), None) => {
let node = nodeprep(&unnormalized[..at]).map_err(|_| Error::NodePrep)?; let node = nodeprep(&unnormalized[..at]).map_err(|_| Error::NodePrep)?;
length_check(node.len(), Error::EmptyNode, Error::NodeTooLong)?; length_check(node.len(), Error::NodeEmpty, Error::NodeTooLong)?;
let domain = nameprep(&unnormalized[at + 1..]).map_err(|_| Error::NamePrep)?; let domain = nameprep(&unnormalized[at + 1..]).map_err(|_| Error::NamePrep)?;
length_check(domain.len(), Error::NoDomain, Error::DomainTooLong)?; length_check(domain.len(), Error::DomainEmpty, Error::DomainTooLong)?;
orig_at = Some(node.len()); orig_at = Some(node.len());
format!("{node}@{domain}") format!("{node}@{domain}")
} }
(None, Some(slash)) => { (None, Some(slash)) => {
let domain = nameprep(&unnormalized[..slash]).map_err(|_| Error::NamePrep)?; let domain = nameprep(&unnormalized[..slash]).map_err(|_| Error::NamePrep)?;
length_check(domain.len(), Error::NoDomain, Error::DomainTooLong)?; length_check(domain.len(), Error::DomainEmpty, Error::DomainTooLong)?;
let resource = let resource =
resourceprep(&unnormalized[slash + 1..]).map_err(|_| Error::ResourcePrep)?; resourceprep(&unnormalized[slash + 1..]).map_err(|_| Error::ResourcePrep)?;
length_check(resource.len(), Error::EmptyResource, Error::ResourceTooLong)?; length_check(resource.len(), Error::ResourceEmpty, Error::ResourceTooLong)?;
orig_slash = Some(domain.len()); orig_slash = Some(domain.len());
format!("{domain}/{resource}") format!("{domain}/{resource}")
} }
(None, None) => { (None, None) => {
let domain = nameprep(unnormalized).map_err(|_| Error::NamePrep)?; let domain = nameprep(unnormalized).map_err(|_| Error::NamePrep)?;
length_check(domain.len(), Error::NoDomain, Error::DomainTooLong)?; length_check(domain.len(), Error::DomainEmpty, Error::DomainTooLong)?;
domain.into_owned() domain.into_owned()
} }

View file

@ -158,7 +158,7 @@ impl TryFrom<Jid> for FullJid {
fn try_from(jid: Jid) -> Result<Self, Self::Error> { fn try_from(jid: Jid) -> Result<Self, Self::Error> {
match jid { match jid {
Jid::Full(full) => Ok(full), Jid::Full(full) => Ok(full),
Jid::Bare(_) => Err(Error::NoResource), Jid::Bare(_) => Err(Error::ResourceMissingInFullJid),
} }
} }
} }
@ -351,7 +351,7 @@ impl FullJid {
if inner.slash.is_some() { if inner.slash.is_some() {
Ok(FullJid { inner }) Ok(FullJid { inner })
} else { } else {
Err(Error::NoResource) Err(Error::ResourceMissingInFullJid)
} }
} }
@ -549,8 +549,14 @@ mod tests {
Ok(FullJid::new("b.c/d").unwrap()) Ok(FullJid::new("b.c/d").unwrap())
); );
assert_eq!(FullJid::from_str("a@b.c"), Err(Error::NoResource)); assert_eq!(
assert_eq!(FullJid::from_str("b.c"), Err(Error::NoResource)); FullJid::from_str("a@b.c"),
Err(Error::ResourceMissingInFullJid)
);
assert_eq!(
FullJid::from_str("b.c"),
Err(Error::ResourceMissingInFullJid)
);
} }
#[test] #[test]
@ -606,7 +612,7 @@ mod tests {
assert_eq!(FullJid::try_from(Jid::Full(full.clone())), Ok(full.clone())); assert_eq!(FullJid::try_from(Jid::Full(full.clone())), Ok(full.clone()));
assert_eq!( assert_eq!(
FullJid::try_from(Jid::Bare(bare.clone())), FullJid::try_from(Jid::Bare(bare.clone())),
Err(Error::NoResource), Err(Error::ResourceMissingInFullJid),
); );
assert_eq!(Jid::Bare(full.clone().to_bare()), bare.clone()); assert_eq!(Jid::Bare(full.clone().to_bare()), bare.clone());
assert_eq!(Jid::Bare(bare.clone()), bare); assert_eq!(Jid::Bare(bare.clone()), bare);
@ -631,18 +637,21 @@ mod tests {
#[test] #[test]
fn invalid_jids() { fn invalid_jids() {
assert_eq!(BareJid::from_str(""), Err(Error::NoDomain)); assert_eq!(BareJid::from_str(""), Err(Error::DomainEmpty));
assert_eq!(BareJid::from_str("/c"), Err(Error::NoDomain)); assert_eq!(BareJid::from_str("/c"), Err(Error::DomainEmpty));
assert_eq!(BareJid::from_str("a@/c"), Err(Error::NoDomain)); assert_eq!(BareJid::from_str("a@/c"), Err(Error::DomainEmpty));
assert_eq!(BareJid::from_str("@b"), Err(Error::EmptyNode)); assert_eq!(BareJid::from_str("@b"), Err(Error::NodeEmpty));
assert_eq!(BareJid::from_str("b/"), Err(Error::EmptyResource)); assert_eq!(BareJid::from_str("b/"), Err(Error::ResourceEmpty));
assert_eq!(FullJid::from_str(""), Err(Error::NoDomain)); assert_eq!(FullJid::from_str(""), Err(Error::DomainEmpty));
assert_eq!(FullJid::from_str("/c"), Err(Error::NoDomain)); assert_eq!(FullJid::from_str("/c"), Err(Error::DomainEmpty));
assert_eq!(FullJid::from_str("a@/c"), Err(Error::NoDomain)); assert_eq!(FullJid::from_str("a@/c"), Err(Error::DomainEmpty));
assert_eq!(FullJid::from_str("@b"), Err(Error::EmptyNode)); assert_eq!(FullJid::from_str("@b"), Err(Error::NodeEmpty));
assert_eq!(FullJid::from_str("b/"), Err(Error::EmptyResource)); assert_eq!(FullJid::from_str("b/"), Err(Error::ResourceEmpty));
assert_eq!(FullJid::from_str("a@b"), Err(Error::NoResource)); assert_eq!(
FullJid::from_str("a@b"),
Err(Error::ResourceMissingInFullJid)
);
} }
#[test] #[test]