From 878d3a1c748a4c287dfe0c02eb8ea84ac4c1af5c Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 26 Feb 2023 16:24:48 +0000 Subject: [PATCH] impl AsRef --- bytestring/CHANGES.md | 1 + bytestring/src/lib.rs | 56 ++++++++++++++++++++++++++++++------------- 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/bytestring/CHANGES.md b/bytestring/CHANGES.md index 120f5a0e..826ff3b8 100644 --- a/bytestring/CHANGES.md +++ b/bytestring/CHANGES.md @@ -1,6 +1,7 @@ # Changes ## Unreleased - 2022-xx-xx +- Implement `AsRef` for `ByteString`. - Minimum supported Rust version (MSRV) is now 1.59. diff --git a/bytestring/src/lib.rs b/bytestring/src/lib.rs index 7058c106..d75a05f5 100644 --- a/bytestring/src/lib.rs +++ b/bytestring/src/lib.rs @@ -51,22 +51,26 @@ impl ByteString { Self(src) } - /// Returns a byte string that is equivalent to the given `subset`. + /// Returns a new byte string that is equivalent to the given `subset`. /// /// 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`. + /// fact a slice of the original `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`. /// /// Corresponds to [`Bytes::slice_ref`]. /// /// This operation is `O(1)`. /// /// # Panics - /// Requires that the given `subset` str is in fact contained within the `ByteString` buffer; - /// otherwise this function will panic. + /// + /// Panics if `subset` is not a sub-slice of this byte string. + /// + /// Note that strings which are only subsets from an equality perspective do not uphold this + /// requirement; see examples. /// /// # Examples + /// /// ``` /// # use bytestring::ByteString; /// let string = ByteString::from_static(" foo "); @@ -74,6 +78,13 @@ impl ByteString { /// let substring = string.slice_ref(subset); /// assert_eq!(substring, "foo"); /// ``` + /// + /// ```should_panic + /// # use bytestring::ByteString; + /// // panics because the given slice is not derived from the original byte string, despite + /// // being a logical subset of the string + /// ByteString::from_static("foo bar").slice_ref("foo"); + /// ``` pub fn slice_ref(&self, subset: &str) -> Self { Self(self.0.slice_ref(subset.as_bytes())) } @@ -91,6 +102,12 @@ impl> PartialEq for ByteString { } } +impl AsRef for ByteString { + fn as_ref(&self) -> &ByteString { + self + } +} + impl AsRef<[u8]> for ByteString { fn as_ref(&self) -> &[u8] { self.0.as_ref() @@ -276,7 +293,10 @@ mod serde { #[cfg(test)] mod test { use alloc::borrow::ToOwned; - use core::hash::{Hash, Hasher}; + use core::{ + hash::{Hash, Hasher}, + panic::{RefUnwindSafe, UnwindSafe}, + }; use ahash::AHasher; use static_assertions::assert_impl_all; @@ -286,16 +306,7 @@ mod test { assert_impl_all!(ByteString: Send, Sync, Unpin, Sized); assert_impl_all!(ByteString: Clone, Default, Eq, PartialOrd, Ord); assert_impl_all!(ByteString: fmt::Debug, fmt::Display); - - #[rustversion::since(1.56)] - mod above_1_56_impls { - // `[Ref]UnwindSafe` traits were only in std until rust 1.56 - - use core::panic::{RefUnwindSafe, UnwindSafe}; - - use super::*; - assert_impl_all!(ByteString: UnwindSafe, RefUnwindSafe); - } + assert_impl_all!(ByteString: UnwindSafe, RefUnwindSafe); #[test] fn test_partial_eq() { @@ -377,9 +388,20 @@ mod test { assert_eq!(s, r#""nice bytes""#); } + #[test] + fn slice_ref() { + let string = ByteString::from_static(" foo "); + let subset = string.trim(); + // subset is derived from original byte string + let substring = string.slice_ref(subset); + assert_eq!(substring, "foo"); + } + #[test] #[should_panic] fn test_slice_ref_catches_not_a_subset() { + // panics because the given slice is not derived from the original byte string, despite + // being a logical subset of the string ByteString::from_static("foo bar").slice_ref("foo"); } }