use std::marker::PhantomData;
use std::panic::Location;
mod ext;
pub use ext::{AnchorExt, AnchorSplit};
mod constant;
mod var;
pub use constant::Constant;
pub use var::{Var, VarSetter};
#[derive(Debug, PartialEq, Eq)]
pub enum Poll {
Updated,
Unchanged,
Pending,
}
pub struct Anchor<O, E: Engine + ?Sized> {
data: E::AnchorHandle,
phantom: PhantomData<O>,
}
impl<O, E: Engine> Anchor<O, E> {
pub fn new(data: E::AnchorHandle) -> Self {
Self {
data,
phantom: PhantomData,
}
}
pub fn token(&self) -> <E::AnchorHandle as AnchorHandle>::Token {
self.data.token()
}
}
impl<O, E: Engine> Clone for Anchor<O, E> {
fn clone(&self) -> Self {
Self {
data: self.data.clone(),
phantom: PhantomData,
}
}
}
impl<O, E: Engine> PartialEq for Anchor<O, E> {
fn eq(&self, other: &Self) -> bool {
self.token() == other.token()
}
}
impl<O, E: Engine> Eq for Anchor<O, E> {}
pub trait AnchorHandle: Sized + Clone {
type Token: Sized + Clone + Copy + PartialEq + Eq + std::hash::Hash;
fn token(&self) -> Self::Token;
}
pub trait Engine: 'static {
type AnchorHandle: AnchorHandle;
type DirtyHandle: DirtyHandle;
fn mount<I: AnchorInner<Self> + 'static>(inner: I) -> Anchor<I::Output, Self>;
}
pub trait DirtyHandle {
fn mark_dirty(&self);
}
pub trait OutputContext<'eng> {
type Engine: Engine + ?Sized;
fn get<'out, O: 'static>(&self, anchor: &Anchor<O, Self::Engine>) -> &'out O
where
'eng: 'out;
}
pub trait UpdateContext {
type Engine: Engine + ?Sized;
fn get<'out, 'slf, O: 'static>(&'slf self, anchor: &Anchor<O, Self::Engine>) -> &'out O
where
'slf: 'out;
fn request<'out, O: 'static>(
&mut self,
anchor: &Anchor<O, Self::Engine>,
necessary: bool,
) -> Poll;
fn unrequest<'out, O: 'static>(&mut self, anchor: &Anchor<O, Self::Engine>);
fn dirty_handle(&mut self) -> <Self::Engine as Engine>::DirtyHandle;
}
pub trait AnchorInner<E: Engine + ?Sized> {
type Output;
fn dirty(&mut self, child: &<E::AnchorHandle as AnchorHandle>::Token);
fn poll_updated<G: UpdateContext<Engine = E>>(&mut self, ctx: &mut G) -> Poll;
fn output<'slf, 'out, G: OutputContext<'out, Engine = E>>(
&'slf self,
ctx: &mut G,
) -> &'out Self::Output
where
'slf: 'out;
fn debug_location(&self) -> Option<(&'static str, &'static Location<'static>)> {
None
}
}