use std::borrow::Cow;
use std::fmt::{self as stdfmt, Debug};
use std::ops::Deref;
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Barr<'a> {
pub inner: Cow<'a, [u8]>,
}
impl<'a> Barr<'a> {
pub const fn brwed(bytes: &'a [u8]) -> Self {
Self {
inner: Cow::Borrowed(bytes),
}
}
pub const fn owned(bytes: Vec<u8>) -> Barr<'static> {
Barr {
inner: Cow::Owned(bytes),
}
}
pub fn as_bytes(&self) -> &[u8] {
&self.inner
}
pub fn to_mut(&mut self) -> &mut Vec<u8> {
self.inner.to_mut()
}
pub fn into_owned(self) -> Barr<'static> {
Barr::owned(self.inner.into_owned())
}
}
impl<'a> Deref for Barr<'a> {
type Target = [u8];
fn deref(&self) -> &[u8] {
&self.inner
}
}
impl<'a> AsRef<[u8]> for Barr<'a> {
fn as_ref(&self) -> &[u8] {
&*self
}
}
impl<'a> From<&'a [u8]> for Barr<'a> {
fn from(bytes: &'a [u8]) -> Self {
Self::brwed(bytes)
}
}
impl From<Vec<u8>> for Barr<'static> {
fn from(bytes: Vec<u8>) -> Self {
Self::owned(bytes)
}
}
impl<'a> Debug for Barr<'a> {
fn fmt(&self, f: &mut stdfmt::Formatter<'_>) -> stdfmt::Result {
write!(f, "{:?}", &self.inner)
}
}
impl<'a> PartialEq<[u8]> for Barr<'a> {
fn eq(&self, other: &[u8]) -> bool {
self.as_ref() == other
}
}
impl<'a> PartialEq<[u8]> for &Barr<'a> {
fn eq(&self, other: &[u8]) -> bool {
self.as_ref() == other
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_eq() {
let one: Barr = b"Hello, world".to_vec().into();
let two: Barr = b"Hello, world"[..].into();
assert_eq!(one, two);
}
#[test]
fn test_hash() {
let mut set = std::collections::HashSet::new();
set.insert(Barr::owned(b"Hello, world!".to_vec()));
let two = Barr::brwed(b"Hello, world!");
assert_eq!(set.contains(&two), true);
}
#[test]
fn test_to_mut() {
let mut x: Barr = b"Hello"[..].into();
assert_eq!(&x, &b"Hello"[..]);
x.to_mut().extend(b", world!".iter());
assert_eq!(&x, b"Hello, world!"[..]);
}
#[test]
fn test_as_ref() {
let x = Barr::brwed(b"Hello, world!");
assert_eq!(x.as_ref(), &b"Hello, world!"[..]);
}
#[test]
fn fmt_test() {
let x = Barr::brwed(&[100]);
assert_eq!(&format!("{:?}", x), "[100]");
let x = Barr::owned(vec![100]);
assert_eq!(&format!("{:?}", x), "[100]");
}
}