@@ -5,7 +5,7 @@ use core::{
5
5
borrow:: Borrow ,
6
6
cmp:: Ordering ,
7
7
error:: Error ,
8
- ffi:: { c_char, CStr } ,
8
+ ffi:: { c_char, CStr , FromBytesWithNulError } ,
9
9
fmt,
10
10
ops:: Deref ,
11
11
} ;
@@ -18,14 +18,6 @@ pub struct CString<const N: usize> {
18
18
inner : Vec < u8 , N > ,
19
19
}
20
20
21
- /// Naive implementation for `memchr`.
22
- ///
23
- /// TODO Consider using [the `memchr` crate](https://github.com/BurntSushi/memchr), which
24
- /// provides a heavily optimized `memchr` function.
25
- fn memchr ( needle : u8 , haystack : & [ u8 ] ) -> Option < usize > {
26
- haystack. iter ( ) . position ( |& byte| byte == needle)
27
- }
28
-
29
21
impl < const N : usize > CString < N > {
30
22
/// Creates a new C-compatible string with a terminating nul byte.
31
23
///
@@ -181,15 +173,17 @@ impl<const N: usize> CString<N> {
181
173
return Err ( CapacityError . into ( ) ) ;
182
174
}
183
175
184
- match memchr ( 0 , bytes) {
185
- Some ( index ) if index + 1 == bytes . len ( ) => {
176
+ match CStr :: from_bytes_with_nul ( bytes) {
177
+ Ok ( _ ) => {
186
178
// SAFETY: A string is left in a valid state because appended bytes are nul-terminated.
187
179
unsafe { self . extend_from_bytes_unchecked ( bytes) } ?;
188
180
189
181
Ok ( ( ) )
190
182
}
191
- Some ( index) => Err ( ExtendError :: InteriorNulByte ( index) ) ,
192
- None => {
183
+ Err ( FromBytesWithNulError :: InteriorNul { position } ) => {
184
+ Err ( ExtendError :: InteriorNul { position } )
185
+ }
186
+ Err ( FromBytesWithNulError :: NotNulTerminated ) => {
193
187
// Because given bytes has no nul byte anywhere, we insert the bytes and
194
188
// then add the nul byte terminator.
195
189
//
@@ -346,7 +340,7 @@ pub enum ExtendError {
346
340
/// The capacity of the [`CString`] is too small.
347
341
Capacity ( CapacityError ) ,
348
342
/// An invalid interior nul byte found in a given byte slice.
349
- InteriorNulByte ( usize ) ,
343
+ InteriorNul { position : usize } ,
350
344
}
351
345
352
346
impl Error for ExtendError { }
@@ -355,7 +349,7 @@ impl fmt::Display for ExtendError {
355
349
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
356
350
match self {
357
351
Self :: Capacity ( error) => write ! ( f, "{error}" ) ,
358
- Self :: InteriorNulByte ( index ) => write ! ( f, "interior nul byte at {index }" ) ,
352
+ Self :: InteriorNul { position } => write ! ( f, "interior nul byte at {position }" ) ,
359
353
}
360
354
}
361
355
}
@@ -403,7 +397,7 @@ mod tests {
403
397
// Call must fail since `w\0rld` contains an interior nul byte.
404
398
assert ! ( matches!(
405
399
c_string. extend_from_bytes( b"w\0 rld" ) ,
406
- Err ( ExtendError :: InteriorNulByte ( 1 ) )
400
+ Err ( ExtendError :: InteriorNul ( 1 ) )
407
401
) ) ;
408
402
409
403
// However, the call above _must not_ have invalidated the state of our CString
0 commit comments