use std::ptr::NonNull;
use crate::Observe;
use crate::general::{DebugHandler, GeneralHandler, GeneralObserver, ReplaceHandler};
use crate::helper::macros::default_impl_ref_observe;
use crate::helper::{AsDeref, AsDerefMut, ObserverState, Unsigned};
use crate::observe::DefaultSpec;
pub type PointerObserver<'ob, S, D> = GeneralObserver<'ob, PointerHandler<<S as AsDeref<D>>::Target>, S, D>;
pub struct PointerHandler<T: ?Sized> {
ptr: Option<NonNull<T>>,
}
impl<T: ?Sized> ObserverState for PointerHandler<T> {
type Target = T;
fn invalidate(_: &mut Self, _: &T) {}
}
impl<T: ?Sized> GeneralHandler for PointerHandler<T> {
fn observe(value: &T) -> Self {
Self {
ptr: Some(NonNull::from(value)),
}
}
}
impl<T: ?Sized> ReplaceHandler for PointerHandler<T> {
unsafe fn is_replace(&self, value: &T) -> bool {
!std::ptr::eq(
value,
self.ptr
.expect("pointer should not be null in GeneralHandler::flush")
.as_ptr(),
)
}
}
impl<T: ?Sized> DebugHandler for PointerHandler<T> {
const NAME: &'static str = "PointerObserver";
}
impl Observe for std::fmt::Arguments<'_> {
type Observer<'ob, S, D>
= PointerObserver<'ob, S, D>
where
Self: 'ob,
D: Unsigned,
S: AsDerefMut<D, Target = Self> + ?Sized + 'ob;
type Spec = DefaultSpec;
}
default_impl_ref_observe! {
impl RefObserve for std::fmt::Arguments<'_>;
}