cycle_ptr 0.1.1

Smart pointers, with cycles
Documentation
//! Metadata implementations.
//!
//! Metadata tracks an object, and permits associated member pointers to be created.
use crate::generation::r#ref::GenerationRef;
use crate::object::DynObjectPtr;
use crate::pointer::{GcMemberPtr, GcPtr};
use crate::prelude::GcMemberPtrNew;
use std::fmt;
use std::pin::Pin;

/// Metadata controls the metadata of a managed object.
///
/// It permits creating member pointers.
#[derive(Clone)]
pub struct Metadata {
    /// The `origin` object for use in member-pointers.
    ///
    /// This is effectively a weak pointer to the instance owning the member pointer.
    this_object: Pin<DynObjectPtr>,
}

impl fmt::Debug for Metadata {
    #[inline]
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
        if self.this_object.has_data() {
            f.write_str("Metadata(initialized)")
        } else {
            f.write_str("Metadata(uninitialized object)")
        }
    }
}

impl Metadata {
    /// Create a new metadata instance.
    ///
    /// `this_object` is the `origin` for member-pointers created from this metadata.
    #[inline]
    pub(crate) const fn new(this_object: Pin<DynObjectPtr>) -> Metadata {
        Metadata { this_object }
    }

    /// Get the generation that owns this object.
    ///
    /// Note that the generation can change under certain conditions, so it is merely a snapshot.
    #[inline]
    pub fn generation(&self) -> GenerationRef {
        GenerationRef::new_from_ptr(self.this_object.get_generation_ptr())
    }
}

impl<T> GcMemberPtrNew<GcPtr<T>, GcMemberPtr<T>> for Metadata
where
    T: 'static,
{
    /// Create a new sendable [GcMemberPtr].
    #[inline]
    fn new_pointer(&self, sp: GcPtr<T>) -> GcMemberPtr<T> {
        GcMemberPtr::new_ptr(self.this_object.clone(), sp)
    }
}

#[cfg(feature = "multi_thread")]
impl<T> GcMemberPtrNew<crate::pointer::sync::GcMtPtr<T>, GcMemberPtr<T>> for Metadata
where
    T: 'static + Send + Sync,
{
    /// Create a new sendable [GcMemberPtr].
    #[inline]
    fn new_pointer(&self, sp: crate::pointer::sync::GcMtPtr<T>) -> GcMemberPtr<T> {
        GcMemberPtr::new_mt_ptr(self.this_object.clone(), sp)
    }
}

#[cfg(feature = "multi_thread")]
impl<T> GcMemberPtrNew<crate::pointer::sync::GcMtPtr<T>, crate::pointer::sync::GcMtMemberPtr<T>>
    for Metadata
where
    T: 'static + Send + Sync,
{
    /// Create a new sendable [GcMtMemberPtr][crate::sync::GcMtMemberPtr].
    #[inline]
    fn new_pointer(
        &self,
        sp: crate::pointer::sync::GcMtPtr<T>,
    ) -> crate::pointer::sync::GcMtMemberPtr<T> {
        crate::pointer::sync::GcMtMemberPtr::new_ptr(self.this_object.clone(), sp)
    }
}

/// Module holding a thread-safe implementation of metadata.
#[cfg(feature = "multi_thread")]
pub(crate) mod sync {
    use crate::generation::r#ref::sync::GenerationRef;
    use crate::object::DynMTObjectPtr;
    use crate::pointer::sync::{GcMtMemberPtr, GcMtPtr};
    use crate::prelude::GcMemberPtrNew;
    use std::fmt;
    use std::pin::Pin;

    /// Metadata controls the metadata of a managed object.
    ///
    /// It permits creating member pointers.
    #[derive(Clone)]
    pub struct Metadata {
        /// The `origin` object for use in member-pointers.
        ///
        /// This is effectively a weak pointer to the instance owning the member pointer.
        this_object: Pin<DynMTObjectPtr>,
    }

    impl fmt::Debug for Metadata {
        #[inline]
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
            if self.this_object.has_data() {
                f.write_str("Metadata(initialized)")
            } else {
                f.write_str("Metadata(uninitialized object)")
            }
        }
    }

    impl Metadata {
        /// Create a new metadata instance.
        ///
        /// `this_object` is the `origin` for member-pointers created from this metadata.
        #[inline]
        pub(crate) const fn new(this_object: Pin<DynMTObjectPtr>) -> Metadata {
            Metadata { this_object }
        }

        /// Get the generation that owns this object.
        ///
        /// Note that the generation can change under certain conditions, so it is merely a snapshot.
        #[inline]
        pub fn generation(&self) -> GenerationRef {
            GenerationRef::new_from_ptr(self.this_object.get_generation_ptr())
        }
    }

    impl<T> GcMemberPtrNew<GcMtPtr<T>, GcMtMemberPtr<T>> for Metadata
    where
        T: 'static + Send + Sync,
    {
        /// Create a new sendable [GcMtMemberPtr].
        #[inline]
        fn new_pointer(&self, sp: GcMtPtr<T>) -> GcMtMemberPtr<T> {
            GcMtMemberPtr::new_mt_ptr(self.this_object.clone(), sp)
        }
    }
}