use std::{
borrow::{Borrow, BorrowMut, Cow},
cmp::Ordering,
convert::Infallible,
ffi::OsStr,
fmt::{self, Debug, Display},
hash::{Hash, Hasher},
net::{SocketAddr, ToSocketAddrs},
ops::{Add, AddAssign, Deref, DerefMut, Index, IndexMut},
path::Path,
slice::SliceIndex,
str::{FromStr, Utf8Error},
};
use bytes::{Bytes, BytesMut};
#[derive(Clone, Default, PartialEq, Eq)]
pub struct BytesString {
pub(crate) bytes: BytesMut,
}
impl BytesString {
pub fn new() -> Self {
Self {
bytes: BytesMut::new(),
}
}
pub fn with_capacity(capacity: usize) -> Self {
Self {
bytes: BytesMut::with_capacity(capacity),
}
}
pub fn len(&self) -> usize {
self.bytes.len()
}
pub fn capacity(&self) -> usize {
self.bytes.capacity()
}
pub fn reserve(&mut self, additional: usize) {
self.bytes.reserve(additional);
}
pub fn split_off(&mut self, at: usize) -> Self {
Self {
bytes: self.bytes.split_off(at),
}
}
pub fn as_bytes(&self) -> &[u8] {
self.bytes.as_ref()
}
pub fn is_empty(&self) -> bool {
self.bytes.is_empty()
}
pub fn truncate(&mut self, new_len: usize) {
if new_len <= self.len() {
assert!(self.is_char_boundary(new_len));
self.bytes.truncate(new_len);
}
}
pub fn clear(&mut self) {
self.bytes.clear();
}
pub fn push(&mut self, ch: char) {
let mut buf = [0; 4];
let bytes = ch.encode_utf8(&mut buf);
self.bytes.extend_from_slice(bytes.as_bytes());
}
pub fn push_str(&mut self, s: &str) {
self.bytes.extend_from_slice(s.as_bytes());
}
pub fn as_str(&self) -> &str {
unsafe { std::str::from_utf8_unchecked(&self.bytes) }
}
pub fn as_mut_str(&mut self) -> &mut str {
unsafe { std::str::from_utf8_unchecked_mut(&mut self.bytes) }
}
pub fn into_bytes(self) -> BytesMut {
self.bytes
}
pub unsafe fn from_bytes_unchecked(bytes: BytesMut) -> Self {
Self { bytes }
}
pub fn from_utf8(bytes: BytesMut) -> Result<Self, Utf8Error> {
std::str::from_utf8(bytes.as_ref())?;
Ok(Self { bytes })
}
pub fn from_utf8_slice(bytes: &[u8]) -> Result<Self, Utf8Error> {
std::str::from_utf8(bytes)?;
Ok(Self {
bytes: BytesMut::from(bytes),
})
}
}
impl Deref for BytesString {
type Target = str;
fn deref(&self) -> &Self::Target {
self.as_str()
}
}
impl DerefMut for BytesString {
fn deref_mut(&mut self) -> &mut Self::Target {
self.as_mut_str()
}
}
impl AsRef<str> for BytesString {
fn as_ref(&self) -> &str {
self.as_str()
}
}
impl Borrow<str> for BytesString {
fn borrow(&self) -> &str {
self.as_str()
}
}
impl From<String> for BytesString {
fn from(s: String) -> Self {
Self {
bytes: Bytes::from(s.into_bytes()).into(),
}
}
}
impl From<&str> for BytesString {
fn from(s: &str) -> Self {
Self {
bytes: BytesMut::from(s),
}
}
}
impl From<BytesString> for BytesMut {
fn from(s: BytesString) -> Self {
s.bytes
}
}
impl From<BytesString> for Bytes {
fn from(s: BytesString) -> Self {
s.bytes.into()
}
}
impl From<char> for BytesString {
fn from(ch: char) -> Self {
let mut bytes = BytesString::with_capacity(ch.len_utf8());
bytes.push(ch);
bytes
}
}
impl PartialEq<str> for BytesString {
fn eq(&self, other: &str) -> bool {
self.as_str() == other
}
}
impl PartialEq<&'_ str> for BytesString {
fn eq(&self, other: &&str) -> bool {
self.as_str() == *other
}
}
impl PartialEq<Cow<'_, str>> for BytesString {
fn eq(&self, other: &Cow<'_, str>) -> bool {
self.as_str() == *other
}
}
impl PartialEq<BytesString> for str {
fn eq(&self, other: &BytesString) -> bool {
self == other.as_str()
}
}
impl PartialEq<BytesString> for &'_ str {
fn eq(&self, other: &BytesString) -> bool {
*self == other.as_str()
}
}
impl PartialEq<BytesString> for Bytes {
fn eq(&self, other: &BytesString) -> bool {
self == other.as_bytes()
}
}
impl PartialEq<String> for BytesString {
fn eq(&self, other: &String) -> bool {
self.as_str() == other
}
}
impl PartialEq<BytesString> for String {
fn eq(&self, other: &BytesString) -> bool {
self == other.as_str()
}
}
impl Add<&str> for BytesString {
type Output = Self;
fn add(mut self, other: &str) -> Self::Output {
self += other;
self
}
}
impl AddAssign<&str> for BytesString {
fn add_assign(&mut self, other: &str) {
self.push_str(other);
}
}
impl Add<BytesString> for BytesString {
type Output = Self;
fn add(mut self, other: BytesString) -> Self::Output {
self += other;
self
}
}
impl AddAssign<BytesString> for BytesString {
fn add_assign(&mut self, other: BytesString) {
self.bytes.extend(other.bytes);
}
}
impl AsMut<str> for BytesString {
fn as_mut(&mut self) -> &mut str {
self.as_mut_str()
}
}
impl AsRef<[u8]> for BytesString {
fn as_ref(&self) -> &[u8] {
self.as_bytes()
}
}
impl AsRef<OsStr> for BytesString {
fn as_ref(&self) -> &OsStr {
OsStr::new(self.as_str())
}
}
impl AsRef<Path> for BytesString {
fn as_ref(&self) -> &Path {
Path::new(self.as_str())
}
}
impl BorrowMut<str> for BytesString {
fn borrow_mut(&mut self) -> &mut str {
self.as_mut_str()
}
}
impl Debug for BytesString {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Debug::fmt(self.as_str(), f)
}
}
impl Display for BytesString {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Display::fmt(self.as_str(), f)
}
}
impl PartialOrd for BytesString {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for BytesString {
fn cmp(&self, other: &Self) -> Ordering {
self.as_str().cmp(other.as_str())
}
}
impl<'a> Extend<&'a char> for BytesString {
fn extend<T: IntoIterator<Item = &'a char>>(&mut self, iter: T) {
self.extend(iter.into_iter().copied());
}
}
impl Extend<char> for BytesString {
fn extend<T: IntoIterator<Item = char>>(&mut self, iter: T) {
let mut buf = [0; 4];
for ch in iter {
let bytes = ch.encode_utf8(&mut buf);
self.bytes.extend_from_slice(bytes.as_bytes());
}
}
}
impl<'a> Extend<&'a str> for BytesString {
fn extend<T: IntoIterator<Item = &'a str>>(&mut self, iter: T) {
for s in iter {
self.push_str(s);
}
}
}
impl Extend<Box<str>> for BytesString {
fn extend<T: IntoIterator<Item = Box<str>>>(&mut self, iter: T) {
for s in iter {
self.push_str(&s);
}
}
}
impl<'a> Extend<Cow<'a, str>> for BytesString {
fn extend<T: IntoIterator<Item = Cow<'a, str>>>(&mut self, iter: T) {
for s in iter {
self.push_str(&s);
}
}
}
impl Extend<String> for BytesString {
fn extend<T: IntoIterator<Item = String>>(&mut self, iter: T) {
for s in iter {
self.push_str(&s);
}
}
}
impl<'a> Extend<&'a String> for BytesString {
fn extend<T: IntoIterator<Item = &'a String>>(&mut self, iter: T) {
for s in iter {
self.push_str(s);
}
}
}
impl Extend<BytesString> for BytesString {
fn extend<T: IntoIterator<Item = BytesString>>(&mut self, iter: T) {
for s in iter {
self.bytes.extend(s.bytes);
}
}
}
impl FromIterator<char> for BytesString {
fn from_iter<T: IntoIterator<Item = char>>(iter: T) -> Self {
let mut bytes = BytesString::new();
bytes.extend(iter);
bytes
}
}
impl<'a> FromIterator<&'a str> for BytesString {
fn from_iter<T: IntoIterator<Item = &'a str>>(iter: T) -> Self {
let mut bytes = BytesString::new();
bytes.extend(iter);
bytes
}
}
impl FromIterator<Box<str>> for BytesString {
fn from_iter<T: IntoIterator<Item = Box<str>>>(iter: T) -> Self {
let mut bytes = BytesString::new();
bytes.extend(iter);
bytes
}
}
impl<'a> FromIterator<Cow<'a, str>> for BytesString {
fn from_iter<T: IntoIterator<Item = Cow<'a, str>>>(iter: T) -> Self {
let mut bytes = BytesString::new();
bytes.extend(iter);
bytes
}
}
impl FromIterator<String> for BytesString {
fn from_iter<T: IntoIterator<Item = String>>(iter: T) -> Self {
let mut bytes = BytesString::new();
bytes.extend(iter);
bytes
}
}
impl FromIterator<BytesString> for BytesString {
fn from_iter<T: IntoIterator<Item = BytesString>>(iter: T) -> Self {
let mut bytes = BytesString::new();
bytes.extend(iter);
bytes
}
}
impl FromStr for BytesString {
type Err = Infallible;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self {
bytes: BytesMut::from(s),
})
}
}
impl<I> Index<I> for BytesString
where
I: SliceIndex<str>,
{
type Output = I::Output;
fn index(&self, index: I) -> &Self::Output {
self.as_str().index(index)
}
}
impl<I> IndexMut<I> for BytesString
where
I: SliceIndex<str>,
{
fn index_mut(&mut self, index: I) -> &mut Self::Output {
self.as_mut_str().index_mut(index)
}
}
impl ToSocketAddrs for BytesString {
type Iter = std::vec::IntoIter<SocketAddr>;
fn to_socket_addrs(&self) -> Result<Self::Iter, std::io::Error> {
self.as_str().to_socket_addrs()
}
}
impl Hash for BytesString {
fn hash<H: Hasher>(&self, state: &mut H) {
self.as_str().hash(state);
}
}
#[cfg(feature = "serde")]
mod serde_impl {
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use super::*;
impl<'de> Deserialize<'de> for BytesString {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
Ok(Self::from(s))
}
}
impl Serialize for BytesString {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(self.as_str())
}
}
}