cycle_ptr 0.1.1

Smart pointers, with cycles
Documentation
//! Declare the [ListEntry] class that needs to be installed on a list element.
use crate::util::NonNull;
use std::fmt;

/// Member variable for [super::List].
pub(crate) struct ListEntry<Type>
where
    Type: ?Sized,
{
    /// Link to predecessor in the list.
    pub(super) pred: Option<NonNull<Type>>,
    /// Link to successor in the list.
    pub(super) succ: Option<NonNull<Type>>,
    /// Indicate if the element is linked into the list.
    pub(super) linked: bool,
}

impl<Type> Default for ListEntry<Type>
where
    Type: ?Sized,
{
    fn default() -> Self {
        ListEntry {
            pred: None,
            succ: None,
            linked: false,
        }
    }
}

/// [ListEntry] does not participate in equality.
///
/// In order to facilitate ease of use, we make it always return `true`.
impl<Type> PartialEq for ListEntry<Type>
where
    Type: ?Sized,
{
    fn eq(&self, _: &Self) -> bool {
        true
    }
}

/// [ListEntry], when cloned, is not linked into the list.
///
/// It simply clones into [ListEntry::default].
impl<Type> Clone for ListEntry<Type>
where
    Type: ?Sized,
{
    fn clone(&self) -> Self {
        Self::default()
    }
}

/// [Drop] is implemented for assertions only.
///
/// An element may only be dropped, when it's not part of a list.
impl<Type> Drop for ListEntry<Type>
where
    Type: ?Sized,
{
    fn drop(&mut self) {
        assert!(!self.linked, "dropping a linked ListEntry is bad");
        assert!(
            self.pred.is_none() && self.succ.is_none(),
            "unlinked ListEntry should not have predecessor or successor"
        );
    }
}

/// A [ListEntry] is [Send], if its entire type is [Send].
unsafe impl<Type> Send for ListEntry<Type> where Type: Send + ?Sized {}

impl<Type> fmt::Debug for ListEntry<Type>
where
    Type: ?Sized,
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
        if self.linked {
            f.write_str("linked")
        } else {
            f.write_str("unlinked")
        }
    }
}