diff --git a/components/casemap/src/provider/data.rs b/components/casemap/src/provider/data.rs index b9b4921a23f..5c4c29d673a 100644 --- a/components/casemap/src/provider/data.rs +++ b/components/casemap/src/provider/data.rs @@ -8,8 +8,7 @@ use alloc::collections::BTreeMap; use core::num::TryFromIntError; use icu_collections::codepointtrie::TrieValue; -use zerovec::ule::{AsULE, RawBytesULE, ULE}; -use zerovec::ZeroVecError; +use zerovec::ule::{AsULE, RawBytesULE, UleError, ULE}; /// The case of a Unicode character /// @@ -270,7 +269,7 @@ impl CaseMapData { /// Attempt to construct from ICU-format integer #[cfg(any(feature = "datagen", test))] - pub(crate) fn try_from_icu_integer(int: u16) -> Result { + pub(crate) fn try_from_icu_integer(int: u16) -> Result { let raw = int.to_unaligned(); CaseMapDataULE::validate_byte_slice(raw.as_bytes())?; @@ -367,7 +366,7 @@ impl CaseMapDataULE { /// their respective safety guidelines: They have been /// 6. The equality invariant is satisfied unsafe impl ULE for CaseMapDataULE { - fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), UleError> { let sixteens = RawBytesULE::<2>::parse_byte_slice(bytes)?; for sixteen in sixteens { @@ -380,7 +379,7 @@ unsafe impl ULE for CaseMapDataULE { // uncased if sixteen >> Self::DELTA_SHIFT != 0 { // We have some used bits in the reserved zone! - return Err(ZeroVecError::parse::()); + return Err(UleError::parse::()); } } } diff --git a/components/collections/src/codepointtrie/cptrie.rs b/components/collections/src/codepointtrie/cptrie.rs index b7f43af8bc5..1d03a583992 100644 --- a/components/collections/src/codepointtrie/cptrie.rs +++ b/components/collections/src/codepointtrie/cptrie.rs @@ -15,8 +15,8 @@ use core::num::TryFromIntError; use core::ops::RangeInclusive; use yoke::Yokeable; use zerofrom::ZeroFrom; +use zerovec::ule::UleError; use zerovec::ZeroVec; -use zerovec::ZeroVecError; /// The type of trie represents whether the trie has an optimization that /// would make it smaller or faster. @@ -431,7 +431,7 @@ impl<'trie, T: TrieValue> CodePointTrie<'trie, T> { /// /// assert_eq!(planes_trie_i8.get32(0x30000), 3); /// ``` - pub fn try_into_converted

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

(self) -> Result, UleError> where P: TrieValue, { diff --git a/components/datetime/src/fields/length.rs b/components/datetime/src/fields/length.rs index 3a9ca12e875..fb4279be521 100644 --- a/components/datetime/src/fields/length.rs +++ b/components/datetime/src/fields/length.rs @@ -5,7 +5,7 @@ use core::cmp::{Ord, PartialOrd}; use core::fmt; use displaydoc::Display; -use zerovec::ule::{AsULE, ZeroVecError, ULE}; +use zerovec::ule::{AsULE, UleError, ULE}; /// An error relating to the length of a field within a date pattern. #[derive(Display, Debug, PartialEq, Copy, Clone)] @@ -164,10 +164,10 @@ impl AsULE for FieldLength { impl FieldLengthULE { #[inline] - pub(crate) fn validate_byte(byte: u8) -> Result<(), ZeroVecError> { + pub(crate) fn validate_byte(byte: u8) -> Result<(), UleError> { FieldLength::from_idx(byte) .map(|_| ()) - .map_err(|_| ZeroVecError::parse::()) + .map_err(|_| UleError::parse::()) } } @@ -181,7 +181,7 @@ impl FieldLengthULE { // 5. All other methods must be left with their default impl. // 6. Byte equality is semantic equality. unsafe impl ULE for FieldLengthULE { - fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), UleError> { for byte in bytes { Self::validate_byte(*byte)?; } diff --git a/components/datetime/src/fields/mod.rs b/components/datetime/src/fields/mod.rs index bed53fe6cd3..eedbb0d7f8d 100644 --- a/components/datetime/src/fields/mod.rs +++ b/components/datetime/src/fields/mod.rs @@ -75,7 +75,7 @@ impl Field { impl FieldULE { #[inline] - pub(crate) fn validate_bytes(bytes: (u8, u8)) -> Result<(), zerovec::ZeroVecError> { + pub(crate) fn validate_bytes(bytes: (u8, u8)) -> Result<(), zerovec::ule::UleError> { symbols::FieldSymbolULE::validate_byte(bytes.0)?; length::FieldLengthULE::validate_byte(bytes.1)?; Ok(()) diff --git a/components/datetime/src/fields/symbols.rs b/components/datetime/src/fields/symbols.rs index e08dc8b03d2..f4d9155d2ad 100644 --- a/components/datetime/src/fields/symbols.rs +++ b/components/datetime/src/fields/symbols.rs @@ -7,7 +7,7 @@ use crate::fields::FieldLength; use core::{cmp::Ordering, convert::TryFrom}; use displaydoc::Display; use icu_provider::prelude::*; -use zerovec::ule::{AsULE, ZeroVecError, ULE}; +use zerovec::ule::{AsULE, UleError, ULE}; /// An error relating to the field symbol for a date pattern field. #[derive(Display, Debug, PartialEq, Copy, Clone)] @@ -198,10 +198,10 @@ impl AsULE for FieldSymbol { impl FieldSymbolULE { #[inline] - pub(crate) fn validate_byte(byte: u8) -> Result<(), ZeroVecError> { + pub(crate) fn validate_byte(byte: u8) -> Result<(), UleError> { FieldSymbol::from_idx(byte) .map(|_| ()) - .map_err(|_| ZeroVecError::parse::()) + .map_err(|_| UleError::parse::()) } } @@ -215,7 +215,7 @@ impl FieldSymbolULE { // 5. All other methods must be left with their default impl. // 6. Byte equality is semantic equality. unsafe impl ULE for FieldSymbolULE { - fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), UleError> { for byte in bytes { Self::validate_byte(*byte)?; } diff --git a/components/datetime/src/pattern/item/ule.rs b/components/datetime/src/pattern/item/ule.rs index ccbbe3dc300..0d096a01700 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, ZeroVecError, ULE}; +use zerovec::ule::{AsULE, UleError, ULE}; /// `PatternItemULE` is a type optimized for efficient storing and /// deserialization of `TypedDateTimeFormatter` `PatternItem` elements using @@ -93,9 +93,9 @@ 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<(), ZeroVecError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), UleError> { if bytes.len() % 3 != 0 { - return Err(ZeroVecError::length::(bytes.len())); + return Err(UleError::length::(bytes.len())); } #[allow(clippy::indexing_slicing)] // chunks @@ -103,7 +103,7 @@ unsafe impl ULE for PatternItemULE { .chunks(3) .all(|c| Self::bytes_in_range((&c[0], &c[1], &c[2]))) { - return Err(ZeroVecError::parse::()); + return Err(UleError::parse::()); } Ok(()) } @@ -251,16 +251,16 @@ 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<(), ZeroVecError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), UleError> { if bytes.len() % 3 != 0 { - return Err(ZeroVecError::length::(bytes.len())); + return Err(UleError::length::(bytes.len())); } #[allow(clippy::indexing_slicing)] // chunks if !bytes .chunks_exact(3) .all(|c| Self::bytes_in_range((&c[0], &c[1], &c[2]))) { - return Err(ZeroVecError::parse::()); + return Err(UleError::parse::()); } Ok(()) } diff --git a/components/experimental/src/dimension/provider/compact_count_ule.rs b/components/experimental/src/dimension/provider/compact_count_ule.rs index ec29a110d2a..42cf4646369 100644 --- a/components/experimental/src/dimension/provider/compact_count_ule.rs +++ b/components/experimental/src/dimension/provider/compact_count_ule.rs @@ -4,7 +4,7 @@ use crate::dimension::provider::currency_compact::CompactCount; use icu_plurals::PluralCategory; -use zerovec::ule::{AsULE, ZeroVecError, ULE}; +use zerovec::ule::{AsULE, UleError, ULE}; /// [`CompactCountULE`] is a type optimized for efficient storing and /// deserialization of [`CompactCount`] using the `ZeroVec` model. @@ -38,14 +38,14 @@ pub struct CompactCountULE(u8); // 5. The other ULE methods use the default impl. // 6. CompactCountULE byte equality is semantic equality. unsafe impl ULE for CompactCountULE { - fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), UleError> { for byte in bytes { if byte & 0b0111_1000 != 0 { - return Err(ZeroVecError::parse::()); + return Err(UleError::parse::()); } if byte & 0b0000_0111 > 5 { - return Err(ZeroVecError::parse::()); + return Err(UleError::parse::()); } } diff --git a/components/experimental/src/dimension/provider/pattern_key.rs b/components/experimental/src/dimension/provider/pattern_key.rs index a35209be77a..e4e310277f6 100644 --- a/components/experimental/src/dimension/provider/pattern_key.rs +++ b/components/experimental/src/dimension/provider/pattern_key.rs @@ -7,8 +7,7 @@ use zerovec::{ maps::ZeroMapKV, - ule::{AsULE, ULE}, - ZeroVecError, + ule::{AsULE, UleError, ULE}, }; use crate::dimension::provider::units_essentials::CompoundCount; @@ -81,11 +80,11 @@ pub struct PatternKeyULE(u8); // 5. The other ULE methods use the default impl. // 6. PatternKeyULE byte equality is semantic equality. unsafe impl ULE for PatternKeyULE { - fn validate_byte_slice(bytes: &[u8]) -> Result<(), zerovec::ZeroVecError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), zerovec::ule::UleError> { for &byte in bytes.iter() { // Ensure the first two bits (b7 & b6) are not 11. if (byte & 0b1100_0000) == 0b1100_0000 { - return Err(ZeroVecError::parse::()); + return Err(UleError::parse::()); } // For the `Power` variant: @@ -95,17 +94,17 @@ unsafe impl ULE for PatternKeyULE { if (byte & 0b1100_0000) == 0b1000_0000 { // b5 must be 1 if (byte & 0b0010_0000) == 0 { - return Err(ZeroVecError::parse::()); + return Err(UleError::parse::()); } // b3 must be 0 if (byte & 0b0000_1000) != 0 { - return Err(ZeroVecError::parse::()); + return Err(UleError::parse::()); } // If b2 is 1, b1 must be 0 if (byte & 0b0000_0100) != 0 && (byte & 0b0000_0010) != 0 { - return Err(ZeroVecError::parse::()); + return Err(UleError::parse::()); } } } @@ -242,12 +241,12 @@ fn test_pattern_key_ule() { let unvalidated_bytes = [0b1100_0000]; assert_eq!( PatternKeyULE::validate_byte_slice(&unvalidated_bytes), - Err(ZeroVecError::parse::()) + Err(UleError::parse::()) ); let unvalidated_bytes = [0b1000_0000]; assert_eq!( PatternKeyULE::validate_byte_slice(&unvalidated_bytes), - Err(ZeroVecError::parse::()) + Err(UleError::parse::()) ); } diff --git a/components/experimental/src/dimension/provider/ule.rs b/components/experimental/src/dimension/provider/ule.rs index 505e4bff418..177f03ec74f 100644 --- a/components/experimental/src/dimension/provider/ule.rs +++ b/components/experimental/src/dimension/provider/ule.rs @@ -4,7 +4,7 @@ use zerovec::{ maps::ZeroMapKV, - ule::{AsULE, ZeroVecError, ULE}, + ule::{AsULE, UleError, ULE}, }; use crate::dimension::provider::currency::{ @@ -44,9 +44,9 @@ pub struct CurrencyPatternConfigULE([u8; 3]); // 5. The other ULE methods use the default impl. // 6. CurrencyPatternConfigULE byte equality is semantic equality. unsafe impl ULE for CurrencyPatternConfigULE { - fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), UleError> { if bytes.len() % 3 != 0 { - return Err(ZeroVecError::length::(bytes.len())); + return Err(UleError::length::(bytes.len())); } Ok(()) diff --git a/components/locale_core/src/helpers.rs b/components/locale_core/src/helpers.rs index 8e1716d1123..0b7f193c033 100644 --- a/components/locale_core/src/helpers.rs +++ b/components/locale_core/src/helpers.rs @@ -284,17 +284,17 @@ macro_rules! impl_tinystr_subtag { // 6. Byte equality is semantic equality. #[cfg(feature = "zerovec")] unsafe impl zerovec::ule::ULE for $name { - fn validate_byte_slice(bytes: &[u8]) -> Result<(), zerovec::ZeroVecError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), zerovec::ule::UleError> { let it = bytes.chunks_exact(core::mem::size_of::()); if !it.remainder().is_empty() { - return Err(zerovec::ZeroVecError::length::(bytes.len())); + return Err(zerovec::ule::UleError::length::(bytes.len())); } for v in it { // The following can be removed once `array_chunks` is stabilized. let mut a = [0; core::mem::size_of::()]; a.copy_from_slice(v); if Self::try_from_raw(a).is_err() { - return Err(zerovec::ZeroVecError::parse::()); + return Err(zerovec::ule::UleError::parse::()); } } Ok(()) diff --git a/components/plurals/src/rules/runtime/ast.rs b/components/plurals/src/rules/runtime/ast.rs index 81a58c303e4..7a2e6993b52 100644 --- a/components/plurals/src/rules/runtime/ast.rs +++ b/components/plurals/src/rules/runtime/ast.rs @@ -9,7 +9,7 @@ use core::{ }; use icu_provider::prelude::*; use zerovec::{ - ule::{tuple::Tuple2ULE, AsULE, ZeroVecError, ULE}, + ule::{tuple::Tuple2ULE, AsULE, UleError, ULE}, {VarZeroVec, ZeroVec}, }; @@ -297,9 +297,9 @@ pub(crate) struct AndOrPolarityOperandULE(u8); // 5 The other ULE methods use the default impl. // 6. AndOrPolarityOperandULE byte equality is semantic equality. unsafe impl ULE for AndOrPolarityOperandULE { - fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), UleError> { for byte in bytes { - Operand::new_from_u8(byte & 0b0011_1111).ok_or_else(ZeroVecError::parse::)?; + Operand::new_from_u8(byte & 0b0011_1111).ok_or_else(UleError::parse::)?; } Ok(()) } diff --git a/components/properties/src/maps.rs b/components/properties/src/maps.rs index 8b47529dd72..99e5523c160 100644 --- a/components/properties/src/maps.rs +++ b/components/properties/src/maps.rs @@ -19,7 +19,7 @@ use core::marker::PhantomData; use core::ops::RangeInclusive; use icu_collections::codepointtrie::{CodePointMapRange, CodePointTrie, TrieValue}; use icu_provider::prelude::*; -use zerovec::ZeroVecError; +use zerovec::ule::UleError; /// A wrapper around code point map data. It is returned by APIs that return Unicode /// property data in a map-like form, ex: enumerated property value data keyed @@ -72,7 +72,7 @@ impl CodePointMapData { /// assert_eq!(gc.get('木'), GeneralCategory::OtherLetter as u8); // U+6728 /// assert_eq!(gc.get('🎃'), GeneralCategory::OtherSymbol as u8); // U+1F383 JACK-O-LANTERN /// ``` - pub fn try_into_converted

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

(self) -> Result, UleError> where P: TrieValue, { diff --git a/components/properties/src/provider.rs b/components/properties/src/provider.rs index 5ff4cffa0f8..0196bf0224e 100644 --- a/components/properties/src/provider.rs +++ b/components/properties/src/provider.rs @@ -28,7 +28,7 @@ use icu_collections::codepointtrie::{CodePointMapRange, CodePointTrie, TrieValue use icu_provider::prelude::*; use zerofrom::ZeroFrom; -use zerovec::{VarZeroVec, ZeroSlice, ZeroVecError}; +use zerovec::{ule::UleError, VarZeroVec, ZeroSlice}; #[cfg(feature = "compiled_data")] #[derive(Debug)] @@ -674,9 +674,7 @@ impl<'data, T: TrieValue> PropertyCodePointMapV1<'data, T> { } #[inline] - pub(crate) fn try_into_converted

( - self, - ) -> Result, ZeroVecError> + pub(crate) fn try_into_converted

(self) -> Result, UleError> where P: TrieValue, { diff --git a/components/properties/src/provider/bidi_data.rs b/components/properties/src/provider/bidi_data.rs index 4779658f7ec..f12c7d3e977 100644 --- a/components/properties/src/provider/bidi_data.rs +++ b/components/properties/src/provider/bidi_data.rs @@ -22,8 +22,7 @@ use displaydoc::Display; use icu_collections::codepointtrie::{CodePointTrie, TrieValue}; use icu_provider::prelude::*; -use zerovec::ule::{AsULE, CharULE, ULE}; -use zerovec::ZeroVecError; +use zerovec::ule::{AsULE, CharULE, UleError, ULE}; /// A data provider struct for properties related to Bidi algorithms, including /// mirroring and bracket pairing. @@ -164,9 +163,9 @@ pub struct MirroredPairedBracketDataULE([u8; 3]); // are used, so no unused bits requires no extra work to zero out unused bits unsafe impl ULE for MirroredPairedBracketDataULE { #[inline] - fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), UleError> { if bytes.len() % 3 != 0 { - return Err(ZeroVecError::length::(bytes.len())); + return Err(UleError::length::(bytes.len())); } // Validate the bytes #[allow(clippy::indexing_slicing)] // Won't panic because the chunks are always 3 bytes long @@ -178,14 +177,14 @@ unsafe impl ULE for MirroredPairedBracketDataULE { mirroring_glyph_code_point = (mirroring_glyph_code_point << 8) | (byte1 as u32); mirroring_glyph_code_point = (mirroring_glyph_code_point << 8) | (byte0 as u32); let _mirroring_glyph = - char::from_u32(mirroring_glyph_code_point).ok_or(ZeroVecError::parse::())?; + char::from_u32(mirroring_glyph_code_point).ok_or(UleError::parse::())?; // skip validating the Bidi_Mirrored boolean since it is always valid // assert that Bidi_Paired_Bracket_Type cannot have a 4th value because it only // has 3 values: Open, Close, None if (byte2 & 0xC0) == 0xC0 { - return Err(ZeroVecError::parse::()); + return Err(UleError::parse::()); } } diff --git a/utils/pattern/src/implementations.rs b/utils/pattern/src/implementations.rs index 692faf5b718..c3b58f54e72 100644 --- a/utils/pattern/src/implementations.rs +++ b/utils/pattern/src/implementations.rs @@ -5,7 +5,11 @@ use crate::{Pattern, SinglePlaceholder, SinglePlaceholderPattern}; use alloc::boxed::Box; -use zerovec::{maps::ZeroMapKV, ule::VarULE, VarZeroSlice, VarZeroVec, ZeroVecError}; +use zerovec::{ + maps::ZeroMapKV, + ule::{UleError, VarULE}, + VarZeroSlice, VarZeroVec, +}; impl<'a> ZeroMapKV<'a> for Pattern { type Container = VarZeroVec<'a, Pattern>; @@ -64,9 +68,9 @@ impl<'a> ZeroMapKV<'a> for Pattern { /// assert_writeable_eq!(borrowed_pattern.interpolate([5]), "5 days"); /// ``` unsafe impl VarULE for Pattern { - fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), UleError> { SinglePlaceholderPattern::try_from_utf8_store(bytes) - .map_err(|_| ZeroVecError::VarZeroVecFormatError)?; + .map_err(|_| UleError::parse::())?; Ok(()) } diff --git a/utils/potential_utf/src/ustr.rs b/utils/potential_utf/src/ustr.rs index 1721530a875..4659153fe45 100644 --- a/utils/potential_utf/src/ustr.rs +++ b/utils/potential_utf/src/ustr.rs @@ -152,7 +152,7 @@ impl<'a> zerovec::maps::ZeroMapKV<'a> for PotentialUtf8 { #[cfg(feature = "zerovec")] unsafe impl zerovec::ule::VarULE for PotentialUtf8 { #[inline] - fn validate_byte_slice(_: &[u8]) -> Result<(), zerovec::ZeroVecError> { + fn validate_byte_slice(_: &[u8]) -> Result<(), zerovec::ule::UleError> { Ok(()) } #[inline] diff --git a/utils/tinystr/src/ule.rs b/utils/tinystr/src/ule.rs index 2ceaccbcff8..64af47fba11 100644 --- a/utils/tinystr/src/ule.rs +++ b/utils/tinystr/src/ule.rs @@ -18,14 +18,14 @@ use zerovec::{ZeroSlice, ZeroVec}; // 6. TinyAsciiStr byte equality is semantic equality unsafe impl ULE for TinyAsciiStr { #[inline] - fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), UleError> { if bytes.len() % N != 0 { - return Err(ZeroVecError::length::(bytes.len())); + return Err(UleError::length::(bytes.len())); } // Validate the bytes for chunk in bytes.chunks_exact(N) { let _ = TinyAsciiStr::::try_from_utf8_inner(chunk, true) - .map_err(|_| ZeroVecError::parse::())?; + .map_err(|_| UleError::parse::())?; } Ok(()) } @@ -63,9 +63,9 @@ impl<'a, const N: usize> ZeroMapKV<'a> for TinyAsciiStr { // 6. UnvalidatedTinyAsciiStr byte equality is semantic equality unsafe impl ULE for UnvalidatedTinyAsciiStr { #[inline] - fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), UleError> { if bytes.len() % N != 0 { - return Err(ZeroVecError::length::(bytes.len())); + return Err(UleError::length::(bytes.len())); } Ok(()) } diff --git a/utils/zerotrie/src/builder/konst/builder.rs b/utils/zerotrie/src/builder/konst/builder.rs index f291a859003..4e7132a0821 100644 --- a/utils/zerotrie/src/builder/konst/builder.rs +++ b/utils/zerotrie/src/builder/konst/builder.rs @@ -8,7 +8,7 @@ use super::store::const_for_each; use super::store::ConstArrayBuilder; use super::store::ConstLengthsStack; use super::store::ConstSlice; -use crate::error::Error; +use crate::error::ZeroTrieBuildError; use crate::varint; /// A low-level builder for ZeroTrieSimpleAscii. Works in const contexts. @@ -110,7 +110,7 @@ impl ZeroTrieBuilderConst { /// Panics if the items are not sorted pub const fn from_tuple_slice<'a, const K: usize>( items: &[(&'a ByteStr, usize)], - ) -> Result { + ) -> Result { let items = ConstSlice::from_slice(items); let mut prev: Option<&'a ByteStr> = None; const_for_each!(items, (ascii_str, _), { @@ -135,7 +135,7 @@ impl ZeroTrieBuilderConst { /// "AsciiTrie Builder: Need more stack", try increasing `K`. pub const fn from_sorted_const_tuple_slice( items: ConstSlice<(&ByteStr, usize)>, - ) -> Result { + ) -> Result { let mut result = Self::new(); let total_size; (result, total_size) = result.create_or_panic::(items); diff --git a/utils/zerotrie/src/builder/litemap.rs b/utils/zerotrie/src/builder/litemap.rs index 9253dd4c279..1a33c84008b 100644 --- a/utils/zerotrie/src/builder/litemap.rs +++ b/utils/zerotrie/src/builder/litemap.rs @@ -6,7 +6,7 @@ use super::konst::*; use crate::builder::bytestr::ByteStr; -use crate::error::Error; +use crate::error::ZeroTrieBuildError; use crate::zerotrie::ZeroTrieSimpleAscii; use crate::ZeroTrie; use alloc::borrow::Borrow; @@ -17,7 +17,7 @@ impl ZeroTrieSimpleAscii> { #[doc(hidden)] pub fn try_from_litemap_with_const_builder<'a, S>( items: &LiteMap<&'a [u8], usize, S>, - ) -> Result + ) -> Result where S: litemap::store::StoreSlice<&'a [u8], usize, Slice = [(&'a [u8], usize)]>, { @@ -37,8 +37,8 @@ where K: Borrow<[u8]>, S: litemap::store::StoreSlice, { - type Error = Error; - fn try_from(items: &LiteMap) -> Result { + type Error = ZeroTrieBuildError; + fn try_from(items: &LiteMap) -> Result { let byte_litemap = items.to_borrowed_keys::<[u8], Vec<_>>(); let byte_slice = byte_litemap.as_slice(); let byte_str_slice = ByteStr::from_byte_slice_with_value(byte_slice); diff --git a/utils/zerotrie/src/builder/nonconst/builder.rs b/utils/zerotrie/src/builder/nonconst/builder.rs index 40abf0c435b..02dd062f82f 100644 --- a/utils/zerotrie/src/builder/nonconst/builder.rs +++ b/utils/zerotrie/src/builder/nonconst/builder.rs @@ -9,7 +9,7 @@ use super::store::NonConstLengthsStack; use super::store::TrieBuilderStore; use crate::builder::bytestr::ByteStr; use crate::byte_phf::PerfectByteHashMapCacheOwned; -use crate::error::Error; +use crate::error::ZeroTrieBuildError; use crate::options::*; use crate::varint; use alloc::borrow::Cow; @@ -32,7 +32,7 @@ impl ZeroTrieBuilder { /// node is prepended. If it is non-ASCII, if there is already a span node at /// the front, we modify the span node to add the new byte; otherwise, we create /// a new span node. Returns the delta in length, which is either 1 or 2. - fn prepend_ascii(&mut self, ascii: u8) -> Result { + fn prepend_ascii(&mut self, ascii: u8) -> Result { if ascii <= 127 { self.data.atbs_push_front(ascii); Ok(1) @@ -61,7 +61,7 @@ impl ZeroTrieBuilder { self.data.atbs_push_front(0b10100001); Ok(2) } else { - Err(Error::NonAsciiError) + Err(ZeroTrieBuildError::NonAsciiError) } } @@ -97,7 +97,7 @@ impl ZeroTrieBuilder { pub fn from_bytes_iter, I: IntoIterator>( iter: I, options: ZeroTrieBuilderOptions, - ) -> Result { + ) -> Result { let items = Vec::<(K, usize)>::from_iter(iter); let mut items = items .iter() @@ -118,7 +118,7 @@ impl ZeroTrieBuilder { pub fn from_sorted_tuple_slice( items: &[(&ByteStr, usize)], options: ZeroTrieBuilderOptions, - ) -> Result { + ) -> Result { let mut items = Cow::Borrowed(items); if matches!(options.case_sensitivity, CaseSensitivity::IgnoreCase) { // We need to re-sort the items with our custom comparator. @@ -133,7 +133,7 @@ impl ZeroTrieBuilder { fn from_sorted_tuple_slice_impl( items: &[(&ByteStr, usize)], options: ZeroTrieBuilderOptions, - ) -> Result { + ) -> Result { for ab in items.windows(2) { debug_assert!(cmp_keys_values( &options, @@ -154,7 +154,7 @@ impl ZeroTrieBuilder { /// The actual builder algorithm. For an explanation, see [`crate::builder`]. #[allow(clippy::unwrap_used)] // lots of indexing, but all indexes should be in range - fn create(&mut self, all_items: &[(&ByteStr, usize)]) -> Result { + fn create(&mut self, all_items: &[(&ByteStr, usize)]) -> Result { let mut prefix_len = match all_items.last() { Some(x) => x.0.len(), // Empty slice: @@ -241,7 +241,7 @@ impl ZeroTrieBuilder { && i == new_i + 2 { // This can happen if two strings were picked up, each with a different case - return Err(Error::MixedCase); + return Err(ZeroTrieBuildError::MixedCase); } debug_assert!( i == new_i || i == new_i + 1, @@ -303,7 +303,7 @@ impl ZeroTrieBuilder { if c.is_ascii_alphabetic() { let i = (c.to_ascii_lowercase() - b'a') as usize; if seen_ascii_alpha[i] { - return Err(Error::MixedCase); + return Err(ZeroTrieBuildError::MixedCase); } else { seen_ascii_alpha[i] = true; } @@ -355,7 +355,7 @@ impl ZeroTrieBuilder { const USIZE_BITS: usize = core::mem::size_of::() * 8; let w = (USIZE_BITS - (total_length.leading_zeros() as usize) - 1) / 8; if w > 3 && matches!(self.options.capacity_mode, CapacityMode::Normal) { - return Err(Error::CapacityExceeded); + return Err(ZeroTrieBuildError::CapacityExceeded); } let mut k = 0; while k <= w { diff --git a/utils/zerotrie/src/byte_phf/builder.rs b/utils/zerotrie/src/byte_phf/builder.rs index 69b97818d24..63f9066e4f7 100644 --- a/utils/zerotrie/src/byte_phf/builder.rs +++ b/utils/zerotrie/src/byte_phf/builder.rs @@ -3,7 +3,7 @@ // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). use super::*; -use crate::error::Error; +use crate::error::ZeroTrieBuildError; use alloc::vec; use alloc::vec::Vec; @@ -17,7 +17,7 @@ const MAX_L2_SEARCH_MISSES: usize = 24; /// /// Returns `(p, [q_0, q_1, ..., q_(N-1)])`, or an error if the PHF could not be computed. #[allow(unused_labels)] // for readability -pub fn find(bytes: &[u8]) -> Result<(u8, Vec), Error> { +pub fn find(bytes: &[u8]) -> Result<(u8, Vec), ZeroTrieBuildError> { let n_usize = bytes.len(); let mut p = 0u8; @@ -87,7 +87,7 @@ pub fn find(bytes: &[u8]) -> Result<(u8, Vec), Error> { // and re-run the loop with a higher `max_allowable_p`. debug_assert_eq!(max_allowable_p, P_REAL_MAX); // println!("Could not solve PHF function"); - return Err(Error::CouldNotSolvePerfectHash); + return Err(ZeroTrieBuildError::CouldNotSolvePerfectHash); } else { p += 1; continue 'p_loop; @@ -117,7 +117,7 @@ impl PerfectByteHashMap> { /// Computes a new [`PerfectByteHashMap`]. /// /// (this is a doc-hidden API) - pub fn try_new(keys: &[u8]) -> Result { + pub fn try_new(keys: &[u8]) -> Result { let n_usize = keys.len(); let n = n_usize as u8; let (p, mut qq) = find(keys)?; diff --git a/utils/zerotrie/src/byte_phf/cached_owned.rs b/utils/zerotrie/src/byte_phf/cached_owned.rs index e6e17e35f26..bcb1b0be06a 100644 --- a/utils/zerotrie/src/byte_phf/cached_owned.rs +++ b/utils/zerotrie/src/byte_phf/cached_owned.rs @@ -3,7 +3,7 @@ // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). use super::*; -use crate::error::Error; +use crate::error::ZeroTrieBuildError; use alloc::collections::btree_map::Entry; use alloc::collections::BTreeMap; use alloc::vec::Vec; @@ -23,7 +23,10 @@ impl PerfectByteHashMapCacheOwned { } /// Gets the [`PerfectByteHashMap`] for the given bytes, calculating it if necessary. - pub fn try_get_or_insert(&mut self, keys: Vec) -> Result<&PerfectByteHashMap<[u8]>, Error> { + pub fn try_get_or_insert( + &mut self, + keys: Vec, + ) -> Result<&PerfectByteHashMap<[u8]>, ZeroTrieBuildError> { let mut_phf = match self.data.entry(keys) { Entry::Vacant(entry) => { let value = PerfectByteHashMap::try_new(entry.key())?; diff --git a/utils/zerotrie/src/error.rs b/utils/zerotrie/src/error.rs index 8ab5b673156..42dbc8b1599 100644 --- a/utils/zerotrie/src/error.rs +++ b/utils/zerotrie/src/error.rs @@ -7,12 +7,12 @@ use displaydoc::Display; /// Error types for the `zerotrie` crate. #[derive(Debug, Copy, Clone, PartialEq, Eq, Display)] #[non_exhaustive] -pub enum Error { - /// Non-ASCII data was added to an ASCII-only collection. - #[displaydoc("Non-ASCII cannot be added to an ASCII-only collection")] +pub enum ZeroTrieBuildError { + /// Non-ASCII data was added to an ASCII-only trie. + #[displaydoc("Non-ASCII cannot be added to an ASCII-only trie")] NonAsciiError, - /// The collection reached its maximum supported capacity. - #[displaydoc("Reached maximum capacity of collection")] + /// The trie reached its maximum supported capacity. + #[displaydoc("Reached maximum capacity of trie")] CapacityExceeded, /// The builder could not solve the perfect hash function. #[displaydoc("Failed to solve the perfect hash function. This is rare! Please report your case to the ICU4X team.")] diff --git a/utils/zerotrie/src/lib.rs b/utils/zerotrie/src/lib.rs index fa14c869fa0..0f6e05f0814 100644 --- a/utils/zerotrie/src/lib.rs +++ b/utils/zerotrie/src/lib.rs @@ -72,7 +72,7 @@ pub use crate::zerotrie::ZeroTrie; pub use crate::zerotrie::ZeroTrieExtendedCapacity; pub use crate::zerotrie::ZeroTriePerfectHash; pub use crate::zerotrie::ZeroTrieSimpleAscii; -pub use error::Error as ZeroTrieError; +pub use error::ZeroTrieBuildError; #[cfg(feature = "alloc")] pub use crate::zerotrie::ZeroTrieStringIterator; diff --git a/utils/zerotrie/src/zerotrie.rs b/utils/zerotrie/src/zerotrie.rs index ecb53d923db..dc94b5dfc74 100644 --- a/utils/zerotrie/src/zerotrie.rs +++ b/utils/zerotrie/src/zerotrie.rs @@ -7,7 +7,9 @@ use crate::reader; use core::borrow::Borrow; #[cfg(feature = "alloc")] -use crate::{builder::bytestr::ByteStr, builder::nonconst::ZeroTrieBuilder, error::Error}; +use crate::{ + builder::bytestr::ByteStr, builder::nonconst::ZeroTrieBuilder, error::ZeroTrieBuildError, +}; #[cfg(feature = "alloc")] use alloc::{boxed::Box, collections::BTreeMap, collections::VecDeque, string::String, vec::Vec}; #[cfg(feature = "litemap")] @@ -58,7 +60,7 @@ use litemap::LiteMap; /// assert_eq!(trie.get("bazzoo"), Some(3)); /// assert_eq!(trie.get("unknown"), None); /// -/// # Ok::<_, zerotrie::ZeroTrieError>(()) +/// # Ok::<_, zerotrie::ZeroTrieBuildError>(()) /// ``` #[derive(Debug, Clone, Copy, PartialEq, Eq)] // Note: The absence of the following derive does not cause any test failures in this crate @@ -94,7 +96,7 @@ pub(crate) enum ZeroTrieFlavor { /// assert_eq!(trie.get(b"bazzoo"), Some(3)); /// assert_eq!(trie.get(b"unknown"), None); /// -/// # Ok::<_, zerotrie::ZeroTrieError>(()) +/// # Ok::<_, zerotrie::ZeroTrieBuildError>(()) /// ``` /// /// The trie can only store ASCII bytes; a string with non-ASCII always returns None: @@ -146,7 +148,7 @@ impl ZeroTrieSimpleAscii { /// assert_eq!(trie.get(b"bazzoo"), Some(3)); /// assert_eq!(trie.get(b"unknown"), None); /// -/// # Ok::<_, zerotrie::ZeroTrieError>(()) +/// # Ok::<_, zerotrie::ZeroTrieBuildError>(()) /// ``` /// /// Strings with different cases of the same character at the same offset are not allowed: @@ -197,7 +199,7 @@ pub struct ZeroAsciiIgnoreCaseTrie { /// assert_eq!(trie.get("båzzøø".as_bytes()), Some(3)); /// assert_eq!(trie.get("bazzoo".as_bytes()), None); /// -/// # Ok::<_, zerotrie::ZeroTrieError>(()) +/// # Ok::<_, zerotrie::ZeroTrieBuildError>(()) /// ``` #[repr(transparent)] #[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] @@ -387,7 +389,7 @@ macro_rules! impl_zerotrie_subtype { } #[cfg(feature = "alloc")] impl $name> { - pub(crate) fn try_from_tuple_slice(items: &[(&ByteStr, usize)]) -> Result { + pub(crate) fn try_from_tuple_slice(items: &[(&ByteStr, usize)]) -> Result { use crate::options::ZeroTrieWithOptions; ZeroTrieBuilder::>::from_sorted_tuple_slice( items, @@ -421,7 +423,7 @@ macro_rules! impl_zerotrie_subtype { where K: Borrow<[u8]> { - type Error = crate::error::Error; + type Error = crate::error::ZeroTrieBuildError; fn try_from(map: &'a BTreeMap) -> Result { let tuples: Vec<(&[u8], usize)> = map .iter() @@ -480,7 +482,7 @@ macro_rules! impl_zerotrie_subtype { K: Borrow<[u8]>, S: litemap::store::StoreIterable<'a, K, usize>, { - type Error = crate::error::Error; + type Error = crate::error::ZeroTrieBuildError; fn try_from(map: &'a LiteMap) -> Result { let tuples: Vec<(&[u8], usize)> = map .iter() @@ -538,7 +540,7 @@ macro_rules! impl_zerotrie_subtype { impl $name> { #[cfg(feature = "serde")] - pub(crate) fn try_from_serde_litemap(items: &LiteMap, usize>) -> Result { + pub(crate) fn try_from_serde_litemap(items: &LiteMap, usize>) -> Result { let lm_borrowed: LiteMap<&ByteStr, usize> = items.to_borrowed_keys(); Self::try_from_tuple_slice(lm_borrowed.as_slice()) } @@ -599,7 +601,7 @@ macro_rules! impl_zerotrie_subtype { Store: zerovec::ule::VarULE, { #[inline] - fn validate_byte_slice(bytes: &[u8]) -> Result<(), zerovec::ZeroVecError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), zerovec::ule::UleError> { Store::validate_byte_slice(bytes) } #[inline] @@ -773,7 +775,9 @@ where #[cfg(feature = "alloc")] impl ZeroTrie> { - pub(crate) fn try_from_tuple_slice(items: &[(&ByteStr, usize)]) -> Result { + pub(crate) fn try_from_tuple_slice( + items: &[(&ByteStr, usize)], + ) -> Result { let is_all_ascii = items.iter().all(|(s, _)| s.is_all_ascii()); if is_all_ascii && items.len() < 512 { ZeroTrieSimpleAscii::try_from_tuple_slice(items).map(|x| x.into_zerotrie()) diff --git a/utils/zerovec/derive/src/make_ule.rs b/utils/zerovec/derive/src/make_ule.rs index da25be75881..0a600dff7e0 100644 --- a/utils/zerovec/derive/src/make_ule.rs +++ b/utils/zerovec/derive/src/make_ule.rs @@ -206,10 +206,10 @@ fn make_ule_enum_impl( unsafe impl zerovec::ule::ULE for #ule_name { #[inline] - fn validate_byte_slice(bytes: &[u8]) -> Result<(), zerovec::ZeroVecError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), zerovec::ule::UleError> { for byte in bytes { if *byte < #min || *byte > #max { - return Err(zerovec::ZeroVecError::parse::()) + return Err(zerovec::ule::UleError::parse::()) } } Ok(()) diff --git a/utils/zerovec/derive/src/ule.rs b/utils/zerovec/derive/src/ule.rs index 2f3e6f9e324..4d2b945129c 100644 --- a/utils/zerovec/derive/src/ule.rs +++ b/utils/zerovec/derive/src/ule.rs @@ -58,11 +58,11 @@ pub fn derive_impl(input: &DeriveInput) -> TokenStream2 { quote! { unsafe impl zerovec::ule::ULE for #name { #[inline] - fn validate_byte_slice(bytes: &[u8]) -> Result<(), zerovec::ZeroVecError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), zerovec::ule::UleError> { const SIZE: usize = ::core::mem::size_of::<#name>(); #[allow(clippy::modulo_one)] if bytes.len() % SIZE != 0 { - return Err(zerovec::ZeroVecError::length::(bytes.len())); + return Err(zerovec::ule::UleError::length::(bytes.len())); } // Validate the bytes #[allow(clippy::indexing_slicing)] // We're slicing a chunk of known size diff --git a/utils/zerovec/derive/src/varule.rs b/utils/zerovec/derive/src/varule.rs index 01f8d42c2e0..d5f88c9d440 100644 --- a/utils/zerovec/derive/src/varule.rs +++ b/utils/zerovec/derive/src/varule.rs @@ -101,10 +101,10 @@ pub fn derive_impl( const #ule_size: usize = 0 #(+ #sizes)*; unsafe impl zerovec::ule::VarULE for #name { #[inline] - fn validate_byte_slice(bytes: &[u8]) -> Result<(), zerovec::ZeroVecError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), zerovec::ule::UleError> { if bytes.len() < #ule_size { - return Err(zerovec::ZeroVecError::parse::()); + return Err(zerovec::ule::UleError::parse::()); } #validators debug_assert_eq!(#remaining_offset, #ule_size); diff --git a/utils/zerovec/design_doc.md b/utils/zerovec/design_doc.md index e4c3643ac3d..4b997be431f 100644 --- a/utils/zerovec/design_doc.md +++ b/utils/zerovec/design_doc.md @@ -174,7 +174,7 @@ where Self: Sized + Copy + 'static, { // Required - fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError>; + fn validate_byte_slice(bytes: &[u8]) -> Result<(), UleError>; // Some automatically provided methods elided } @@ -214,7 +214,7 @@ Unsized types use [`VarULE`]. Unlike sized types, there is no `AsVarULE` type fo ```rust pub unsafe trait VarULE: 'static { - fn validate_byte_slice(_bytes: &[u8]) -> Result<(), ZeroVecError>; + fn validate_byte_slice(_bytes: &[u8]) -> Result<(), UleError>; unsafe fn from_byte_slice_unchecked(bytes: &[u8]) -> &Self; // Some automatically provided methods elided diff --git a/utils/zerovec/src/error.rs b/utils/zerovec/src/error.rs deleted file mode 100644 index 0511625489b..00000000000 --- a/utils/zerovec/src/error.rs +++ /dev/null @@ -1,68 +0,0 @@ -// This file is part of ICU4X. For terms of use, please see the file -// 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, PartialEq, Eq)] -#[non_exhaustive] -pub enum ZeroVecError { - /// Attempted to parse a buffer into a slice of the given ULE type but its - /// length was not compatible. - /// - /// Typically created by a [`ULE`] impl via [`ZeroVecError::length()`]. - /// - /// [`ULE`]: crate::ule::ULE - InvalidLength { ty: &'static str, len: usize }, - /// The byte sequence provided for `ty` failed to parse correctly in the - /// given ULE type. - /// - /// Typically created by a [`ULE`] impl via [`ZeroVecError::parse()`]. - /// - /// [`ULE`]: crate::ule::ULE - ParseError { ty: &'static str }, - /// The byte buffer was not in the appropriate format for VarZeroVec. - /// - /// [`ULE`] impls should not return errors of this variant. - /// - /// [`ULE`]: crate::ule::ULE - VarZeroVecFormatError, -} - -impl fmt::Display for ZeroVecError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - match *self { - ZeroVecError::InvalidLength { ty, len } => { - write!(f, "Invalid length {len} for slice of type {ty}") - } - ZeroVecError::ParseError { ty } => { - write!(f, "Could not parse bytes to slice of type {ty}") - } - ZeroVecError::VarZeroVecFormatError => { - write!(f, "Invalid format for VarZeroVec buffer") - } - } - } -} - -impl ZeroVecError { - /// Construct a parse error for the given type - 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) -> ZeroVecError { - ZeroVecError::InvalidLength { - ty: any::type_name::(), - len, - } - } -} - -#[cfg(feature = "std")] -impl ::std::error::Error for ZeroVecError {} diff --git a/utils/zerovec/src/flexzerovec/slice.rs b/utils/zerovec/src/flexzerovec/slice.rs index 8e8f7570646..9546bf849b7 100644 --- a/utils/zerovec/src/flexzerovec/slice.rs +++ b/utils/zerovec/src/flexzerovec/slice.rs @@ -3,7 +3,7 @@ // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). use super::FlexZeroVec; -use crate::ZeroVecError; +use crate::ule::UleError; use alloc::vec::Vec; use core::cmp::Ordering; use core::fmt; @@ -92,11 +92,11 @@ impl FlexZeroSlice { /// assert_eq!(FZS.get(3), None); /// assert_eq!(FZS.last(), Some(0xFFFF)); /// ``` - pub const fn parse_byte_slice(bytes: &[u8]) -> Result<&Self, ZeroVecError> { + pub const fn parse_byte_slice(bytes: &[u8]) -> Result<&Self, UleError> { let (width_u8, data) = match bytes.split_first() { Some(v) => v, None => { - return Err(ZeroVecError::InvalidLength { + return Err(UleError::InvalidLength { ty: "FlexZeroSlice", len: 0, }) @@ -104,12 +104,12 @@ impl FlexZeroSlice { }; let width = *width_u8 as usize; if width < 1 || width > USIZE_WIDTH { - return Err(ZeroVecError::ParseError { + return Err(UleError::ParseError { ty: "FlexZeroSlice", }); } if data.len() % width != 0 { - return Err(ZeroVecError::InvalidLength { + return Err(UleError::InvalidLength { ty: "FlexZeroSlice", len: bytes.len(), }); diff --git a/utils/zerovec/src/flexzerovec/vec.rs b/utils/zerovec/src/flexzerovec/vec.rs index d83f600b572..e149d51d75d 100644 --- a/utils/zerovec/src/flexzerovec/vec.rs +++ b/utils/zerovec/src/flexzerovec/vec.rs @@ -4,7 +4,7 @@ use super::FlexZeroSlice; use super::FlexZeroVecOwned; -use crate::ZeroVecError; +use crate::ule::UleError; use core::cmp::Ordering; use core::iter::FromIterator; use core::ops::Deref; @@ -164,7 +164,7 @@ impl<'a> FlexZeroVec<'a> { /// assert!(matches!(zv, FlexZeroVec::Borrowed(_))); /// assert_eq!(zv.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 FlexZeroSlice = FlexZeroSlice::parse_byte_slice(bytes)?; Ok(Self::Borrowed(slice)) } diff --git a/utils/zerovec/src/lib.rs b/utils/zerovec/src/lib.rs index aea73c6058d..4f54d9fbc7b 100644 --- a/utils/zerovec/src/lib.rs +++ b/utils/zerovec/src/lib.rs @@ -213,7 +213,6 @@ extern crate alloc; -mod error; mod flexzerovec; #[cfg(feature = "hashmap")] pub mod hashmap; @@ -232,7 +231,6 @@ pub mod ule; mod yoke_impls; mod zerofrom_impls; -pub use crate::error::ZeroVecError; #[cfg(feature = "hashmap")] pub use crate::hashmap::ZeroHashMap; pub use crate::map::map::ZeroMap; diff --git a/utils/zerovec/src/map/map.rs b/utils/zerovec/src/map/map.rs index d87231c3c14..1dc97412578 100644 --- a/utils/zerovec/src/map/map.rs +++ b/utils/zerovec/src/map/map.rs @@ -3,8 +3,8 @@ // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). use super::*; -use crate::ule::{AsULE, EncodeAsVarULE, VarULE}; -use crate::{VarZeroVec, ZeroSlice, ZeroVec, ZeroVecError}; +use crate::ule::{AsULE, EncodeAsVarULE, UleError, VarULE}; +use crate::{VarZeroVec, ZeroSlice, ZeroVec}; use alloc::borrow::Borrow; use alloc::boxed::Box; use core::cmp::Ordering; @@ -352,7 +352,7 @@ where /// # Panics /// /// Panics if `K::ULE` and `P::ULE` are not the same size. - pub fn try_convert_zv_k_unchecked

(self) -> Result, ZeroVecError> + pub fn try_convert_zv_k_unchecked

(self) -> Result, UleError> where P: AsULE + ZeroMapKV<'a, Container = ZeroVec<'a, P>>, { @@ -394,7 +394,7 @@ where /// # Panics /// /// Panics if `V::ULE` and `P::ULE` are not the same size. - pub fn try_convert_zv_v_unchecked

(self) -> Result, ZeroVecError> + pub fn try_convert_zv_v_unchecked

(self) -> Result, UleError> where P: AsULE + ZeroMapKV<'a, Container = ZeroVec<'a, P>>, { diff --git a/utils/zerovec/src/ule/chars.rs b/utils/zerovec/src/ule/chars.rs index e4c1efc4ec2..2e1bf82a3a5 100644 --- a/utils/zerovec/src/ule/chars.rs +++ b/utils/zerovec/src/ule/chars.rs @@ -66,9 +66,9 @@ impl CharULE { // 6. CharULE byte equality is semantic equality unsafe impl ULE for CharULE { #[inline] - fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), UleError> { if bytes.len() % 3 != 0 { - return Err(ZeroVecError::length::(bytes.len())); + return Err(UleError::length::(bytes.len())); } // Validate the bytes for chunk in bytes.chunks_exact(3) { @@ -76,7 +76,7 @@ unsafe impl ULE for CharULE { #[allow(clippy::indexing_slicing)] // Won't panic because the chunks are always 3 bytes long let u = u32::from_le_bytes([chunk[0], chunk[1], chunk[2], 0]); - char::try_from(u).map_err(|_| ZeroVecError::parse::())?; + char::try_from(u).map_err(|_| UleError::parse::())?; } Ok(()) } diff --git a/utils/zerovec/src/ule/custom.rs b/utils/zerovec/src/ule/custom.rs index 5a31c66e4b6..fbc6f2d2fca 100644 --- a/utils/zerovec/src/ule/custom.rs +++ b/utils/zerovec/src/ule/custom.rs @@ -67,11 +67,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<(), ZeroVecError> { +//! fn validate_byte_slice(bytes: &[u8]) -> Result<(), UleError> { //! // validate each field -//! ::ULE::validate_byte_slice(&bytes[0..3]).map_err(|_| ZeroVecError::parse::())?; -//! ::ULE::validate_byte_slice(&bytes[3..7]).map_err(|_| ZeroVecError::parse::())?; -//! let _ = ZeroVec::::parse_byte_slice(&bytes[7..]).map_err(|_| ZeroVecError::parse::())?; +//! ::ULE::validate_byte_slice(&bytes[0..3]).map_err(|_| UleError::parse::())?; +//! ::ULE::validate_byte_slice(&bytes[3..7]).map_err(|_| UleError::parse::())?; +//! let _ = ZeroVec::::parse_byte_slice(&bytes[7..]).map_err(|_| UleError::parse::())?; //! Ok(()) //! } //! unsafe fn from_byte_slice_unchecked(bytes: &[u8]) -> &Self { diff --git a/utils/zerovec/src/ule/mod.rs b/utils/zerovec/src/ule/mod.rs index dbd235430d5..1a08b65d095 100644 --- a/utils/zerovec/src/ule/mod.rs +++ b/utils/zerovec/src/ule/mod.rs @@ -22,7 +22,6 @@ mod plain; mod slices; pub mod tuple; -pub use super::ZeroVecError; pub use chars::CharULE; pub use encode::{encode_varule_to_box, EncodeAsVarULE}; pub use multi::MultiFieldsULE; @@ -33,7 +32,7 @@ pub use plain::RawBytesULE; use alloc::alloc::Layout; use alloc::borrow::ToOwned; use alloc::boxed::Box; -use core::{mem, slice}; +use core::{any, fmt, mem, slice}; /// Fixed-width, byte-aligned data that can be cast to and from a little-endian byte slice. /// @@ -83,8 +82,8 @@ 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<(), ZeroVecError>; + /// should be returned; otherwise, `Err` should be returned. + fn validate_byte_slice(bytes: &[u8]) -> Result<(), UleError>; /// Parses a byte slice, `&[u8]`, and return it as `&[Self]` with the same lifetime. /// @@ -96,7 +95,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], ZeroVecError> { + 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) }) @@ -296,7 +295,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<(), ZeroVecError>; + fn validate_byte_slice(_bytes: &[u8]) -> Result<(), UleError>; /// Parses a byte slice, `&[u8]`, and return it as `&Self` with the same lifetime. /// @@ -309,7 +308,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, ZeroVecError> { + 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)); @@ -390,3 +389,56 @@ pub use zerovec_derive::ULE; /// a custom [`VarULE`] type. #[cfg(feature = "derive")] pub use zerovec_derive::VarULE; + +/// An error type to be used for decoding slices of ULE types +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +#[non_exhaustive] +pub enum UleError { + /// Attempted to parse a buffer into a slice of the given ULE type but its + /// length was not compatible. + /// + /// Typically created by a [`ULE`] impl via [`UleError::length()`]. + /// + /// [`ULE`]: crate::ule::ULE + InvalidLength { ty: &'static str, len: usize }, + /// The byte sequence provided for `ty` failed to parse correctly in the + /// given ULE type. + /// + /// Typically created by a [`ULE`] impl via [`UleError::parse()`]. + /// + /// [`ULE`]: crate::ule::ULE + ParseError { ty: &'static str }, +} + +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 {len} for slice of type {ty}") + } + UleError::ParseError { ty } => { + write!(f, "Could not parse bytes to slice of type {ty}") + } + } + } +} + +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::(), + len, + } + } +} + +#[cfg(feature = "std")] +impl ::std::error::Error for UleError {} diff --git a/utils/zerovec/src/ule/multi.rs b/utils/zerovec/src/ule/multi.rs index 3281b208882..d5ae94ba7f9 100644 --- a/utils/zerovec/src/ule/multi.rs +++ b/utils/zerovec/src/ule/multi.rs @@ -74,10 +74,7 @@ impl MultiFieldsULE { /// /// - `index` must be in range #[inline] - pub unsafe fn validate_field( - &self, - index: usize, - ) -> Result<(), ZeroVecError> { + pub unsafe fn validate_field(&self, index: usize) -> Result<(), UleError> { T::validate_byte_slice(self.0.get_unchecked(index)) } @@ -140,7 +137,7 @@ unsafe impl VarULE for MultiFieldsULE { /// /// This impl exists so that EncodeAsVarULE can work. #[inline] - fn validate_byte_slice(slice: &[u8]) -> Result<(), ZeroVecError> { + fn validate_byte_slice(slice: &[u8]) -> Result<(), UleError> { >::validate_byte_slice(slice) } diff --git a/utils/zerovec/src/ule/niche.rs b/utils/zerovec/src/ule/niche.rs index b7574f65df0..df1ba439b2e 100644 --- a/utils/zerovec/src/ule/niche.rs +++ b/utils/zerovec/src/ule/niche.rs @@ -116,7 +116,7 @@ impl + ULE + Eq, const N: usize> Eq for NichedOptionULE { /// 6. NichedOptionULE equality is based on ULE equality of the subfield, assuming that NicheBytes /// has been implemented correctly (this is a correctness but not a safety guarantee). unsafe impl + ULE, const N: usize> ULE for NichedOptionULE { - fn validate_byte_slice(bytes: &[u8]) -> Result<(), crate::ZeroVecError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), crate::ule::UleError> { let size = size_of::(); // The implemention is only correct if NICHE_BIT_PATTERN has same number of bytes as the // type. @@ -124,7 +124,7 @@ unsafe impl + ULE, const N: usize> ULE for NichedOptionULE(bytes.len())); + return Err(crate::ule::UleError::length::(bytes.len())); } bytes.chunks(size).try_for_each(|chunk| { // Associated const cannot be referenced in a pattern diff --git a/utils/zerovec/src/ule/option.rs b/utils/zerovec/src/ule/option.rs index 303bb908a64..3a764322165 100644 --- a/utils/zerovec/src/ule/option.rs +++ b/utils/zerovec/src/ule/option.rs @@ -73,10 +73,10 @@ impl core::fmt::Debug for OptionULE { // 6. OptionULE byte equality is semantic equality by relying on the ULE equality // invariant on the subfields unsafe impl ULE for OptionULE { - fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), UleError> { let size = mem::size_of::(); if bytes.len() % size != 0 { - return Err(ZeroVecError::length::(bytes.len())); + return Err(UleError::length::(bytes.len())); } for chunk in bytes.chunks(size) { #[allow(clippy::indexing_slicing)] // `chunk` will have enough bytes to fit Self @@ -85,11 +85,11 @@ unsafe impl ULE for OptionULE { // Rust booleans are always size 1, align 1 values with valid bit patterns 0x0 or 0x1 0 => { if !chunk[1..].iter().all(|x| *x == 0) { - return Err(ZeroVecError::parse::()); + return Err(UleError::parse::()); } } 1 => U::validate_byte_slice(&chunk[1..])?, - _ => return Err(ZeroVecError::parse::()), + _ => return Err(UleError::parse::()), } } Ok(()) @@ -175,9 +175,9 @@ impl core::fmt::Debug for OptionVarULE // 7. OptionVarULE byte equality is semantic equality (achieved by being an aggregate) unsafe impl VarULE for OptionVarULE { #[inline] - fn validate_byte_slice(slice: &[u8]) -> Result<(), ZeroVecError> { + fn validate_byte_slice(slice: &[u8]) -> Result<(), UleError> { if slice.is_empty() { - return Err(ZeroVecError::length::(slice.len())); + return Err(UleError::length::(slice.len())); } #[allow(clippy::indexing_slicing)] // slice already verified to be nonempty match slice[0] { @@ -185,13 +185,13 @@ unsafe impl VarULE for OptionVarULE { // Rust booleans are always size 1, align 1 values with valid bit patterns 0x0 or 0x1 0 => { if slice.len() != 1 { - Err(ZeroVecError::length::(slice.len())) + Err(UleError::length::(slice.len())) } else { Ok(()) } } 1 => U::validate_byte_slice(&slice[1..]), - _ => Err(ZeroVecError::parse::()), + _ => Err(UleError::parse::()), } } diff --git a/utils/zerovec/src/ule/plain.rs b/utils/zerovec/src/ule/plain.rs index f244f6b6825..54eea13842b 100644 --- a/utils/zerovec/src/ule/plain.rs +++ b/utils/zerovec/src/ule/plain.rs @@ -42,12 +42,12 @@ impl RawBytesULE { // 6. RawBytesULE byte equality is semantic equality unsafe impl ULE for RawBytesULE { #[inline] - fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), UleError> { if bytes.len() % N == 0 { // Safe because Self is transparent over [u8; N] Ok(()) } else { - Err(ZeroVecError::length::(bytes.len())) + Err(UleError::length::(bytes.len())) } } } @@ -94,13 +94,13 @@ macro_rules! impl_const_constructors { /// instead. /// /// See [`ZeroSlice::cast()`] for an example. - pub const fn try_from_bytes(bytes: &[u8]) -> Result<&Self, ZeroVecError> { + pub const fn try_from_bytes(bytes: &[u8]) -> Result<&Self, UleError> { let len = bytes.len(); #[allow(clippy::modulo_one)] if len % $size == 0 { Ok(unsafe { Self::from_bytes_unchecked(bytes) }) } else { - Err(ZeroVecError::InvalidLength { + Err(UleError::InvalidLength { ty: concat!(""), len, }) @@ -188,7 +188,7 @@ impl_const_constructors!(bool, 1); // 6. u8 byte equality is semantic equality unsafe impl ULE for u8 { #[inline] - fn validate_byte_slice(_bytes: &[u8]) -> Result<(), ZeroVecError> { + fn validate_byte_slice(_bytes: &[u8]) -> Result<(), UleError> { Ok(()) } } @@ -217,10 +217,10 @@ unsafe impl EqULE for u8 {} // 6. NonZeroU8 byte equality is semantic equality unsafe impl ULE for NonZeroU8 { #[inline] - fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), UleError> { bytes.iter().try_for_each(|b| { if *b == 0x00 { - Err(ZeroVecError::parse::()) + Err(UleError::parse::()) } else { Ok(()) } @@ -255,7 +255,7 @@ impl NicheBytes<1> for NonZeroU8 { // 6. i8 byte equality is semantic equality unsafe impl ULE for i8 { #[inline] - fn validate_byte_slice(_bytes: &[u8]) -> Result<(), ZeroVecError> { + fn validate_byte_slice(_bytes: &[u8]) -> Result<(), UleError> { Ok(()) } } @@ -338,12 +338,12 @@ unsafe impl EqULE for f64 {} // 6. bool byte equality is semantic equality unsafe impl ULE for bool { #[inline] - fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), UleError> { for byte in bytes { // https://doc.rust-lang.org/reference/types/boolean.html // Rust booleans are always size 1, align 1 values with valid bit patterns 0x0 or 0x1 if *byte > 1 { - return Err(ZeroVecError::parse::()); + return Err(UleError::parse::()); } } Ok(()) diff --git a/utils/zerovec/src/ule/slices.rs b/utils/zerovec/src/ule/slices.rs index 271e49e9595..e0a9fa5863f 100644 --- a/utils/zerovec/src/ule/slices.rs +++ b/utils/zerovec/src/ule/slices.rs @@ -13,7 +13,7 @@ use crate::ule::*; // 6. [T; N] byte equality is semantic equality since T is ULE unsafe impl ULE for [T; N] { #[inline] - fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), UleError> { // a slice of multiple Selfs is equivalent to just a larger slice of Ts T::validate_byte_slice(bytes) } @@ -43,14 +43,14 @@ unsafe impl EqULE for [T; N] {} // 7. str byte equality is semantic equality unsafe impl VarULE for str { #[inline] - fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError> { - core::str::from_utf8(bytes).map_err(|_| ZeroVecError::parse::())?; + fn validate_byte_slice(bytes: &[u8]) -> Result<(), UleError> { + core::str::from_utf8(bytes).map_err(|_| UleError::parse::())?; Ok(()) } #[inline] - fn parse_byte_slice(bytes: &[u8]) -> Result<&Self, ZeroVecError> { - core::str::from_utf8(bytes).map_err(|_| ZeroVecError::parse::()) + fn parse_byte_slice(bytes: &[u8]) -> Result<&Self, UleError> { + core::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` @@ -91,7 +91,7 @@ where T: ULE, { #[inline] - fn validate_byte_slice(slice: &[u8]) -> Result<(), ZeroVecError> { + fn validate_byte_slice(slice: &[u8]) -> Result<(), UleError> { T::validate_byte_slice(slice) } diff --git a/utils/zerovec/src/ule/tuple.rs b/utils/zerovec/src/ule/tuple.rs index 457a10f41b0..6a8c0f63994 100644 --- a/utils/zerovec/src/ule/tuple.rs +++ b/utils/zerovec/src/ule/tuple.rs @@ -45,11 +45,11 @@ macro_rules! tuple_ule { // 6. TupleULE byte equality is semantic equality by relying on the ULE equality // invariant on the subfields unsafe impl<$($t: ULE),+> ULE for $name<$($t),+> { - fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), UleError> { // expands to: 0size + mem::size_of::() + mem::size_of::(); let ule_bytes = 0usize $(+ mem::size_of::<$t>())+; if bytes.len() % ule_bytes != 0 { - return Err(ZeroVecError::length::(bytes.len())); + return Err(UleError::length::(bytes.len())); } for chunk in bytes.chunks(ule_bytes) { let mut i = 0; diff --git a/utils/zerovec/src/varzerovec/components.rs b/utils/zerovec/src/varzerovec/components.rs index 80f79f0a9a9..6bc3af8965b 100644 --- a/utils/zerovec/src/varzerovec/components.rs +++ b/utils/zerovec/src/varzerovec/components.rs @@ -2,6 +2,7 @@ // called LICENSE at the top level of the ICU4X source tree // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). +use super::VarZeroVecFormatError; use crate::ule::*; use alloc::boxed::Box; use alloc::format; @@ -161,7 +162,7 @@ impl<'a, T: VarULE + ?Sized, F: VarZeroVecFormat> VarZeroVecComponents<'a, T, F> /// - `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 { // The empty VZV is special-cased to the empty slice if slice.is_empty() { return Ok(VarZeroVecComponents { @@ -174,23 +175,23 @@ impl<'a, T: VarULE + ?Sized, F: VarZeroVecFormat> VarZeroVecComponents<'a, T, F> } let len_bytes = slice .get(0..LENGTH_WIDTH) - .ok_or(ZeroVecError::VarZeroVecFormatError)?; + .ok_or(VarZeroVecFormatError::Metadata)?; let len_ule = RawBytesULE::::parse_byte_slice(len_bytes) - .map_err(|_| ZeroVecError::VarZeroVecFormatError)?; + .map_err(|_| VarZeroVecFormatError::Metadata)?; let len = len_ule .first() - .ok_or(ZeroVecError::VarZeroVecFormatError)? + .ok_or(VarZeroVecFormatError::Metadata)? .as_unsigned_int(); let indices_bytes = slice .get( LENGTH_WIDTH + METADATA_WIDTH ..LENGTH_WIDTH + METADATA_WIDTH + F::INDEX_WIDTH * (len as usize), ) - .ok_or(ZeroVecError::VarZeroVecFormatError)?; + .ok_or(VarZeroVecFormatError::Metadata)?; let things = slice .get(F::INDEX_WIDTH * (len as usize) + LENGTH_WIDTH + METADATA_WIDTH..) - .ok_or(ZeroVecError::VarZeroVecFormatError)?; + .ok_or(VarZeroVecFormatError::Metadata)?; let borrowed = VarZeroVecComponents { len, @@ -317,11 +318,11 @@ impl<'a, T: VarULE + ?Sized, F: VarZeroVecFormat> VarZeroVecComponents<'a, T, F> /// assume that the slice has been passed through check_indices_and_things #[inline] #[allow(clippy::len_zero)] // more explicit to enforce safety invariants - fn check_indices_and_things(self) -> Result<(), ZeroVecError> { + fn check_indices_and_things(self) -> Result<(), VarZeroVecFormatError> { assert_eq!(self.len(), self.indices_slice().len()); if self.len() == 0 { if self.things.len() > 0 { - return Err(ZeroVecError::VarZeroVecFormatError); + return Err(VarZeroVecFormatError::Metadata); } else { return Ok(()); } @@ -329,7 +330,7 @@ impl<'a, T: VarULE + ?Sized, F: VarZeroVecFormat> VarZeroVecComponents<'a, T, F> // Safety: i is in bounds (assertion above) let mut start = F::rawbytes_to_usize(unsafe { *self.indices_slice().get_unchecked(0) }); if start != 0 { - return Err(ZeroVecError::VarZeroVecFormatError); + return Err(VarZeroVecFormatError::Metadata); } for i in 0..self.len() { let end = if i == self.len() - 1 { @@ -339,14 +340,14 @@ impl<'a, T: VarULE + ?Sized, F: VarZeroVecFormat> VarZeroVecComponents<'a, T, F> F::rawbytes_to_usize(unsafe { *self.indices_slice().get_unchecked(i + 1) }) }; if start > end { - return Err(ZeroVecError::VarZeroVecFormatError); + return Err(VarZeroVecFormatError::Metadata); } if end > self.things.len() { - return Err(ZeroVecError::VarZeroVecFormatError); + return Err(VarZeroVecFormatError::Metadata); } // Safety: start..end is a valid range in self.things let bytes = unsafe { self.things.get_unchecked(start..end) }; - T::parse_byte_slice(bytes)?; + T::parse_byte_slice(bytes).map_err(VarZeroVecFormatError::Values)?; start = end; } Ok(()) diff --git a/utils/zerovec/src/varzerovec/error.rs b/utils/zerovec/src/varzerovec/error.rs new file mode 100644 index 00000000000..66fa880beb6 --- /dev/null +++ b/utils/zerovec/src/varzerovec/error.rs @@ -0,0 +1,11 @@ +// This file is part of ICU4X. For terms of use, please see the file +// called LICENSE at the top level of the ICU4X source tree +// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). + +#[derive(Debug)] +pub enum VarZeroVecFormatError { + /// The byte buffer was not in the appropriate format for VarZeroVec. + Metadata, + #[allow(dead_code)] + Values(crate::ule::UleError), +} diff --git a/utils/zerovec/src/varzerovec/mod.rs b/utils/zerovec/src/varzerovec/mod.rs index 2e9f6800065..97049e32e23 100644 --- a/utils/zerovec/src/varzerovec/mod.rs +++ b/utils/zerovec/src/varzerovec/mod.rs @@ -5,6 +5,7 @@ //! See [`VarZeroVec`](crate::VarZeroVec) for details pub(crate) mod components; +pub(crate) mod error; pub(crate) mod owned; pub(crate) mod slice; pub(crate) mod vec; @@ -24,3 +25,5 @@ pub use components::VarZeroVecComponents; pub use components::{Index16, Index32, VarZeroVecFormat}; pub use owned::VarZeroVecOwned; + +pub use error::VarZeroVecFormatError; diff --git a/utils/zerovec/src/varzerovec/slice.rs b/utils/zerovec/src/varzerovec/slice.rs index 58703ac5340..7292f7f9664 100644 --- a/utils/zerovec/src/varzerovec/slice.rs +++ b/utils/zerovec/src/varzerovec/slice.rs @@ -135,14 +135,12 @@ impl VarZeroSlice { /// # Example /// /// ```rust - /// # use zerovec::ule::ZeroVecError; /// # use zerovec::VarZeroVec; /// /// let strings = vec!["foo", "bar", "baz", "quux"]; /// let vec = VarZeroVec::::from(&strings); /// /// assert_eq!(vec.len(), 4); - /// # Ok::<(), ZeroVecError>(()) /// ``` pub fn len(&self) -> usize { self.as_components().len() @@ -153,14 +151,12 @@ impl VarZeroSlice { /// # Examples /// /// ``` - /// # use zerovec::ule::ZeroVecError; /// # use zerovec::VarZeroVec; /// /// let strings: Vec = vec![]; /// let vec = VarZeroVec::::from(&strings); /// /// assert!(vec.is_empty()); - /// # Ok::<(), ZeroVecError>(()) /// ``` pub fn is_empty(&self) -> bool { self.as_components().is_empty() @@ -171,7 +167,6 @@ impl VarZeroSlice { /// # Example /// /// ```rust - /// # use zerovec::ule::ZeroVecError; /// # use zerovec::VarZeroVec; /// /// let strings = vec!["foo", "bar", "baz", "quux"]; @@ -182,7 +177,6 @@ impl VarZeroSlice { /// assert_eq!(iter_results[1], "bar"); /// assert_eq!(iter_results[2], "baz"); /// assert_eq!(iter_results[3], "quux"); - /// # Ok::<(), ZeroVecError>(()) /// ``` pub fn iter<'b>(&'b self) -> impl Iterator { self.as_components().iter() @@ -193,7 +187,6 @@ impl VarZeroSlice { /// # Example /// /// ```rust - /// # use zerovec::ule::ZeroVecError; /// # use zerovec::VarZeroVec; /// /// let strings = vec!["foo", "bar", "baz", "quux"]; @@ -205,7 +198,6 @@ impl VarZeroSlice { /// assert_eq!(vec.get(2), Some("baz")); /// assert_eq!(vec.get(3), Some("quux")); /// assert_eq!(vec.get(4), None); - /// # Ok::<(), ZeroVecError>(()) /// ``` pub fn get(&self, idx: usize) -> Option<&T> { self.as_components().get(idx) @@ -220,7 +212,6 @@ impl VarZeroSlice { /// # Example /// /// ```rust - /// # use zerovec::ule::ZeroVecError; /// # use zerovec::VarZeroVec; /// /// let strings = vec!["foo", "bar", "baz", "quux"]; @@ -233,7 +224,6 @@ impl VarZeroSlice { /// assert_eq!(vec.get_unchecked(2), "baz"); /// assert_eq!(vec.get_unchecked(3), "quux"); /// } - /// # Ok::<(), ZeroVecError>(()) /// ``` pub unsafe fn get_unchecked(&self, idx: usize) -> &T { self.as_components().get_unchecked(idx) @@ -253,15 +243,12 @@ impl VarZeroSlice { /// # Example /// /// ```rust - /// # use zerovec::ule::ZeroVecError; /// # use zerovec::VarZeroVec; /// /// let strings = vec!["foo", "bar", "baz"]; /// let vzv = VarZeroVec::::from(&strings); /// /// assert_eq!(vzv, VarZeroVec::parse_byte_slice(vzv.as_bytes()).unwrap()); - /// - /// # Ok::<(), ZeroVecError>(()) /// ``` #[inline] pub const fn as_bytes(&self) -> &[u8] { @@ -279,7 +266,7 @@ impl VarZeroSlice { /// Parse a VarZeroSlice from a slice of the appropriate format /// /// Slices of the right format can be obtained via [`VarZeroSlice::as_bytes()`] - pub fn parse_byte_slice<'a>(slice: &'a [u8]) -> Result<&'a Self, ZeroVecError> { + pub fn parse_byte_slice<'a>(slice: &'a [u8]) -> Result<&'a Self, UleError> { ::parse_byte_slice(slice) } @@ -312,7 +299,6 @@ where /// # Example /// /// ``` - /// # use zerovec::ule::ZeroVecError; /// # use zerovec::VarZeroVec; /// /// let strings = vec!["a", "b", "f", "g"]; @@ -320,7 +306,6 @@ where /// /// assert_eq!(vec.binary_search("f"), Ok(2)); /// assert_eq!(vec.binary_search("e"), Err(2)); - /// # Ok::<(), ZeroVecError>(()) /// ``` /// /// [`binary_search`]: https://doc.rust-lang.org/std/primitive.slice.html#method.binary_search @@ -339,9 +324,7 @@ where /// # Example /// /// ``` - /// # use zerovec::ule::ZeroVecError; /// # use zerovec::VarZeroVec; - /// /// let strings = vec!["a", "b", "f", "g", "m", "n", "q"]; /// let vec = VarZeroVec::::from(&strings); /// @@ -360,7 +343,6 @@ where /// // Will return `None` if the range is out of bounds: /// assert_eq!(vec.binary_search_in_range("x", 100..200), None); /// assert_eq!(vec.binary_search_in_range("x", 0..200), None); - /// # Ok::<(), ZeroVecError>(()) /// ``` /// /// [`binary_search`]: https://doc.rust-lang.org/std/primitive.slice.html#method.binary_search @@ -386,15 +368,12 @@ where /// # Example /// /// ``` - /// # use zerovec::ule::ZeroVecError; /// # use zerovec::VarZeroVec; - /// /// let strings = vec!["a", "b", "f", "g"]; /// let vec = VarZeroVec::::from(&strings); /// /// assert_eq!(vec.binary_search_by(|probe| probe.cmp("f")), Ok(2)); /// assert_eq!(vec.binary_search_by(|probe| probe.cmp("e")), Err(2)); - /// # Ok::<(), ZeroVecError>(()) /// ``` /// /// [`binary_search_by`]: https://doc.rust-lang.org/std/primitive.slice.html#method.binary_search_by @@ -413,9 +392,7 @@ where /// # Example /// /// ``` - /// # use zerovec::ule::ZeroVecError; /// # use zerovec::VarZeroVec; - /// /// let strings = vec!["a", "b", "f", "g", "m", "n", "q"]; /// let vec = VarZeroVec::::from(&strings); /// @@ -455,7 +432,6 @@ where /// None /// ); /// assert_eq!(vec.binary_search_in_range_by(|v| v.cmp("x"), 0..200), None); - /// # Ok::<(), ZeroVecError>(()) /// ``` /// /// [`binary_search`]: https://doc.rust-lang.org/std/primitive.slice.html#method.binary_search @@ -479,8 +455,9 @@ where // 6. `as_byte_slice()` is equivalent to a regular transmute of the underlying data // 7. VarZeroSlice byte equality is semantic equality (relying on the guideline of the underlying VarULE type) unsafe impl VarULE for VarZeroSlice { - fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError> { - let _: VarZeroVecComponents = VarZeroVecComponents::parse_byte_slice(bytes)?; + fn validate_byte_slice(bytes: &[u8]) -> Result<(), UleError> { + let _: VarZeroVecComponents = + VarZeroVecComponents::parse_byte_slice(bytes).map_err(|_| UleError::parse::())?; Ok(()) } diff --git a/utils/zerovec/src/varzerovec/vec.rs b/utils/zerovec/src/varzerovec/vec.rs index 95d26b62b4b..1bb11cafb0c 100644 --- a/utils/zerovec/src/varzerovec/vec.rs +++ b/utils/zerovec/src/varzerovec/vec.rs @@ -56,7 +56,6 @@ use super::*; /// # Example /// /// ```rust -/// # use zerovec::ule::ZeroVecError; /// use zerovec::VarZeroVec; /// /// // The little-endian bytes correspond to the list of strings. @@ -81,13 +80,11 @@ use super::*; /// /// assert_eq!(deserialized.strings.get(2), Some("文")); /// assert_eq!(deserialized.strings, &*strings); -/// # Ok::<(), ZeroVecError>(()) /// ``` /// /// Here's another example with `ZeroSlice` (similar to `[T]`): /// /// ```rust -/// # use zerovec::ule::ZeroVecError; /// use zerovec::VarZeroVec; /// use zerovec::ZeroSlice; /// @@ -117,8 +114,6 @@ use super::*; /// /// assert_eq!(deserialized.vecs[0].get(1).unwrap(), 25); /// assert_eq!(deserialized.vecs[1], *numbers[1]); -/// -/// # Ok::<(), ZeroVecError>(()) /// ``` /// /// [`VarZeroVec`]s can be nested infinitely via a similar mechanism, see the docs of [`VarZeroSlice`] @@ -255,7 +250,6 @@ impl<'a, T: VarULE + ?Sized, F: VarZeroVecFormat> VarZeroVec<'a, T, F> { /// # Example /// /// ```rust - /// # use zerovec::ule::ZeroVecError; /// # use zerovec::VarZeroVec; /// /// let strings = vec!["foo", "bar", "baz", "quux"]; @@ -265,9 +259,8 @@ impl<'a, T: VarULE + ?Sized, F: VarZeroVecFormat> VarZeroVec<'a, T, F> { /// assert_eq!(&vec[1], "bar"); /// assert_eq!(&vec[2], "baz"); /// assert_eq!(&vec[3], "quux"); - /// # Ok::<(), ZeroVecError>(()) /// ``` - pub fn parse_byte_slice(slice: &'a [u8]) -> Result { + pub fn parse_byte_slice(slice: &'a [u8]) -> Result { let borrowed = VarZeroSlice::::parse_byte_slice(slice)?; Ok(VarZeroVec::Borrowed(borrowed)) @@ -288,9 +281,7 @@ impl<'a, T: VarULE + ?Sized, F: VarZeroVecFormat> VarZeroVec<'a, T, F> { /// # Example /// /// ```rust,ignore - /// # use zerovec::ule::ZeroVecError; /// # use zerovec::VarZeroVec; - /// /// let strings = vec!["foo", "bar", "baz", "quux"]; /// let mut vec = VarZeroVec::::from(&strings); /// @@ -303,7 +294,6 @@ impl<'a, T: VarULE + ?Sized, F: VarZeroVecFormat> VarZeroVec<'a, T, F> { /// assert_eq!(&vec[2], "dolor sit"); /// assert_eq!(&vec[3], "quux"); /// assert_eq!(&vec[4], "lorem ipsum"); - /// # Ok::<(), ZeroVecError>(()) /// ``` // // This function is crate-public for now since we don't yet want to stabilize @@ -325,7 +315,6 @@ impl<'a, T: VarULE + ?Sized, F: VarZeroVecFormat> VarZeroVec<'a, T, F> { /// # Example /// /// ``` - /// # use zerovec::ule::ZeroVecError; /// # use zerovec::VarZeroVec; /// /// let strings = vec!["foo", "bar", "baz", "quux"]; @@ -334,7 +323,6 @@ impl<'a, T: VarULE + ?Sized, F: VarZeroVecFormat> VarZeroVec<'a, T, F> { /// assert_eq!(vec.len(), 4); /// // has 'static lifetime /// let owned = vec.into_owned(); - /// # Ok::<(), ZeroVecError>(()) /// ``` pub fn into_owned(mut self) -> VarZeroVec<'static, T, F> { self.make_mut(); @@ -362,16 +350,13 @@ impl<'a, T: VarULE + ?Sized, F: VarZeroVecFormat> VarZeroVec<'a, T, F> { /// # Example /// /// ```rust - /// # use zerovec::ule::ZeroVecError; /// # use zerovec::VarZeroVec; /// /// let strings = vec!["foo", "bar", "baz"]; /// let bytes = VarZeroVec::::from(&strings).into_bytes(); /// - /// let mut borrowed: VarZeroVec = VarZeroVec::parse_byte_slice(&bytes)?; + /// let mut borrowed: VarZeroVec = VarZeroVec::parse_byte_slice(&bytes).unwrap(); /// assert_eq!(borrowed, &*strings); - /// - /// # Ok::<(), ZeroVecError>(()) /// ``` pub fn into_bytes(self) -> Vec { match self { diff --git a/utils/zerovec/src/zerovec/mod.rs b/utils/zerovec/src/zerovec/mod.rs index ca6e8658148..13eec4ea485 100644 --- a/utils/zerovec/src/zerovec/mod.rs +++ b/utils/zerovec/src/zerovec/mod.rs @@ -369,7 +369,7 @@ impl<'a, T: AsULE> ZeroVec<'a, T> { /// assert!(!zerovec.is_owned()); /// 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::new_borrowed(slice)) } @@ -529,7 +529,7 @@ impl<'a, T: AsULE> ZeroVec<'a, T> { /// assert!(!zv_u16.is_owned()); /// assert_eq!(zv_u16.get(0), Some(0xF37F)); /// ``` - pub fn try_into_converted(self) -> Result, ZeroVecError> { + pub fn try_into_converted(self) -> Result, UleError> { assert_eq!( core::mem::size_of::<::ULE>(), core::mem::size_of::<

::ULE>() @@ -645,7 +645,7 @@ impl<'a> ZeroVec<'a, u8> { /// assert!(zerovec.is_owned()); /// assert_eq!(zerovec.get(0), Some(211)); /// ``` - pub fn try_into_parsed(self) -> Result, ZeroVecError> { + pub fn try_into_parsed(self) -> Result, UleError> { match self.into_cow() { Cow::Borrowed(bytes) => { let slice: &'a [T::ULE] = T::ULE::parse_byte_slice(bytes)?; diff --git a/utils/zerovec/src/zerovec/slice.rs b/utils/zerovec/src/zerovec/slice.rs index 12d88deff8e..025bf4fcb89 100644 --- a/utils/zerovec/src/zerovec/slice.rs +++ b/utils/zerovec/src/zerovec/slice.rs @@ -54,7 +54,7 @@ where /// Attempt to construct a `&ZeroSlice` from a byte slice, returning an error /// if it's not a valid byte sequence - pub fn parse_byte_slice(bytes: &[u8]) -> Result<&Self, ZeroVecError> { + pub fn parse_byte_slice(bytes: &[u8]) -> Result<&Self, UleError> { T::ULE::parse_byte_slice(bytes).map(Self::from_ule_slice) } @@ -302,7 +302,7 @@ where /// assert_eq!(zs_u8_4.get(0), Some([0x7F, 0xF3, 0x01, 0x00])); /// ``` #[inline] - pub fn try_as_converted(&self) -> Result<&ZeroSlice

, ZeroVecError> { + pub fn try_as_converted(&self) -> Result<&ZeroSlice

, UleError> { let new_slice = P::ULE::parse_byte_slice(self.as_bytes())?; Ok(ZeroSlice::from_ule_slice(new_slice)) } @@ -470,7 +470,7 @@ where // 7. `[T::ULE]` byte equality is semantic equality (relying on the guideline of the underlying `ULE` type) unsafe impl VarULE for ZeroSlice { #[inline] - fn validate_byte_slice(bytes: &[u8]) -> Result<(), ZeroVecError> { + fn validate_byte_slice(bytes: &[u8]) -> Result<(), UleError> { T::ULE::validate_byte_slice(bytes) }