use std::hash::Hasher; use std::{ borrow::Cow, fmt::{Display, Formatter}, hash::Hash, ops::Deref, sync::Arc, }; #[derive(Debug, Eq)] pub enum ArcOrCowStr { Arc(Arc), Cow(Cow<'static, str>), } impl Hash for ArcOrCowStr { fn hash(&self, state: &mut H) { (**self).hash(state); } } impl PartialEq for ArcOrCowStr { fn eq(&self, other: &ArcOrCowStr) -> bool { **self == **other } } impl From> for ArcOrCowStr { fn from(v: Arc) -> Self { Self::Arc(v) } } impl From> for ArcOrCowStr { fn from(v: Cow<'static, str>) -> Self { Self::Cow(v) } } impl From<&'static str> for ArcOrCowStr { fn from(v: &'static str) -> Self { Self::Cow(Cow::Borrowed(v)) } } impl From for ArcOrCowStr { fn from(v: String) -> Self { Self::Cow(Cow::Owned(v)) } } impl AsRef for ArcOrCowStr { fn as_ref(&self) -> &str { match self { Self::Arc(v) => v.as_ref(), Self::Cow(v) => v.as_ref(), } } } impl Deref for ArcOrCowStr { type Target = str; fn deref(&self) -> &Self::Target { self.as_ref() } } impl Display for ArcOrCowStr { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(&**self, f) } } #[cfg(test)] mod test { mod arc_or_cow_str { use crate::util::ArcOrCowStr; use std::borrow::Cow; use std::sync::Arc; #[test] fn from_arc() { assert_eq!( ArcOrCowStr::from(Arc::from("hello world".to_string())), "hello world".into() ); } #[test] fn from_cow() { assert_eq!( ArcOrCowStr::from(Cow::Borrowed("hello world")), "hello world".into() ); } #[test] fn from_string() { assert_eq!( ArcOrCowStr::from("hello world".to_string()), "hello world".into() ); } } }