@@ -125,6 +125,52 @@ impl AsciiStr {
125
125
bytes. as_ref ( ) . as_ascii_str ( )
126
126
}
127
127
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
+
128
174
/// Converts anything that can be represented as a byte slice to an `AsciiStr` without checking
129
175
/// for non-ASCII characters..
130
176
///
0 commit comments