jid: Refactor all three JID types
The main reason for this refactor was to make common operations simpler, for instance formatting a JID is now a simple clone of a String. Instead of having three different String for each of node, domain and resource, we now have a single String with offsets pointing to where the at and slash are (if they are present). This also reduces the size of a FullJid from 72 bytes to 32 bytes on 64-bit platforms (less so on 32-bit), and BareJid from 48 bytes to 32 bytes. Jid is still 40 bytes instead of 32, but that can be improved in a future version where InnerJid has been inlined into each struct.
This commit is contained in:
parent
187e156b0b
commit
cf25bd3fee
4 changed files with 420 additions and 437 deletions
|
|
@ -12,7 +12,7 @@ use std::error::Error as StdError;
|
|||
use std::fmt;
|
||||
|
||||
/// An error that signifies that a `Jid` cannot be parsed from a string.
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum JidParseError {
|
||||
/// Happens when there is no domain, that is either the string is empty,
|
||||
/// starts with a /, or contains the @/ sequence.
|
||||
|
|
@ -27,47 +27,44 @@ pub enum JidParseError {
|
|||
/// Happens when the resource is empty, that is the string ends with a /.
|
||||
EmptyResource,
|
||||
|
||||
/// Happens when the JID is invalid according to stringprep. TODO: make errors
|
||||
/// meaningful.
|
||||
Stringprep(stringprep::Error),
|
||||
}
|
||||
/// Happens when the localpart is longer than 1023 bytes.
|
||||
NodeTooLong,
|
||||
|
||||
impl From<stringprep::Error> for JidParseError {
|
||||
fn from(e: stringprep::Error) -> JidParseError {
|
||||
JidParseError::Stringprep(e)
|
||||
}
|
||||
}
|
||||
/// Happens when the domain is longer than 1023 bytes.
|
||||
DomainTooLong,
|
||||
|
||||
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(_)) => true, // TODO: fix that upstream.
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
/// Happens when the resource is longer than 1023 bytes.
|
||||
ResourceTooLong,
|
||||
|
||||
impl Eq for JidParseError {}
|
||||
/// Happens when the localpart is invalid according to nodeprep.
|
||||
NodePrep,
|
||||
|
||||
/// Happens when the domain is invalid according to nameprep.
|
||||
NamePrep,
|
||||
|
||||
/// Happens when the resource is invalid according to resourceprep.
|
||||
ResourcePrep,
|
||||
|
||||
/// Happens when parsing a bare JID and there is a resource.
|
||||
ResourceInBareJid,
|
||||
}
|
||||
|
||||
impl StdError for JidParseError {}
|
||||
|
||||
impl fmt::Display for JidParseError {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
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 /",
|
||||
JidParseError::Stringprep(_err) => "TODO",
|
||||
}
|
||||
)
|
||||
fmt.write_str(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 /",
|
||||
JidParseError::NodeTooLong => "localpart longer than 1023 bytes",
|
||||
JidParseError::DomainTooLong => "domain longer than 1023 bytes",
|
||||
JidParseError::ResourceTooLong => "resource longer than 1023 bytes",
|
||||
JidParseError::NodePrep => "localpart doesn’t pass nodeprep validation",
|
||||
JidParseError::NamePrep => "domain doesn’t pass nameprep validation",
|
||||
JidParseError::ResourcePrep => "resource doesn’t pass resourceprep validation",
|
||||
JidParseError::ResourceInBareJid => "resource found while parsing a bare JID",
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue