From 7cbcd78645813193a5d1df9d463660b9bff5a27b Mon Sep 17 00:00:00 2001 From: rowan Date: Sun, 6 Jul 2025 20:12:06 -0400 Subject: [PATCH] add mut version --- .gitignore | 2 ++ Cargo.lock | 7 +++++ src/lib.rs | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dc0d833 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +target/ + diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..cb637c3 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "maybe_owned" +version = "0.1.0" diff --git a/src/lib.rs b/src/lib.rs index ee6f8bc..3782384 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,22 +1,110 @@ +use std::{ + borrow::Cow, + ops::{Deref, DerefMut}, +}; + +#[derive(Clone, Copy, Debug)] pub enum MaybeOwned<'a, T: 'a> { Owned(T), Borrowed(&'a T), } +impl<'a, T> Deref for MaybeOwned<'a, T> { + type Target = T; + + fn deref(&self) -> &Self::Target { + match self { + MaybeOwned::Owned(v) => v, + MaybeOwned::Borrowed(v) => v, + } + } +} + impl<'a, T: 'a> From for MaybeOwned<'a, T> { fn from(value: T) -> Self { Self::Owned(value) } } +impl<'a, T: 'a> From> for MaybeOwned<'a, T> { + fn from(value: MaybeOwnedMut<'a, T>) -> Self { + match value { + MaybeOwnedMut::Owned(v) => MaybeOwned::Owned(v), + MaybeOwnedMut::Borrowed(v) => MaybeOwned::Borrowed(v), + } + } +} + impl<'a, T: 'a> From<&'a T> for MaybeOwned<'a, T> { fn from(value: &'a T) -> Self { Self::Borrowed(value) } } +impl<'a, T: 'a + Clone> From> for MaybeOwned<'a, T> { + fn from(value: Cow<'a, T>) -> Self { + match value { + Cow::Owned(v) => MaybeOwned::Owned(v), + Cow::Borrowed(v) => MaybeOwned::Borrowed(v), + } + } +} + impl<'a, T: 'a + Default> Default for MaybeOwned<'a, T> { fn default() -> Self { MaybeOwned::Owned(T::default()) } } + +#[derive(Debug)] +pub enum MaybeOwnedMut<'a, T: 'a> { + Owned(T), + Borrowed(&'a mut T), +} + +impl<'a, T: 'a + Clone> Clone for MaybeOwnedMut<'a, T> { + fn clone(&self) -> Self { + match self { + Self::Owned(v) => Self::Owned(v.clone()), + Self::Borrowed(v) => Self::Owned((*v).to_owned()), + } + } +} + +impl<'a, T> Deref for MaybeOwnedMut<'a, T> { + type Target = T; + + fn deref(&self) -> &Self::Target { + match self { + MaybeOwnedMut::Owned(v) => v, + MaybeOwnedMut::Borrowed(v) => *v, + } + } +} + +impl<'a, T> DerefMut for MaybeOwnedMut<'a, T> { + fn deref_mut(&mut self) -> &mut Self::Target { + match self { + MaybeOwnedMut::Owned(v) => v, + MaybeOwnedMut::Borrowed(v) => *v, + } + } +} + +impl<'a, T: 'a> From for MaybeOwnedMut<'a, T> { + fn from(value: T) -> Self { + Self::Owned(value) + } +} + +impl<'a, T: 'a> From<&'a mut T> for MaybeOwnedMut<'a, T> { + fn from(value: &'a mut T) -> Self { + Self::Borrowed(value) + } +} + +impl<'a, T: 'a + Default> Default for MaybeOwnedMut<'a, T> { + fn default() -> Self { + MaybeOwnedMut::Owned(T::default()) + } +}