use std::borrow::{Borrow, Cow, IntoCow, ToOwned};
use std::fmt;
use std::hash;
use std::iter::{FromIterator, IntoIterator};
use std::ops;
pub trait BorrowBytes {
fn borrow_bytes<'a>(&'a self) -> &'a [u8];
}
impl BorrowBytes for String {
fn borrow_bytes(&self) -> &[u8] { self.as_bytes() }
}
impl BorrowBytes for str {
fn borrow_bytes(&self) -> &[u8] { self.as_bytes() }
}
impl BorrowBytes for Vec<u8> {
fn borrow_bytes(&self) -> &[u8] { &**self }
}
impl BorrowBytes for ByteString {
fn borrow_bytes(&self) -> &[u8] { &**self }
}
impl BorrowBytes for [u8] {
fn borrow_bytes(&self) -> &[u8] { self }
}
impl<'a, B: ?Sized> BorrowBytes for Cow<'a, B>
where B: BorrowBytes + ToOwned, <B as ToOwned>::Owned: BorrowBytes {
fn borrow_bytes(&self) -> &[u8] {
match *self {
Cow::Borrowed(v) => v.borrow_bytes(),
Cow::Owned(ref v) => v.borrow_bytes(),
}
}
}
impl<'a, T: ?Sized + BorrowBytes> BorrowBytes for &'a T {
fn borrow_bytes(&self) -> &[u8] { (*self).borrow_bytes() }
}
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct ByteString(Vec<u8>);
impl ByteString {
pub fn from_bytes<'a, S>(bs: S) -> ByteString where S: IntoCow<'a, [u8]> {
ByteString(bs.into_cow().into_owned())
}
pub fn into_bytes(self) -> Vec<u8> {
self.0
}
pub fn as_bytes<'a>(&'a self) -> &'a [u8] {
&**self
}
pub fn into_utf8_string(self) -> Result<String, ByteString> {
String::from_utf8(self.into_bytes())
.map_err(|err| ByteString(err.into_bytes()))
}
pub fn len(&self) -> usize {
self.as_bytes().len()
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
}
impl fmt::Debug for ByteString {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", &**self)
}
}
impl ops::Deref for ByteString {
type Target = [u8];
fn deref<'a>(&'a self) -> &'a [u8] {
&*self.0
}
}
impl ops::Index<ops::RangeFull> for ByteString {
type Output = [u8];
fn index<'a>(&'a self, _: &ops::RangeFull) -> &'a [u8] {
&**self
}
}
impl ops::Index<ops::RangeFrom<usize>> for ByteString {
type Output = [u8];
fn index<'a>(&'a self, index: &ops::RangeFrom<usize>) -> &'a [u8] {
&(&**self)[index.start..]
}
}
impl ops::Index<ops::RangeTo<usize>> for ByteString {
type Output = [u8];
fn index<'a>(&'a self, index: &ops::RangeTo<usize>) -> &'a [u8] {
&(&**self)[..index.end]
}
}
impl ops::Index<ops::Range<usize>> for ByteString {
type Output = [u8];
fn index<'a>(&'a self, index: &ops::Range<usize>) -> &'a [u8] {
&(&**self)[index.start..index.end]
}
}
impl hash::Hash for ByteString {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
self.0.hash(state);
}
}
impl<S> PartialEq<S> for ByteString where S: ops::Deref<Target=str> {
fn eq(&self, other: &S) -> bool {
self.as_bytes() == other.as_bytes()
}
}
impl FromIterator<u8> for ByteString {
fn from_iter<I: IntoIterator<Item=u8>>(it: I) -> ByteString {
ByteString::from_bytes(it.into_iter().collect::<Vec<_>>())
}
}
impl Borrow<[u8]> for ByteString {
fn borrow(&self) -> &[u8] { &*self.0 }
}