use core;
#[cfg(not(feature="no_std"))]
use std;
#[cfg(not(feature="no_std"))]
use ByteString;
use iterators;
use IntoMatcher;
use PrefixMatcher;
use SufixMatcher;
use ForwardSearcher;
use ReverseSearcher;
#[derive(PartialEq, Eq)]
pub struct ByteStr {
inner: [u8],
}
impl ByteStr {
#[inline]
pub fn empty<'a>() -> &'a Self {
Self::from_slice(&[])
}
#[inline]
pub fn empty_mut<'a>() -> &'a mut Self {
Self::from_slice_mut(&mut [])
}
#[inline]
pub fn from_slice(bytes: &[u8]) -> &Self {
unsafe { core::mem::transmute(bytes) }
}
#[inline]
pub fn from_slice_mut(bytes: &mut [u8]) -> &mut Self {
unsafe { core::mem::transmute(bytes) }
}
#[inline]
pub unsafe fn from_raw_parts<'a>(ptr: *const u8, len: usize) -> &'a Self {
ByteStr::from_slice(core::slice::from_raw_parts(ptr, len))
}
#[inline]
pub unsafe fn from_raw_parts_mut<'a>(ptr: *mut u8, len: usize) -> &'a mut Self {
ByteStr::from_slice_mut(core::slice::from_raw_parts_mut(ptr, len))
}
#[inline]
pub fn as_slice(&self) -> &[u8] {
&self.inner
}
#[inline]
pub fn as_mut_slice(&mut self) -> &mut [u8] {
&mut self.inner
}
#[cfg(not(feature="no_std"))]
#[inline]
pub fn to_vec(&self) -> Vec<u8> {
self.as_slice().to_vec()
}
#[cfg(not(feature="no_std"))]
#[inline]
pub fn to_byte_string(&self) -> ByteString {
ByteString::from_vec(self.to_vec())
}
#[cfg(not(feature="no_std"))]
pub fn into_boxed_slice(self: Box<Self>) -> Box<[u8]> {
unsafe { Box::from_raw(Box::into_raw(self) as *mut [u8]) }
}
#[cfg(not(feature="no_std"))]
pub fn into_vec(self: Box<Self>) -> Vec<u8> {
self.into_boxed_slice().into_vec()
}
#[cfg(not(feature="no_std"))]
pub fn into_byte_string(self: Box<Self>) -> ByteString {
ByteString::from_vec(self.into_vec())
}
#[inline]
pub fn len(&self) -> usize {
self.as_slice().len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
#[inline]
pub fn as_ptr(&self) -> *const u8 {
self.as_slice().as_ptr()
}
#[inline]
pub fn as_mut_ptr(&mut self) -> *mut u8 {
self.as_mut_slice().as_mut_ptr()
}
#[inline]
pub fn get(&self, index: usize) -> Option<&u8> {
self.as_slice().get(index)
}
#[inline]
pub fn get_mut(&mut self, index: usize) -> Option<&mut u8> {
self.as_mut_slice().get_mut(index)
}
#[inline]
pub fn first(&self) -> Option<&u8> {
self.as_slice().first()
}
#[inline]
pub fn first_mut(&mut self) -> Option<&mut u8> {
self.as_mut_slice().first_mut()
}
#[inline]
pub fn last(&self) -> Option<&u8> {
self.as_slice().last()
}
#[inline]
pub fn last_mut(&mut self) -> Option<&mut u8> {
self.as_mut_slice().last_mut()
}
#[inline]
pub fn split_first(&self) -> Option<(&u8, &ByteStr)> {
self.as_slice().split_first().map(|(f, r)| (f, Self::from_slice(r)))
}
#[inline]
pub fn split_first_mut(&mut self) -> Option<(&mut u8, &mut ByteStr)> {
self.as_mut_slice().split_first_mut().map(|(f, r)| (f, Self::from_slice_mut(r)))
}
#[inline]
pub fn split_last(&self) -> Option<(&u8, &ByteStr)> {
self.as_slice().split_last().map(|(f, r)| (f, Self::from_slice(r)))
}
#[inline]
pub fn split_last_mut(&mut self) -> Option<(&mut u8, &mut ByteStr)> {
self.as_mut_slice().split_last_mut().map(|(f, r)| (f, Self::from_slice_mut(r)))
}
#[inline]
pub fn iter<'a>(&'a self) -> core::slice::Iter<'a, u8> {
self.as_slice().iter()
}
#[inline]
pub fn iter_mut<'a>(&'a mut self) -> core::slice::IterMut<'a, u8> {
self.as_mut_slice().iter_mut()
}
#[inline]
pub fn windows<'a>(&'a self, size: usize) -> iterators::Windows<'a> {
iterators::Windows::new(self, size)
}
#[inline]
pub fn chunks<'a>(&'a self, size: usize) -> iterators::Chunks<'a> {
iterators::Chunks::new(self, size)
}
#[inline]
pub fn chunks_mut<'a>(&'a mut self, size: usize) -> iterators::ChunksMut<'a> {
iterators::ChunksMut::new(self, size)
}
#[inline]
pub fn split_at(&self, mid: usize) -> (&ByteStr, &ByteStr) {
let (first, second) = self.as_slice().split_at(mid);
(ByteStr::from_slice(first), ByteStr::from_slice(second))
}
#[inline]
pub fn split_at_mut(&mut self, mid: usize) -> (&mut ByteStr, &mut ByteStr) {
let (first, second) = self.as_mut_slice().split_at_mut(mid);
(ByteStr::from_slice_mut(first), ByteStr::from_slice_mut(second))
}
#[inline]
pub fn split<'a, M: IntoMatcher>(&'a self, m: M) -> iterators::Split<'a, M::Matcher>
where <M as IntoMatcher>::Matcher: ForwardSearcher
{
iterators::Split::new(self, m.into_matcher())
}
#[inline]
pub fn split_mut<'a, M: IntoMatcher>(&'a mut self, m: M) -> iterators::SplitMut<'a, M::Matcher>
where <M as IntoMatcher>::Matcher: ForwardSearcher
{
iterators::SplitMut::new(self, m.into_matcher())
}
#[inline]
pub fn rsplit<'a, M: IntoMatcher>(&'a self, m: M) -> iterators::RSplit<'a, M::Matcher>
where <M as IntoMatcher>::Matcher: ReverseSearcher
{
iterators::RSplit::new(self, m.into_matcher())
}
#[inline]
pub fn rsplit_mut<'a, M: IntoMatcher>(&'a mut self, m: M) -> iterators::RSplitMut<'a, M::Matcher>
where <M as IntoMatcher>::Matcher: ReverseSearcher
{
iterators::RSplitMut::new(self, m.into_matcher())
}
#[inline]
pub fn splitn<'a, M: IntoMatcher>(&'a self, n: usize, m: M) -> iterators::SplitN<'a, M::Matcher>
where <M as IntoMatcher>::Matcher: ForwardSearcher
{
iterators::SplitN::new(self, n, m.into_matcher())
}
#[inline]
pub fn splitn_mut<'a, M: IntoMatcher>(&'a mut self, n: usize, m: M) -> iterators::SplitNMut<'a, M::Matcher>
where <M as IntoMatcher>::Matcher: ForwardSearcher
{
iterators::SplitNMut::new(self, n, m.into_matcher())
}
#[inline]
pub fn rsplitn<'a, M: IntoMatcher>(&'a self, n: usize, m: M) -> iterators::RSplitN<'a, M::Matcher>
where <M as IntoMatcher>::Matcher: ReverseSearcher
{
iterators::RSplitN::new(self, n, m.into_matcher())
}
#[inline]
pub fn rsplitn_mut<'a, M: IntoMatcher>(&'a mut self, n: usize, m: M) -> iterators::RSplitNMut<'a, M::Matcher>
where <M as IntoMatcher>::Matcher: ReverseSearcher
{
iterators::RSplitNMut::new(self, n, m.into_matcher())
}
#[inline]
pub fn matches<'a, M: IntoMatcher>(&'a self, m: M) -> iterators::Matches<'a, M::Matcher>
where <M as IntoMatcher>::Matcher: ForwardSearcher
{
iterators::Matches::new(self, m.into_matcher())
}
#[inline]
pub fn matches_mut<'a, M: IntoMatcher>(&'a mut self, m: M) -> iterators::MatchesMut<'a, M::Matcher>
where <M as IntoMatcher>::Matcher: ForwardSearcher
{
iterators::MatchesMut::new(self, m.into_matcher())
}
#[inline]
pub fn rmatches<'a, M: IntoMatcher>(&'a self, m: M) -> iterators::RMatches<'a, M::Matcher>
where <M as IntoMatcher>::Matcher: ReverseSearcher
{
iterators::RMatches::new(self, m.into_matcher())
}
#[inline]
pub fn rmatches_mut<'a, M: IntoMatcher>(&'a mut self, m: M) -> iterators::RMatchesMut<'a, M::Matcher>
where <M as IntoMatcher>::Matcher: ReverseSearcher
{
iterators::RMatchesMut::new(self, m.into_matcher())
}
#[inline]
pub fn match_indices<'a, M: IntoMatcher>(&'a self, m: M) -> iterators::MatchIndices<'a, M::Matcher>
where <M as IntoMatcher>::Matcher: ForwardSearcher
{
iterators::MatchIndices::new(self, m.into_matcher())
}
#[inline]
pub fn match_indices_mut<'a, M: IntoMatcher>(&'a mut self, m: M) -> iterators::MatchIndicesMut<'a, M::Matcher>
where <M as IntoMatcher>::Matcher: ForwardSearcher
{
iterators::MatchIndicesMut::new(self, m.into_matcher())
}
#[inline]
pub fn rmatch_indices<'a, M: IntoMatcher>(&'a self, m: M) -> iterators::RMatchIndices<'a, M::Matcher>
where <M as IntoMatcher>::Matcher: ReverseSearcher
{
iterators::RMatchIndices::new(self, m.into_matcher())
}
#[inline]
pub fn rmatch_indices_mut<'a, M: IntoMatcher>(&'a mut self, m: M) -> iterators::RMatchIndicesMut<'a, M::Matcher>
where <M as IntoMatcher>::Matcher: ReverseSearcher
{
iterators::RMatchIndicesMut::new(self, m.into_matcher())
}
#[inline]
pub fn contains<M: IntoMatcher>(&self, m: M) -> bool
where <M as IntoMatcher>::Matcher: ForwardSearcher
{
m.into_matcher().find(self).is_some()
}
#[inline]
pub fn starts_with<M: IntoMatcher>(&self, m: M) -> bool
where <M as IntoMatcher>::Matcher: PrefixMatcher
{
m.into_matcher().is_prefix_of(self)
}
#[inline]
pub fn ends_with<M: IntoMatcher>(&self, m: M) -> bool
where <M as IntoMatcher>::Matcher: SufixMatcher
{
m.into_matcher().is_sufix_of(self)
}
#[inline]
pub fn find<M: IntoMatcher>(&self, m: M) -> Option<usize>
where <M as IntoMatcher>::Matcher: ForwardSearcher
{
m.into_matcher().find(self).map(|(a, _)| a)
}
#[inline]
pub fn rfind<M: IntoMatcher>(&self, m: M) -> Option<usize>
where <M as IntoMatcher>::Matcher: ReverseSearcher
{
m.into_matcher().rfind(self).map(|(_, b)| b)
}
#[inline]
pub fn swap(&mut self, a: usize, b: usize) {
self.as_mut_slice().swap(a, b);
}
#[inline]
pub fn reverse(&mut self) {
self.as_mut_slice().reverse();
}
#[inline]
pub fn copy_from_slice(&mut self, src: &[u8]) {
self.as_mut_slice().copy_from_slice(src);
}
#[inline]
pub fn copy_from_byte_str(&mut self, src: &ByteStr) {
self.as_mut_slice().copy_from_slice(src.as_slice());
}
}
impl<'a> Default for &'a ByteStr {
#[inline]
fn default() -> Self {
ByteStr::empty()
}
}
impl<'a> Default for &'a mut ByteStr {
#[inline]
fn default() -> Self {
ByteStr::empty_mut()
}
}
impl core::fmt::Debug for ByteStr {
fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
use core::fmt::Write;
fn to_hex(nibble: u8) -> u8 {
if nibble < 10 {
b'0' + nibble
} else {
b'a' + nibble - 10
}
}
f.write_str("b\"")?;
for &byte in self.iter() {
match byte {
b'\t' => f.write_str("\\t")?,
b'\r' => f.write_str("\\r")?,
b'\n' => f.write_str("\\n")?,
b'\\' => f.write_str("\\\\")?,
b'"' => f.write_str("\\\"")?,
0x20 ... 0x7E => f.write_char(byte as char)?,
_ => {
f.write_str("\\x")?;
f.write_char(to_hex(byte >> 4) as char)?;
f.write_char(to_hex(byte & 0xF) as char)?;
}
}
}
f.write_char('"')?;
Ok(())
}
}
#[cfg(not(feature="no_std"))]
impl std::borrow::ToOwned for ByteStr {
type Owned = ByteString;
#[inline]
fn to_owned(&self) -> ByteString {
self.to_byte_string()
}
}
impl core::convert::AsRef<ByteStr> for ByteStr {
#[inline]
fn as_ref(&self) -> &ByteStr {
self
}
}
impl core::convert::AsRef<[u8]> for ByteStr {
#[inline]
fn as_ref(&self) -> &[u8] {
self.as_slice()
}
}
impl core::convert::AsMut<ByteStr> for ByteStr {
#[inline]
fn as_mut(&mut self) -> &mut ByteStr {
self
}
}
impl core::convert::AsMut<[u8]> for ByteStr {
#[inline]
fn as_mut(&mut self) -> &mut [u8] {
self.as_mut_slice()
}
}
impl<'a> core::cmp::PartialEq<ByteStr> for &'a ByteStr {
#[inline]
fn eq(&self, other: &ByteStr) -> bool {
self.as_slice() == other.as_slice()
}
}
impl core::cmp::PartialEq<[u8]> for ByteStr {
#[inline]
fn eq(&self, other: &[u8]) -> bool {
self.as_slice() == other
}
}
impl<'a> core::cmp::PartialEq<[u8]> for &'a ByteStr {
#[inline]
fn eq(&self, other: &[u8]) -> bool {
self.as_slice() == other
}
}
macro_rules! impl_partial_eq_array {
($size:expr) => {
impl core::cmp::PartialEq<[u8; $size]> for ByteStr {
#[inline]
fn eq(&self, other: &[u8; $size]) -> bool {
self.as_slice() == other
}
}
impl<'a> core::cmp::PartialEq<[u8; $size]> for &'a ByteStr {
#[inline]
fn eq(&self, other: &[u8; $size]) -> bool {
self.as_slice() == other
}
}
}
}
impl_partial_eq_array!(0);
impl_partial_eq_array!(1);
impl_partial_eq_array!(2);
impl_partial_eq_array!(3);
impl_partial_eq_array!(4);
impl_partial_eq_array!(5);
impl_partial_eq_array!(6);
impl_partial_eq_array!(7);
impl_partial_eq_array!(8);
impl_partial_eq_array!(9);
impl_partial_eq_array!(10);
impl_partial_eq_array!(11);
impl_partial_eq_array!(12);
impl_partial_eq_array!(13);
impl_partial_eq_array!(14);
impl_partial_eq_array!(15);
impl_partial_eq_array!(16);
impl_partial_eq_array!(17);
impl_partial_eq_array!(18);
impl_partial_eq_array!(19);
impl_partial_eq_array!(20);
impl_partial_eq_array!(21);
impl_partial_eq_array!(22);
impl_partial_eq_array!(23);
impl_partial_eq_array!(24);
impl_partial_eq_array!(25);
impl_partial_eq_array!(26);
impl_partial_eq_array!(27);
impl_partial_eq_array!(28);
impl_partial_eq_array!(29);
impl_partial_eq_array!(30);
impl_partial_eq_array!(31);
impl_partial_eq_array!(32);
#[cfg(not(feature="no_std"))]
impl core::cmp::PartialEq<ByteString> for ByteStr {
#[inline]
fn eq(&self, other: &ByteString) -> bool {
self.as_slice() == other.as_slice()
}
}
#[cfg(not(feature="no_std"))]
impl<'a> core::cmp::PartialEq<ByteString> for &'a ByteStr {
#[inline]
fn eq(&self, other: &ByteString) -> bool {
self.as_slice() == other.as_slice()
}
}
#[cfg(not(feature="no_std"))]
impl<'b> core::cmp::PartialEq<std::borrow::Cow<'b, ByteStr>> for ByteStr {
#[inline]
fn eq(&self, other: &std::borrow::Cow<'b, ByteStr>) -> bool {
self.as_slice() == other.as_slice()
}
}
#[cfg(not(feature="no_std"))]
impl<'a, 'b> core::cmp::PartialEq<std::borrow::Cow<'b, ByteStr>> for &'a ByteStr {
#[inline]
fn eq(&self, other: &std::borrow::Cow<'b, ByteStr>) -> bool {
self.as_slice() == other.as_slice()
}
}
impl<'a, T: ?Sized> core::cmp::PartialEq<&'a T> for ByteStr
where ByteStr: core::cmp::PartialEq<T>
{
#[inline]
fn eq(&self, other: &&'a T) -> bool {
self == *other
}
}
impl core::ops::Index<usize> for ByteStr {
type Output = u8;
#[inline]
fn index(&self, index: usize) -> &u8 {
&self.as_slice()[index]
}
}
impl core::ops::Index<core::ops::Range<usize>> for ByteStr {
type Output = ByteStr;
#[inline]
fn index(&self, index: core::ops::Range<usize>) -> &ByteStr {
ByteStr::from_slice(&self.as_slice()[index])
}
}
impl core::ops::Index<core::ops::RangeFrom<usize>> for ByteStr {
type Output = ByteStr;
#[inline]
fn index(&self, index: core::ops::RangeFrom<usize>) -> &ByteStr {
ByteStr::from_slice(&self.as_slice()[index])
}
}
impl core::ops::Index<core::ops::RangeTo<usize>> for ByteStr {
type Output = ByteStr;
#[inline]
fn index(&self, index: core::ops::RangeTo<usize>) -> &ByteStr {
ByteStr::from_slice(&self.as_slice()[index])
}
}
impl core::ops::Index<core::ops::RangeFull> for ByteStr {
type Output = ByteStr;
#[inline]
fn index(&self, index: core::ops::RangeFull) -> &ByteStr {
ByteStr::from_slice(&self.as_slice()[index])
}
}
impl core::ops::IndexMut<usize> for ByteStr {
#[inline]
fn index_mut(&mut self, index: usize) -> &mut u8 {
&mut self.as_mut_slice()[index]
}
}
impl core::ops::IndexMut<core::ops::Range<usize>> for ByteStr {
#[inline]
fn index_mut(&mut self, index: core::ops::Range<usize>) -> &mut ByteStr {
ByteStr::from_slice_mut(&mut self.as_mut_slice()[index])
}
}
impl core::ops::IndexMut<core::ops::RangeFrom<usize>> for ByteStr {
#[inline]
fn index_mut(&mut self, index: core::ops::RangeFrom<usize>) -> &mut ByteStr {
ByteStr::from_slice_mut(&mut self.as_mut_slice()[index])
}
}
impl core::ops::IndexMut<core::ops::RangeTo<usize>> for ByteStr {
#[inline]
fn index_mut(&mut self, index: core::ops::RangeTo<usize>) -> &mut ByteStr {
ByteStr::from_slice_mut(&mut self.as_mut_slice()[index])
}
}
impl core::ops::IndexMut<core::ops::RangeFull> for ByteStr {
#[inline]
fn index_mut(&mut self, index: core::ops::RangeFull) -> &mut ByteStr {
ByteStr::from_slice_mut(&mut self.as_mut_slice()[index])
}
}
impl<'a> core::iter::IntoIterator for &'a ByteStr {
type Item = &'a u8;
type IntoIter = core::slice::Iter<'a, u8>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a> core::iter::IntoIterator for &'a mut ByteStr {
type Item = &'a mut u8;
type IntoIter = core::slice::IterMut<'a, u8>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}