use core::{
convert::Infallible,
fmt::Display,
hash::Hash,
mem::take,
ops::{Add, AddAssign, Deref, Index},
slice::SliceIndex,
str::FromStr,
};
use alloc::string::{String, ToString};
use crate::Str;
impl Hash for Str {
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
self.deref().hash(state);
}
}
impl PartialEq for Str {
fn eq(&self, other: &Self) -> bool {
self.deref().eq(&**other)
}
}
impl PartialEq<&str> for Str {
fn eq(&self, other: &&str) -> bool {
self.deref().eq(*other)
}
}
impl PartialEq<str> for Str {
fn eq(&self, other: &str) -> bool {
self.deref().eq(other)
}
}
impl PartialEq<String> for Str {
fn eq(&self, other: &String) -> bool {
self.deref().eq(other)
}
}
impl PartialEq<Str> for &str {
fn eq(&self, other: &Str) -> bool {
(*self).eq(&**other)
}
}
impl PartialEq<Str> for str {
fn eq(&self, other: &Str) -> bool {
self.eq(&**other)
}
}
impl PartialEq<Str> for String {
fn eq(&self, other: &Str) -> bool {
self.eq(&**other)
}
}
impl<I: SliceIndex<str>> Index<I> for Str {
type Output = <I as SliceIndex<str>>::Output;
fn index(&self, index: I) -> &Self::Output {
self.deref().index(index)
}
}
impl FromStr for Str {
type Err = Infallible;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self::from(s.to_string()))
}
}
impl<S: AsRef<str>> FromIterator<S> for Str {
fn from_iter<T: IntoIterator<Item = S>>(iter: T) -> Self {
iter.into_iter()
.fold(Self::new(), |state, s| state + s.as_ref())
}
}
impl Eq for Str {}
impl PartialOrd for Str {
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Str {
fn cmp(&self, other: &Self) -> core::cmp::Ordering {
self.deref().cmp(&**other)
}
}
impl Display for Str {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
self.deref().fmt(f)
}
}
impl<'a> Extend<&'a str> for Str {
fn extend<T: IntoIterator<Item = &'a str>>(&mut self, iter: T) {
self.handle(move |string| {
string.extend(iter);
});
}
}
impl Extend<String> for Str {
fn extend<T: IntoIterator<Item = String>>(&mut self, iter: T) {
self.handle(move |string| {
string.extend(iter);
});
}
}
impl Extend<Self> for Str {
fn extend<T: IntoIterator<Item = Self>>(&mut self, iter: T) {
self.handle(move |string| {
for s in iter {
string.push_str(&s);
}
});
}
}
impl<T> Add<T> for &Str
where
T: AsRef<str>,
{
type Output = Str;
fn add(self, rhs: T) -> Self::Output {
self.clone().add(rhs)
}
}
impl<T> Add<T> for Str
where
T: AsRef<str>,
{
type Output = Self;
fn add(self, rhs: T) -> Self::Output {
let rhs = rhs.as_ref();
(self.into_string() + rhs).into()
}
}
impl<T> AddAssign<T> for Str
where
T: AsRef<str>,
{
fn add_assign(&mut self, rhs: T) {
let rhs = rhs.as_ref();
let string = take(self).into_string();
*self = (string + rhs).into();
}
}
#[cfg(feature = "serde")]
mod serde {
use core::ops::Deref;
use super::Str;
use alloc::string::{String, ToString};
use serde::{Deserialize, Deserializer, Serialize, de::Visitor};
struct StrVisitor;
impl Serialize for Str {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
self.deref().serialize(serializer)
}
}
impl Visitor<'_> for StrVisitor {
type Value = Str;
fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
formatter.write_str("a string")
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> {
Ok(v.to_string().into())
}
fn visit_string<E>(self, v: String) -> Result<Self::Value, E> {
Ok(v.into())
}
}
impl<'de> Deserialize<'de> for Str {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_string(StrVisitor)
}
}
}