use std::borrow::{Borrow, Cow};
use std::cmp::Ordering;
use std::fmt::Display;
use std::ops::Deref;
#[derive(Eq, Ord, Debug, Hash)]
pub enum Borrowned<'b, T> {
Owned(T),
Borrowed(&'b T),
}
impl<'b, T> Borrowned<'b, T> {
pub fn is_owned(&self) -> bool {
matches!(*self, Self::Owned(_))
}
pub fn is_borrowed(&self) -> bool {
matches!(*self, Self::Borrowed(_))
}
pub fn into_owned(self) -> Result<T, Self> {
match self {
Borrowned::Owned(owned) => Ok(owned),
Borrowned::Borrowed(_) => Err(self),
}
}
pub fn into_borrowed(self) -> Result<&'b T, Self> {
match self {
Borrowned::Borrowed(borrowed) => Ok(borrowed),
Borrowned::Owned(_) => Err(self),
}
}
fn inner_ref(&self) -> &T {
match self {
Borrowned::Owned(owned) => owned,
Borrowned::Borrowed(borrowed) => *borrowed,
}
}
}
shared_impls!();
#[doc(hidden)]
pub trait Reflective {
type Same;
}
#[doc(hidden)]
impl<T> Reflective for T {
type Same = Self;
}
impl<'b, T> From<Cow<'b, T>> for Borrowned<'b, T>
where
T: Clone,
<T as ToOwned>::Owned: Reflective<Same = T>,
{
fn from(c: Cow<'b, T>) -> Self {
match c {
Cow::Borrowed(t) => Borrowned::Borrowed(t),
Cow::Owned(t) => Borrowned::Owned(t),
}
}
}
#[cfg(test)]
mod tests {
use crate::read_only::Borrowned;
#[test]
fn into_owned_gives_owned_when_owned() {
let hw = "Hello World".to_string();
let ob = Borrowned::Owned(hw.clone());
let hw2 = ob.into_owned();
assert_eq!(hw2, Ok(hw));
}
#[test]
fn into_owned_gives_self_when_not_owned() {
let hw = "Hello World".to_string();
let ob = Borrowned::Borrowed(&hw);
let hw2 = ob.into_owned();
assert!(hw2.is_err());
}
#[test]
fn into_borrowed_gives_borrowed_when_borrowed() {
let hw = "Hello World".to_string();
let ob = Borrowned::Borrowed(&hw);
let hw2 = ob.into_borrowed();
assert!(hw2.is_ok());
}
#[test]
fn into_borrowed_gives_self_when_not_borrowed() {
let hw = "Hello World".to_string();
let ob = Borrowned::Owned(hw);
let hw2 = ob.into_borrowed();
assert!(hw2.is_err());
}
}