diff --git a/src/ptr.rs b/src/ptr.rs index 2f6d143..a9086cc 100644 --- a/src/ptr.rs +++ b/src/ptr.rs @@ -1,12 +1,13 @@ use std::{ - any::Any, - fmt::Debug, marker::PhantomData, mem::ManuallyDrop, ops::{Deref, DerefMut}, ptr::NonNull, }; +mod any; +mod traits; + #[repr(transparent)] pub struct OwnRef<'a, T: ?Sized>(Option>, PhantomData<(&'a mut [u8], T)>); @@ -33,12 +34,6 @@ impl DerefMut for OwnRef<'_, T> { } } -impl Debug for OwnRef<'_, T> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_tuple("OwnRef").field(&&**self).finish() - } -} - impl OwnRef<'_, T> { pub unsafe fn new_unchecked(p: NonNull) -> Self { Self(Some(p), PhantomData) @@ -67,31 +62,6 @@ impl OwnRef<'_, T> { } } -impl<'a, T: Any> OwnRef<'a, T> { - pub fn into_any(mut self) -> OwnRef<'a, dyn Any> { - let mut p = self.0.take().unwrap(); - let p = unsafe { p.as_mut() } as &'a mut dyn Any; - OwnRef(Some(p.into()), PhantomData) - } -} - -impl<'a> OwnRef<'a, dyn Any> { - pub fn downcast(mut self) -> Result, Self> { - if !self.is::() { - return Err(self); - } - let p = self.0.take().unwrap(); - let p = p.cast::(); - Ok(OwnRef(Some(p), PhantomData)) - } -} - -impl OwnRef<'_, dyn Any> { - pub fn take(self) -> Result { - self.downcast::().map(|r| r.take()) - } -} - #[doc(hidden)] pub mod _refs { pub use std::mem::ManuallyDrop; @@ -139,15 +109,4 @@ mod tests { let s: String = obj.take(); assert_eq!(s, "some string"); } - - #[test] - fn test_any() { - let obj = "some string".to_string(); - to_own_ref!(obj); - let obj = obj.into_any(); - let obj = obj.downcast::().unwrap_err(); - let obj = obj.downcast::<&'static str>().unwrap_err(); - let s: OwnRef = obj.downcast().unwrap(); - assert_eq!(*s, "some string"); - } } diff --git a/src/ptr/any.rs b/src/ptr/any.rs new file mode 100644 index 0000000..52a1bfa --- /dev/null +++ b/src/ptr/any.rs @@ -0,0 +1,46 @@ +use std::{any::Any, marker::PhantomData}; + +use super::OwnRef; + +impl<'a, T: Any> OwnRef<'a, T> { + pub fn into_any(mut self) -> OwnRef<'a, dyn Any> { + let mut p = self.0.take().unwrap(); + let p = unsafe { p.as_mut() } as &'a mut dyn Any; + OwnRef(Some(p.into()), PhantomData) + } +} + +impl<'a> OwnRef<'a, dyn Any> { + pub fn downcast(mut self) -> Result, Self> { + if !self.is::() { + return Err(self); + } + let p = self.0.take().unwrap(); + let p = p.cast::(); + Ok(OwnRef(Some(p), PhantomData)) + } +} + +impl OwnRef<'_, dyn Any> { + pub fn take(self) -> Result { + self.downcast::().map(|r| r.take()) + } +} + +#[cfg(test)] +mod tests { + use crate::ptr::to_own_ref; + + use super::*; + + #[test] + fn test_any() { + let obj = "some string".to_string(); + to_own_ref!(obj); + let obj = obj.into_any(); + let obj = obj.downcast::().unwrap_err(); + let obj = obj.downcast::<&'static str>().unwrap_err(); + let s: OwnRef = obj.downcast().unwrap(); + assert_eq!(*s, "some string"); + } +} diff --git a/src/ptr/traits.rs b/src/ptr/traits.rs new file mode 100644 index 0000000..dc8e01b --- /dev/null +++ b/src/ptr/traits.rs @@ -0,0 +1,9 @@ +use std::fmt::Debug; + +use super::OwnRef; + +impl Debug for OwnRef<'_, T> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("OwnRef").field(&&**self).finish() + } +}