Skip to content

Commit

Permalink
Add Then combinator and refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
matthunz committed Feb 18, 2024
1 parent 07d08b7 commit f114b67
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 20 deletions.
21 changes: 1 addition & 20 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1 @@
use std::rc::Rc;

pub struct Context<M, A> {
waker: Rc<dyn Fn(Rc<dyn Fn(&mut M) -> Option<A>>)>,
}

pub trait Task<M, A = ()> {
type Output;

type State;

fn build(&mut self, cx: &Context<M, A>, model: &mut M) -> (Self::Output, Self::State);

fn rebuild(
&mut self,
cx: &Context<M, A>,
model: &mut M,
state: &mut Self::State,
) -> Self::Output;
}
pub mod task;
51 changes: 51 additions & 0 deletions src/task/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use std::rc::Rc;

mod then;
pub use self::then::Then;

pub struct Context<M, A> {
waker: Rc<dyn Fn(Rc<dyn Fn(&mut M) -> Option<A>>)>,
}

pub trait Task<M, A = ()> {
type Output;

type State;

fn build(&mut self, cx: &Context<M, A>, model: &mut M) -> (Self::Output, Self::State);

fn rebuild(
&mut self,
cx: &Context<M, A>,
model: &mut M,
state: &mut Self::State,
) -> Self::Output;

fn then<F, T>(self, f: F) -> Then<Self, F, T, M>
where
Self: Sized + 'static,
F: FnMut(&mut M, Self::Output) -> T + 'static,
T: Task<M> + 'static,
M: 'static,
{
Then::new(self, f)
}
}

impl<M> Task<M> for () {
type Output = ();

type State = ();

fn build(&mut self, _cx: &Context<M, ()>, _model: &mut M) -> (Self::Output, Self::State) {
((), ())
}

fn rebuild(
&mut self,
_cx: &Context<M, ()>,
_model: &mut M,
_state: &mut Self::State,
) -> Self::Output {
}
}
48 changes: 48 additions & 0 deletions src/task/then.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
use super::{Context, Task};
use std::marker::PhantomData;

pub struct Then<T1, F, T2, M> {
task: T1,
f: F,
_marker: PhantomData<(T2, M)>,
}

impl<T1, F, T2, M> Then<T1, F, T2, M> {
pub(super) fn new(task: T1, f: F) -> Self {
Self {
task,
f,
_marker: PhantomData,
}
}
}

impl<T1, F, T2, M> Task<M> for Then<T1, F, T2, M>
where
T1: Task<M> + 'static,
F: FnMut(&mut M, T1::Output) -> T2 + 'static,
T2: Task<M> + 'static,
M: 'static,
{
type Output = T2::Output;

type State = (T1::State, T2::State);

fn build(&mut self, cx: &Context<M, ()>, model: &mut M) -> (Self::Output, Self::State) {
let (output, state) = self.task.build(cx, model);
let mut next = (self.f)(model, output);
let (next_output, next_state) = next.build(cx, model);
(next_output, (state, next_state))
}

fn rebuild(
&mut self,
cx: &Context<M, ()>,
model: &mut M,
state: &mut Self::State,
) -> Self::Output {
let output = self.task.rebuild(cx, model, &mut state.0);
let mut next = (self.f)(model, output);
next.rebuild(cx, model, &mut state.1)
}
}

0 comments on commit f114b67

Please sign in to comment.