diff --git a/crates/graph/src/lib.rs b/crates/graph/src/lib.rs index 7dfa89e..78fc57d 100644 --- a/crates/graph/src/lib.rs +++ b/crates/graph/src/lib.rs @@ -107,7 +107,7 @@ impl Graph { } impl Graph { - pub fn set_output + 'static>(&mut self, rule: R) { + pub fn set_output>(&mut self, rule: R) { let input = self.add_rule(rule); self.output = Some(input.node_idx); } @@ -126,14 +126,18 @@ impl Graph { return self.add_node(ConstNode::new(value.clone())); } - pub fn add_rule + 'static, V: Clone + 'static>(&mut self, rule: R) -> Input { + pub fn add_rule(&mut self, rule: R) -> Input + where + R: Rule, + R::Output: Clone, + { return self.add_node(RuleNode::new(rule)); } - pub fn add_invalidatable_rule(&mut self, mut f: F) -> Input + pub fn add_invalidatable_rule(&mut self, mut f: F) -> Input where - R: Rule + 'static, - V: Clone + 'static, + R: Rule, + R::Output: Clone, F: FnMut(InvalidationSignal) -> R, { let node_idx = Rc::new(Cell::new(None)); @@ -189,22 +193,23 @@ impl Graph { } impl Graph { - pub fn set_async_output + 'static>(&mut self, rule: R) { + pub fn set_async_output>(&mut self, rule: R) { let input = self.add_async_rule(rule); self.output = Some(input.node_idx); } - pub fn add_async_rule + 'static, V: Clone + 'static>( - &mut self, - rule: R, - ) -> Input { + pub fn add_async_rule(&mut self, rule: R) -> Input + where + R: AsyncRule, + R::Output: Clone, + { self.add_node(AsyncRuleNode::new(rule)) } - pub fn add_invalidatable_async_rule(&mut self, mut f: F) -> Input + pub fn add_invalidatable_async_rule(&mut self, mut f: F) -> Input where - R: AsyncRule + 'static, - V: Clone + 'static, + R: AsyncRule, + R::Output: Clone, F: FnMut(InvalidationSignal) -> R, { let node_idx = Rc::new(Cell::new(None)); @@ -494,7 +499,7 @@ struct RuleNode { synchronicity: std::marker::PhantomData, } -impl, V, S> RuleNode { +impl RuleNode { fn new(rule: R) -> Self { Self { rule, @@ -505,7 +510,7 @@ impl, V, S> RuleNode { } } -impl + 'static, V: Clone + 'static, S: Synchronicity> Node for RuleNode { +impl Node for RuleNode { fn is_valid(&self) -> bool { self.valid } @@ -531,7 +536,7 @@ impl + 'static, V: Clone + 'static, S: Synchronicity> Node for S::make_update_result() } - fn value_rc(&self) -> Rc>> { + fn value_rc(&self) -> Rc>> { Rc::clone(&self.value) } } @@ -542,7 +547,7 @@ struct AsyncRuleNode { valid: bool, } -impl, V> AsyncRuleNode { +impl AsyncRuleNode { fn new(rule: R) -> Self { Self { rule, @@ -552,7 +557,10 @@ impl, V> AsyncRuleNode { } } -impl + 'static, V: Clone + 'static> Node for AsyncRuleNode { +impl Node for AsyncRuleNode +where + R::Output: Clone, +{ fn is_valid(&self) -> bool { self.valid } @@ -575,12 +583,12 @@ impl + 'static, V: Clone + 'static> Node for As Box::pin(self.do_update()) } - fn value_rc(&self) -> Rc>> { + fn value_rc(&self) -> Rc>> { Rc::clone(&self.value) } } -impl, V> AsyncRuleNode { +impl AsyncRuleNode { async fn do_update(&mut self) { let new_value = self.rule.evaluate().await; self.valid = true; @@ -588,16 +596,20 @@ impl, V> AsyncRuleNode { } } -pub trait Rule { +pub trait Rule: 'static { + type Output; + fn visit_inputs(&mut self, visitor: &mut impl InputVisitor); - fn evaluate(&mut self) -> Output; + fn evaluate(&mut self) -> Self::Output; } -pub trait AsyncRule { +pub trait AsyncRule: 'static { + type Output: 'static; + fn visit_inputs(&mut self, visitor: &mut impl InputVisitor); - async fn evaluate(&mut self) -> Output; + async fn evaluate(&mut self) -> Self::Output; } pub trait InputVisitor { @@ -616,7 +628,8 @@ mod tests { } struct ConstantRule(i32); - impl Rule for ConstantRule { + impl Rule for ConstantRule { + type Output = i32; fn visit_inputs(&mut self, _visitor: &mut impl InputVisitor) {} fn evaluate(&mut self) -> i32 { self.0 @@ -641,7 +654,8 @@ mod tests { } struct Double(Input); - impl Rule for Double { + impl Rule for Double { + type Output = i32; fn visit_inputs(&mut self, visitor: &mut impl InputVisitor) { visitor.visit(&mut self.0); } @@ -667,7 +681,8 @@ mod tests { assert_eq!(graph.freeze().unwrap().evaluate(), 168); } struct Inc(i32); - impl Rule for Inc { + impl Rule for Inc { + type Output = i32; fn visit_inputs(&mut self, _visitor: &mut impl InputVisitor) {} fn evaluate(&mut self) -> i32 { self.0 += 1; @@ -694,7 +709,8 @@ mod tests { } struct Add(Input, Input); - impl Rule for Add { + impl Rule for Add { + type Output = i32; fn visit_inputs(&mut self, visitor: &mut impl InputVisitor) { visitor.visit(&mut self.0); visitor.visit(&mut self.1); @@ -741,7 +757,8 @@ mod tests { } struct DeferredInput(Rc>>>); - impl Rule for DeferredInput { + impl Rule for DeferredInput { + type Output = i32; fn visit_inputs(&mut self, visitor: &mut impl InputVisitor) { let mut borrowed = self.0.borrow_mut(); let input = borrowed.as_mut().unwrap(); @@ -811,7 +828,8 @@ mod tests { #[tokio::test] async fn async_rule() { struct AsyncConst(i32); - impl AsyncRule for AsyncConst { + impl AsyncRule for AsyncConst { + type Output = i32; fn visit_inputs(&mut self, _visitor: &mut impl InputVisitor) {} async fn evaluate(&mut self) -> i32 { self.0