split implementation into files
This commit is contained in:
parent
5c5fc00fd1
commit
80a96c089a
47
src/ptr.rs
47
src/ptr.rs
|
|
@ -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
46
src/ptr/any.rs
Normal 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
9
src/ptr/traits.rs
Normal 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()
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user