Observer

Trait Observer 

Source
pub trait Observer<'i>: Default
where Self: AsDerefMutCoinductive<Succ<Self::OuterDepth>, Target = ObserverPointer<Self::Head>>,
{ type InnerDepth: Unsigned; type OuterDepth: Unsigned; type Head: AsDerefMut<Self::InnerDepth> + ?Sized + 'i; // Required method fn observe(value: &'i mut Self::Head) -> Self; // Provided methods fn as_ptr(this: &Self) -> &ObserverPointer<Self::Head> { ... } fn as_inner<'j>( this: &Self, ) -> &'j mut <Self::Head as AsDeref<Self::InnerDepth>>::Target where 'i: 'j { ... } fn track_inner<'j>( this: &mut Self, ) -> &'j mut <Self::Head as AsDeref<Self::InnerDepth>>::Target where 'i: 'j { ... } }
Expand description

A trait for observer types that wrap and track mutations to values.

Observers provide transparent access to the underlying value while recording any mutations that occur. They form a dereference chain that allows multiple levels of observation.

§Type Parameters

  • Head: The type stored in the internal ObserverPointer, representing the head of the dereference chain
  • InnerDepth: Type-level number indicating how many times Head must be dereferenced to reach the observed type
  • OuterDepth: Type-level number indicating how many times Self must be dereferenced (plus one) to reach ObserverPointer<Head>

See the module documentation for more details about how observers work with dereference chains.

Required Associated Types§

Source

type InnerDepth: Unsigned

Type-level number of dereferences from Head to the observed type.

Source

type OuterDepth: Unsigned

Type-level number of dereferences from Self to ObserverPointer<Head> minus one.

Source

type Head: AsDerefMut<Self::InnerDepth> + ?Sized + 'i

The head type of the dereference chain.

Required Methods§

Source

fn observe(value: &'i mut Self::Head) -> Self

Creates a new observer for the given value.

This is the primary way to create an observer. The observer will track all mutations to the provided value.

§Example
use morphix::observe::{Observer, ShallowObserver};

let mut value = 42;
let observer = ShallowObserver::<i32>::observe(&mut value);

Provided Methods§

Source

fn as_ptr(this: &Self) -> &ObserverPointer<Self::Head>

Gets a reference to the internal pointer.

This is primarily used internally by observer implementations.

Source

fn as_inner<'j>( this: &Self, ) -> &'j mut <Self::Head as AsDeref<Self::InnerDepth>>::Target
where 'i: 'j,

Gets a mutable reference to the inner observed value without triggering observation.

This method bypasses the entire observer chain, directly accessing the observed value through the internal pointer. No DerefMut hooks are triggered, making this useful for internal operations that shouldn’t be recorded as mutations.

§Usage

This method is primarily used internally by observer implementations when they need to perform operations on the observed value without recording them as changes.

Source

fn track_inner<'j>( this: &mut Self, ) -> &'j mut <Self::Head as AsDeref<Self::InnerDepth>>::Target
where 'i: 'j,

Gets a mutable reference to the inner observed value while triggering observation.

This method traverses the entire dereference chain, triggering DerefMut hooks on all observers in the chain. This ensures that any mutations through the returned reference are properly tracked by all relevant observers.

§Usage

Use this method when you need to access the inner value in a way that should be recorded as a potential mutation, such as when implementing specialized methods on observers.

§Example

Implementing Vec::pop for a VecObserver:

impl VecObserver<'i> {
    pub fn pop(&mut self) -> Option<T> {
        if self.as_deref().len() > self.initial_len() {
            // If the current length exceeds the initial length, the pop operation can be
            // expressed by `MutationKind::Append`, so we do not trigger full mutation.
            Observer::as_inner(self).pop()
        } else {
            // Otherwise, we need to treat the pop operation as `MutationKind::Replace`.
            Observer::track_inner(self).pop()
        }
    }
}

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§

Source§

impl<'i, H, S, N> Observer<'i> for GeneralObserver<'i, H, S, N>
where N: Unsigned, S: AsDerefMut<N> + 'i + ?Sized, H: GeneralHandler<S::Target>,