add some variants for invalid byte lengths

This commit is contained in:
KodrAus 2021-11-16 08:44:18 +10:00
parent 3e6cb8703b
commit 90ccef64f9
3 changed files with 39 additions and 8 deletions

View File

@ -14,6 +14,9 @@ pub(crate) enum ErrorKind {
///
/// [`Uuid`]: ../struct.Uuid.html
SimpleLength { len: usize },
/// A byte array didn't contain 16 bytes
#[allow(dead_code)]
ByteLength { len: usize },
/// A hyphenated [`Uuid`] didn't contain 5 groups
///
/// [`Uuid`]: ../struct.Uuid.html
@ -26,6 +29,9 @@ pub(crate) enum ErrorKind {
len: usize,
index: usize,
},
/// Some other error occurred.
#[allow(dead_code)]
Other,
}
/// A string that is guaranteed to fail to parse to a [`Uuid`].
@ -126,6 +132,9 @@ impl fmt::Display for Error {
len
)
}
ErrorKind::ByteLength { len } => {
write!(f, "invalid length: expected 16 bytes, found {}", len)
}
ErrorKind::GroupCount { count } => {
write!(f, "invalid group count: expected 5, found {}", count)
}
@ -137,6 +146,7 @@ impl fmt::Display for Error {
group, expected, len
)
}
ErrorKind::Other => write!(f, "failed to parse a UUID"),
}
}
}

View File

@ -308,7 +308,7 @@ impl Uuid {
/// ```
pub fn from_slice(b: &[u8]) -> Result<Uuid, Error> {
if b.len() != 16 {
return Err(Error(ErrorKind::SimpleLength { len: b.len() * 2 }));
return Err(Error(ErrorKind::ByteLength { len: b.len() }));
}
let mut bytes: Bytes = [0; 16];
@ -349,7 +349,7 @@ impl Uuid {
/// ```
pub fn from_slice_le(b: &[u8]) -> Result<Uuid, Error> {
if b.len() != 16 {
return Err(Error(ErrorKind::SimpleLength { len: b.len() * 2 }));
return Err(Error(ErrorKind::ByteLength { len: b.len() }));
}
let mut bytes: Bytes = [0; 16];
@ -452,9 +452,7 @@ impl Uuid {
/// ```
pub fn from_bytes_ref(bytes: &Bytes) -> &Uuid {
// SAFETY: `Bytes` and `Uuid` have the same ABI
unsafe {
&*(bytes as *const Bytes as *const Uuid)
}
unsafe { &*(bytes as *const Bytes as *const Uuid) }
}
}

View File

@ -66,12 +66,35 @@ impl Uuid {
.map_err(InvalidUuid::into_err)
}
/// Intended to replace `Uuid::parse_str`
/// Parses a `Uuid` from a string of hexadecimal digits with optional
/// hyphens.
///
/// This function is similar to [`parse_str`], in fact `parse_str` shares
/// the same underlying parser. The difference is that if `try_parse`
/// fails, it won't generate very useful error messages. The `parse_str`
/// function will eventually be deprecated in favor or `try_parse`.
///
/// # Examples
///
/// Parse a hyphenated UUID:
///
/// ```
/// # use uuid::{Uuid, Version, Variant};
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// let uuid = Uuid::try_parse("550e8400-e29b-41d4-a716-446655440000")?;
///
/// assert_eq!(Some(Version::Random), uuid.get_version());
/// assert_eq!(Variant::RFC4122, uuid.get_variant());
/// # Ok(())
/// # }
/// ```
///
/// [`parse_str`]: #method.parse_str
#[inline]
pub const fn try_parse(input: &str) -> Result<Uuid, InvalidUuid> {
pub const fn try_parse(input: &str) -> Result<Uuid, Error> {
match imp::try_parse(input) {
Ok(bytes) => Ok(Uuid::from_bytes(bytes)),
Err(e) => Err(e),
Err(_) => Err(Error(ErrorKind::Other)),
}
}
}