diff --git a/src/lib.rs b/src/lib.rs index 3039821..96eb417 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,4 @@ +pub mod opt; pub mod ptr; pub use ptr::OwnRef; diff --git a/src/opt.rs b/src/opt.rs new file mode 100644 index 0000000..8c3df79 --- /dev/null +++ b/src/opt.rs @@ -0,0 +1,46 @@ +#![forbid(unsafe_code)] + +use std::ops::{Deref, DerefMut}; + +pub struct OwnRef<'a, T>(Option<&'a mut Option>); + +impl Drop for OwnRef<'_, T> { + fn drop(&mut self) { + let _: T = self.0.take().unwrap().take().unwrap(); + } +} + +impl Deref for OwnRef<'_, T> { + type Target = T; + fn deref(&self) -> &Self::Target { + self.0.as_ref().unwrap().as_ref().unwrap() + } +} + +impl DerefMut for OwnRef<'_, T> { + fn deref_mut(&mut self) -> &mut Self::Target { + self.0.as_mut().unwrap().as_mut().unwrap() + } +} + +impl<'a, T> OwnRef<'a, T> { + pub fn from_option(p: &'a mut Option) -> Self { + assert!(p.is_some()); + Self(Some(p)) + } + + pub fn into_option(mut self) -> &'a mut Option { + self.0.take().unwrap() + } +} + +impl OwnRef<'_, T> { + pub fn take(mut self) -> T { + self.0.take().unwrap().take().unwrap() + } +} + +#[cfg(test)] +mod tests { + use super::*; +}