Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add UleError type; use for PlainOldULE and char conversions #1147

Merged
merged 3 commits into from
Oct 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions utils/zerovec/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ getrandom = { version = "0.2", features = ["js"] }

[features]
bench = []
std = []

[[bench]]
name = "zerovec"
Expand Down
2 changes: 1 addition & 1 deletion utils/zerovec/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
//! # } // feature = "serde"
//! ```

#![cfg_attr(not(test), no_std)]
#![cfg_attr(not(any(test, feature = "std")), no_std)]
// this crate does a lot of nuanced lifetime manipulation, being explicit
// is better here.
#![allow(clippy::needless_lifetimes)]
Expand Down
8 changes: 7 additions & 1 deletion utils/zerovec/src/ule/chars.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,16 @@ pub struct CharULE([u8; 4]);
// This is safe to implement because from_byte_slice_unchecked returns
// the same value as parse_byte_slice
unsafe impl ULE for CharULE {
type Error = core::char::CharTryFromError;
type Error = ULEError<core::char::CharTryFromError>;

#[inline]
fn validate_byte_slice(bytes: &[u8]) -> Result<(), Self::Error> {
if bytes.len() % 4 != 0 {
return Err(ULEError::InvalidLength {
ty: "char",
len: bytes.len(),
});
}
// Validate the bytes
for chunk in bytes.chunks_exact(4) {
// TODO: Use slice::as_chunks() when stabilized
Expand Down
32 changes: 32 additions & 0 deletions utils/zerovec/src/ule/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// 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::fmt;

/// A generic error type to be used for decoding slices of ULE types
#[derive(Copy, Clone, Debug)]
pub enum ULEError<E> {
InvalidLength { ty: &'static str, len: usize },
ParseError(E),
}
zbraniecki marked this conversation as resolved.
Show resolved Hide resolved

impl<E: fmt::Display> fmt::Display for ULEError<E> {
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),
}
}
}

impl<E> From<E> for ULEError<E> {
fn from(e: E) -> Self {
ULEError::ParseError(e)
}
}

#[cfg(feature = "std")]
impl<E: fmt::Display + fmt::Debug> ::std::error::Error for ULEError<E> {}
2 changes: 2 additions & 0 deletions utils/zerovec/src/ule/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
//! Traits over unaligned little-endian data (ULE, pronounced "yule").

mod chars;
mod error;
mod plain;
mod string;
mod vec;

pub use chars::CharULE;
pub use error::ULEError;
pub use plain::PlainOldULE;

use alloc::alloc::Layout;
Expand Down
15 changes: 11 additions & 4 deletions utils/zerovec/src/ule/plain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,19 @@ macro_rules! impl_byte_slice_size {
// This is safe to implement because from_byte_slice_unchecked returns
// the same value as parse_byte_slice
unsafe impl ULE for PlainOldULE<$size> {
type Error = core::convert::Infallible;
type Error = ULEError<core::convert::Infallible>;

#[inline]
fn validate_byte_slice(_bytes: &[u8]) -> Result<(), Self::Error> {
// Safe because Self is transparent over [u8; $size]
Ok(())
fn validate_byte_slice(bytes: &[u8]) -> Result<(), Self::Error> {
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(),
})
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion utils/zerovec/src/varzerovec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ pub use ule::VarZeroVecULE;
/// for (zv, v) in zerovec.iter().zip(numbers.iter()) {
/// assert_eq!(zv, v);
/// }
/// # Ok::<(), VarZeroVecError<std::convert::Infallible>>(())
/// # Ok::<(), VarZeroVecError<ULEError<_>>>(())
/// ```
///
///
Expand Down