Skip to content

Commit 18d5b4d

Browse files
committed
Add AsciiStr::from_ascii_str() and from_ascii_bytes()
As `const fn` alternatives to the trait-based from_ascii(). Closes tomprogrammer#84
1 parent df1d68d commit 18d5b4d

File tree

1 file changed

+46
-0
lines changed

1 file changed

+46
-0
lines changed

src/ascii_str.rs

+46
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,52 @@ impl AsciiStr {
125125
bytes.as_ref().as_ascii_str()
126126
}
127127

128+
/// Convert a byte slice innto an `AsciiStr`.
129+
///
130+
/// [`from_ascii()`](#method.from_ascii) should be preferred outside of `const` contexts
131+
/// as it might be faster due to using functions that are not `const fn`.
132+
///
133+
/// # Errors
134+
/// Returns `Err` if not all bytes are valid ASCII values.
135+
///
136+
/// # Examples
137+
/// ```
138+
/// # use ascii::AsciiStr;
139+
/// assert!(AsciiStr::from_ascii_bytes(b"\x00\x22\x44").is_ok());
140+
/// assert!(AsciiStr::from_ascii_bytes(b"\x66\x77\x88").is_err());
141+
/// ```
142+
pub const fn from_ascii_bytes(b: &[u8]) -> Result<&Self, AsAsciiStrError> {
143+
let mut valid = 0;
144+
loop {
145+
if valid == b.len() {
146+
// SAFETY: `is_ascii` having returned true for all bytes guarantees all bytes are within ascii range.
147+
return unsafe { Ok(mem::transmute(b)) };
148+
} else if b[valid].is_ascii() {
149+
valid += 1;
150+
} else {
151+
return Err(AsAsciiStrError(valid));
152+
}
153+
}
154+
}
155+
156+
/// Convert a `str` innto an `AsciiStr`.
157+
///
158+
/// [`from_ascii()`](#method.from_ascii) should be preferred outside of `const` contexts
159+
/// as it might be faster due to using functions that are not `const fn`.
160+
///
161+
/// # Errors
162+
/// Returns `Err` if it contains non-ASCII codepoints.
163+
///
164+
/// # Examples
165+
/// ```
166+
/// # use ascii::AsciiStr;
167+
/// assert!(AsciiStr::from_ascii_str("25 C").is_ok());
168+
/// assert!(AsciiStr::from_ascii_str("35°C").is_err());
169+
/// ```
170+
pub const fn from_ascii_str(s: &str) -> Result<&Self, AsAsciiStrError> {
171+
Self::from_ascii_bytes(s.as_bytes())
172+
}
173+
128174
/// Converts anything that can be represented as a byte slice to an `AsciiStr` without checking
129175
/// for non-ASCII characters..
130176
///

0 commit comments

Comments
 (0)