split implementation into files

This commit is contained in:
numzero 2026-05-07 22:12:20 +03:00
parent 5c5fc00fd1
commit 80a96c089a
3 changed files with 58 additions and 44 deletions

View File

@ -1,12 +1,13 @@
use std::{ use std::{
any::Any,
fmt::Debug,
marker::PhantomData, marker::PhantomData,
mem::ManuallyDrop, mem::ManuallyDrop,
ops::{Deref, DerefMut}, ops::{Deref, DerefMut},
ptr::NonNull, ptr::NonNull,
}; };
mod any;
mod traits;
#[repr(transparent)] #[repr(transparent)]
pub struct OwnRef<'a, T: ?Sized>(Option<NonNull<T>>, PhantomData<(&'a mut [u8], T)>); pub struct OwnRef<'a, T: ?Sized>(Option<NonNull<T>>, PhantomData<(&'a mut [u8], T)>);
@ -33,12 +34,6 @@ impl<T: ?Sized> DerefMut for OwnRef<'_, T> {
} }
} }
impl<T: Debug + ?Sized> Debug for OwnRef<'_, T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("OwnRef").field(&&**self).finish()
}
}
impl<T: ?Sized> OwnRef<'_, T> { impl<T: ?Sized> OwnRef<'_, T> {
pub unsafe fn new_unchecked(p: NonNull<T>) -> Self { pub unsafe fn new_unchecked(p: NonNull<T>) -> Self {
Self(Some(p), PhantomData) Self(Some(p), PhantomData)
@ -67,31 +62,6 @@ impl<T> 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<U: 'static>(mut self) -> Result<OwnRef<'a, U>, Self> {
if !self.is::<U>() {
return Err(self);
}
let p = self.0.take().unwrap();
let p = p.cast::<U>();
Ok(OwnRef(Some(p), PhantomData))
}
}
impl OwnRef<'_, dyn Any> {
pub fn take<U: 'static>(self) -> Result<U, Self> {
self.downcast::<U>().map(|r| r.take())
}
}
#[doc(hidden)] #[doc(hidden)]
pub mod _refs { pub mod _refs {
pub use std::mem::ManuallyDrop; pub use std::mem::ManuallyDrop;
@ -139,15 +109,4 @@ mod tests {
let s: String = obj.take(); let s: String = obj.take();
assert_eq!(s, "some string"); 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::<usize>().unwrap_err();
let obj = obj.downcast::<&'static str>().unwrap_err();
let s: OwnRef<String> = obj.downcast().unwrap();
assert_eq!(*s, "some string");
}
} }

46
src/ptr/any.rs Normal file
View File

@ -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<U: 'static>(mut self) -> Result<OwnRef<'a, U>, Self> {
if !self.is::<U>() {
return Err(self);
}
let p = self.0.take().unwrap();
let p = p.cast::<U>();
Ok(OwnRef(Some(p), PhantomData))
}
}
impl OwnRef<'_, dyn Any> {
pub fn take<U: 'static>(self) -> Result<U, Self> {
self.downcast::<U>().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::<usize>().unwrap_err();
let obj = obj.downcast::<&'static str>().unwrap_err();
let s: OwnRef<String> = obj.downcast().unwrap();
assert_eq!(*s, "some string");
}
}

9
src/ptr/traits.rs Normal file
View File

@ -0,0 +1,9 @@
use std::fmt::Debug;
use super::OwnRef;
impl<T: Debug + ?Sized> Debug for OwnRef<'_, T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("OwnRef").field(&&**self).finish()
}
}