From dd7a5dc98ce89b05785c9319c5f0ea5efd0b2676 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 13 Dec 2021 14:43:27 +0530 Subject: [PATCH 1/8] Replace all ZeroVec errors with ULEError --- utils/zerovec/src/ule/chars.rs | 11 +++-------- utils/zerovec/src/ule/error.rs | 28 ++++++++++++++++++++-------- utils/zerovec/src/ule/mod.rs | 9 +++------ utils/zerovec/src/ule/pair.rs | 31 ++++--------------------------- utils/zerovec/src/ule/plain.rs | 14 ++++---------- utils/zerovec/src/ule/slices.rs | 2 +- utils/zerovec/src/zerovec/mod.rs | 6 +++--- utils/zerovec/src/zerovec/ule.rs | 2 +- 8 files changed, 39 insertions(+), 64 deletions(-) diff --git a/utils/zerovec/src/ule/chars.rs b/utils/zerovec/src/ule/chars.rs index accfbc204f3..17f88c6ae85 100644 --- a/utils/zerovec/src/ule/chars.rs +++ b/utils/zerovec/src/ule/chars.rs @@ -49,21 +49,16 @@ pub struct CharULE([u8; 4]); // 5. The other ULE methods use the default impl. // 6. CharULE byte equality is semantic equality unsafe impl ULE for CharULE { - type Error = ULEError; - #[inline] - fn validate_byte_slice(bytes: &[u8]) -> Result<(), Self::Error> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), ULEError> { if bytes.len() % 4 != 0 { - return Err(ULEError::InvalidLength { - ty: "char", - len: bytes.len(), - }); + return Err(ULEError::length::(bytes.len())); } // Validate the bytes for chunk in bytes.chunks_exact(4) { // TODO: Use slice::as_chunks() when stabilized let u = u32::from_le_bytes([chunk[0], chunk[1], chunk[2], chunk[3]]); - char::try_from(u)?; + char::try_from(u).map_err(|_| ULEError::parse::())?; } Ok(()) } diff --git a/utils/zerovec/src/ule/error.rs b/utils/zerovec/src/ule/error.rs index 93d26c85a83..c9b85805440 100644 --- a/utils/zerovec/src/ule/error.rs +++ b/utils/zerovec/src/ule/error.rs @@ -2,31 +2,43 @@ // called LICENSE at the top level of the ICU4X source tree // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). +use core::any; use core::fmt; /// A generic error type to be used for decoding slices of ULE types #[derive(Copy, Clone, Debug)] -pub enum ULEError { +pub enum ULEError { InvalidLength { ty: &'static str, len: usize }, - ParseError(E), + ParseError { ty: &'static str }, } -impl fmt::Display for ULEError { +impl fmt::Display for ULEError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { match *self { ULEError::InvalidLength { ty, len } => { write!(f, "Invalid length {} for slice of type {}", len, ty) } - ULEError::ParseError(ref e) => e.fmt(f), + ULEError::ParseError { ty } => { + write!(f, "Could not parse data as valud {}", ty) + } } } } -impl From for ULEError { - fn from(e: E) -> Self { - ULEError::ParseError(e) +impl ULEError { + pub fn parse() -> ULEError { + ULEError::ParseError { + ty: any::type_name::(), + } + } + + pub fn length(len: usize) -> ULEError { + ULEError::InvalidLength { + ty: any::type_name::(), + len, + } } } #[cfg(feature = "std")] -impl ::std::error::Error for ULEError {} +impl ::std::error::Error for ULEError {} diff --git a/utils/zerovec/src/ule/mod.rs b/utils/zerovec/src/ule/mod.rs index 4e2aa842a7d..d0916d1ff29 100644 --- a/utils/zerovec/src/ule/mod.rs +++ b/utils/zerovec/src/ule/mod.rs @@ -14,7 +14,7 @@ mod slices; pub use chars::CharULE; pub use error::ULEError; -pub use pair::{PairULE, PairULEError}; +pub use pair::PairULE; pub use plain::PlainOldULE; use alloc::alloc::Layout; @@ -63,15 +63,12 @@ where Self: Sized, Self: Copy + 'static, { - /// The error that occurs if a byte array is not valid for this ULE. - type Error: fmt::Display; - /// Validates a byte slice, `&[u8]`. /// /// If `Self` is not well-defined for all possible bit values, the bytes should be validated. /// If the bytes can be transmuted, *in their entirety*, to a valid slice of `Self`, then `Ok` /// should be returned; otherwise, `Self::Error` should be returned. - fn validate_byte_slice(bytes: &[u8]) -> Result<(), Self::Error>; + fn validate_byte_slice(bytes: &[u8]) -> Result<(), ULEError>; /// Parses a byte slice, `&[u8]`, and return it as `&[Self]` with the same lifetime. /// @@ -83,7 +80,7 @@ where /// /// Note: The following equality should hold: `bytes.len() % size_of::() == 0`. This /// means that the returned slice can span the entire byte slice. - fn parse_byte_slice(bytes: &[u8]) -> Result<&[Self], Self::Error> { + fn parse_byte_slice(bytes: &[u8]) -> Result<&[Self], ULEError> { Self::validate_byte_slice(bytes)?; debug_assert_eq!(bytes.len() % mem::size_of::(), 0); Ok(unsafe { Self::from_byte_slice_unchecked(bytes) }) diff --git a/utils/zerovec/src/ule/pair.rs b/utils/zerovec/src/ule/pair.rs index 71688efdc38..447809b6746 100644 --- a/utils/zerovec/src/ule/pair.rs +++ b/utils/zerovec/src/ule/pair.rs @@ -22,17 +22,15 @@ pub struct PairULE(pub A, pub B); // 6. PairULE byte equality is semantic equality by relying on the ULE equality // invariant on the subfields unsafe impl ULE for PairULE { - type Error = PairULEError; - - fn validate_byte_slice(bytes: &[u8]) -> Result<(), Self::Error> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), ULEError> { let a_len = mem::size_of::(); let b_len = mem::size_of::(); if bytes.len() % (a_len + b_len) != 0 { - return Err(PairULEError::IndivisibleLength(a_len + b_len, bytes.len())); + return Err(ULEError::length::(bytes.len())); } for chunk in bytes.chunks(a_len + b_len) { - A::validate_byte_slice(&chunk[..a_len]).map_err(PairULEError::First)?; - B::validate_byte_slice(&chunk[a_len..]).map_err(PairULEError::Second)?; + A::validate_byte_slice(&chunk[..a_len])?; + B::validate_byte_slice(&chunk[a_len..])?; } Ok(()) } @@ -55,27 +53,6 @@ impl AsULE for (A, B) { } } -#[derive(Clone, Debug)] -pub enum PairULEError { - First(E), - Second(F), - IndivisibleLength(/* expected */ usize, /* found */ usize), -} - -impl fmt::Display for PairULEError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - match *self { - PairULEError::First(ref e) => e.fmt(f), - PairULEError::Second(ref e) => e.fmt(f), - PairULEError::IndivisibleLength(expected, found) => write!( - f, - "Indivisible length for PairULE: expected multiple of {} found {}", - expected, found - ), - } - } -} - impl fmt::Debug for PairULE { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { let a = self.0; diff --git a/utils/zerovec/src/ule/plain.rs b/utils/zerovec/src/ule/plain.rs index 3551fadb5ea..b2f53224be9 100644 --- a/utils/zerovec/src/ule/plain.rs +++ b/utils/zerovec/src/ule/plain.rs @@ -36,18 +36,13 @@ macro_rules! impl_byte_slice_size { // 5. The other ULE methods use the default impl. // 6. PlainOldULE byte equality is semantic equality unsafe impl ULE for PlainOldULE<$size> { - type Error = ULEError; - #[inline] - fn validate_byte_slice(bytes: &[u8]) -> Result<(), Self::Error> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), ULEError> { if bytes.len() % $size == 0 { // Safe because Self is transparent over [u8; $size] Ok(()) } else { - Err(ULEError::InvalidLength { - ty: concat!("PlainOldULE<", stringify!($size), ">"), - len: bytes.len(), - }) + Err(ULEError::length::(bytes.len())) } } } @@ -112,13 +107,12 @@ impl_byte_slice_type!(i128, 16); // 5. The other ULE methods use the default impl. // 6. u8 byte equality is semantic equality unsafe impl ULE for u8 { - type Error = core::convert::Infallible; #[inline] - fn validate_byte_slice(_bytes: &[u8]) -> Result<(), Self::Error> { + fn validate_byte_slice(_bytes: &[u8]) -> Result<(), ULEError> { Ok(()) } #[inline] - fn parse_byte_slice(bytes: &[u8]) -> Result<&[Self], Self::Error> { + fn parse_byte_slice(bytes: &[u8]) -> Result<&[Self], ULEError> { Ok(bytes) } #[inline] diff --git a/utils/zerovec/src/ule/slices.rs b/utils/zerovec/src/ule/slices.rs index c78d2f7b50e..61ce2ea0c3f 100644 --- a/utils/zerovec/src/ule/slices.rs +++ b/utils/zerovec/src/ule/slices.rs @@ -46,7 +46,7 @@ unsafe impl VarULE for [T] where T: ULE + AsULE, { - type Error = T::Error; + type Error = ULEError; #[inline] fn validate_byte_slice(slice: &[u8]) -> Result<(), Self::Error> { diff --git a/utils/zerovec/src/zerovec/mod.rs b/utils/zerovec/src/zerovec/mod.rs index 2ec2cd4d11d..002a6d240c1 100644 --- a/utils/zerovec/src/zerovec/mod.rs +++ b/utils/zerovec/src/zerovec/mod.rs @@ -192,7 +192,7 @@ where /// assert!(matches!(zerovec, ZeroVec::Borrowed(_))); /// assert_eq!(zerovec.get(2), Some(421)); /// ``` - pub fn parse_byte_slice(bytes: &'a [u8]) -> Result::ULE as ULE>::Error> { + pub fn parse_byte_slice(bytes: &'a [u8]) -> Result { let slice: &'a [T::ULE] = T::ULE::parse_byte_slice(bytes)?; Ok(Self::Borrowed(slice)) } @@ -378,7 +378,7 @@ where /// assert!(matches!(zv_u16, ZeroVec::Borrowed(_))); /// assert_eq!(zv_u16.get(0), Some(0xF37F)); /// ``` - pub fn try_into_converted(self) -> Result, ::Error> { + pub fn try_into_converted(self) -> Result, ULEError> { assert_eq!( core::mem::size_of::<::ULE>(), core::mem::size_of::<

::ULE>() @@ -446,7 +446,7 @@ impl<'a> ZeroVec<'a, u8> { /// assert!(matches!(zerovec, ZeroVec::Owned(_))); /// assert_eq!(zerovec.get(0), Some(211)); /// ``` - pub fn try_into_parsed(self) -> Result, ::Error> { + pub fn try_into_parsed(self) -> Result, ULEError> { match self { ZeroVec::Borrowed(bytes) => { let slice: &'a [T::ULE] = T::ULE::parse_byte_slice(bytes)?; diff --git a/utils/zerovec/src/zerovec/ule.rs b/utils/zerovec/src/zerovec/ule.rs index c2f3f201f16..16d6493f513 100644 --- a/utils/zerovec/src/zerovec/ule.rs +++ b/utils/zerovec/src/zerovec/ule.rs @@ -71,7 +71,7 @@ where // 6. `as_byte_slice()` and `parse_byte_slice()` are defaulted // 7. `[T::ULE]` byte equality is semantic equality (relying on the guideline of the underlying `ULE` type) unsafe impl VarULE for ZeroVecULE { - type Error = ::Error; + type Error = ULEError; #[inline] fn validate_byte_slice(bytes: &[u8]) -> Result<(), Self::Error> { From 1eb37a38f476c557416a2da38874dbe2e8825bbb Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 13 Dec 2021 14:50:48 +0530 Subject: [PATCH 2/8] Use ULEError for VarZeroVec --- utils/zerovec/src/lib.rs | 3 +- utils/zerovec/src/ule/error.rs | 8 ++- utils/zerovec/src/ule/mod.rs | 9 +-- utils/zerovec/src/ule/slices.rs | 14 ++--- utils/zerovec/src/varzerovec/borrowed.rs | 35 ++++-------- utils/zerovec/src/varzerovec/mod.rs | 71 ++++++++---------------- utils/zerovec/src/varzerovec/ule.rs | 4 +- utils/zerovec/src/zerovec/ule.rs | 4 +- 8 files changed, 54 insertions(+), 94 deletions(-) diff --git a/utils/zerovec/src/lib.rs b/utils/zerovec/src/lib.rs index 2b49deeab7c..5b5fc178887 100644 --- a/utils/zerovec/src/lib.rs +++ b/utils/zerovec/src/lib.rs @@ -108,5 +108,6 @@ pub mod zerovec; mod yoke_impls; pub use crate::map::ZeroMap; -pub use crate::varzerovec::{VarZeroVec, VarZeroVecError}; +pub use crate::varzerovec::VarZeroVec; pub use crate::zerovec::ZeroVec; +pub use crate::ule::ULEError; diff --git a/utils/zerovec/src/ule/error.rs b/utils/zerovec/src/ule/error.rs index c9b85805440..af738b2dbb5 100644 --- a/utils/zerovec/src/ule/error.rs +++ b/utils/zerovec/src/ule/error.rs @@ -10,6 +10,7 @@ use core::fmt; pub enum ULEError { InvalidLength { ty: &'static str, len: usize }, ParseError { ty: &'static str }, + FormatError, } impl fmt::Display for ULEError { @@ -21,18 +22,21 @@ impl fmt::Display for ULEError { ULEError::ParseError { ty } => { write!(f, "Could not parse data as valud {}", ty) } + ULEError::FormatError => { + write!(f, "Invalid format for VarZeroVec buffer") + } } } } impl ULEError { - pub fn parse() -> ULEError { + pub fn parse() -> ULEError { ULEError::ParseError { ty: any::type_name::(), } } - pub fn length(len: usize) -> ULEError { + pub fn length(len: usize) -> ULEError { ULEError::InvalidLength { ty: any::type_name::(), len, diff --git a/utils/zerovec/src/ule/mod.rs b/utils/zerovec/src/ule/mod.rs index d0916d1ff29..5e4d66bb505 100644 --- a/utils/zerovec/src/ule/mod.rs +++ b/utils/zerovec/src/ule/mod.rs @@ -20,7 +20,7 @@ pub use plain::PlainOldULE; use alloc::alloc::Layout; use alloc::borrow::ToOwned; use alloc::boxed::Box; -use core::{fmt, mem, slice}; +use core::{mem, slice}; /// Fixed-width, byte-aligned data that can be cast to and from a little-endian byte slice. /// @@ -260,15 +260,12 @@ where /// Failure to follow this invariant will cause surprising behavior in `PartialEq`, which may /// result in unpredictable operations on `ZeroVec`, `VarZeroVec`, and `ZeroMap`. pub unsafe trait VarULE: 'static { - /// The error that occurs if a byte array is not valid for this ULE. - type Error: fmt::Display; - /// Validates a byte slice, `&[u8]`. /// /// If `Self` is not well-defined for all possible bit values, the bytes should be validated. /// If the bytes can be transmuted, *in their entirety*, to a valid `&Self`, then `Ok` should /// be returned; otherwise, `Self::Error` should be returned. - fn validate_byte_slice(_bytes: &[u8]) -> Result<(), Self::Error>; + fn validate_byte_slice(_bytes: &[u8]) -> Result<(), ULEError>; /// Parses a byte slice, `&[u8]`, and return it as `&Self` with the same lifetime. /// @@ -281,7 +278,7 @@ pub unsafe trait VarULE: 'static { /// Note: The following equality should hold: `size_of_val(result) == size_of_val(bytes)`, /// where `result` is the successful return value of the method. This means that the return /// value spans the entire byte slice. - fn parse_byte_slice(bytes: &[u8]) -> Result<&Self, Self::Error> { + fn parse_byte_slice(bytes: &[u8]) -> Result<&Self, ULEError> { Self::validate_byte_slice(bytes)?; let result = unsafe { Self::from_byte_slice_unchecked(bytes) }; debug_assert_eq!(mem::size_of_val(result), mem::size_of_val(bytes)); diff --git a/utils/zerovec/src/ule/slices.rs b/utils/zerovec/src/ule/slices.rs index 61ce2ea0c3f..6048fc9fe8d 100644 --- a/utils/zerovec/src/ule/slices.rs +++ b/utils/zerovec/src/ule/slices.rs @@ -14,17 +14,15 @@ use core::str; // 6. `parse_byte_slice()` is equivalent to `validate_byte_slice()` followed by `from_byte_slice_unchecked()` // 7. str byte equality is semantic equality unsafe impl VarULE for str { - type Error = str::Utf8Error; - #[inline] - fn validate_byte_slice(bytes: &[u8]) -> Result<(), Self::Error> { - str::from_utf8(bytes)?; + fn validate_byte_slice(bytes: &[u8]) -> Result<(), ULEError> { + str::from_utf8(bytes).map_err(|_| ULEError::parse::())?; Ok(()) } #[inline] - fn parse_byte_slice(bytes: &[u8]) -> Result<&Self, Self::Error> { - str::from_utf8(bytes) + fn parse_byte_slice(bytes: &[u8]) -> Result<&Self, ULEError> { + str::from_utf8(bytes).map_err(|_| ULEError::parse::()) } /// Invariant: must be safe to call when called on a slice that previously /// succeeded with `parse_byte_slice` @@ -46,10 +44,8 @@ unsafe impl VarULE for [T] where T: ULE + AsULE, { - type Error = ULEError; - #[inline] - fn validate_byte_slice(slice: &[u8]) -> Result<(), Self::Error> { + fn validate_byte_slice(slice: &[u8]) -> Result<(), ULEError> { T::validate_byte_slice(slice) } diff --git a/utils/zerovec/src/varzerovec/borrowed.rs b/utils/zerovec/src/varzerovec/borrowed.rs index 8ef76f247df..6aa459d76d2 100644 --- a/utils/zerovec/src/varzerovec/borrowed.rs +++ b/utils/zerovec/src/varzerovec/borrowed.rs @@ -89,7 +89,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVecBorrowed<'a, T> { /// - `indices[len - 1]..things.len()` must index into a valid section of /// `things`, such that it parses to a `T::VarULE` #[inline] - pub fn parse_byte_slice(slice: &'a [u8]) -> Result> { + pub fn parse_byte_slice(slice: &'a [u8]) -> Result { if slice.is_empty() { return Ok(VarZeroVecBorrowed { indices: &[], @@ -98,20 +98,15 @@ impl<'a, T: VarULE + ?Sized> VarZeroVecBorrowed<'a, T> { marker: PhantomData, }); } - let len_bytes = slice.get(0..4).ok_or(VarZeroVecError::FormatError)?; - let len_ule = PlainOldULE::<4>::parse_byte_slice(len_bytes) - .map_err(|_| VarZeroVecError::FormatError)?; + let len_bytes = slice.get(0..4).ok_or(ULEError::FormatError)?; + let len_ule = + PlainOldULE::<4>::parse_byte_slice(len_bytes).map_err(|_| ULEError::FormatError)?; - let len = - u32::from_unaligned(*len_ule.get(0).ok_or(VarZeroVecError::FormatError)?) as usize; - let indices_bytes = slice - .get(4..4 * len + 4) - .ok_or(VarZeroVecError::FormatError)?; - let indices = PlainOldULE::<4>::parse_byte_slice(indices_bytes) - .map_err(|_| VarZeroVecError::FormatError)?; - let things = slice - .get(4 * len + 4..) - .ok_or(VarZeroVecError::FormatError)?; + let len = u32::from_unaligned(*len_ule.get(0).ok_or(ULEError::FormatError)?) as usize; + let indices_bytes = slice.get(4..4 * len + 4).ok_or(ULEError::FormatError)?; + let indices = + PlainOldULE::<4>::parse_byte_slice(indices_bytes).map_err(|_| ULEError::FormatError)?; + let things = slice.get(4 * len + 4..).ok_or(ULEError::FormatError)?; let borrowed = VarZeroVecBorrowed { indices, @@ -215,16 +210,12 @@ impl<'a, T: VarULE + ?Sized> VarZeroVecBorrowed<'a, T> { /// This method is NOT allowed to call any other methods on VarZeroVecBorrowed since all other methods /// assume that the slice has been passed through iter_checked #[inline] - fn iter_checked(self) -> impl Iterator>> { + fn iter_checked(self) -> impl Iterator> { let last = iter::from_fn(move || { if !self.is_empty() { let start = usizeify(self.indices[self.len() - 1]); let end = self.things.len(); - Some( - self.things - .get(start..end) - .ok_or(VarZeroVecError::FormatError), - ) + Some(self.things.get(start..end).ok_or(ULEError::FormatError)) } else { None } @@ -236,9 +227,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVecBorrowed<'a, T> { let start = usizeify(win[0]); let end = usizeify(win[1]); // the .get() here automatically verifies that end>=start - self.things - .get(start..end) - .ok_or(VarZeroVecError::FormatError) + self.things.get(start..end).ok_or(ULEError::FormatError) }) .chain(last) .map(|s| s.and_then(|s| T::parse_byte_slice(s).map_err(|e| e.into()))) diff --git a/utils/zerovec/src/varzerovec/mod.rs b/utils/zerovec/src/varzerovec/mod.rs index 790e0160dae..4e50a5dd36b 100644 --- a/utils/zerovec/src/varzerovec/mod.rs +++ b/utils/zerovec/src/varzerovec/mod.rs @@ -5,7 +5,7 @@ use crate::ule::*; use alloc::boxed::Box; use alloc::vec::Vec; -use core::fmt::{self, Display}; +use core::fmt; use core::ops::Index; pub(crate) mod borrowed; @@ -62,7 +62,7 @@ pub use ule::VarZeroVecULE; /// /// ```rust /// # use std::str::Utf8Error; -/// # use zerovec::VarZeroVecError; +/// # use zerovec::ule::ULEError; /// use zerovec::VarZeroVec; /// /// // The little-endian bytes correspond to the list of strings. @@ -76,14 +76,14 @@ pub use ule::VarZeroVecULE; /// /// assert_eq!(zerovec.get(2), Some("文")); /// assert_eq!(zerovec, &*strings); -/// # Ok::<(), VarZeroVecError>(()) +/// # Ok::<(), ULEError>(()) /// ``` /// /// Here's another example with `ZeroVecULE` (similar to `[T]`): /// /// ```rust /// # use std::str::Utf8Error; -/// # use zerovec::VarZeroVecError; +/// # use zerovec::ule::ULEError; /// use zerovec::VarZeroVec; /// use zerovec::ZeroVec; /// use zerovec::zerovec::ZeroVecULE; @@ -107,7 +107,7 @@ pub use ule::VarZeroVecULE; /// for (zv, v) in zerovec.iter().zip(numbers.iter()) { /// assert_eq!(zv, &**v); /// } -/// # Ok::<(), VarZeroVecError>>(()) +/// # Ok::<(), ULEError>(()) /// ``` /// /// @@ -158,21 +158,6 @@ impl<'a, T: ?Sized> Clone for VarZeroVec<'a, T> { } } -#[derive(Clone, Debug)] -pub enum VarZeroVecError { - FormatError, - ParseError(E), -} - -impl Display for VarZeroVecError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match *self { - Self::FormatError => write!(f, "Incorrect slice format"), - Self::ParseError(ref e) => e.fmt(f), - } - } -} - impl fmt::Debug for VarZeroVec<'_, T> where T: fmt::Debug, @@ -182,14 +167,6 @@ where } } -pub type ParseErrorFor = VarZeroVecError<::Error>; - -impl From for VarZeroVecError { - fn from(e: E) -> Self { - Self::ParseError(e) - } -} - impl<'a, T: ?Sized> From> for VarZeroVec<'a, T> { #[inline] fn from(other: VarZeroVecOwned) -> Self { @@ -250,7 +227,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVec<'a, T> { /// /// ```rust /// # use std::str::Utf8Error; - /// # use zerovec::VarZeroVecError; + /// # use zerovec::ule::ULEError; /// # use zerovec::VarZeroVec; /// /// let strings = vec!["foo".to_owned(), "bar".to_owned(), @@ -259,7 +236,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVec<'a, T> { /// /// let mut vec: VarZeroVec = VarZeroVec::parse_byte_slice(&bytes)?; /// assert_eq!(vec.len(), 4); - /// # Ok::<(), VarZeroVecError>(()) + /// # Ok::<(), ULEError>(()) /// ``` pub fn len(&self) -> usize { self.as_borrowed().len() @@ -271,7 +248,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVec<'a, T> { /// /// ``` /// # use std::str::Utf8Error; - /// # use zerovec::VarZeroVecError; + /// # use zerovec::ule::ULEError; /// # use zerovec::VarZeroVec; /// /// let strings: Vec = vec![]; @@ -279,7 +256,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVec<'a, T> { /// /// let mut vec: VarZeroVec = VarZeroVec::parse_byte_slice(&bytes)?; /// assert!(vec.is_empty()); - /// # Ok::<(), VarZeroVecError>(()) + /// # Ok::<(), ULEError>(()) /// ``` pub fn is_empty(&self) -> bool { self.as_borrowed().is_empty() @@ -294,7 +271,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVec<'a, T> { /// /// ```rust /// # use std::str::Utf8Error; - /// # use zerovec::VarZeroVecError; + /// # use zerovec::ule::ULEError; /// # use zerovec::VarZeroVec; /// /// let strings = vec!["foo".to_owned(), "bar".to_owned(), @@ -306,9 +283,9 @@ impl<'a, T: VarULE + ?Sized> VarZeroVec<'a, T> { /// assert_eq!(&vec[1], "bar"); /// assert_eq!(&vec[2], "baz"); /// assert_eq!(&vec[3], "quux"); - /// # Ok::<(), VarZeroVecError>(()) + /// # Ok::<(), ULEError>(()) /// ``` - pub fn parse_byte_slice(slice: &'a [u8]) -> Result> { + pub fn parse_byte_slice(slice: &'a [u8]) -> Result { if slice.is_empty() { // does not allocate return Ok(VarZeroVec::Owned(VarZeroVecOwned::new())); @@ -325,7 +302,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVec<'a, T> { /// /// ```rust /// # use std::str::Utf8Error; - /// # use zerovec::VarZeroVecError; + /// # use zerovec::ule::ULEError; /// # use zerovec::VarZeroVec; /// /// let strings = vec!["foo".to_owned(), "bar".to_owned(), @@ -338,7 +315,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVec<'a, T> { /// assert_eq!(iter_results[1], "bar"); /// assert_eq!(iter_results[2], "baz"); /// assert_eq!(iter_results[3], "quux"); - /// # Ok::<(), VarZeroVecError>(()) + /// # Ok::<(), ULEError>(()) /// ``` pub fn iter<'b: 'a>(&'b self) -> impl Iterator { self.as_borrowed().iter() @@ -350,7 +327,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVec<'a, T> { /// /// ```rust /// # use std::str::Utf8Error; - /// # use zerovec::VarZeroVecError; + /// # use zerovec::ule::ULEError; /// # use zerovec::VarZeroVec; /// /// let strings = vec!["foo".to_owned(), "bar".to_owned(), @@ -364,7 +341,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVec<'a, T> { /// assert_eq!(vec.get(2), Some("baz")); /// assert_eq!(vec.get(3), Some("quux")); /// assert_eq!(vec.get(4), None); - /// # Ok::<(), VarZeroVecError>(()) + /// # Ok::<(), ULEError>(()) /// ``` pub fn get(&self, idx: usize) -> Option<&T> { self.as_borrowed().get(idx) @@ -377,7 +354,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVec<'a, T> { /// /// ```rust,ignore /// # use std::str::Utf8Error; - /// # use zerovec::VarZeroVecError; + /// # use zerovec::ule::ULEError; /// # use zerovec::VarZeroVec; /// /// let strings = vec!["foo".to_owned(), "bar".to_owned(), @@ -394,7 +371,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVec<'a, T> { /// assert_eq!(&vec[2], "dolor sit"); /// assert_eq!(&vec[3], "quux"); /// assert_eq!(&vec[4], "lorem ipsum"); - /// # Ok::<(), VarZeroVecError>(()) + /// # Ok::<(), ULEError>(()) /// ``` // // This function is crate-public for now since we don't yet want to stabilize @@ -417,7 +394,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVec<'a, T> { /// /// ``` /// # use std::str::Utf8Error; - /// # use zerovec::VarZeroVecError; + /// # use zerovec::ule::ULEError; /// # use zerovec::VarZeroVec; /// /// let strings = vec!["foo".to_owned(), "bar".to_owned(), @@ -428,7 +405,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVec<'a, T> { /// assert_eq!(vec.len(), 4); /// // has 'static lifetime /// let owned = vec.into_owned(); - /// # Ok::<(), VarZeroVecError>(()) + /// # Ok::<(), ULEError>(()) /// ``` pub fn into_owned(mut self) -> VarZeroVec<'static, T> { self.make_mut(); @@ -472,7 +449,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVec<'a, T> { /// /// ```rust /// # use std::str::Utf8Error; - /// # use zerovec::VarZeroVecError; + /// # use zerovec::ule::ULEError; /// # use zerovec::VarZeroVec; /// /// let strings = vec!["foo".to_owned(), "bar".to_owned(), "baz".to_owned()]; @@ -481,7 +458,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVec<'a, T> { /// let mut borrowed: VarZeroVec = VarZeroVec::parse_byte_slice(&bytes)?; /// assert_eq!(borrowed, &*strings); /// - /// # Ok::<(), VarZeroVecError>(()) + /// # Ok::<(), ULEError>(()) /// ``` /// pub fn get_serializable_bytes>(elements: &[A]) -> Option> { @@ -512,7 +489,7 @@ where /// /// ``` /// # use std::str::Utf8Error; - /// # use zerovec::VarZeroVecError; + /// # use zerovec::ule::ULEError; /// # use zerovec::VarZeroVec; /// /// let strings = vec!["a".to_owned(), "b".to_owned(), @@ -522,7 +499,7 @@ where /// /// assert_eq!(vec.binary_search("f"), Ok(2)); /// assert_eq!(vec.binary_search("e"), Err(2)); - /// # Ok::<(), VarZeroVecError>(()) + /// # Ok::<(), ULEError>(()) /// ``` /// /// [`binary_search`]: https://doc.rust-lang.org/std/primitive.slice.html#method.binary_search diff --git a/utils/zerovec/src/varzerovec/ule.rs b/utils/zerovec/src/varzerovec/ule.rs index 766adf859af..b68d1c82192 100644 --- a/utils/zerovec/src/varzerovec/ule.rs +++ b/utils/zerovec/src/varzerovec/ule.rs @@ -117,9 +117,7 @@ where // 6. `as_byte_slice()` is equivalent to a regular transmute of the underlying data // 7. VarZeroVecULE byte equality is semantic equality (relying on the guideline of the underlying VarULE type) unsafe impl VarULE for VarZeroVecULE { - type Error = ParseErrorFor; - - fn validate_byte_slice(bytes: &[u8]) -> Result<(), Self::Error> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), ULEError> { let _: VarZeroVecBorrowed = VarZeroVecBorrowed::parse_byte_slice(bytes)?; Ok(()) } diff --git a/utils/zerovec/src/zerovec/ule.rs b/utils/zerovec/src/zerovec/ule.rs index 16d6493f513..d4f6463799d 100644 --- a/utils/zerovec/src/zerovec/ule.rs +++ b/utils/zerovec/src/zerovec/ule.rs @@ -71,10 +71,8 @@ where // 6. `as_byte_slice()` and `parse_byte_slice()` are defaulted // 7. `[T::ULE]` byte equality is semantic equality (relying on the guideline of the underlying `ULE` type) unsafe impl VarULE for ZeroVecULE { - type Error = ULEError; - #[inline] - fn validate_byte_slice(bytes: &[u8]) -> Result<(), Self::Error> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), ULEError> { T::ULE::validate_byte_slice(bytes) } From d6135508c4055b963f21993e3368af94d66ba92d Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 13 Dec 2021 14:56:59 +0530 Subject: [PATCH 3/8] Use new ULE impl everywhere --- components/datetime/src/fields/ule.rs | 16 +++++------ components/datetime/src/pattern/item/ule.rs | 30 ++++++++++----------- components/plurals/src/rules/runtime/ast.rs | 15 +++++------ components/properties/src/ule.rs | 9 +++---- utils/codepointtrie/src/codepointtrie.rs | 8 ++---- utils/zerovec/benches/zerovec.rs | 1 - utils/zerovec/src/lib.rs | 2 +- utils/zerovec/src/ule/custom/mod.rs | 9 +++---- utils/zerovec/src/varzerovec/borrowed.rs | 2 +- 9 files changed, 40 insertions(+), 52 deletions(-) diff --git a/components/datetime/src/fields/ule.rs b/components/datetime/src/fields/ule.rs index cc4bba8a4bc..c0ed13d6249 100644 --- a/components/datetime/src/fields/ule.rs +++ b/components/datetime/src/fields/ule.rs @@ -3,7 +3,7 @@ // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). use crate::fields; -use zerovec::ule::{AsULE, ULE}; +use zerovec::ule::{AsULE, ULEError, ULE}; /// `FieldULE` is a type optimized for efficent storing and /// deserialization of `DateTimeFormat` `Field` elements using @@ -70,15 +70,15 @@ impl AsULE for fields::Field { // 5 The other ULE methods use the default impl. // 6. FieldULE byte equality is semantic equality. unsafe impl ULE for FieldULE { - type Error = &'static str; - - fn validate_byte_slice(bytes: &[u8]) -> Result<(), Self::Error> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), ULEError> { let mut chunks = bytes.chunks_exact(2); - if !chunks.all(|c| fields::Field::bytes_in_range(&c[0], &c[1])) - || !chunks.remainder().is_empty() - { - return Err("Invalid byte sequence"); + if !chunks.all(|c| fields::Field::bytes_in_range(&c[0], &c[1])) { + return Err(ULEError::parse::()); + } + + if !chunks.remainder().is_empty() { + return Err(ULEError::length::(bytes.len())); } Ok(()) } diff --git a/components/datetime/src/pattern/item/ule.rs b/components/datetime/src/pattern/item/ule.rs index 91e554b0b3d..77551a4ac18 100644 --- a/components/datetime/src/pattern/item/ule.rs +++ b/components/datetime/src/pattern/item/ule.rs @@ -5,7 +5,7 @@ use super::{GenericPatternItem, PatternItem}; use crate::fields; use core::convert::TryFrom; -use zerovec::ule::{AsULE, ULE}; +use zerovec::ule::{AsULE, ULEError, ULE}; /// `PatternItemULE` is a type optimized for efficent storing and /// deserialization of `DateTimeFormat` `PatternItem` elements using @@ -93,15 +93,15 @@ impl PatternItemULE { // 5. The other ULE methods use the default impl. // 6. PatternItemULE byte equality is semantic equality. unsafe impl ULE for PatternItemULE { - type Error = &'static str; - - fn validate_byte_slice(bytes: &[u8]) -> Result<(), Self::Error> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), ULEError> { let mut chunks = bytes.chunks_exact(3); - if !chunks.all(|c| Self::bytes_in_range((&c[0], &c[1], &c[2]))) - || !chunks.remainder().is_empty() - { - return Err("Invalid byte sequence"); + if !chunks.all(|c| Self::bytes_in_range((&c[0], &c[1], &c[2]))) { + return Err(ULEError::parse::()); + } + + if !chunks.remainder().is_empty() { + return Err(ULEError::length::(bytes.len())); } Ok(()) } @@ -228,15 +228,15 @@ impl GenericPatternItemULE { // 5. The other ULE methods use the default impl. // 6. GenericPatternItemULE byte equality is semantic equality. unsafe impl ULE for GenericPatternItemULE { - type Error = &'static str; - - fn validate_byte_slice(bytes: &[u8]) -> Result<(), Self::Error> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), ULEError> { let mut chunks = bytes.chunks_exact(3); - if !chunks.all(|c| Self::bytes_in_range((&c[0], &c[1], &c[2]))) - || !chunks.remainder().is_empty() - { - return Err("Invalid byte sequence"); + if !chunks.all(|c| Self::bytes_in_range((&c[0], &c[1], &c[2]))) { + return Err(ULEError::parse::()); + } + + if !chunks.remainder().is_empty() { + return Err(ULEError::length::(bytes.len())); } Ok(()) } diff --git a/components/plurals/src/rules/runtime/ast.rs b/components/plurals/src/rules/runtime/ast.rs index 424859a6285..d8953f91a4e 100644 --- a/components/plurals/src/rules/runtime/ast.rs +++ b/components/plurals/src/rules/runtime/ast.rs @@ -13,7 +13,7 @@ use core::{ use icu_provider::yoke::{self, *}; use num_enum::{IntoPrimitive, TryFromPrimitive, UnsafeFromPrimitive}; use zerovec::{ - ule::{custom::EncodeAsVarULE, AsULE, PairULE, PlainOldULE, VarULE, ULE}, + ule::{custom::EncodeAsVarULE, AsULE, PairULE, PlainOldULE, ULEError, VarULE, ULE}, {VarZeroVec, ZeroVec}, }; @@ -326,8 +326,8 @@ impl RelationULE { } #[inline] - fn validate_andor_polarity_operand(encoded: u8) -> Result<(), &'static str> { - Operand::try_from(encoded & 0b0011_1111).map_err(|_| "Failed to decode operand.")?; + fn validate_andor_polarity_operand(encoded: u8) -> Result<(), ULEError> { + Operand::try_from(encoded & 0b0011_1111).map_err(|_| ULEError::parse::())?; Ok(()) } @@ -361,8 +361,6 @@ impl RelationULE { // 6. The other VarULE methods use the default impl. // 7. RelationULE byte equality is semantic equality. unsafe impl VarULE for RelationULE { - type Error = &'static str; - #[inline] unsafe fn from_byte_slice_unchecked(bytes: &[u8]) -> &Self { let ptr = bytes.as_ptr(); @@ -387,15 +385,14 @@ unsafe impl VarULE for RelationULE { } #[inline] - fn validate_byte_slice(bytes: &[u8]) -> Result<(), Self::Error> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), ULEError> { RelationULE::validate_andor_polarity_operand(bytes[0])?; // Skip bytes 1-4 as they're always valid `u32` for `Modulo`. if bytes.len() < 5 { - return Err("byte slice is too short"); + return Err(ULEError::parse::()); } let remaining = &bytes[5..]; - RangeOrValueULE::validate_byte_slice(remaining) - .map_err(|_| "Invalid list of RangeOrValueULE")?; + RangeOrValueULE::validate_byte_slice(remaining)?; Ok(()) } } diff --git a/components/properties/src/ule.rs b/components/properties/src/ule.rs index 82d34171935..d547a18fd0f 100644 --- a/components/properties/src/ule.rs +++ b/components/properties/src/ule.rs @@ -8,8 +8,7 @@ use crate::{ }; use core::convert::TryFrom; -use num_enum::TryFromPrimitiveError; -use zerovec::ule::{AsULE, PlainOldULE, ULE}; +use zerovec::ule::{AsULE, PlainOldULE, ULEError, ULE}; #[repr(transparent)] #[derive(Debug, PartialEq, Eq, Clone, Copy)] @@ -42,12 +41,10 @@ impl AsULE for GeneralSubcategory { // 5. The other ULE methods use the default impl. // 6. The PartialEq implementation on GeneralSubcategory uses byte equality. unsafe impl ULE for GeneralSubcategoryULE { - type Error = TryFromPrimitiveError; - - fn validate_byte_slice(bytes: &[u8]) -> Result<(), Self::Error> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), ULEError> { // Validate the bytes for b in bytes { - GeneralSubcategory::try_from(*b)?; + GeneralSubcategory::try_from(*b).map_err(|_| ULEError::parse::())?; } Ok(()) } diff --git a/utils/codepointtrie/src/codepointtrie.rs b/utils/codepointtrie/src/codepointtrie.rs index e2a33f1ce13..c181c723bd7 100644 --- a/utils/codepointtrie/src/codepointtrie.rs +++ b/utils/codepointtrie/src/codepointtrie.rs @@ -11,6 +11,7 @@ use core::num::TryFromIntError; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; use yoke::{Yokeable, ZeroCopyFrom}; +use zerovec::ULEError; use zerovec::ZeroVec; /// The type of trie represents whether the trie has an optimization that @@ -331,12 +332,7 @@ impl<'trie, T: TrieValue> CodePointTrie<'trie, T> { /// let cpt2: CodePointTrie = cpt1.try_into_converted() /// .expect("infallible"); /// ``` - pub fn try_into_converted

( - self, - ) -> Result< - CodePointTrie<'trie, P>, - <

::ULE as zerovec::ule::ULE>::Error, - > + pub fn try_into_converted

(self) -> Result, ULEError> where P: TrieValue, { diff --git a/utils/zerovec/benches/zerovec.rs b/utils/zerovec/benches/zerovec.rs index fdde6d8c477..7e950d67e7e 100644 --- a/utils/zerovec/benches/zerovec.rs +++ b/utils/zerovec/benches/zerovec.rs @@ -48,7 +48,6 @@ fn get_needles_and_haystack() -> (Vec, Vec) { fn vec_to_unaligned_uvec<'a, T>(vec: &Vec, buffer: &'a mut AlignedBuffer) -> ZeroVec<'a, T> where T: EqULE + Copy + PartialEq + fmt::Debug, - ::Error: fmt::Debug, { // Pad with zero to ensure it is not aligned buffer.0.push(0); diff --git a/utils/zerovec/src/lib.rs b/utils/zerovec/src/lib.rs index 5b5fc178887..b7bee1cb0b6 100644 --- a/utils/zerovec/src/lib.rs +++ b/utils/zerovec/src/lib.rs @@ -108,6 +108,6 @@ pub mod zerovec; mod yoke_impls; pub use crate::map::ZeroMap; +pub use crate::ule::ULEError; pub use crate::varzerovec::VarZeroVec; pub use crate::zerovec::ZeroVec; -pub use crate::ule::ULEError; diff --git a/utils/zerovec/src/ule/custom/mod.rs b/utils/zerovec/src/ule/custom/mod.rs index a02529fa45c..51efd77d3ad 100644 --- a/utils/zerovec/src/ule/custom/mod.rs +++ b/utils/zerovec/src/ule/custom/mod.rs @@ -57,12 +57,11 @@ //! // 6. The other VarULE methods use the default impl. //! // 7. FooULE byte equality is semantic equality //! unsafe impl VarULE for FooULE { -//! type Error = &'static str; // use strings for simplicity -//! fn validate_byte_slice(bytes: &[u8]) -> Result<(), Self::Error> { +//! fn validate_byte_slice(bytes: &[u8]) -> Result<(), ULEError> { //! // validate each field -//! ::ULE::validate_byte_slice(&bytes[0..4]).map_err(|_| "validating char failed")?; -//! ::ULE::validate_byte_slice(&bytes[4..8]).map_err(|_| "validating u32 failed")?; -//! let _ = ZeroVec::::parse_byte_slice(&bytes[8..]).map_err(|_| "validating ZeroVec failed")?; +//! ::ULE::validate_byte_slice(&bytes[0..4]).map_err(|_| ULEError::parse::())?; +//! ::ULE::validate_byte_slice(&bytes[4..8]).map_err(|_| ULEError::parse::())?; +//! let _ = ZeroVec::::parse_byte_slice(&bytes[8..]).map_err(|_| ULEError::parse::())?; //! Ok(()) //! } //! unsafe fn from_byte_slice_unchecked(bytes: &[u8]) -> &Self { diff --git a/utils/zerovec/src/varzerovec/borrowed.rs b/utils/zerovec/src/varzerovec/borrowed.rs index 6aa459d76d2..66a57015821 100644 --- a/utils/zerovec/src/varzerovec/borrowed.rs +++ b/utils/zerovec/src/varzerovec/borrowed.rs @@ -230,7 +230,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVecBorrowed<'a, T> { self.things.get(start..end).ok_or(ULEError::FormatError) }) .chain(last) - .map(|s| s.and_then(|s| T::parse_byte_slice(s).map_err(|e| e.into()))) + .map(|s| s.and_then(|s| T::parse_byte_slice(s))) } /// Create an iterator over the Ts contained in VarZeroVecBorrowed From bccc94025b962c317e5db44a175192c507a4eaec Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 14 Dec 2021 09:16:56 +0530 Subject: [PATCH 4/8] Update utils/zerovec/src/ule/error.rs Co-authored-by: Shane F. Carr --- utils/zerovec/src/ule/error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/zerovec/src/ule/error.rs b/utils/zerovec/src/ule/error.rs index af738b2dbb5..2e61fffeb8f 100644 --- a/utils/zerovec/src/ule/error.rs +++ b/utils/zerovec/src/ule/error.rs @@ -20,7 +20,7 @@ impl fmt::Display for ULEError { write!(f, "Invalid length {} for slice of type {}", len, ty) } ULEError::ParseError { ty } => { - write!(f, "Could not parse data as valud {}", ty) + write!(f, "Could not parse bytes to slice of type {}", ty) } ULEError::FormatError => { write!(f, "Invalid format for VarZeroVec buffer") From e787aa937aab9c30a7de6d9a39b0c35a8a12b6fb Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 14 Dec 2021 09:23:27 +0530 Subject: [PATCH 5/8] document + name errors --- utils/zerovec/src/ule/error.rs | 10 ++++++++-- utils/zerovec/src/varzerovec/borrowed.rs | 18 +++++++++--------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/utils/zerovec/src/ule/error.rs b/utils/zerovec/src/ule/error.rs index 2e61fffeb8f..71b0637a76a 100644 --- a/utils/zerovec/src/ule/error.rs +++ b/utils/zerovec/src/ule/error.rs @@ -8,9 +8,13 @@ use core::fmt; /// A generic error type to be used for decoding slices of ULE types #[derive(Copy, Clone, Debug)] pub enum ULEError { + /// Attempted to parse a buffer into a slice of the given ULE type but its + /// length was not compatible InvalidLength { ty: &'static str, len: usize }, + /// The byte sequence provided for `ty` failed to parse correctly ParseError { ty: &'static str }, - FormatError, + /// The byte buffer was not in the appropriate format for VarZeroVec + VZVFormatError, } impl fmt::Display for ULEError { @@ -22,7 +26,7 @@ impl fmt::Display for ULEError { ULEError::ParseError { ty } => { write!(f, "Could not parse bytes to slice of type {}", ty) } - ULEError::FormatError => { + ULEError::VZVFormatError => { write!(f, "Invalid format for VarZeroVec buffer") } } @@ -30,12 +34,14 @@ impl fmt::Display for ULEError { } impl ULEError { + /// Construct a parse error for the given type pub fn parse() -> ULEError { ULEError::ParseError { ty: any::type_name::(), } } + /// Construct an "invalid length" error for the given type and length pub fn length(len: usize) -> ULEError { ULEError::InvalidLength { ty: any::type_name::(), diff --git a/utils/zerovec/src/varzerovec/borrowed.rs b/utils/zerovec/src/varzerovec/borrowed.rs index 66a57015821..88eee6b31fe 100644 --- a/utils/zerovec/src/varzerovec/borrowed.rs +++ b/utils/zerovec/src/varzerovec/borrowed.rs @@ -98,15 +98,15 @@ impl<'a, T: VarULE + ?Sized> VarZeroVecBorrowed<'a, T> { marker: PhantomData, }); } - let len_bytes = slice.get(0..4).ok_or(ULEError::FormatError)?; + let len_bytes = slice.get(0..4).ok_or(ULEError::VZVFormatError)?; let len_ule = - PlainOldULE::<4>::parse_byte_slice(len_bytes).map_err(|_| ULEError::FormatError)?; + PlainOldULE::<4>::parse_byte_slice(len_bytes).map_err(|_| ULEError::VZVFormatError)?; - let len = u32::from_unaligned(*len_ule.get(0).ok_or(ULEError::FormatError)?) as usize; - let indices_bytes = slice.get(4..4 * len + 4).ok_or(ULEError::FormatError)?; - let indices = - PlainOldULE::<4>::parse_byte_slice(indices_bytes).map_err(|_| ULEError::FormatError)?; - let things = slice.get(4 * len + 4..).ok_or(ULEError::FormatError)?; + let len = u32::from_unaligned(*len_ule.get(0).ok_or(ULEError::VZVFormatError)?) as usize; + let indices_bytes = slice.get(4..4 * len + 4).ok_or(ULEError::VZVFormatError)?; + let indices = PlainOldULE::<4>::parse_byte_slice(indices_bytes) + .map_err(|_| ULEError::VZVFormatError)?; + let things = slice.get(4 * len + 4..).ok_or(ULEError::VZVFormatError)?; let borrowed = VarZeroVecBorrowed { indices, @@ -215,7 +215,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVecBorrowed<'a, T> { if !self.is_empty() { let start = usizeify(self.indices[self.len() - 1]); let end = self.things.len(); - Some(self.things.get(start..end).ok_or(ULEError::FormatError)) + Some(self.things.get(start..end).ok_or(ULEError::VZVFormatError)) } else { None } @@ -227,7 +227,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVecBorrowed<'a, T> { let start = usizeify(win[0]); let end = usizeify(win[1]); // the .get() here automatically verifies that end>=start - self.things.get(start..end).ok_or(ULEError::FormatError) + self.things.get(start..end).ok_or(ULEError::VZVFormatError) }) .chain(last) .map(|s| s.and_then(|s| T::parse_byte_slice(s))) From de4163aac84df133ef13997d3568ec84b5bec150 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 14 Dec 2021 09:28:25 +0530 Subject: [PATCH 6/8] rename to ZeroVecError --- components/datetime/src/fields/ule.rs | 8 ++-- components/datetime/src/pattern/item/ule.rs | 14 +++---- components/plurals/src/rules/runtime/ast.rs | 10 ++--- components/properties/src/ule.rs | 6 +-- utils/codepointtrie/src/codepointtrie.rs | 4 +- utils/zerovec/src/lib.rs | 2 +- utils/zerovec/src/ule/chars.rs | 6 +-- utils/zerovec/src/ule/custom/mod.rs | 8 ++-- utils/zerovec/src/ule/error.rs | 22 +++++----- utils/zerovec/src/ule/mod.rs | 10 ++--- utils/zerovec/src/ule/pair.rs | 4 +- utils/zerovec/src/ule/plain.rs | 8 ++-- utils/zerovec/src/ule/slices.rs | 10 ++--- utils/zerovec/src/varzerovec/borrowed.rs | 33 ++++++++++----- utils/zerovec/src/varzerovec/mod.rs | 46 ++++++++++----------- utils/zerovec/src/varzerovec/ule.rs | 2 +- utils/zerovec/src/zerovec/mod.rs | 6 +-- utils/zerovec/src/zerovec/ule.rs | 2 +- 18 files changed, 106 insertions(+), 95 deletions(-) diff --git a/components/datetime/src/fields/ule.rs b/components/datetime/src/fields/ule.rs index c0ed13d6249..d8e4aed9841 100644 --- a/components/datetime/src/fields/ule.rs +++ b/components/datetime/src/fields/ule.rs @@ -3,7 +3,7 @@ // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). use crate::fields; -use zerovec::ule::{AsULE, ULEError, ULE}; +use zerovec::ule::{AsULE, ZeroVecError, ULE}; /// `FieldULE` is a type optimized for efficent storing and /// deserialization of `DateTimeFormat` `Field` elements using @@ -70,15 +70,15 @@ impl AsULE for fields::Field { // 5 The other ULE methods use the default impl. // 6. FieldULE byte equality is semantic equality. unsafe impl ULE for FieldULE { - fn validate_byte_slice(bytes: &[u8]) -> Result<(), ULEError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError> { let mut chunks = bytes.chunks_exact(2); if !chunks.all(|c| fields::Field::bytes_in_range(&c[0], &c[1])) { - return Err(ULEError::parse::()); + return Err(ZeroVecError::parse::()); } if !chunks.remainder().is_empty() { - return Err(ULEError::length::(bytes.len())); + return Err(ZeroVecError::length::(bytes.len())); } Ok(()) } diff --git a/components/datetime/src/pattern/item/ule.rs b/components/datetime/src/pattern/item/ule.rs index 77551a4ac18..364412b4b56 100644 --- a/components/datetime/src/pattern/item/ule.rs +++ b/components/datetime/src/pattern/item/ule.rs @@ -5,7 +5,7 @@ use super::{GenericPatternItem, PatternItem}; use crate::fields; use core::convert::TryFrom; -use zerovec::ule::{AsULE, ULEError, ULE}; +use zerovec::ule::{AsULE, ZeroVecError, ULE}; /// `PatternItemULE` is a type optimized for efficent storing and /// deserialization of `DateTimeFormat` `PatternItem` elements using @@ -93,15 +93,15 @@ impl PatternItemULE { // 5. The other ULE methods use the default impl. // 6. PatternItemULE byte equality is semantic equality. unsafe impl ULE for PatternItemULE { - fn validate_byte_slice(bytes: &[u8]) -> Result<(), ULEError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError> { let mut chunks = bytes.chunks_exact(3); if !chunks.all(|c| Self::bytes_in_range((&c[0], &c[1], &c[2]))) { - return Err(ULEError::parse::()); + return Err(ZeroVecError::parse::()); } if !chunks.remainder().is_empty() { - return Err(ULEError::length::(bytes.len())); + return Err(ZeroVecError::length::(bytes.len())); } Ok(()) } @@ -228,15 +228,15 @@ impl GenericPatternItemULE { // 5. The other ULE methods use the default impl. // 6. GenericPatternItemULE byte equality is semantic equality. unsafe impl ULE for GenericPatternItemULE { - fn validate_byte_slice(bytes: &[u8]) -> Result<(), ULEError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError> { let mut chunks = bytes.chunks_exact(3); if !chunks.all(|c| Self::bytes_in_range((&c[0], &c[1], &c[2]))) { - return Err(ULEError::parse::()); + return Err(ZeroVecError::parse::()); } if !chunks.remainder().is_empty() { - return Err(ULEError::length::(bytes.len())); + return Err(ZeroVecError::length::(bytes.len())); } Ok(()) } diff --git a/components/plurals/src/rules/runtime/ast.rs b/components/plurals/src/rules/runtime/ast.rs index d8953f91a4e..7b6c9591346 100644 --- a/components/plurals/src/rules/runtime/ast.rs +++ b/components/plurals/src/rules/runtime/ast.rs @@ -13,7 +13,7 @@ use core::{ use icu_provider::yoke::{self, *}; use num_enum::{IntoPrimitive, TryFromPrimitive, UnsafeFromPrimitive}; use zerovec::{ - ule::{custom::EncodeAsVarULE, AsULE, PairULE, PlainOldULE, ULEError, VarULE, ULE}, + ule::{custom::EncodeAsVarULE, AsULE, PairULE, PlainOldULE, VarULE, ZeroVecError, ULE}, {VarZeroVec, ZeroVec}, }; @@ -326,8 +326,8 @@ impl RelationULE { } #[inline] - fn validate_andor_polarity_operand(encoded: u8) -> Result<(), ULEError> { - Operand::try_from(encoded & 0b0011_1111).map_err(|_| ULEError::parse::())?; + fn validate_andor_polarity_operand(encoded: u8) -> Result<(), ZeroVecError> { + Operand::try_from(encoded & 0b0011_1111).map_err(|_| ZeroVecError::parse::())?; Ok(()) } @@ -385,11 +385,11 @@ unsafe impl VarULE for RelationULE { } #[inline] - fn validate_byte_slice(bytes: &[u8]) -> Result<(), ULEError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError> { RelationULE::validate_andor_polarity_operand(bytes[0])?; // Skip bytes 1-4 as they're always valid `u32` for `Modulo`. if bytes.len() < 5 { - return Err(ULEError::parse::()); + return Err(ZeroVecError::parse::()); } let remaining = &bytes[5..]; RangeOrValueULE::validate_byte_slice(remaining)?; diff --git a/components/properties/src/ule.rs b/components/properties/src/ule.rs index d547a18fd0f..a5e2b68f0fd 100644 --- a/components/properties/src/ule.rs +++ b/components/properties/src/ule.rs @@ -8,7 +8,7 @@ use crate::{ }; use core::convert::TryFrom; -use zerovec::ule::{AsULE, PlainOldULE, ULEError, ULE}; +use zerovec::ule::{AsULE, PlainOldULE, ZeroVecError, ULE}; #[repr(transparent)] #[derive(Debug, PartialEq, Eq, Clone, Copy)] @@ -41,10 +41,10 @@ impl AsULE for GeneralSubcategory { // 5. The other ULE methods use the default impl. // 6. The PartialEq implementation on GeneralSubcategory uses byte equality. unsafe impl ULE for GeneralSubcategoryULE { - fn validate_byte_slice(bytes: &[u8]) -> Result<(), ULEError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError> { // Validate the bytes for b in bytes { - GeneralSubcategory::try_from(*b).map_err(|_| ULEError::parse::())?; + GeneralSubcategory::try_from(*b).map_err(|_| ZeroVecError::parse::())?; } Ok(()) } diff --git a/utils/codepointtrie/src/codepointtrie.rs b/utils/codepointtrie/src/codepointtrie.rs index c181c723bd7..8da6a1e230b 100644 --- a/utils/codepointtrie/src/codepointtrie.rs +++ b/utils/codepointtrie/src/codepointtrie.rs @@ -11,8 +11,8 @@ use core::num::TryFromIntError; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; use yoke::{Yokeable, ZeroCopyFrom}; -use zerovec::ULEError; use zerovec::ZeroVec; +use zerovec::ZeroVecError; /// The type of trie represents whether the trie has an optimization that /// would make it small or fast. @@ -332,7 +332,7 @@ impl<'trie, T: TrieValue> CodePointTrie<'trie, T> { /// let cpt2: CodePointTrie = cpt1.try_into_converted() /// .expect("infallible"); /// ``` - pub fn try_into_converted

(self) -> Result, ULEError> + pub fn try_into_converted

::ULE>() @@ -446,7 +446,7 @@ impl<'a> ZeroVec<'a, u8> { /// assert!(matches!(zerovec, ZeroVec::Owned(_))); /// assert_eq!(zerovec.get(0), Some(211)); /// ``` - pub fn try_into_parsed(self) -> Result, ULEError> { + pub fn try_into_parsed(self) -> Result, ZeroVecError> { match self { ZeroVec::Borrowed(bytes) => { let slice: &'a [T::ULE] = T::ULE::parse_byte_slice(bytes)?; diff --git a/utils/zerovec/src/zerovec/ule.rs b/utils/zerovec/src/zerovec/ule.rs index d4f6463799d..cdc9df44b51 100644 --- a/utils/zerovec/src/zerovec/ule.rs +++ b/utils/zerovec/src/zerovec/ule.rs @@ -72,7 +72,7 @@ where // 7. `[T::ULE]` byte equality is semantic equality (relying on the guideline of the underlying `ULE` type) unsafe impl VarULE for ZeroVecULE { #[inline] - fn validate_byte_slice(bytes: &[u8]) -> Result<(), ULEError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError> { T::ULE::validate_byte_slice(bytes) } From 0426032fd1345f2a2f846f2facddd8994fad975a Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 14 Dec 2021 10:09:36 +0530 Subject: [PATCH 7/8] rename VZVFE --- utils/zerovec/src/ule/error.rs | 4 ++-- utils/zerovec/src/varzerovec/borrowed.rs | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/utils/zerovec/src/ule/error.rs b/utils/zerovec/src/ule/error.rs index 73030fc1416..e72fc75732c 100644 --- a/utils/zerovec/src/ule/error.rs +++ b/utils/zerovec/src/ule/error.rs @@ -14,7 +14,7 @@ pub enum ZeroVecError { /// The byte sequence provided for `ty` failed to parse correctly ParseError { ty: &'static str }, /// The byte buffer was not in the appropriate format for VarZeroVec - VZVFormatError, + VarZeroVecFormatError, } impl fmt::Display for ZeroVecError { @@ -26,7 +26,7 @@ impl fmt::Display for ZeroVecError { ZeroVecError::ParseError { ty } => { write!(f, "Could not parse bytes to slice of type {}", ty) } - ZeroVecError::VZVFormatError => { + ZeroVecError::VarZeroVecFormatError => { write!(f, "Invalid format for VarZeroVec buffer") } } diff --git a/utils/zerovec/src/varzerovec/borrowed.rs b/utils/zerovec/src/varzerovec/borrowed.rs index b66a460c259..f2fa06912e1 100644 --- a/utils/zerovec/src/varzerovec/borrowed.rs +++ b/utils/zerovec/src/varzerovec/borrowed.rs @@ -98,20 +98,20 @@ impl<'a, T: VarULE + ?Sized> VarZeroVecBorrowed<'a, T> { marker: PhantomData, }); } - let len_bytes = slice.get(0..4).ok_or(ZeroVecError::VZVFormatError)?; + let len_bytes = slice.get(0..4).ok_or(ZeroVecError::VarZeroVecFormatError)?; let len_ule = PlainOldULE::<4>::parse_byte_slice(len_bytes) - .map_err(|_| ZeroVecError::VZVFormatError)?; + .map_err(|_| ZeroVecError::VarZeroVecFormatError)?; let len = - u32::from_unaligned(*len_ule.get(0).ok_or(ZeroVecError::VZVFormatError)?) as usize; + u32::from_unaligned(*len_ule.get(0).ok_or(ZeroVecError::VarZeroVecFormatError)?) as usize; let indices_bytes = slice .get(4..4 * len + 4) - .ok_or(ZeroVecError::VZVFormatError)?; + .ok_or(ZeroVecError::VarZeroVecFormatError)?; let indices = PlainOldULE::<4>::parse_byte_slice(indices_bytes) - .map_err(|_| ZeroVecError::VZVFormatError)?; + .map_err(|_| ZeroVecError::VarZeroVecFormatError)?; let things = slice .get(4 * len + 4..) - .ok_or(ZeroVecError::VZVFormatError)?; + .ok_or(ZeroVecError::VarZeroVecFormatError)?; let borrowed = VarZeroVecBorrowed { indices, @@ -223,7 +223,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVecBorrowed<'a, T> { Some( self.things .get(start..end) - .ok_or(ZeroVecError::VZVFormatError), + .ok_or(ZeroVecError::VarZeroVecFormatError), ) } else { None @@ -238,7 +238,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVecBorrowed<'a, T> { // the .get() here automatically verifies that end>=start self.things .get(start..end) - .ok_or(ZeroVecError::VZVFormatError) + .ok_or(ZeroVecError::VarZeroVecFormatError) }) .chain(last) .map(|s| s.and_then(|s| T::parse_byte_slice(s))) From 8ef69fb14ed1c2088c2528f04ef0ceacb4b0f748 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 14 Dec 2021 10:10:49 +0530 Subject: [PATCH 8/8] Move error up one folder --- utils/zerovec/src/{ule => }/error.rs | 0 utils/zerovec/src/lib.rs | 3 ++- utils/zerovec/src/ule/mod.rs | 3 +-- utils/zerovec/src/varzerovec/borrowed.rs | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) rename utils/zerovec/src/{ule => }/error.rs (100%) diff --git a/utils/zerovec/src/ule/error.rs b/utils/zerovec/src/error.rs similarity index 100% rename from utils/zerovec/src/ule/error.rs rename to utils/zerovec/src/error.rs diff --git a/utils/zerovec/src/lib.rs b/utils/zerovec/src/lib.rs index 199de7e6251..197c8a14fb3 100644 --- a/utils/zerovec/src/lib.rs +++ b/utils/zerovec/src/lib.rs @@ -97,6 +97,7 @@ extern crate alloc; +mod error; pub mod map; #[cfg(test)] pub mod samples; @@ -107,7 +108,7 @@ pub mod zerovec; #[cfg(feature = "yoke")] mod yoke_impls; +pub use crate::error::ZeroVecError; pub use crate::map::ZeroMap; -pub use crate::ule::ZeroVecError; pub use crate::varzerovec::VarZeroVec; pub use crate::zerovec::ZeroVec; diff --git a/utils/zerovec/src/ule/mod.rs b/utils/zerovec/src/ule/mod.rs index 4530adb469c..e94009c1f5c 100644 --- a/utils/zerovec/src/ule/mod.rs +++ b/utils/zerovec/src/ule/mod.rs @@ -7,13 +7,12 @@ mod chars; pub mod custom; -mod error; mod pair; mod plain; mod slices; +pub use super::ZeroVecError; pub use chars::CharULE; -pub use error::ZeroVecError; pub use pair::PairULE; pub use plain::PlainOldULE; diff --git a/utils/zerovec/src/varzerovec/borrowed.rs b/utils/zerovec/src/varzerovec/borrowed.rs index f2fa06912e1..89447d60ced 100644 --- a/utils/zerovec/src/varzerovec/borrowed.rs +++ b/utils/zerovec/src/varzerovec/borrowed.rs @@ -102,8 +102,8 @@ impl<'a, T: VarULE + ?Sized> VarZeroVecBorrowed<'a, T> { let len_ule = PlainOldULE::<4>::parse_byte_slice(len_bytes) .map_err(|_| ZeroVecError::VarZeroVecFormatError)?; - let len = - u32::from_unaligned(*len_ule.get(0).ok_or(ZeroVecError::VarZeroVecFormatError)?) as usize; + let len = u32::from_unaligned(*len_ule.get(0).ok_or(ZeroVecError::VarZeroVecFormatError)?) + as usize; let indices_bytes = slice .get(4..4 * len + 4) .ok_or(ZeroVecError::VarZeroVecFormatError)?;

(self) -> Result, ZeroVecError> where P: TrieValue, { diff --git a/utils/zerovec/src/lib.rs b/utils/zerovec/src/lib.rs index b7bee1cb0b6..199de7e6251 100644 --- a/utils/zerovec/src/lib.rs +++ b/utils/zerovec/src/lib.rs @@ -108,6 +108,6 @@ pub mod zerovec; mod yoke_impls; pub use crate::map::ZeroMap; -pub use crate::ule::ULEError; +pub use crate::ule::ZeroVecError; pub use crate::varzerovec::VarZeroVec; pub use crate::zerovec::ZeroVec; diff --git a/utils/zerovec/src/ule/chars.rs b/utils/zerovec/src/ule/chars.rs index 17f88c6ae85..2432452915e 100644 --- a/utils/zerovec/src/ule/chars.rs +++ b/utils/zerovec/src/ule/chars.rs @@ -50,15 +50,15 @@ pub struct CharULE([u8; 4]); // 6. CharULE byte equality is semantic equality unsafe impl ULE for CharULE { #[inline] - fn validate_byte_slice(bytes: &[u8]) -> Result<(), ULEError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError> { if bytes.len() % 4 != 0 { - return Err(ULEError::length::(bytes.len())); + return Err(ZeroVecError::length::(bytes.len())); } // Validate the bytes for chunk in bytes.chunks_exact(4) { // TODO: Use slice::as_chunks() when stabilized let u = u32::from_le_bytes([chunk[0], chunk[1], chunk[2], chunk[3]]); - char::try_from(u).map_err(|_| ULEError::parse::())?; + char::try_from(u).map_err(|_| ZeroVecError::parse::())?; } Ok(()) } diff --git a/utils/zerovec/src/ule/custom/mod.rs b/utils/zerovec/src/ule/custom/mod.rs index 51efd77d3ad..2b6deac6c05 100644 --- a/utils/zerovec/src/ule/custom/mod.rs +++ b/utils/zerovec/src/ule/custom/mod.rs @@ -57,11 +57,11 @@ //! // 6. The other VarULE methods use the default impl. //! // 7. FooULE byte equality is semantic equality //! unsafe impl VarULE for FooULE { -//! fn validate_byte_slice(bytes: &[u8]) -> Result<(), ULEError> { +//! fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError> { //! // validate each field -//! ::ULE::validate_byte_slice(&bytes[0..4]).map_err(|_| ULEError::parse::())?; -//! ::ULE::validate_byte_slice(&bytes[4..8]).map_err(|_| ULEError::parse::())?; -//! let _ = ZeroVec::::parse_byte_slice(&bytes[8..]).map_err(|_| ULEError::parse::())?; +//! ::ULE::validate_byte_slice(&bytes[0..4]).map_err(|_| ZeroVecError::parse::())?; +//! ::ULE::validate_byte_slice(&bytes[4..8]).map_err(|_| ZeroVecError::parse::())?; +//! let _ = ZeroVec::::parse_byte_slice(&bytes[8..]).map_err(|_| ZeroVecError::parse::())?; //! Ok(()) //! } //! unsafe fn from_byte_slice_unchecked(bytes: &[u8]) -> &Self { diff --git a/utils/zerovec/src/ule/error.rs b/utils/zerovec/src/ule/error.rs index 71b0637a76a..73030fc1416 100644 --- a/utils/zerovec/src/ule/error.rs +++ b/utils/zerovec/src/ule/error.rs @@ -7,7 +7,7 @@ use core::fmt; /// A generic error type to be used for decoding slices of ULE types #[derive(Copy, Clone, Debug)] -pub enum ULEError { +pub enum ZeroVecError { /// Attempted to parse a buffer into a slice of the given ULE type but its /// length was not compatible InvalidLength { ty: &'static str, len: usize }, @@ -17,33 +17,33 @@ pub enum ULEError { VZVFormatError, } -impl fmt::Display for ULEError { +impl fmt::Display for ZeroVecError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { match *self { - ULEError::InvalidLength { ty, len } => { + ZeroVecError::InvalidLength { ty, len } => { write!(f, "Invalid length {} for slice of type {}", len, ty) } - ULEError::ParseError { ty } => { + ZeroVecError::ParseError { ty } => { write!(f, "Could not parse bytes to slice of type {}", ty) } - ULEError::VZVFormatError => { + ZeroVecError::VZVFormatError => { write!(f, "Invalid format for VarZeroVec buffer") } } } } -impl ULEError { +impl ZeroVecError { /// Construct a parse error for the given type - pub fn parse() -> ULEError { - ULEError::ParseError { + pub fn parse() -> ZeroVecError { + ZeroVecError::ParseError { ty: any::type_name::(), } } /// Construct an "invalid length" error for the given type and length - pub fn length(len: usize) -> ULEError { - ULEError::InvalidLength { + pub fn length(len: usize) -> ZeroVecError { + ZeroVecError::InvalidLength { ty: any::type_name::(), len, } @@ -51,4 +51,4 @@ impl ULEError { } #[cfg(feature = "std")] -impl ::std::error::Error for ULEError {} +impl ::std::error::Error for ZeroVecError {} diff --git a/utils/zerovec/src/ule/mod.rs b/utils/zerovec/src/ule/mod.rs index 5e4d66bb505..4530adb469c 100644 --- a/utils/zerovec/src/ule/mod.rs +++ b/utils/zerovec/src/ule/mod.rs @@ -13,7 +13,7 @@ mod plain; mod slices; pub use chars::CharULE; -pub use error::ULEError; +pub use error::ZeroVecError; pub use pair::PairULE; pub use plain::PlainOldULE; @@ -68,7 +68,7 @@ where /// If `Self` is not well-defined for all possible bit values, the bytes should be validated. /// If the bytes can be transmuted, *in their entirety*, to a valid slice of `Self`, then `Ok` /// should be returned; otherwise, `Self::Error` should be returned. - fn validate_byte_slice(bytes: &[u8]) -> Result<(), ULEError>; + fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError>; /// Parses a byte slice, `&[u8]`, and return it as `&[Self]` with the same lifetime. /// @@ -80,7 +80,7 @@ where /// /// Note: The following equality should hold: `bytes.len() % size_of::() == 0`. This /// means that the returned slice can span the entire byte slice. - fn parse_byte_slice(bytes: &[u8]) -> Result<&[Self], ULEError> { + fn parse_byte_slice(bytes: &[u8]) -> Result<&[Self], ZeroVecError> { Self::validate_byte_slice(bytes)?; debug_assert_eq!(bytes.len() % mem::size_of::(), 0); Ok(unsafe { Self::from_byte_slice_unchecked(bytes) }) @@ -265,7 +265,7 @@ pub unsafe trait VarULE: 'static { /// If `Self` is not well-defined for all possible bit values, the bytes should be validated. /// If the bytes can be transmuted, *in their entirety*, to a valid `&Self`, then `Ok` should /// be returned; otherwise, `Self::Error` should be returned. - fn validate_byte_slice(_bytes: &[u8]) -> Result<(), ULEError>; + fn validate_byte_slice(_bytes: &[u8]) -> Result<(), ZeroVecError>; /// Parses a byte slice, `&[u8]`, and return it as `&Self` with the same lifetime. /// @@ -278,7 +278,7 @@ pub unsafe trait VarULE: 'static { /// Note: The following equality should hold: `size_of_val(result) == size_of_val(bytes)`, /// where `result` is the successful return value of the method. This means that the return /// value spans the entire byte slice. - fn parse_byte_slice(bytes: &[u8]) -> Result<&Self, ULEError> { + fn parse_byte_slice(bytes: &[u8]) -> Result<&Self, ZeroVecError> { Self::validate_byte_slice(bytes)?; let result = unsafe { Self::from_byte_slice_unchecked(bytes) }; debug_assert_eq!(mem::size_of_val(result), mem::size_of_val(bytes)); diff --git a/utils/zerovec/src/ule/pair.rs b/utils/zerovec/src/ule/pair.rs index 447809b6746..da6ca274cba 100644 --- a/utils/zerovec/src/ule/pair.rs +++ b/utils/zerovec/src/ule/pair.rs @@ -22,11 +22,11 @@ pub struct PairULE(pub A, pub B); // 6. PairULE byte equality is semantic equality by relying on the ULE equality // invariant on the subfields unsafe impl ULE for PairULE { - fn validate_byte_slice(bytes: &[u8]) -> Result<(), ULEError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError> { let a_len = mem::size_of::(); let b_len = mem::size_of::(); if bytes.len() % (a_len + b_len) != 0 { - return Err(ULEError::length::(bytes.len())); + return Err(ZeroVecError::length::(bytes.len())); } for chunk in bytes.chunks(a_len + b_len) { A::validate_byte_slice(&chunk[..a_len])?; diff --git a/utils/zerovec/src/ule/plain.rs b/utils/zerovec/src/ule/plain.rs index b2f53224be9..4f001b70d6a 100644 --- a/utils/zerovec/src/ule/plain.rs +++ b/utils/zerovec/src/ule/plain.rs @@ -37,12 +37,12 @@ macro_rules! impl_byte_slice_size { // 6. PlainOldULE byte equality is semantic equality unsafe impl ULE for PlainOldULE<$size> { #[inline] - fn validate_byte_slice(bytes: &[u8]) -> Result<(), ULEError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError> { if bytes.len() % $size == 0 { // Safe because Self is transparent over [u8; $size] Ok(()) } else { - Err(ULEError::length::(bytes.len())) + Err(ZeroVecError::length::(bytes.len())) } } } @@ -108,11 +108,11 @@ impl_byte_slice_type!(i128, 16); // 6. u8 byte equality is semantic equality unsafe impl ULE for u8 { #[inline] - fn validate_byte_slice(_bytes: &[u8]) -> Result<(), ULEError> { + fn validate_byte_slice(_bytes: &[u8]) -> Result<(), ZeroVecError> { Ok(()) } #[inline] - fn parse_byte_slice(bytes: &[u8]) -> Result<&[Self], ULEError> { + fn parse_byte_slice(bytes: &[u8]) -> Result<&[Self], ZeroVecError> { Ok(bytes) } #[inline] diff --git a/utils/zerovec/src/ule/slices.rs b/utils/zerovec/src/ule/slices.rs index 6048fc9fe8d..ce5bb1abdef 100644 --- a/utils/zerovec/src/ule/slices.rs +++ b/utils/zerovec/src/ule/slices.rs @@ -15,14 +15,14 @@ use core::str; // 7. str byte equality is semantic equality unsafe impl VarULE for str { #[inline] - fn validate_byte_slice(bytes: &[u8]) -> Result<(), ULEError> { - str::from_utf8(bytes).map_err(|_| ULEError::parse::())?; + fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError> { + str::from_utf8(bytes).map_err(|_| ZeroVecError::parse::())?; Ok(()) } #[inline] - fn parse_byte_slice(bytes: &[u8]) -> Result<&Self, ULEError> { - str::from_utf8(bytes).map_err(|_| ULEError::parse::()) + fn parse_byte_slice(bytes: &[u8]) -> Result<&Self, ZeroVecError> { + str::from_utf8(bytes).map_err(|_| ZeroVecError::parse::()) } /// Invariant: must be safe to call when called on a slice that previously /// succeeded with `parse_byte_slice` @@ -45,7 +45,7 @@ where T: ULE + AsULE, { #[inline] - fn validate_byte_slice(slice: &[u8]) -> Result<(), ULEError> { + fn validate_byte_slice(slice: &[u8]) -> Result<(), ZeroVecError> { T::validate_byte_slice(slice) } diff --git a/utils/zerovec/src/varzerovec/borrowed.rs b/utils/zerovec/src/varzerovec/borrowed.rs index 88eee6b31fe..b66a460c259 100644 --- a/utils/zerovec/src/varzerovec/borrowed.rs +++ b/utils/zerovec/src/varzerovec/borrowed.rs @@ -89,7 +89,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVecBorrowed<'a, T> { /// - `indices[len - 1]..things.len()` must index into a valid section of /// `things`, such that it parses to a `T::VarULE` #[inline] - pub fn parse_byte_slice(slice: &'a [u8]) -> Result { + pub fn parse_byte_slice(slice: &'a [u8]) -> Result { if slice.is_empty() { return Ok(VarZeroVecBorrowed { indices: &[], @@ -98,15 +98,20 @@ impl<'a, T: VarULE + ?Sized> VarZeroVecBorrowed<'a, T> { marker: PhantomData, }); } - let len_bytes = slice.get(0..4).ok_or(ULEError::VZVFormatError)?; - let len_ule = - PlainOldULE::<4>::parse_byte_slice(len_bytes).map_err(|_| ULEError::VZVFormatError)?; + let len_bytes = slice.get(0..4).ok_or(ZeroVecError::VZVFormatError)?; + let len_ule = PlainOldULE::<4>::parse_byte_slice(len_bytes) + .map_err(|_| ZeroVecError::VZVFormatError)?; - let len = u32::from_unaligned(*len_ule.get(0).ok_or(ULEError::VZVFormatError)?) as usize; - let indices_bytes = slice.get(4..4 * len + 4).ok_or(ULEError::VZVFormatError)?; + let len = + u32::from_unaligned(*len_ule.get(0).ok_or(ZeroVecError::VZVFormatError)?) as usize; + let indices_bytes = slice + .get(4..4 * len + 4) + .ok_or(ZeroVecError::VZVFormatError)?; let indices = PlainOldULE::<4>::parse_byte_slice(indices_bytes) - .map_err(|_| ULEError::VZVFormatError)?; - let things = slice.get(4 * len + 4..).ok_or(ULEError::VZVFormatError)?; + .map_err(|_| ZeroVecError::VZVFormatError)?; + let things = slice + .get(4 * len + 4..) + .ok_or(ZeroVecError::VZVFormatError)?; let borrowed = VarZeroVecBorrowed { indices, @@ -210,12 +215,16 @@ impl<'a, T: VarULE + ?Sized> VarZeroVecBorrowed<'a, T> { /// This method is NOT allowed to call any other methods on VarZeroVecBorrowed since all other methods /// assume that the slice has been passed through iter_checked #[inline] - fn iter_checked(self) -> impl Iterator> { + fn iter_checked(self) -> impl Iterator> { let last = iter::from_fn(move || { if !self.is_empty() { let start = usizeify(self.indices[self.len() - 1]); let end = self.things.len(); - Some(self.things.get(start..end).ok_or(ULEError::VZVFormatError)) + Some( + self.things + .get(start..end) + .ok_or(ZeroVecError::VZVFormatError), + ) } else { None } @@ -227,7 +236,9 @@ impl<'a, T: VarULE + ?Sized> VarZeroVecBorrowed<'a, T> { let start = usizeify(win[0]); let end = usizeify(win[1]); // the .get() here automatically verifies that end>=start - self.things.get(start..end).ok_or(ULEError::VZVFormatError) + self.things + .get(start..end) + .ok_or(ZeroVecError::VZVFormatError) }) .chain(last) .map(|s| s.and_then(|s| T::parse_byte_slice(s))) diff --git a/utils/zerovec/src/varzerovec/mod.rs b/utils/zerovec/src/varzerovec/mod.rs index 4e50a5dd36b..fd802bb670f 100644 --- a/utils/zerovec/src/varzerovec/mod.rs +++ b/utils/zerovec/src/varzerovec/mod.rs @@ -62,7 +62,7 @@ pub use ule::VarZeroVecULE; /// /// ```rust /// # use std::str::Utf8Error; -/// # use zerovec::ule::ULEError; +/// # use zerovec::ule::ZeroVecError; /// use zerovec::VarZeroVec; /// /// // The little-endian bytes correspond to the list of strings. @@ -76,14 +76,14 @@ pub use ule::VarZeroVecULE; /// /// assert_eq!(zerovec.get(2), Some("文")); /// assert_eq!(zerovec, &*strings); -/// # Ok::<(), ULEError>(()) +/// # Ok::<(), ZeroVecError>(()) /// ``` /// /// Here's another example with `ZeroVecULE` (similar to `[T]`): /// /// ```rust /// # use std::str::Utf8Error; -/// # use zerovec::ule::ULEError; +/// # use zerovec::ule::ZeroVecError; /// use zerovec::VarZeroVec; /// use zerovec::ZeroVec; /// use zerovec::zerovec::ZeroVecULE; @@ -107,7 +107,7 @@ pub use ule::VarZeroVecULE; /// for (zv, v) in zerovec.iter().zip(numbers.iter()) { /// assert_eq!(zv, &**v); /// } -/// # Ok::<(), ULEError>(()) +/// # Ok::<(), ZeroVecError>(()) /// ``` /// /// @@ -227,7 +227,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVec<'a, T> { /// /// ```rust /// # use std::str::Utf8Error; - /// # use zerovec::ule::ULEError; + /// # use zerovec::ule::ZeroVecError; /// # use zerovec::VarZeroVec; /// /// let strings = vec!["foo".to_owned(), "bar".to_owned(), @@ -236,7 +236,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVec<'a, T> { /// /// let mut vec: VarZeroVec = VarZeroVec::parse_byte_slice(&bytes)?; /// assert_eq!(vec.len(), 4); - /// # Ok::<(), ULEError>(()) + /// # Ok::<(), ZeroVecError>(()) /// ``` pub fn len(&self) -> usize { self.as_borrowed().len() @@ -248,7 +248,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVec<'a, T> { /// /// ``` /// # use std::str::Utf8Error; - /// # use zerovec::ule::ULEError; + /// # use zerovec::ule::ZeroVecError; /// # use zerovec::VarZeroVec; /// /// let strings: Vec = vec![]; @@ -256,7 +256,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVec<'a, T> { /// /// let mut vec: VarZeroVec = VarZeroVec::parse_byte_slice(&bytes)?; /// assert!(vec.is_empty()); - /// # Ok::<(), ULEError>(()) + /// # Ok::<(), ZeroVecError>(()) /// ``` pub fn is_empty(&self) -> bool { self.as_borrowed().is_empty() @@ -271,7 +271,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVec<'a, T> { /// /// ```rust /// # use std::str::Utf8Error; - /// # use zerovec::ule::ULEError; + /// # use zerovec::ule::ZeroVecError; /// # use zerovec::VarZeroVec; /// /// let strings = vec!["foo".to_owned(), "bar".to_owned(), @@ -283,9 +283,9 @@ impl<'a, T: VarULE + ?Sized> VarZeroVec<'a, T> { /// assert_eq!(&vec[1], "bar"); /// assert_eq!(&vec[2], "baz"); /// assert_eq!(&vec[3], "quux"); - /// # Ok::<(), ULEError>(()) + /// # Ok::<(), ZeroVecError>(()) /// ``` - pub fn parse_byte_slice(slice: &'a [u8]) -> Result { + pub fn parse_byte_slice(slice: &'a [u8]) -> Result { if slice.is_empty() { // does not allocate return Ok(VarZeroVec::Owned(VarZeroVecOwned::new())); @@ -302,7 +302,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVec<'a, T> { /// /// ```rust /// # use std::str::Utf8Error; - /// # use zerovec::ule::ULEError; + /// # use zerovec::ule::ZeroVecError; /// # use zerovec::VarZeroVec; /// /// let strings = vec!["foo".to_owned(), "bar".to_owned(), @@ -315,7 +315,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVec<'a, T> { /// assert_eq!(iter_results[1], "bar"); /// assert_eq!(iter_results[2], "baz"); /// assert_eq!(iter_results[3], "quux"); - /// # Ok::<(), ULEError>(()) + /// # Ok::<(), ZeroVecError>(()) /// ``` pub fn iter<'b: 'a>(&'b self) -> impl Iterator { self.as_borrowed().iter() @@ -327,7 +327,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVec<'a, T> { /// /// ```rust /// # use std::str::Utf8Error; - /// # use zerovec::ule::ULEError; + /// # use zerovec::ule::ZeroVecError; /// # use zerovec::VarZeroVec; /// /// let strings = vec!["foo".to_owned(), "bar".to_owned(), @@ -341,7 +341,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVec<'a, T> { /// assert_eq!(vec.get(2), Some("baz")); /// assert_eq!(vec.get(3), Some("quux")); /// assert_eq!(vec.get(4), None); - /// # Ok::<(), ULEError>(()) + /// # Ok::<(), ZeroVecError>(()) /// ``` pub fn get(&self, idx: usize) -> Option<&T> { self.as_borrowed().get(idx) @@ -354,7 +354,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVec<'a, T> { /// /// ```rust,ignore /// # use std::str::Utf8Error; - /// # use zerovec::ule::ULEError; + /// # use zerovec::ule::ZeroVecError; /// # use zerovec::VarZeroVec; /// /// let strings = vec!["foo".to_owned(), "bar".to_owned(), @@ -371,7 +371,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVec<'a, T> { /// assert_eq!(&vec[2], "dolor sit"); /// assert_eq!(&vec[3], "quux"); /// assert_eq!(&vec[4], "lorem ipsum"); - /// # Ok::<(), ULEError>(()) + /// # Ok::<(), ZeroVecError>(()) /// ``` // // This function is crate-public for now since we don't yet want to stabilize @@ -394,7 +394,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVec<'a, T> { /// /// ``` /// # use std::str::Utf8Error; - /// # use zerovec::ule::ULEError; + /// # use zerovec::ule::ZeroVecError; /// # use zerovec::VarZeroVec; /// /// let strings = vec!["foo".to_owned(), "bar".to_owned(), @@ -405,7 +405,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVec<'a, T> { /// assert_eq!(vec.len(), 4); /// // has 'static lifetime /// let owned = vec.into_owned(); - /// # Ok::<(), ULEError>(()) + /// # Ok::<(), ZeroVecError>(()) /// ``` pub fn into_owned(mut self) -> VarZeroVec<'static, T> { self.make_mut(); @@ -449,7 +449,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVec<'a, T> { /// /// ```rust /// # use std::str::Utf8Error; - /// # use zerovec::ule::ULEError; + /// # use zerovec::ule::ZeroVecError; /// # use zerovec::VarZeroVec; /// /// let strings = vec!["foo".to_owned(), "bar".to_owned(), "baz".to_owned()]; @@ -458,7 +458,7 @@ impl<'a, T: VarULE + ?Sized> VarZeroVec<'a, T> { /// let mut borrowed: VarZeroVec = VarZeroVec::parse_byte_slice(&bytes)?; /// assert_eq!(borrowed, &*strings); /// - /// # Ok::<(), ULEError>(()) + /// # Ok::<(), ZeroVecError>(()) /// ``` /// pub fn get_serializable_bytes>(elements: &[A]) -> Option> { @@ -489,7 +489,7 @@ where /// /// ``` /// # use std::str::Utf8Error; - /// # use zerovec::ule::ULEError; + /// # use zerovec::ule::ZeroVecError; /// # use zerovec::VarZeroVec; /// /// let strings = vec!["a".to_owned(), "b".to_owned(), @@ -499,7 +499,7 @@ where /// /// assert_eq!(vec.binary_search("f"), Ok(2)); /// assert_eq!(vec.binary_search("e"), Err(2)); - /// # Ok::<(), ULEError>(()) + /// # Ok::<(), ZeroVecError>(()) /// ``` /// /// [`binary_search`]: https://doc.rust-lang.org/std/primitive.slice.html#method.binary_search diff --git a/utils/zerovec/src/varzerovec/ule.rs b/utils/zerovec/src/varzerovec/ule.rs index b68d1c82192..fc60ba2705d 100644 --- a/utils/zerovec/src/varzerovec/ule.rs +++ b/utils/zerovec/src/varzerovec/ule.rs @@ -117,7 +117,7 @@ where // 6. `as_byte_slice()` is equivalent to a regular transmute of the underlying data // 7. VarZeroVecULE byte equality is semantic equality (relying on the guideline of the underlying VarULE type) unsafe impl VarULE for VarZeroVecULE { - fn validate_byte_slice(bytes: &[u8]) -> Result<(), ULEError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError> { let _: VarZeroVecBorrowed = VarZeroVecBorrowed::parse_byte_slice(bytes)?; Ok(()) } diff --git a/utils/zerovec/src/zerovec/mod.rs b/utils/zerovec/src/zerovec/mod.rs index 002a6d240c1..b3538f3bfef 100644 --- a/utils/zerovec/src/zerovec/mod.rs +++ b/utils/zerovec/src/zerovec/mod.rs @@ -192,7 +192,7 @@ where /// assert!(matches!(zerovec, ZeroVec::Borrowed(_))); /// assert_eq!(zerovec.get(2), Some(421)); /// ``` - pub fn parse_byte_slice(bytes: &'a [u8]) -> Result { + pub fn parse_byte_slice(bytes: &'a [u8]) -> Result { let slice: &'a [T::ULE] = T::ULE::parse_byte_slice(bytes)?; Ok(Self::Borrowed(slice)) } @@ -378,7 +378,7 @@ where /// assert!(matches!(zv_u16, ZeroVec::Borrowed(_))); /// assert_eq!(zv_u16.get(0), Some(0xF37F)); /// ``` - pub fn try_into_converted(self) -> Result, ULEError> { + pub fn try_into_converted(self) -> Result, ZeroVecError> { assert_eq!( core::mem::size_of::<::ULE>(), core::mem::size_of::<