pub use core::borrow::{Borrow, BorrowMut};
use core::cmp::Ordering;
use core::hash::{Hash, Hasher};
use core::iter::FromIterator;
use core::ops::{Add, AddAssign, Deref};
use std::borrow::ToOwned;
use std::ffi::{CStr, CString, OsStr, OsString};
use std::path::{Path, PathBuf};
use std::sync::Arc;
use std::rc::Rc;
use std::fmt;
use std::string::String;
use UnevalCow::*;
impl<'a, B: ?Sized> Borrow<B> for UnevalCow<'a, B>
where
B: ToOwned,
<B as ToOwned>::Owned: 'a,
{
fn borrow(&self) -> &B {
&**self
}
}
pub enum UnevalCow<'a, B: ?Sized + 'a>
where
B: ToOwned,
{
Borrowed(&'a B),
Owned(<B as ToOwned>::Owned),
}
impl<B: ?Sized + ToOwned> Clone for UnevalCow<'_, B> {
fn clone(&self) -> Self {
match *self {
Borrowed(b) => Borrowed(b),
Owned(ref o) => {
let b: &B = o.borrow();
Owned(b.to_owned())
}
}
}
}
impl<B: ?Sized + ToOwned> UnevalCow<'_, B> {
pub fn to_mut(&mut self) -> &mut <B as ToOwned>::Owned {
match *self {
Borrowed(borrowed) => {
*self = Owned(borrowed.to_owned());
match *self {
Borrowed(..) => unreachable!(),
Owned(ref mut owned) => owned,
}
}
Owned(ref mut owned) => owned,
}
}
pub fn into_owned(self) -> <B as ToOwned>::Owned {
match self {
Borrowed(borrowed) => borrowed.to_owned(),
Owned(owned) => owned,
}
}
}
impl<B: ?Sized + ToOwned> Deref for UnevalCow<'_, B> {
type Target = B;
fn deref(&self) -> &B {
match *self {
Borrowed(borrowed) => borrowed,
Owned(ref owned) => owned.borrow(),
}
}
}
impl<B: ?Sized> Eq for UnevalCow<'_, B> where B: Eq + ToOwned {}
impl<B: ?Sized> Ord for UnevalCow<'_, B>
where
B: Ord + ToOwned,
{
#[inline]
fn cmp(&self, other: &Self) -> Ordering {
Ord::cmp(&**self, &**other)
}
}
impl<'a, 'b, B: ?Sized, C: ?Sized> PartialEq<UnevalCow<'b, C>> for UnevalCow<'a, B>
where
B: PartialEq<C> + ToOwned,
C: ToOwned,
{
#[inline]
fn eq(&self, other: &UnevalCow<'b, C>) -> bool {
PartialEq::eq(&**self, &**other)
}
}
impl<'a, B: ?Sized> PartialOrd for UnevalCow<'a, B>
where
B: PartialOrd + ToOwned,
{
#[inline]
fn partial_cmp(&self, other: &UnevalCow<'a, B>) -> Option<Ordering> {
PartialOrd::partial_cmp(&**self, &**other)
}
}
impl<B: ?Sized> fmt::Debug for UnevalCow<'_, B>
where
B: fmt::Debug + 'static,
B: ToOwned,
<B as ToOwned>::Owned: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use core::any::TypeId;
let ty_id = TypeId::of::<B>();
match *self {
Borrowed(ref b) => f.write_fmt(format_args!("UnevalCow::Borrowed( &{:?} )", b)),
Owned(ref o) => {
if ty_id == TypeId::of::<str>() {
return f.write_fmt(format_args!("UnevalCow::Borrowed( {:?} )", o));
} else {
return f.write_fmt(format_args!("UnevalCow::Borrowed( &{:?} )", o));
}
}
}
}
}
impl<B: ?Sized> fmt::Display for UnevalCow<'_, B>
where
B: fmt::Display,
B: ToOwned,
<B as ToOwned>::Owned: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
Borrowed(ref b) => fmt::Display::fmt(b, f),
Owned(ref o) => fmt::Display::fmt(o, f),
}
}
}
impl<B: ?Sized> Default for UnevalCow<'_, B>
where
B: ToOwned,
<B as ToOwned>::Owned: Default,
{
fn default() -> Self {
Owned(<B as ToOwned>::Owned::default())
}
}
impl<B: ?Sized> Hash for UnevalCow<'_, B>
where
B: Hash + ToOwned,
{
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
Hash::hash(&**self, state)
}
}
impl<T: ?Sized + ToOwned> AsRef<T> for UnevalCow<'_, T> {
fn as_ref(&self) -> &T {
self
}
}
impl<'a> Add<&'a str> for UnevalCow<'a, str> {
type Output = UnevalCow<'a, str>;
#[inline]
fn add(mut self, rhs: &'a str) -> Self::Output {
self += rhs;
self
}
}
impl<'a> Add<UnevalCow<'a, str>> for UnevalCow<'a, str> {
type Output = UnevalCow<'a, str>;
#[inline]
fn add(mut self, rhs: UnevalCow<'a, str>) -> Self::Output {
self += rhs;
self
}
}
impl<'a> AddAssign<&'a str> for UnevalCow<'a, str> {
fn add_assign(&mut self, rhs: &'a str) {
if self.is_empty() {
*self = UnevalCow::Borrowed(rhs)
} else if !rhs.is_empty() {
if let UnevalCow::Borrowed(lhs) = *self {
let mut s = String::with_capacity(lhs.len() + rhs.len());
s.push_str(lhs);
*self = UnevalCow::Owned(s);
}
self.to_mut().push_str(rhs);
}
}
}
impl<'a> AddAssign<UnevalCow<'a, str>> for UnevalCow<'a, str> {
fn add_assign(&mut self, rhs: UnevalCow<'a, str>) {
if self.is_empty() {
*self = rhs
} else if !rhs.is_empty() {
if let UnevalCow::Borrowed(lhs) = *self {
let mut s = String::with_capacity(lhs.len() + rhs.len());
s.push_str(lhs);
*self = UnevalCow::Owned(s);
}
self.to_mut().push_str(&rhs);
}
}
}
impl<'a, T: Clone> From<&'a [T]> for UnevalCow<'a, [T]> {
fn from(s: &'a [T]) -> UnevalCow<'a, [T]> {
UnevalCow::Borrowed(s)
}
}
impl<'a, T: Clone> From<Vec<T>> for UnevalCow<'a, [T]> {
fn from(v: Vec<T>) -> UnevalCow<'a, [T]> {
UnevalCow::Owned(v)
}
}
impl<'a, T: Clone> From<&'a Vec<T>> for UnevalCow<'a, [T]> {
fn from(v: &'a Vec<T>) -> UnevalCow<'a, [T]> {
UnevalCow::Borrowed(v.as_slice())
}
}
impl<'a, T> FromIterator<T> for UnevalCow<'a, [T]>
where
T: Clone,
{
fn from_iter<I: IntoIterator<Item = T>>(it: I) -> UnevalCow<'a, [T]> {
UnevalCow::Owned(FromIterator::from_iter(it))
}
}
impl<'a> From<&'a Path> for UnevalCow<'a, Path> {
#[inline]
fn from(s: &'a Path) -> UnevalCow<'a, Path> {
UnevalCow::Borrowed(s)
}
}
impl<'a> From<PathBuf> for UnevalCow<'a, Path> {
#[inline]
fn from(s: PathBuf) -> UnevalCow<'a, Path> {
UnevalCow::Owned(s)
}
}
impl<'a> From<&'a PathBuf> for UnevalCow<'a, Path> {
#[inline]
fn from(p: &'a PathBuf) -> UnevalCow<'a, Path> {
UnevalCow::Borrowed(p.as_path())
}
}
impl AsRef<Path> for UnevalCow<'_, OsStr> {
fn as_ref(&self) -> &Path {
Path::new(self)
}
}
impl From<UnevalCow<'_, Path>> for Box<Path> {
#[inline]
fn from(cow: UnevalCow<'_, Path>) -> Box<Path> {
match cow {
UnevalCow::Borrowed(path) => Box::from(path),
UnevalCow::Owned(path) => Box::from(path),
}
}
}
impl<'a> From<UnevalCow<'a, Path>> for PathBuf {
#[inline]
fn from(p: UnevalCow<'a, Path>) -> Self {
p.into_owned()
}
}
impl<'a> Extend<UnevalCow<'a, str>> for String {
fn extend<I: IntoIterator<Item = UnevalCow<'a, str>>>(&mut self, iter: I) {
iter.into_iter().for_each(move |s| self.push_str(&s));
}
}
impl<'a> From<CString> for UnevalCow<'a, CStr> {
#[inline]
fn from(s: CString) -> UnevalCow<'a, CStr> {
UnevalCow::Owned(s)
}
}
impl<'a> From<&'a CStr> for UnevalCow<'a, CStr> {
#[inline]
fn from(s: &'a CStr) -> UnevalCow<'a, CStr> {
UnevalCow::Borrowed(s)
}
}
impl<'a> From<&'a CString> for UnevalCow<'a, CStr> {
#[inline]
fn from(s: &'a CString) -> UnevalCow<'a, CStr> {
UnevalCow::Borrowed(s.as_c_str())
}
}
impl<'a> From<OsString> for UnevalCow<'a, OsStr> {
#[inline]
fn from(s: OsString) -> UnevalCow<'a, OsStr> {
UnevalCow::Owned(s)
}
}
impl<'a> From<&'a OsStr> for UnevalCow<'a, OsStr> {
#[inline]
fn from(s: &'a OsStr) -> UnevalCow<'a, OsStr> {
UnevalCow::Borrowed(s)
}
}
impl<'a> From<&'a OsString> for UnevalCow<'a, OsStr> {
#[inline]
fn from(s: &'a OsString) -> UnevalCow<'a, OsStr> {
UnevalCow::Borrowed(s.as_os_str())
}
}
impl<'a> From<&'a str> for UnevalCow<'a, str> {
#[inline]
fn from(s: &'a str) -> UnevalCow<'a, str> {
UnevalCow::Borrowed(s)
}
}
impl<'a> From<String> for UnevalCow<'a, str> {
#[inline]
fn from(s: String) -> UnevalCow<'a, str> {
UnevalCow::Owned(s)
}
}
impl<'a> From<&'a String> for UnevalCow<'a, str> {
#[inline]
fn from(s: &'a String) -> UnevalCow<'a, str> {
UnevalCow::Borrowed(s.as_str())
}
}
impl<'a> FromIterator<char> for UnevalCow<'a, str> {
fn from_iter<I: IntoIterator<Item = char>>(it: I) -> UnevalCow<'a, str> {
UnevalCow::Owned(FromIterator::from_iter(it))
}
}
impl<'a, 'b> FromIterator<&'b str> for UnevalCow<'a, str> {
fn from_iter<I: IntoIterator<Item = &'b str>>(it: I) -> UnevalCow<'a, str> {
UnevalCow::Owned(FromIterator::from_iter(it))
}
}
impl<'a> FromIterator<String> for UnevalCow<'a, str> {
fn from_iter<I: IntoIterator<Item = String>>(it: I) -> UnevalCow<'a, str> {
UnevalCow::Owned(FromIterator::from_iter(it))
}
}
impl<T: Copy> From<UnevalCow<'_, [T]>> for Box<[T]> {
#[inline]
fn from(cow: UnevalCow<'_, [T]>) -> Box<[T]> {
match cow {
UnevalCow::Borrowed(slice) => Box::from(slice),
UnevalCow::Owned(slice) => Box::from(slice),
}
}
}
impl From<UnevalCow<'_, str>> for Box<str> {
#[inline]
fn from(cow: UnevalCow<'_, str>) -> Box<str> {
match cow {
UnevalCow::Borrowed(s) => Box::from(s),
UnevalCow::Owned(s) => Box::from(s),
}
}
}
impl<'a, B> From<UnevalCow<'a, B>> for Arc<B>
where
B: ToOwned + ?Sized,
Arc<B>: From<&'a B> + From<B::Owned>,
{
#[inline]
fn from(cow: UnevalCow<'a, B>) -> Arc<B> {
match cow {
UnevalCow::Borrowed(s) => Arc::from(s),
UnevalCow::Owned(s) => Arc::from(s),
}
}
}
impl<'a, B> From<UnevalCow<'a, B>> for Rc<B>
where
B: ToOwned + ?Sized,
Rc<B>: From<&'a B> + From<B::Owned>,
{
#[inline]
fn from(cow: UnevalCow<'a, B>) -> Rc<B> {
match cow {
UnevalCow::Borrowed(s) => Rc::from(s),
UnevalCow::Owned(s) => Rc::from(s),
}
}
}