use std::borrow::Borrow;
use std::fmt::{self, Debug, Display, Formatter};
use std::hash::{Hash, Hasher};
use std::ops::Deref;
use std::sync::Arc;
#[derive(Clone, Eq)]
pub enum UStr {
Static(&'static str),
Shared(Arc<str>),
}
impl UStr {
pub fn new(s: &str) -> Self {
UStr::Shared(Arc::from(s.to_owned()))
}
}
impl Deref for UStr {
type Target = str;
#[inline]
fn deref(&self) -> &str {
match self {
UStr::Static(s) => s,
UStr::Shared(s) => s,
}
}
}
impl Hash for UStr {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
(&**self).hash(state);
}
}
impl Borrow<str> for UStr {
#[inline]
fn borrow(&self) -> &str {
&**self
}
}
impl PartialEq<UStr> for UStr {
fn eq(&self, other: &UStr) -> bool {
(**self).eq(&**other)
}
}
impl From<&'static str> for UStr {
#[inline]
fn from(s: &'static str) -> Self {
UStr::Static(s)
}
}
impl From<String> for UStr {
#[inline]
fn from(s: String) -> Self {
UStr::Shared(s.into())
}
}
impl Debug for UStr {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.pad(self)
}
}
impl Display for UStr {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.pad(self)
}
}
#[cfg(feature = "offline")]
impl<'de> serde::Deserialize<'de> for UStr {
fn deserialize<D>(deserializer: D) -> Result<Self, <D as serde::Deserializer<'de>>::Error>
where
D: serde::Deserializer<'de>,
{
Ok(String::deserialize(deserializer)?.into())
}
}
#[cfg(feature = "offline")]
impl serde::Serialize for UStr {
fn serialize<S>(
&self,
serializer: S,
) -> Result<<S as serde::Serializer>::Ok, <S as serde::Serializer>::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(&self)
}
}