Skip to content

Commit

Permalink
api: add more Borrow and BorrowMut trait impls
Browse files Browse the repository at this point in the history
These additions allow `BStr`s and `BString`s to be used as lookup keys
in `HashMap`s containing byte slices, byte vecs, and strings.

I mirrored these impls off of the ones in `std`.

There is some concern that these impls aren't appropriate for one reason
or another. For example, std has a `AsRef<[u8]>` impl for `str` but not
a `Borrow<[u8]>` impl. So one wonders whether we should do the same for
the `BStr` and `BString` types. But the bstr types are true wrappers
around `[u8]` and `Vec<u8>` in the sense that they implement `Deref` and
`DerefMut`. That is, they are meant to be essentially equivalent in
every way. The only reason they really exist is for type level
shenanigans. (e.g., Acting as a target for trait impls like for Serde
and std::fmt::Debug.)

Closes #157
  • Loading branch information
lopopolo authored and BurntSushi committed May 21, 2023
1 parent 7d96589 commit f639abd
Showing 1 changed file with 84 additions and 2 deletions.
86 changes: 84 additions & 2 deletions src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ mod bstring {
};

use alloc::{
borrow::{Borrow, Cow, ToOwned},
borrow::{Borrow, BorrowMut, Cow, ToOwned},
string::String,
vec,
vec::Vec,
Expand Down Expand Up @@ -134,13 +134,55 @@ mod bstring {
}
}

impl Borrow<[u8]> for BString {
#[inline]
fn borrow(&self) -> &[u8] {
self.as_bytes()
}
}

impl Borrow<BStr> for BString {
#[inline]
fn borrow(&self) -> &BStr {
self.as_bstr()
}
}

impl Borrow<BStr> for Vec<u8> {
#[inline]
fn borrow(&self) -> &BStr {
self.as_slice().as_bstr()
}
}

impl Borrow<BStr> for String {
#[inline]
fn borrow(&self) -> &BStr {
self.as_bytes().as_bstr()
}
}

impl BorrowMut<[u8]> for BString {
#[inline]
fn borrow_mut(&mut self) -> &mut [u8] {
self.as_bytes_mut()
}
}

impl BorrowMut<BStr> for BString {
#[inline]
fn borrow_mut(&mut self) -> &mut BStr {
self.as_mut_bstr()
}
}

impl BorrowMut<BStr> for Vec<u8> {
#[inline]
fn borrow_mut(&mut self) -> &mut BStr {
BStr::new_mut(self.as_mut_slice())
}
}

impl ToOwned for BStr {
type Owned = BString;

Expand Down Expand Up @@ -338,7 +380,12 @@ mod bstring {
}

mod bstr {
use core::{cmp::Ordering, convert::TryFrom, fmt, ops};
use core::{
borrow::{Borrow, BorrowMut},
cmp::Ordering,
convert::TryFrom,
fmt, ops,
};

#[cfg(feature = "alloc")]
use alloc::{borrow::Cow, boxed::Box, string::String, vec::Vec};
Expand Down Expand Up @@ -612,6 +659,41 @@ mod bstr {
}
}

impl Borrow<BStr> for [u8] {
#[inline]
fn borrow(&self) -> &BStr {
self.as_bstr()
}
}

impl Borrow<BStr> for str {
#[inline]
fn borrow(&self) -> &BStr {
self.as_bytes().as_bstr()
}
}

impl Borrow<[u8]> for BStr {
#[inline]
fn borrow(&self) -> &[u8] {
self.as_bytes()
}
}

impl BorrowMut<BStr> for [u8] {
#[inline]
fn borrow_mut(&mut self) -> &mut BStr {
BStr::new_mut(self)
}
}

impl BorrowMut<[u8]> for BStr {
#[inline]
fn borrow_mut(&mut self) -> &mut [u8] {
self.as_bytes_mut()
}
}

impl<'a> Default for &'a BStr {
fn default() -> &'a BStr {
BStr::from_bytes(b"")
Expand Down

0 comments on commit f639abd

Please sign in to comment.