use std::str;
pub unsafe trait Str<'de>: 'de + Sized {
fn len(&self) -> usize;
fn as_bytes(&self) -> &[u8];
fn is_empty(&self) -> bool {
self.len() == 0
}
unsafe fn get_u8_char(&self, i: usize) -> Option<u8>;
unsafe fn clone_slice(&self, i: usize, j: usize) -> Option<Self>;
unsafe fn find(&self, i: usize, char: u8) -> Option<usize>;
unsafe fn range_from(&self, i: usize) -> Self;
unsafe fn range(&self, i: usize, j: usize) -> Self;
}
unsafe impl<'de> Str<'de> for &'de str {
fn len(&self) -> usize {
str::len(*self)
}
fn as_bytes(&self) -> &[u8] {
str::as_bytes(*self)
}
unsafe fn get_u8_char(&self, i: usize) -> Option<u8> {
debug_assert!(i < self.len());
debug_assert!(self.is_char_boundary(i));
if self.is_char_boundary(i + 1) {
Some(*self.as_bytes().get_unchecked(i))
} else {
None
}
}
unsafe fn clone_slice(&self, i: usize, j: usize) -> Option<Self> {
debug_assert!(i < self.len());
debug_assert!(self.is_char_boundary(i));
if self.is_char_boundary(j) {
let bytes = str::as_bytes(*self).get_unchecked(i..j);
Some(str::from_utf8_unchecked(bytes)) } else {
None
}
}
unsafe fn find(&self, i: usize, char: u8) -> Option<usize> {
self.as_bytes().find(i, char)
}
unsafe fn range_from(&self, i: usize) -> Self {
debug_assert!(i <= self.len());
debug_assert!(self.is_char_boundary(i));
self.get_unchecked(i..)
}
unsafe fn range(&self, i: usize, j: usize) -> Self {
debug_assert!(i <= j);
debug_assert!(j <= self.len());
debug_assert!(self.is_char_boundary(i));
debug_assert!(self.is_char_boundary(j));
self.get_unchecked(i..j)
}
}
unsafe impl<'de> Str<'de> for String {
fn len(&self) -> usize {
str::len(self.as_str())
}
fn as_bytes(&self) -> &[u8] {
str::as_bytes(self.as_str())
}
unsafe fn get_u8_char(&self, i: usize) -> Option<u8> {
self.as_str().get_u8_char(i)
}
unsafe fn clone_slice(&self, i: usize, j: usize) -> Option<Self> {
self.as_str().clone_slice(i, j).map(|s| s.to_string())
}
unsafe fn find(&self, i: usize, char: u8) -> Option<usize> {
self.as_bytes().find(i, char)
}
unsafe fn range_from(&self, i: usize) -> Self {
self.as_str().range_from(i).to_string()
}
unsafe fn range(&self, i: usize, j: usize) -> Self {
self.as_str().range(i, j).to_string()
}
}
unsafe impl<'de> Str<'de> for &'de [u8] {
fn len(&self) -> usize {
<[u8]>::len(*self)
}
fn as_bytes(&self) -> &[u8] {
*self
}
unsafe fn get_u8_char(&self, i: usize) -> Option<u8> {
debug_assert!(i < self.len());
Some(*self.get_unchecked(i))
}
unsafe fn clone_slice(&self, i: usize, j: usize) -> Option<Self> {
debug_assert!(i < self.len());
Some(self.get_unchecked(i..j))
}
unsafe fn find(&self, i: usize, char: u8) -> Option<usize> {
debug_assert!(i < self.len());
let slice = self.get_unchecked((i + 1)..);
let index = slice.iter().position(|&other| char == other);
index.map(|index| i + 1 + index)
}
unsafe fn range_from(&self, i: usize) -> Self {
self.get_unchecked(i..)
}
unsafe fn range(&self, i: usize, j: usize) -> Self {
self.get_unchecked(i..j)
}
}
unsafe impl<'de> Str<'de> for Vec<u8> {
fn len(&self) -> usize {
<[u8]>::len(self.as_slice())
}
fn as_bytes(&self) -> &[u8] {
self.as_slice()
}
unsafe fn get_u8_char(&self, i: usize) -> Option<u8> {
self.as_slice().get_u8_char(i)
}
unsafe fn clone_slice(&self, i: usize, j: usize) -> Option<Self> {
self.as_slice().clone_slice(i, j).map(|s| s.to_vec())
}
unsafe fn find(&self, i: usize, char: u8) -> Option<usize> {
self.as_slice().find(i, char)
}
unsafe fn range_from(&self, i: usize) -> Self {
self.get_unchecked(i..).to_vec()
}
unsafe fn range(&self, i: usize, j: usize) -> Self {
self.get_unchecked(i..j).to_vec()
}
}