diff options
| author | Manish Goregaokar <manishsmail@gmail.com> | 2020-07-18 16:50:54 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-07-18 16:50:54 -0700 |
| commit | f305b200df5af87608677f30c272f47cf2210623 (patch) | |
| tree | c476911c7e60d8128ebd76eb49651c2c875000a0 /src/libstd | |
| parent | a6266e2d606802b8e9e326dee6410f914959e546 (diff) | |
| parent | 30b8835d1d0f531aa1d5875cde5ffae347177fd3 (diff) | |
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); ```
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/ffi/c_str.rs | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index dca1fdde482..da25a0ede72 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -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")] impl AsRef<CStr> for CStr { #[inline] @@ -1747,4 +1768,21 @@ mod tests { 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()..]; + } } |
