Skip to content

Commit

Permalink
Add Adopt::try_adopt
Browse files Browse the repository at this point in the history
  • Loading branch information
lopopolo committed Jun 15, 2021
1 parent 009bf34 commit 05ec7c1
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 3 deletions.
33 changes: 30 additions & 3 deletions src/adopt.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use core::fmt;
use core::ptr;

use crate::link::Link;
Expand All @@ -13,6 +14,21 @@ mod sealed {
impl<T> Sealed for Rc<T> {}
}

/// The error type for `try_adopt` methods.
///
/// See [`Adopt::try_adopt`] for more information.
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct AdoptError(());

#[cfg(feature = "std")]
impl std::error::Error for AdoptError {}

impl fmt::Display for AdoptError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("Rc adoption failed because the Rc does not own a pointer to the adoptee")
}
}

/// Build a graph of linked [`Rc`] smart pointers to enable busting cycles on
/// drop.
///
Expand All @@ -34,12 +50,20 @@ mod sealed {
///
/// [`adopt_unchecked`]: Adopt::adopt_unchecked
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
pub unsafe trait Adopt: sealed::Sealed {
pub unsafe trait Adopt: sealed::Sealed + Sized {
/// The smart pointer's inner owned value.
type Inner;

/// TODO: document me!
fn adopt(this: &mut Self, other: &Self)
fn adopt(this: &mut Self, other: &Self) -> Self
where
Self::Inner: Trace,
{
Self::try_adopt(this, other).unwrap_or_else(|err| panic!("{}", err))
}

/// TODO: document me!
fn try_adopt(this: &mut Self, other: &Self) -> Result<Self, AdoptError>
where
Self::Inner: Trace;

Expand Down Expand Up @@ -92,7 +116,7 @@ unsafe impl<T> Adopt for Rc<T> {
type Inner = T;

/// TODO: document me!
fn adopt(this: &mut Self, other: &Self)
fn try_adopt(this: &mut Self, other: &Self) -> Result<Self, AdoptError>
where
Self::Inner: Trace,
{
Expand Down Expand Up @@ -125,6 +149,9 @@ unsafe impl<T> Adopt for Rc<T> {
unsafe {
Self::adopt_unchecked(this, &node);
}
Ok(node)
} else {
Err(AdoptError(()))
}
}

Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ mod trace;
pub mod implementing_self_referential_data_structures;

pub use adopt::Adopt;
pub use adopt::AdoptError;
pub use rc::Rc;
pub use rc::Weak;
pub use trace::Trace;
Expand Down

0 comments on commit 05ec7c1

Please sign in to comment.