#![deny(anonymous_parameters)]
#![deny(elided_lifetimes_in_paths)]
#![deny(ellipsis_inclusive_range_patterns)]
#![deny(nonstandard_style)]
#![deny(rust_2018_idioms)]
#![deny(trivial_numeric_casts)]
#![warn(unsafe_code)]
#![deny(rustdoc::broken_intra_doc_links)]
#![deny(unused)]
#![warn(missing_copy_implementations)]
#![warn(missing_debug_implementations)]
#![warn(variant_size_differences)]
#![warn(clippy::pedantic)]
#[macro_use]
mod util;
pub mod read_only;
use std::borrow::{Borrow, BorrowMut};
use std::cmp::Ordering;
use std::fmt::Display;
use std::ops::{Deref, DerefMut};
#[derive(Eq, Ord, Debug, Hash)]
pub enum Borrowned<'b, T> {
Owned(T),
Borrowed(&'b mut 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 mut 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,
}
}
fn inner_mut(&mut self) -> &mut T {
match self {
Borrowned::Owned(owned) => owned,
Borrowned::Borrowed(borrowed) => *borrowed,
}
}
}
shared_impls!();
impl<'b, T> DerefMut for Borrowned<'b, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.inner_mut()
}
}
impl<'b, T> BorrowMut<T> for Borrowned<'b, T> {
fn borrow_mut(&mut self) -> &mut T {
self.inner_mut()
}
}
impl<'b, T> AsMut<T> for Borrowned<'b, T> {
fn as_mut(&mut self) -> &mut T {
self.inner_mut()
}
}
impl<'i, 'b, T> IntoIterator for &'i mut Borrowned<'b, T>
where
&'i mut T: IntoIterator,
{
type Item = <&'i mut T as IntoIterator>::Item;
type IntoIter = <&'i mut T as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.inner_mut().into_iter()
}
}
#[cfg(test)]
mod tests {
use crate::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 mut hw = "Hello World".to_string();
let ob = Borrowned::Borrowed(&mut hw);
let hw2 = ob.into_owned();
assert!(hw2.is_err());
}
#[test]
fn into_borrowed_gives_borrowed_when_borrowed() {
let mut hw = "Hello World".to_string();
let ob = Borrowned::Borrowed(&mut 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());
}
}