Skip to content

Commit

Permalink
Add AsciiStr::from_ascii_str() and from_ascii_bytes()
Browse files Browse the repository at this point in the history
As `const fn` alternatives to the trait-based from_ascii().

Closes tomprogrammer#84
  • Loading branch information
tormol committed Jun 9, 2022
1 parent df1d68d commit 3b75b4e
Showing 1 changed file with 47 additions and 0 deletions.
47 changes: 47 additions & 0 deletions src/ascii_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,53 @@ impl AsciiStr {
bytes.as_ref().as_ascii_str()
}

/// Convert a byte slice innto an `AsciiStr`.
///
/// [`from_ascii()`](#method.from_ascii) should be preferred outside of `const` contexts
/// as it might be faster due to using functions that are not `const fn`.
///
/// # Errors
/// Returns `Err` if not all bytes are valid ASCII values.
///
/// # Examples
/// ```
/// # use ascii::AsciiStr;
/// assert!(AsciiStr::from_ascii_bytes(b"\x00\x22\x44").is_ok());
/// assert!(AsciiStr::from_ascii_bytes(b"\x66\x77\x88").is_err());
/// ```
pub const fn from_ascii_bytes(b: &[u8]) -> Result<&Self, AsAsciiStrError> {
#![allow(clippy::indexing_slicing)] // .get() is not const yes (as of Rust 1.61)
let mut valid = 0;
loop {
if valid == b.len() {
// SAFETY: `is_ascii` having returned true for all bytes guarantees all bytes are within ascii range.
return unsafe { Ok(mem::transmute(b)) };
} else if b[valid].is_ascii() {
valid += 1;
} else {
return Err(AsAsciiStrError(valid));
}
}
}

/// Convert a `str` innto an `AsciiStr`.
///
/// [`from_ascii()`](#method.from_ascii) should be preferred outside of `const` contexts
/// as it might be faster due to using functions that are not `const fn`.
///
/// # Errors
/// Returns `Err` if it contains non-ASCII codepoints.
///
/// # Examples
/// ```
/// # use ascii::AsciiStr;
/// assert!(AsciiStr::from_ascii_str("25 C").is_ok());
/// assert!(AsciiStr::from_ascii_str("35°C").is_err());
/// ```
pub const fn from_ascii_str(s: &str) -> Result<&Self, AsAsciiStrError> {
Self::from_ascii_bytes(s.as_bytes())
}

/// Converts anything that can be represented as a byte slice to an `AsciiStr` without checking
/// for non-ASCII characters..
///
Expand Down

0 comments on commit 3b75b4e

Please sign in to comment.