From 363984ad75d47fc305830813fb405a26f7f2eaf1 Mon Sep 17 00:00:00 2001 From: "Wang, Chi" Date: Tue, 8 Nov 2022 04:16:46 +0800 Subject: [PATCH] Add ByteString::slice_ref (#470) --- bytestring/CHANGES.md | 2 ++ bytestring/src/lib.rs | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/bytestring/CHANGES.md b/bytestring/CHANGES.md index 2cdf6d91..d7c4c2be 100644 --- a/bytestring/CHANGES.md +++ b/bytestring/CHANGES.md @@ -2,7 +2,9 @@ ## Unreleased - 2022-xx-xx - Minimum supported Rust version (MSRV) is now 1.57. +- Add `ByteString::slice_ref` which can safely slice a `ByteString` into a new one with zero copy. [#470] +[#470]: https://github.com/actix/actix-net/pull/470 ## 1.1.0 - 2022-06-11 - Implement `From>` for `ByteString`. [#458] diff --git a/bytestring/src/lib.rs b/bytestring/src/lib.rs index 27357602..06117d7c 100644 --- a/bytestring/src/lib.rs +++ b/bytestring/src/lib.rs @@ -50,6 +50,34 @@ impl ByteString { pub const unsafe fn from_bytes_unchecked(src: Bytes) -> ByteString { Self(src) } + + /// Returns a slice of self that is equivalent to the given `subset`. Corresponds to [`Bytes::slice_ref`]. + /// + /// When processing a `ByteString` buffer with other tools, one often gets a + /// `&str` which is in fact a slice of the `ByteString`, i.e. a subset of it. + /// This function turns that `&str` into another `ByteString`, as if one had + /// sliced the `ByteString` with the offsets that correspond to `subset`. + /// + /// This operation is `O(1)`. + /// + /// # Examples + /// + /// ``` + /// use bytestring::ByteString; + /// + /// let string = ByteString::from_static(" foo "); + /// let subset = string.trim(); + /// let substring = string.slice_ref(subset); + /// assert_eq!(substring, "foo"); + /// ``` + /// + /// # Panics + /// + /// Requires that the given `subset` str is in fact contained within the + /// `ByteString` buffer; otherwise this function will panic. + pub fn slice_ref(&self, subset: &str) -> Self { + Self(self.0.slice_ref(subset.as_bytes())) + } } impl PartialEq for ByteString { @@ -349,4 +377,10 @@ mod test { let s = serde_json::to_string(&ByteString::from_static("nice bytes")).unwrap(); assert_eq!(s, r#""nice bytes""#); } + + #[test] + #[should_panic] + fn test_slice_ref_catches_not_a_subset() { + ByteString::from_static("foo bar").slice_ref("foo"); + } }