bloom-core 0.1.2

A react-like framework for descriptive UIs. Renderer Agnostic but built with HTML in mind.
Documentation
use std::hash::{DefaultHasher, Hash, Hasher};

use async_context::with_async_context_mut;

use crate::hook::Hook;

pub struct Cleanup(Box<dyn FnOnce()>);

impl From<()> for Cleanup {
    fn from(_: ()) -> Self {
        Self(Box::new(|| {}))
    }
}

impl<C> From<C> for Cleanup
where
    C: FnOnce() + 'static,
{
    fn from(cleanup: C) -> Self {
        Self(Box::new(cleanup))
    }
}

impl Cleanup {
    pub(crate) fn run(self) {
        let cleanup = self.0;
        cleanup()
    }
}

pub(crate) struct Effect(Box<dyn FnOnce() -> Cleanup + Send + Sync + 'static>);

impl Effect {
    pub(crate) fn run(self) -> Cleanup {
        let effect = self.0;
        effect()
    }
}

pub fn use_effect<A, C>(arg: A, effect: fn(A) -> C)
where
    A: Hash + Send + Sync + 'static,
    C: Into<Cleanup> + 'static,
{
    with_async_context_mut(|hook: Option<&mut Hook>| {
        if let Some(hook) = hook {
            let mut hasher = DefaultHasher::new();
            arg.hash(&mut hasher);
            let arg_hash = hasher.finish();

            hook.effects
                .push((arg_hash, Effect(Box::new(move || effect(arg).into()))));
        }
    })
}