diff --git a/src/task/from_fn.rs b/src/task/from_fn.rs new file mode 100644 index 0000000..3afed9f --- /dev/null +++ b/src/task/from_fn.rs @@ -0,0 +1,39 @@ +use super::Task; +use std::marker::PhantomData; + +pub fn from_fn(f: F) -> FromFn +where + F: FnMut(&mut M) -> O, +{ + FromFn { + f, + _marker: PhantomData, + } +} + +pub struct FromFn { + f: F, + _marker: PhantomData, +} + +impl Task for FromFn +where + F: FnMut(&mut M) -> O, +{ + type Output = O; + + type State = (); + + fn build(&mut self, _cx: &super::Context, model: &mut M) -> (Self::Output, Self::State) { + ((self.f)(model), ()) + } + + fn rebuild( + &mut self, + _cx: &super::Context, + model: &mut M, + _state: &mut Self::State, + ) -> Self::Output { + (self.f)(model) + } +} diff --git a/src/task/mod.rs b/src/task/mod.rs index a445957..9810c98 100644 --- a/src/task/mod.rs +++ b/src/task/mod.rs @@ -1,5 +1,8 @@ use std::rc::Rc; +mod from_fn; +pub use self::from_fn::{from_fn, FromFn}; + mod then; pub use self::then::Then; @@ -7,6 +10,12 @@ pub struct Context { waker: Rc Option>)>, } +impl Context { + pub fn update(&self, f: impl Fn(&mut M) -> Option + 'static) { + (self.waker)(Rc::new(f)) + } +} + pub trait Task { type Output;