#![no_std]
use core::cmp::Ordering;
use core::hash::{Hash, Hasher};
use core::ops::Deref;
use core::fmt;
use self::Boo::*;
pub use core::borrow::{Borrow, BorrowMut};
impl<'a, B: ?Sized> Borrow<B> for Boo<'a, B>
where B: ToOwned,
<B as ToOwned>::Owned: 'a
{
fn borrow(&self) -> &B {
&**self
}
}
pub trait ToOwned {
type Owned: Borrow<Self>;
fn to_owned(&self) -> Self::Owned;
fn clone_into(&self, target: &mut Self::Owned) {
*target = self.to_owned();
}
}
impl<T> ToOwned for T
where T: Clone
{
type Owned = T;
fn to_owned(&self) -> T {
self.clone()
}
fn clone_into(&self, target: &mut T) {
target.clone_from(self);
}
}
pub enum Boo<'a, B: ?Sized + 'a>
where B: ToOwned
{
Borrowed(&'a B),
Owned(<B as ToOwned>::Owned),
}
impl<'a, B: ?Sized> Clone for Boo<'a, B>
where B: ToOwned
{
fn clone(&self) -> Boo<'a, B> {
match *self {
Borrowed(b) => Borrowed(b),
Owned(ref o) => {
let b: &B = o.borrow();
Owned(b.to_owned())
}
}
}
fn clone_from(&mut self, source: &Boo<'a, B>) {
if let Owned(ref mut dest) = *self {
if let Owned(ref o) = *source {
o.borrow().clone_into(dest);
return;
}
}
*self = source.clone();
}
}
impl<'a, B: ?Sized> Boo<'a, B>
where B: ToOwned
{
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<'a, B: ?Sized> Deref for Boo<'a, B>
where B: ToOwned
{
type Target = B;
fn deref(&self) -> &B {
match *self {
Borrowed(borrowed) => borrowed,
Owned(ref owned) => owned.borrow(),
}
}
}
impl<'a, B: ?Sized> Eq for Boo<'a, B> where B: Eq + ToOwned {}
impl<'a, B: ?Sized> Ord for Boo<'a, B>
where B: Ord + ToOwned
{
#[inline]
fn cmp(&self, other: &Boo<'a, B>) -> Ordering {
Ord::cmp(&**self, &**other)
}
}
impl<'a, 'b, B: ?Sized, C: ?Sized> PartialEq<Boo<'b, C>> for Boo<'a, B>
where B: PartialEq<C> + ToOwned,
C: ToOwned
{
#[inline]
fn eq(&self, other: &Boo<'b, C>) -> bool {
PartialEq::eq(&**self, &**other)
}
}
impl<'a, B: ?Sized> PartialOrd for Boo<'a, B>
where B: PartialOrd + ToOwned
{
#[inline]
fn partial_cmp(&self, other: &Boo<'a, B>) -> Option<Ordering> {
PartialOrd::partial_cmp(&**self, &**other)
}
}
impl<'a, B: ?Sized> fmt::Debug for Boo<'a, B>
where B: fmt::Debug + ToOwned,
<B as ToOwned>::Owned: fmt::Debug
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Borrowed(ref b) => fmt::Debug::fmt(b, f),
Owned(ref o) => fmt::Debug::fmt(o, f),
}
}
}
impl<'a, B: ?Sized> fmt::Display for Boo<'a, B>
where B: fmt::Display + 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<'a, B: ?Sized> Default for Boo<'a, B>
where B: ToOwned,
<B as ToOwned>::Owned: Default
{
fn default() -> Boo<'a, B> {
Owned(<B as ToOwned>::Owned::default())
}
}
impl<'a, B: ?Sized> Hash for Boo<'a, B>
where B: Hash + ToOwned
{
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
Hash::hash(&**self, state)
}
}
#[allow(deprecated)]
impl<'a, T: ?Sized + ToOwned> AsRef<T> for Boo<'a, T> {
fn as_ref(&self) -> &T {
self
}
}