#![no_std]
use containers::collections::Vec;
use core::{borrow::{Borrow, BorrowMut}, convert::TryFrom, ops::{Deref, DerefMut}, str::{self, Utf8Error}};
#[repr(transparent)]
#[derive(Debug, PartialEq, Eq, Hash)]
pub struct String(Vec<u8>);
impl String {
#[inline]
pub fn new() -> Self { Self(Vec::new()) }
#[inline]
pub fn from_str(s: &str) -> Option<Self> {
Vec::from_slice(s.as_bytes()).map(|x| unsafe { Self::from_vec_unchecked(x) })
}
#[inline(always)]
pub unsafe fn from_vec_unchecked(x: Vec<u8>) -> Self { Self(x) }
}
impl From<String> for Vec<u8> {
#[inline(always)]
fn from(x: String) -> Self { x.0 }
}
impl TryFrom<Vec<u8>> for String {
type Error = FromUtf8Error;
#[inline]
fn try_from(bs: Vec<u8>) -> Result<Self, FromUtf8Error> {
match str::from_utf8(&bs) {
Ok(_) => Ok(String(bs)),
Err(e) => Err(FromUtf8Error { bytes: bs, error: e })
}
}
}
#[derive(Debug, PartialEq, Eq)]
pub struct FromUtf8Error {
bytes: Vec<u8>,
error: Utf8Error,
}
impl FromUtf8Error {
#[inline]
pub fn into_bytes(self) -> Vec<u8> { self.bytes }
#[inline]
pub fn utf8_error(&self) -> Utf8Error { self.error }
}
impl Deref for String {
type Target = str;
#[inline]
fn deref(&self) -> &str { unsafe { core::str::from_utf8_unchecked(&self.0) } }
}
impl DerefMut for String {
#[inline]
fn deref_mut(&mut self) -> &mut str { unsafe { core::str::from_utf8_unchecked_mut(&mut self.0) } }
}
impl Borrow<str> for String {
#[inline]
fn borrow(&self) -> &str { self.deref() }
}
impl BorrowMut<str> for String {
fn borrow_mut(&mut self) -> &mut str { self.deref_mut() }
}
impl core::fmt::Display for String {
#[inline]
fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { self.deref().fmt(fmt) }
}
#[macro_export]
macro_rules! format {
($($x:tt)*) => ({
let s = $crate::String::new();
core::fmt::write(&mut s, format_args!($($x)*)).ok().map(|()| s)
});
}