use std::fmt;
use std::ops::{Add, Deref};
use std::sync::Arc;
use std::path::Path;
use std::str::FromStr;
use std::string::ParseError;
#[derive(Clone, Eq, PartialOrd, Ord, Hash)]
pub struct ImmutString(Arc<String>);
impl ImmutString {
#[inline]
pub fn new(string: String) -> Self {
ImmutString(Arc::new(string))
}
#[inline]
pub fn new_empty() -> Self {
Self::new(String::new())
}
#[inline]
pub fn push(&self, ch: char) -> Self {
let mut string = self.0.deref().clone();
string.push(ch);
string.into()
}
#[inline]
pub fn push_str(&self, s: &str) -> Self {
let mut string = self.0.deref().clone();
string.push_str(s);
string.into()
}
#[inline]
pub fn append(&self, s: &ImmutString) -> Self {
let mut string = self.0.deref().clone();
unsafe {
string.as_mut_vec().extend(s.as_bytes());
}
string.into()
}
#[inline]
pub fn append_string(&self, s: String) -> Self {
let mut string = self.0.deref().clone();
unsafe {
string.as_mut_vec().extend(s.into_bytes());
}
string.into()
}
#[inline]
pub fn as_string(&self) -> &String {
self.0.deref()
}
#[inline]
pub fn into_string(&self) -> String {
self.as_string().clone()
}
#[inline]
pub fn into_bytes(&self) -> Vec<u8> {
self.as_string().as_bytes().to_vec()
}
}
impl fmt::Debug for ImmutString {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Debug::fmt(&self.0, f)
}
}
impl fmt::Display for ImmutString {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&self.0, f)
}
}
impl Add<ImmutString> for ImmutString {
type Output = ImmutString;
#[inline(always)]
fn add(self, rhs: ImmutString) -> Self::Output {
Add::add(&self, &rhs)
}
}
impl<'a> Add<&'a ImmutString> for &'a ImmutString {
type Output = ImmutString;
#[inline]
fn add(self, rhs: &'a ImmutString) -> Self::Output {
self.push_str(rhs.deref())
}
}
impl<'a> Add<ImmutString> for &'a ImmutString {
type Output = ImmutString;
#[inline]
fn add(self, rhs: ImmutString) -> Self::Output {
Add::add(self, &rhs)
}
}
impl<'a> Add<&'a ImmutString> for ImmutString {
type Output = ImmutString;
#[inline]
fn add(self, rhs: &'a ImmutString) -> Self::Output {
Add::add(&self, rhs)
}
}
impl Add<char> for ImmutString {
type Output = ImmutString;
#[inline(always)]
fn add(self, rhs: char) -> Self::Output {
Add::add(&self, rhs)
}
}
impl<'a> Add<char> for &'a ImmutString {
type Output = ImmutString;
#[inline]
fn add(self, rhs: char) -> Self::Output {
self.push(rhs)
}
}
impl<'a> Add<&'a str> for ImmutString {
type Output = ImmutString;
#[inline(always)]
fn add(self, rhs: &'a str) -> Self::Output {
Add::add(&self, rhs)
}
}
impl<'a> Add<&'a str> for &'a ImmutString {
type Output = ImmutString;
#[inline]
fn add(self, rhs: &'a str) -> Self::Output {
self.push_str(rhs)
}
}
impl Add<String> for ImmutString {
type Output = ImmutString;
#[inline(always)]
fn add(self, rhs: String) -> Self::Output {
Add::add(&self, rhs)
}
}
impl<'a> Add<String> for &'a ImmutString {
type Output = ImmutString;
#[inline]
fn add(self, rhs: String) -> Self::Output {
self.append_string(rhs)
}
}
impl AsRef<Path> for ImmutString {
fn as_ref(&self) -> &Path {
Path::new(self.deref())
}
}
impl AsRef<str> for ImmutString {
#[inline]
fn as_ref(&self) -> &str {
self.deref()
}
}
impl AsRef<[u8]> for ImmutString {
#[inline]
fn as_ref(&self) -> &[u8] {
self.as_bytes()
}
}
impl<'a> From<&'a str> for ImmutString {
#[inline]
fn from(value: &'a str) -> Self {
ImmutString::new(value.into())
}
}
impl From<String> for ImmutString {
#[inline]
fn from(value: String) -> Self {
ImmutString::new(value)
}
}
impl FromStr for ImmutString {
type Err = ParseError;
#[inline]
fn from_str(s: &str) -> Result<ImmutString, ParseError> {
Ok(ImmutString::from(s))
}
}
impl PartialEq<str> for ImmutString {
#[inline]
fn eq(&self, other: &str) -> bool {
self.0.deref() == other
}
}
impl<'a> PartialEq<&'a str> for ImmutString {
#[inline]
fn eq(&self, other: &&'a str) -> bool {
self.0.deref() == other
}
}
impl PartialEq<String> for ImmutString {
#[inline]
fn eq(&self, other: &String) -> bool {
self.0.deref() == other
}
}
impl PartialEq<ImmutString> for ImmutString {
#[inline]
fn eq(&self, other: &ImmutString) -> bool {
self.0.deref() == other.deref()
}
}
impl Deref for ImmutString {
type Target = String;
#[inline]
fn deref(&self) -> &Self::Target {
self.0.deref()
}
}