use alloc::borrow::{Cow, ToOwned};
use alloc::string::String;
use core::cmp::Ordering;
use core::fmt::Formatter;
use core::hash::Hasher;
use core::ops::Deref;
#[derive(Clone)]
pub enum CowStr<'a> {
Borrowed(&'a str),
Static(&'static str),
Owned(String),
}
impl<'a> CowStr<'a> {
#[must_use]
pub fn as_borrowed<'b>(&'b self) -> CowStr<'b>
where
'a: 'b,
{
match self {
CowStr::Borrowed(s) => CowStr::Borrowed(s),
CowStr::Static(s) => CowStr::Static(s),
CowStr::Owned(s) => CowStr::Borrowed(s),
}
}
#[must_use]
pub fn into_owned_cowstr(self) -> CowStr<'static> {
match self {
CowStr::Borrowed(s) => CowStr::Owned(s.to_owned()),
CowStr::Static(s) => CowStr::Static(s),
CowStr::Owned(s) => CowStr::Owned(s),
}
}
#[must_use]
pub fn as_owned_cowstr(&self) -> CowStr<'static> {
match self {
CowStr::Borrowed(s) => CowStr::Owned((*s).to_owned()),
CowStr::Static(s) => CowStr::Static(s),
CowStr::Owned(s) => CowStr::Owned(s.clone()),
}
}
#[must_use]
pub fn into_string(self) -> String {
match self {
CowStr::Borrowed(s) | CowStr::Static(s) => s.to_owned(),
CowStr::Owned(s) => s,
}
}
}
impl<'a> core::fmt::Debug for CowStr<'a> {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
self.deref().fmt(f)
}
}
impl<'a> Deref for CowStr<'a> {
type Target = str;
fn deref(&self) -> &Self::Target {
match self {
CowStr::Borrowed(s) | CowStr::Static(s) => s,
CowStr::Owned(s) => s.as_str(),
}
}
}
impl From<&'static str> for CowStr<'static> {
fn from(value: &'static str) -> Self {
CowStr::Static(value)
}
}
impl From<String> for CowStr<'static> {
fn from(value: String) -> Self {
CowStr::Owned(value)
}
}
impl<'a> From<Cow<'a, str>> for CowStr<'a> {
fn from(value: Cow<'a, str>) -> Self {
match value {
Cow::Borrowed(s) => CowStr::Borrowed(s),
Cow::Owned(s) => CowStr::Owned(s),
}
}
}
impl<'a> From<CowStr<'a>> for Cow<'a, str> {
fn from(value: CowStr<'a>) -> Self {
match value {
CowStr::Borrowed(s) | CowStr::Static(s) => Cow::Borrowed(s),
CowStr::Owned(s) => Cow::Owned(s),
}
}
}
impl<'a, 'b> PartialEq<CowStr<'b>> for CowStr<'a> {
fn eq(&self, other: &CowStr<'b>) -> bool {
str::eq(&**self, &**other)
}
}
impl<'a> PartialEq<str> for CowStr<'a> {
fn eq(&self, other: &str) -> bool {
str::eq(&**self, other)
}
}
impl<'a, 'b> PartialEq<&'b str> for CowStr<'a> {
fn eq(&self, other: &&'b str) -> bool {
str::eq(&**self, *other)
}
}
impl<'a> PartialEq<CowStr<'a>> for str {
fn eq(&self, other: &CowStr<'a>) -> bool {
str::eq(self, &**other)
}
}
impl<'a> PartialEq<CowStr<'a>> for &str {
fn eq(&self, other: &CowStr<'a>) -> bool {
str::eq(self, &**other)
}
}
impl<'a> Eq for CowStr<'a> {}
impl<'a, 'b> PartialOrd<CowStr<'b>> for CowStr<'a> {
fn partial_cmp(&self, other: &CowStr<'b>) -> Option<Ordering> {
str::partial_cmp(&**self, &**other)
}
}
impl<'a> Ord for CowStr<'a> {
fn cmp(&self, other: &Self) -> Ordering {
str::cmp(&**self, &**other)
}
}
impl<'a> core::hash::Hash for CowStr<'a> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.deref().hash(state);
}
}
impl<'a> core::fmt::Display for CowStr<'a> {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
self.deref().fmt(f)
}
}
impl<'a> core::borrow::Borrow<str> for CowStr<'a> {
fn borrow(&self) -> &str {
self
}
}
impl<'a> core::borrow::Borrow<str> for &CowStr<'a> {
fn borrow(&self) -> &str {
self
}
}