ranvier_std/nodes/
math.rs1use async_trait::async_trait;
2use num_traits::Num;
3use ranvier_core::{bus::Bus, outcome::Outcome, transition::Transition};
4use schemars::JsonSchema;
5use serde::{Deserialize, Serialize};
6use std::{fmt::Debug, marker::PhantomData};
7
8#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq)]
9pub enum MathOperation {
10 Add,
11 Sub,
12 Mul,
13 Div,
14}
15
16#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
17pub struct MathNode<T> {
18 pub operation: MathOperation,
19 pub operand: T,
20 #[serde(skip)]
21 pub _marker: PhantomData<T>,
22}
23
24impl<T> MathNode<T> {
25 pub fn new(operation: MathOperation, operand: T) -> Self {
26 Self {
27 operation,
28 operand,
29 _marker: PhantomData,
30 }
31 }
32}
33
34#[async_trait]
35impl<T> Transition<T, T> for MathNode<T>
36where
37 T: Num + Clone + Send + Sync + Debug + 'static,
38{
39 type Error = String;
40 type Resources = ();
41
42 async fn run(
43 &self,
44 input: T,
45 _resources: &Self::Resources,
46 _bus: &mut Bus,
47 ) -> Outcome<T, Self::Error> {
48 let result = match self.operation {
49 MathOperation::Add => input.clone() + self.operand.clone(),
50 MathOperation::Sub => input.clone() - self.operand.clone(),
51 MathOperation::Mul => input.clone() * self.operand.clone(),
52 MathOperation::Div => input.clone() / self.operand.clone(),
53 };
54
55 Outcome::next(result)
56 }
57}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62
63 #[tokio::test]
64 async fn math_add() {
65 let node = MathNode::new(MathOperation::Add, 10i64);
66 let mut bus = Bus::new();
67 let result = node.run(5i64, &(), &mut bus).await;
68 assert!(matches!(result, Outcome::Next(15)));
69 }
70
71 #[tokio::test]
72 async fn math_sub() {
73 let node = MathNode::new(MathOperation::Sub, 3i64);
74 let mut bus = Bus::new();
75 let result = node.run(10i64, &(), &mut bus).await;
76 assert!(matches!(result, Outcome::Next(7)));
77 }
78
79 #[tokio::test]
80 async fn math_mul() {
81 let node = MathNode::new(MathOperation::Mul, 4i64);
82 let mut bus = Bus::new();
83 let result = node.run(5i64, &(), &mut bus).await;
84 assert!(matches!(result, Outcome::Next(20)));
85 }
86
87 #[tokio::test]
88 async fn math_div() {
89 let node = MathNode::new(MathOperation::Div, 2i64);
90 let mut bus = Bus::new();
91 let result = node.run(10i64, &(), &mut bus).await;
92 assert!(matches!(result, Outcome::Next(5)));
93 }
94}