Rollup merge of #74021 - 1011X:master, r=dtolnay
impl Index<RangeFrom> for CStr This change implements (partial) slicing for `CStr`. Since a `CStr` must end in a null byte, it's not possible to trim from the right and still have a valid `CStr`. But, it *is* possible to trim from the left. This lets us be a bit more flexible and treat them more like strings. ```rust let string = CStr::from_bytes_with_nul(b"Hello World!\0"); let result = CStr::from_bytes_with_nul(b"World!\0"); assert_eq!(&string[6..], result); ```
This commit is contained in:
commit
f305b200df
1 changed files with 38 additions and 0 deletions
|
@ -1551,6 +1551,27 @@ impl ops::Index<ops::RangeFull> for CString {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[stable(feature = "cstr_range_from", since = "1.47.0")]
|
||||||
|
impl ops::Index<ops::RangeFrom<usize>> for CStr {
|
||||||
|
type Output = CStr;
|
||||||
|
|
||||||
|
fn index(&self, index: ops::RangeFrom<usize>) -> &CStr {
|
||||||
|
let bytes = self.to_bytes_with_nul();
|
||||||
|
// we need to manually check the starting index to account for the null
|
||||||
|
// byte, since otherwise we could get an empty string that doesn't end
|
||||||
|
// in a null.
|
||||||
|
if index.start < bytes.len() {
|
||||||
|
unsafe { CStr::from_bytes_with_nul_unchecked(&bytes[index.start..]) }
|
||||||
|
} else {
|
||||||
|
panic!(
|
||||||
|
"index out of bounds: the len is {} but the index is {}",
|
||||||
|
bytes.len(),
|
||||||
|
index.start
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[stable(feature = "cstring_asref", since = "1.7.0")]
|
#[stable(feature = "cstring_asref", since = "1.7.0")]
|
||||||
impl AsRef<CStr> for CStr {
|
impl AsRef<CStr> for CStr {
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -1747,4 +1768,21 @@ mod tests {
|
||||||
|
|
||||||
assert_eq!(CSTR.to_str().unwrap(), "Hello, world!");
|
assert_eq!(CSTR.to_str().unwrap(), "Hello, world!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn cstr_index_from() {
|
||||||
|
let original = b"Hello, world!\0";
|
||||||
|
let cstr = CStr::from_bytes_with_nul(original).unwrap();
|
||||||
|
let result = CStr::from_bytes_with_nul(&original[7..]).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(&cstr[7..], result);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn cstr_index_from_empty() {
|
||||||
|
let original = b"Hello, world!\0";
|
||||||
|
let cstr = CStr::from_bytes_with_nul(original).unwrap();
|
||||||
|
let _ = &cstr[original.len()..];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue