From d89a68ef67eedd7771a04534db56e23e8d5ee225 Mon Sep 17 00:00:00 2001 From: Raphael Date: Mon, 2 Feb 2026 08:22:31 +0100 Subject: [PATCH 1/3] fix: made context mutable to prevent panic when sharing --- taurus/src/context/argument.rs | 18 +-- taurus/src/context/executor.rs | 63 ++++---- taurus/src/context/macros.rs | 10 +- taurus/src/context/registry.rs | 2 +- taurus/src/implementation/array.rs | 102 ++++++------ taurus/src/implementation/boolean.rs | 14 +- taurus/src/implementation/control.rs | 46 ++---- taurus/src/implementation/http.rs | 37 +++-- taurus/src/implementation/number.rs | 222 ++++++++++++++++++++++----- taurus/src/implementation/object.rs | 12 +- taurus/src/implementation/text.rs | 64 ++++---- taurus/src/main.rs | 39 +++-- 12 files changed, 397 insertions(+), 232 deletions(-) diff --git a/taurus/src/context/argument.rs b/taurus/src/context/argument.rs index 8789fe8..1bbbe6a 100644 --- a/taurus/src/context/argument.rs +++ b/taurus/src/context/argument.rs @@ -24,10 +24,10 @@ pub trait TryFromArgument: Sized { fn try_from_argument(a: &Argument) -> Result; } -fn type_err(msg: &str) -> Signal { +fn type_err(msg: &str, a: &Argument) -> Signal { Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", - msg.to_string(), + format!("{} but it was the arugment: {:?}", msg, a), )) } @@ -35,7 +35,7 @@ impl TryFromArgument for Value { fn try_from_argument(a: &Argument) -> Result { match a { Argument::Eval(v) => Ok(v.clone()), - _ => Err(type_err("Expected evaluated value but got lazy thunk")), + _ => Err(type_err("Expected evaluated value but got lazy thunk", a)), } } } @@ -46,7 +46,7 @@ impl TryFromArgument for f64 { Argument::Eval(Value { kind: Some(Kind::NumberValue(n)), }) => Ok(*n), - _ => Err(type_err("Expected number")), + _ => Err(type_err("Expected number", a)), } } } @@ -57,7 +57,7 @@ impl TryFromArgument for bool { Argument::Eval(Value { kind: Some(Kind::BoolValue(b)), }) => Ok(*b), - _ => Err(type_err("Expected boolean")), + _ => Err(type_err("Expected boolean", a)), } } } @@ -68,7 +68,7 @@ impl TryFromArgument for String { Argument::Eval(Value { kind: Some(Kind::StringValue(s)), }) => Ok(s.clone()), - _ => Err(type_err("Expected string")), + _ => Err(type_err("Expected string", a)), } } } @@ -79,7 +79,7 @@ impl TryFromArgument for Struct { Argument::Eval(Value { kind: Some(Kind::StructValue(s)), }) => Ok(s.clone()), - _ => Err(type_err("Expected struct")), + _ => Err(type_err("Expected struct", a)), } } } @@ -90,9 +90,9 @@ impl TryFromArgument for ListValue { Argument::Eval(Value { kind: Some(Kind::ListValue(list)), }) => Ok(list.clone()), - _ => Err(Signal::Failure(RuntimeError::simple_str( + _ => Err(Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", - "Expected array (ListValue)", + format!("Expected array (ListValue) but it was: {:?}", a), ))), } } diff --git a/taurus/src/context/executor.rs b/taurus/src/context/executor.rs index 05ef442..2622f8a 100644 --- a/taurus/src/context/executor.rs +++ b/taurus/src/context/executor.rs @@ -3,38 +3,31 @@ use crate::context::context::{Context, ContextResult}; use crate::context::registry::FunctionStore; use crate::context::signal::Signal; use crate::error::RuntimeError; -use std::cell::RefCell; use std::collections::HashMap; use tucana::shared::NodeFunction; pub struct Executor<'a> { functions: &'a FunctionStore, nodes: HashMap, - context: RefCell, } impl<'a> Executor<'a> { - pub fn new( - functions: &'a FunctionStore, - nodes: HashMap, - context: Context, - ) -> Self { - Executor { - functions, - nodes, - context: RefCell::new(context), - } + pub fn new(functions: &'a FunctionStore, nodes: HashMap) -> Self { + Executor { functions, nodes } } - pub fn execute(&self, starting_node_id: i64) -> Signal { + pub fn execute(&self, starting_node_id: i64, ctx: &mut Context) -> Signal { let mut current_node_id = starting_node_id; loop { let node = match self.nodes.get(¤t_node_id) { None => { - return Signal::Failure(RuntimeError::simple_str( + return Signal::Failure(RuntimeError::simple( "NodeNotFound", - "The node with the id was not found", + format!( + "The node with the database id: {} was not found", + current_node_id + ), )); } Some(n) => n.clone(), @@ -42,9 +35,12 @@ impl<'a> Executor<'a> { let entry = match self.functions.get(node.runtime_function_id.as_str()) { None => { - return Signal::Failure(RuntimeError::simple_str( + return Signal::Failure(RuntimeError::simple( "FunctionNotFound", - "The function was not found", + format!( + "The function {} (database id: {}) was not found", + node.runtime_function_id, node.database_id + ), )); } Some(f) => f, @@ -57,7 +53,7 @@ impl<'a> Executor<'a> { None => { return Signal::Failure(RuntimeError::simple_str( "NodeValueNotFound", - "Missing parameter value", + "Missing parameter value: {}", )); } }; @@ -76,7 +72,6 @@ impl<'a> Executor<'a> { args.push(Argument::Eval(val.clone())) } tucana::shared::node_value::Value::ReferenceValue(reference) => { - let mut ctx = self.context.borrow_mut(); let value = ctx.get(reference.node_id); match value { ContextResult::Error(runtime_error) => { @@ -108,19 +103,26 @@ impl<'a> Executor<'a> { if matches!(mode, ParameterNode::Eager) && let Argument::Thunk(id) = *a { - match self.execute(id) { - Signal::Success(v) => *a = Argument::Eval(v), - s @ (Signal::Failure(_) - | Signal::Return(_) - | Signal::Respond(_) - | Signal::Stop) => return s, + match self.execute(id, ctx) { + Signal::Success(v) => { + log::debug!( + "Successfully executed node with database id {}, resulted in value: {:?}", + id, + a + ); + *a = Argument::Eval(v) + } + Signal::Failure(err) => { + log::error!("Failed to execute node with database id: {}", id); + return Signal::Failure(err); + } + s @ (Signal::Return(_) | Signal::Respond(_) | Signal::Stop) => return s, } } } - let mut run = |node_id: i64| self.execute(node_id); - let mut ctx = self.context.borrow_mut(); - let result = (entry.handler)(&args, &mut ctx, &mut run); + let mut run = |node_id: i64, ctx: &mut Context| self.execute(node_id, ctx); + let result = (entry.handler)(&args, ctx, &mut run); match result { Signal::Success(value) => { @@ -128,6 +130,11 @@ impl<'a> Executor<'a> { current_node_id = next_node_id; continue; } else { + log::debug!( + "Successfully executed node with database id {}, resulted in value: {:?}", + current_node_id, + value + ); return Signal::Success(value); } } diff --git a/taurus/src/context/macros.rs b/taurus/src/context/macros.rs index 27f7826..ead9e8a 100644 --- a/taurus/src/context/macros.rs +++ b/taurus/src/context/macros.rs @@ -20,7 +20,15 @@ macro_rules! args { $ty as $crate::context::argument::TryFromArgument >::try_from_argument(& $args_ident[__i]) { Ok(v) => v, - Err(sig) => return sig, + Err(sig) => { + log::debug!( + "Failed to parse argument '{}' (index {}, type {})", + stringify!($name), + __i, + ::core::any::type_name::<$ty>(), + ); + return sig; + } }; __i += 1; )+ diff --git a/taurus/src/context/registry.rs b/taurus/src/context/registry.rs index c2b399c..fd1e42b 100644 --- a/taurus/src/context/registry.rs +++ b/taurus/src/context/registry.rs @@ -8,7 +8,7 @@ use std::collections::HashMap; /// - For lazy params, the executor will pass Argument::Thunk(node_id). /// - If a handler wants to execute a lazy arg, it calls run(node_id). pub type HandlerFn = - fn(args: &[Argument], ctx: &mut Context, run: &mut dyn FnMut(i64) -> Signal) -> Signal; + fn(args: &[Argument], ctx: &mut Context, run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal; pub struct HandlerFunctionEntry { pub handler: HandlerFn, diff --git a/taurus/src/implementation/array.rs b/taurus/src/implementation/array.rs index c80c0a8..6637637 100644 --- a/taurus/src/implementation/array.rs +++ b/taurus/src/implementation/array.rs @@ -10,38 +10,38 @@ use crate::{context::context::Context, error::RuntimeError}; pub fn collect_array_functions() -> Vec<(&'static str, HandlerFunctionEntry)> { vec![ - ("std::array::at", HandlerFn::eager(at, 2)), - ("std::array::concat", HandlerFn::eager(concat, 2)), - ("std::array::filter", HandlerFn::eager(filter, 2)), - ("std::array::find", HandlerFn::eager(find, 2)), - ("std::array::find_last", HandlerFn::eager(find_last, 2)), - ("std::array::find_index", HandlerFn::eager(find_index, 2)), - ("std::array::first", HandlerFn::eager(first, 1)), - ("std::array::last", HandlerFn::eager(last, 1)), - ("std::array::for_each", HandlerFn::eager(for_each, 0)), - ("std::array::map", HandlerFn::eager(map, 2)), - ("std::array::push", HandlerFn::eager(push, 2)), - ("std::array::pop", HandlerFn::eager(pop, 1)), - ("std::array::remove", HandlerFn::eager(remove, 2)), - ("std::array::is_empty", HandlerFn::eager(is_empty, 1)), - ("std::array::size", HandlerFn::eager(size, 1)), - ("std::array::index_of", HandlerFn::eager(index_of, 2)), - ("std::array::to_unique", HandlerFn::eager(to_unique, 1)), - ("std::array::sort", HandlerFn::eager(sort, 2)), + ("std::list::at", HandlerFn::eager(at, 2)), + ("std::list::concat", HandlerFn::eager(concat, 2)), + ("std::list::filter", HandlerFn::eager(filter, 2)), + ("std::list::find", HandlerFn::eager(find, 2)), + ("std::list::find_last", HandlerFn::eager(find_last, 2)), + ("std::list::find_index", HandlerFn::eager(find_index, 2)), + ("std::list::first", HandlerFn::eager(first, 1)), + ("std::list::last", HandlerFn::eager(last, 1)), + ("std::list::for_each", HandlerFn::eager(for_each, 0)), + ("std::list::map", HandlerFn::eager(map, 2)), + ("std::list::push", HandlerFn::eager(push, 2)), + ("std::list::pop", HandlerFn::eager(pop, 1)), + ("std::list::remove", HandlerFn::eager(remove, 2)), + ("std::list::is_empty", HandlerFn::eager(is_empty, 1)), + ("std::list::size", HandlerFn::eager(size, 1)), + ("std::list::index_of", HandlerFn::eager(index_of, 2)), + ("std::list::to_unique", HandlerFn::eager(to_unique, 1)), + ("std::list::sort", HandlerFn::eager(sort, 2)), ( - "std::array::sort_reverse", + "std::list::sort_reverse", HandlerFn::eager(sort_reverse, 2), ), - ("std::array::reverse", HandlerFn::eager(reverse, 1)), - ("std::array::flat", HandlerFn::eager(flat, 1)), - ("std::array::min", HandlerFn::eager(min, 1)), - ("std::array::max", HandlerFn::eager(max, 1)), - ("std::array::sum", HandlerFn::eager(sum, 1)), - ("std::array::join", HandlerFn::eager(join, 2)), + ("std::list::reverse", HandlerFn::eager(reverse, 1)), + ("std::list::flat", HandlerFn::eager(flat, 1)), + ("std::list::min", HandlerFn::eager(min, 1)), + ("std::list::max", HandlerFn::eager(max, 1)), + ("std::list::sum", HandlerFn::eager(sum, 1)), + ("std::list::join", HandlerFn::eager(join, 2)), ] } -fn at(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn at(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { // array, index args!(args => array: ListValue, index: f64); @@ -61,7 +61,7 @@ fn at(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal } } -fn concat(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn concat(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => lhs_v: Value, rhs_v: Value); let Kind::ListValue(lhs) = lhs_v.kind.clone().ok_or(()).unwrap_or(Kind::NullValue(0)) else { @@ -91,7 +91,7 @@ fn concat(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Si }) } -fn filter(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn filter(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => array_v: Value, predicate_v: Value); let Kind::ListValue(array) = array_v.kind.ok_or(()).unwrap_or(Kind::NullValue(0)) else { return Signal::Failure(RuntimeError::simple( @@ -132,7 +132,7 @@ fn filter(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Si }) } -fn find(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn find(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => array_v: Value, predicate_v: Value); let Kind::ListValue(array) = array_v.kind.ok_or(()).unwrap_or(Kind::NullValue(0)) else { return Signal::Failure(RuntimeError::simple_str( @@ -176,7 +176,7 @@ fn find(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Sign } } -fn find_last(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn find_last(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => array_v: Value, predicate_v: Value); let Kind::ListValue(array) = array_v.kind.ok_or(()).unwrap_or(Kind::NullValue(0)) else { return Signal::Failure(RuntimeError::simple_str( @@ -222,7 +222,7 @@ fn find_last(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> fn find_index( args: &[Argument], _ctx: &mut Context, - _run: &mut dyn FnMut(i64) -> Signal, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, ) -> Signal { args!(args => array_v: Value, predicate_v: Value); let Kind::ListValue(array) = array_v.kind.ok_or(()).unwrap_or(Kind::NullValue(0)) else { @@ -267,7 +267,7 @@ fn find_index( } } -fn first(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn first(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => array: ListValue); match array.values.first() { @@ -279,7 +279,7 @@ fn first(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Sig } } -fn last(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn last(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => array: ListValue); match array.values.last() { Some(v) => Signal::Success(v.clone()), @@ -296,14 +296,14 @@ fn last(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Sign /// The definition itself takes in an array and a node /// The node itself will be executed on the arrays elements /// If the node is (CONSUMER) resolved it goes in this function --> therefor all code is already executed -fn for_each(_args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn for_each(_args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { // Already executed by the engine (consumer); return Null Signal::Success(Value { kind: Some(Kind::NullValue(0)), }) } -fn map(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn map(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { // (array, transformed_results[]) args!(args => _array_v: Value, transform_v: Value); let Kind::ListValue(transform_result) = @@ -319,7 +319,7 @@ fn map(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signa }) } -fn push(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn push(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => array_v: Value, item: Value); let Kind::ListValue(mut array) = array_v.kind.ok_or(()).unwrap_or(Kind::NullValue(0)) else { return Signal::Failure(RuntimeError::simple_str( @@ -333,7 +333,7 @@ fn push(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Sign }) } -fn pop(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn pop(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => array_v: Value); let Kind::ListValue(mut array) = array_v.kind.ok_or(()).unwrap_or(Kind::NullValue(0)) else { return Signal::Failure(RuntimeError::simple_str( @@ -347,7 +347,7 @@ fn pop(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signa }) } -fn remove(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn remove(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => array_v: Value, item: Value); let Kind::ListValue(mut array) = array_v.kind.ok_or(()).unwrap_or(Kind::NullValue(0)) else { return Signal::Failure(RuntimeError::simple_str( @@ -369,7 +369,7 @@ fn remove(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Si } } -fn is_empty(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn is_empty(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => array_v: Value); let Kind::ListValue(array) = array_v.kind.ok_or(()).unwrap_or(Kind::NullValue(0)) else { return Signal::Failure(RuntimeError::simple_str( @@ -382,7 +382,7 @@ fn is_empty(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> }) } -fn size(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn size(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => array_v: Value); let Kind::ListValue(array) = array_v.kind.ok_or(()).unwrap_or(Kind::NullValue(0)) else { return Signal::Failure(RuntimeError::simple_str( @@ -395,7 +395,7 @@ fn size(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Sign }) } -fn index_of(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn index_of(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => array_v: Value, item: Value); let Kind::ListValue(array) = array_v.kind.ok_or(()).unwrap_or(Kind::NullValue(0)) else { return Signal::Failure(RuntimeError::simple_str( @@ -415,7 +415,7 @@ fn index_of(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> } } -fn to_unique(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn to_unique(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => array_v: Value); let Kind::ListValue(array) = array_v.kind.ok_or(()).unwrap_or(Kind::NullValue(0)) else { return Signal::Failure(RuntimeError::simple_str( @@ -436,7 +436,7 @@ fn to_unique(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> }) } -fn sort(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn sort(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { // array, resolved comparator yields -1/0/1 sequence args!(args => array_v: Value, cmp_v: Value); let Kind::ListValue(mut arr) = array_v.kind.ok_or(()).unwrap_or(Kind::NullValue(0)) else { @@ -478,7 +478,7 @@ fn sort(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Sign fn sort_reverse( args: &[Argument], _ctx: &mut Context, - _run: &mut dyn FnMut(i64) -> Signal, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, ) -> Signal { args!(args => array_v: Value, cmp_v: Value); let Kind::ListValue(mut arr) = array_v.kind.ok_or(()).unwrap_or(Kind::NullValue(0)) else { @@ -519,7 +519,7 @@ fn sort_reverse( }) } -fn reverse(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn reverse(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => array_v: Value); let Kind::ListValue(mut array) = array_v.kind.ok_or(()).unwrap_or(Kind::NullValue(0)) else { return Signal::Failure(RuntimeError::simple_str( @@ -533,7 +533,7 @@ fn reverse(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> S }) } -fn flat(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn flat(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => array_v: Value); let Kind::ListValue(array) = array_v.kind.ok_or(()).unwrap_or(Kind::NullValue(0)) else { return Signal::Failure(RuntimeError::simple_str( @@ -555,7 +555,7 @@ fn flat(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Sign }) } -fn min(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn min(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => array: ListValue); let mut nums: Vec = Vec::new(); @@ -576,7 +576,7 @@ fn min(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signa } } -fn max(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn max(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => array: ListValue); let mut nums: Vec = Vec::new(); @@ -597,7 +597,7 @@ fn max(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signa } } -fn sum(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn sum(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => array: ListValue); let mut s = 0.0; @@ -612,7 +612,7 @@ fn sum(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signa }) } -fn join(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn join(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => array: ListValue, separator: String); let mut parts: Vec = Vec::new(); @@ -690,7 +690,7 @@ mod tests { } } - fn dummy_run(_: i64) -> Signal { + fn dummy_run(_: i64, _: &mut Context) -> Signal { Signal::Success(Value { kind: Some(Kind::NullValue(0)), }) diff --git a/taurus/src/implementation/boolean.rs b/taurus/src/implementation/boolean.rs index 7161a13..28107f8 100644 --- a/taurus/src/implementation/boolean.rs +++ b/taurus/src/implementation/boolean.rs @@ -19,14 +19,14 @@ pub fn collect_boolean_functions() -> Vec<(&'static str, HandlerFunctionEntry)> ] } -fn as_number(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn as_number(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => value: bool); Signal::Success(Value { kind: Some(Kind::NumberValue((value as i64) as f64)), }) } -fn as_text(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn as_text(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => value: bool); Signal::Success(Value { kind: Some(Kind::StringValue(value.to_string())), @@ -36,7 +36,7 @@ fn as_text(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> S fn from_number( args: &[Argument], _ctx: &mut Context, - _run: &mut dyn FnMut(i64) -> Signal, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, ) -> Signal { args!(args => number: f64); let is_zero = number == 0.0; @@ -45,7 +45,7 @@ fn from_number( }) } -fn from_text(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn from_text(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => text: String); match text.to_lowercase().parse::() { @@ -59,14 +59,14 @@ fn from_text(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> } } -fn is_equal(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn is_equal(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => lhs: bool, rhs: bool); Signal::Success(Value { kind: Some(Kind::BoolValue(lhs == rhs)), }) } -fn negate(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn negate(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => value: bool); Signal::Success(Value { kind: Some(Kind::BoolValue(!value)), @@ -122,7 +122,7 @@ mod tests { } // dummy `run` closure (unused by these handlers) - fn dummy_run(_: i64) -> Signal { + fn dummy_run(_: i64, _: &mut Context) -> Signal { Signal::Success(Value { kind: Some(Kind::BoolValue(true)), }) diff --git a/taurus/src/implementation/control.rs b/taurus/src/implementation/control.rs index d9671a8..ca8ce05 100644 --- a/taurus/src/implementation/control.rs +++ b/taurus/src/implementation/control.rs @@ -23,41 +23,31 @@ pub fn collect_control_functions() -> Vec<(&'static str, HandlerFunctionEntry)> ] } -fn stop(_args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn stop(_args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { Signal::Stop } -fn r#return(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn r#return(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => value: Value); Signal::Return(value) } -fn r#if(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn r#if(args: &[Argument], ctx: &mut Context, run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { let [ Argument::Eval(Value { - kind: Some(Kind::StringValue(text)), + kind: Some(Kind::BoolValue(bool)), }), Argument::Thunk(if_pointer), ] = args else { return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", - format!("Expected a string value but received {:?}", args), + format!("Expected a bool value but received {:?}", args), )); }; - let bool: bool = match text.to_lowercase().parse() { - Ok(value) => value, - Err(_) => { - return Signal::Failure(RuntimeError::simple( - "InvalidArgumentRuntimeError", - format!("Failed to parse boolean from string: {:?}", text), - )); - } - }; - - if bool { - _run(*if_pointer) + if *bool { + run(*if_pointer, ctx) } else { Signal::Return(Value { kind: Some(Kind::NullValue(0)), @@ -65,10 +55,10 @@ fn r#if(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Sign } } -fn if_else(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn if_else(args: &[Argument], ctx: &mut Context, run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { let [ Argument::Eval(Value { - kind: Some(Kind::StringValue(text)), + kind: Some(Kind::BoolValue(bool)), }), Argument::Thunk(if_pointer), Argument::Thunk(else_pointer), @@ -76,23 +66,13 @@ fn if_else(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> S else { return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", - format!("Expected a string value but received {:?}", args), + format!("Expected a bool value but received {:?}", args), )); }; - let bool: bool = match text.to_lowercase().parse() { - Ok(value) => value, - Err(_) => { - return Signal::Failure(RuntimeError::simple( - "InvalidArgumentRuntimeError", - format!("Failed to parse boolean from string: {:?}", text), - )); - } - }; - - if bool { - _run(*if_pointer) + if *bool { + run(*if_pointer, ctx) } else { - _run(*else_pointer) + run(*else_pointer, ctx) } } diff --git a/taurus/src/implementation/http.rs b/taurus/src/implementation/http.rs index b7a7576..905ee40 100644 --- a/taurus/src/implementation/http.rs +++ b/taurus/src/implementation/http.rs @@ -5,7 +5,7 @@ use crate::context::registry::{HandlerFn, HandlerFunctionEntry, IntoFunctionEntr use crate::context::signal::Signal; use crate::error::RuntimeError; use tucana::shared::value::Kind; -use tucana::shared::{Struct, Value}; +use tucana::shared::{ListValue, Struct, Value}; pub fn collect_http_functions() -> Vec<(&'static str, HandlerFunctionEntry)> { vec![ @@ -14,11 +14,15 @@ pub fn collect_http_functions() -> Vec<(&'static str, HandlerFunctionEntry)> { "http::response::create", HandlerFn::eager(create_response, 4), ), - ("http::control::respond", HandlerFn::eager(respond, 3)), + ("rest::control::respond", HandlerFn::eager(respond, 3)), ] } -fn respond(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn respond( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => struct_val: Struct); let fields = &struct_val.fields; @@ -43,10 +47,10 @@ fn respond(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> S )); }; - let Some(Kind::StructValue(_headers_struct)) = &headers_val.kind else { - return Signal::Failure(RuntimeError::simple( + let Some(Kind::ListValue(_headers_struct)) = &headers_val.kind else { + return Signal::Failure(RuntimeError::simple_str( "InvalidArgumentRuntimeError", - "Expected 'headers' to be StructValue".to_string(), + "Expected 'headers' to be ListValue", )); }; @@ -72,9 +76,9 @@ fn respond(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> S fn create_request( args: &[Argument], _ctx: &mut Context, - _run: &mut dyn FnMut(i64) -> Signal, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, ) -> Signal { - args!(args => http_method: String, headers: Struct, http_url: String, payload: Value); + args!(args => http_method: String, headers: ListValue, http_url: String, payload: Value); let mut fields = std::collections::HashMap::new(); fields.insert( @@ -94,7 +98,7 @@ fn create_request( fields.insert( "headers".to_string(), Value { - kind: Some(Kind::StructValue(headers.clone())), + kind: Some(Kind::ListValue(headers.clone())), }, ); fields.insert("body".to_string(), payload.clone()); @@ -107,22 +111,29 @@ fn create_request( fn create_response( args: &[Argument], _ctx: &mut Context, - _run: &mut dyn FnMut(i64) -> Signal, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, ) -> Signal { - args!(args => http_status_code: f64, headers: Struct, payload: Value); + args!(args => http_status_code: String, headers: ListValue, payload: Value); let mut fields = std::collections::HashMap::new(); + let code = match http_status_code.as_str().parse::() { + Ok(c) => c, + Err(_) => return Signal::Failure(RuntimeError::simple_str( + "InvalidArgumentExeption", + "Expected http_status_code to be parsed to float", + )), + }; fields.insert( "status_code".to_string(), Value { - kind: Some(Kind::NumberValue(http_status_code)), + kind: Some(Kind::NumberValue(code)), }, ); fields.insert( "headers".to_string(), Value { - kind: Some(Kind::StructValue(headers.clone())), + kind: Some(Kind::ListValue(headers.clone())), }, ); fields.insert("payload".to_string(), payload.clone()); diff --git a/taurus/src/implementation/number.rs b/taurus/src/implementation/number.rs index 8e489a6..19c53b8 100644 --- a/taurus/src/implementation/number.rs +++ b/taurus/src/implementation/number.rs @@ -37,7 +37,7 @@ pub fn collect_number_functions() -> Vec<(&'static str, HandlerFunctionEntry)> { ("std::number::min", HandlerFn::eager(min, 2)), ("std::number::max", HandlerFn::eager(max, 2)), ("std::number::negate", HandlerFn::eager(negate, 1)), - ("std::number::random", HandlerFn::eager(random, 2)), + ("std::number::random_number", HandlerFn::eager(random, 2)), ("std::number::sin", HandlerFn::eager(sin, 1)), ("std::number::cos", HandlerFn::eager(cos, 1)), ("std::number::tan", HandlerFn::eager(tan, 1)), @@ -51,28 +51,44 @@ pub fn collect_number_functions() -> Vec<(&'static str, HandlerFunctionEntry)> { ] } -fn add(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn add( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => lhs: f64, rhs: f64); Signal::Success(Value { kind: Some(Kind::NumberValue(lhs + rhs)), }) } -fn multiply(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn multiply( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => lhs: f64, rhs: f64); Signal::Success(Value { kind: Some(Kind::NumberValue(lhs * rhs)), }) } -fn substract(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn substract( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => lhs: f64, rhs: f64); Signal::Success(Value { kind: Some(Kind::NumberValue(lhs - rhs)), }) } -fn divide(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn divide( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => lhs: f64, rhs: f64); if rhs == 0.0 { @@ -87,7 +103,11 @@ fn divide(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Si }) } -fn modulo(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn modulo( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => lhs: f64, rhs: f64); if rhs == 0.0 { @@ -102,7 +122,11 @@ fn modulo(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Si }) } -fn abs(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn abs( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: f64); Signal::Success(Value { kind: Some(Kind::NumberValue(value.abs())), @@ -112,7 +136,7 @@ fn abs(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signa fn is_positive( args: &[Argument], _ctx: &mut Context, - _run: &mut dyn FnMut(i64) -> Signal, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, ) -> Signal { args!(args => value: f64); Signal::Success(Value { @@ -123,7 +147,7 @@ fn is_positive( fn is_greater( args: &[Argument], _ctx: &mut Context, - _run: &mut dyn FnMut(i64) -> Signal, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, ) -> Signal { args!(args => lhs: f64, rhs: f64); Signal::Success(Value { @@ -131,21 +155,33 @@ fn is_greater( }) } -fn is_less(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn is_less( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => lhs: f64, rhs: f64); Signal::Success(Value { kind: Some(Kind::BoolValue(lhs < rhs)), }) } -fn is_zero(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn is_zero( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: f64); Signal::Success(Value { kind: Some(Kind::BoolValue(value == 0.0)), }) } -fn square(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn square( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: f64); Signal::Success(Value { kind: Some(Kind::NumberValue(value.powf(2.0))), @@ -155,7 +191,7 @@ fn square(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Si fn exponential( args: &[Argument], _ctx: &mut Context, - _run: &mut dyn FnMut(i64) -> Signal, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, ) -> Signal { args!(args => base: f64, exponent: f64); Signal::Success(Value { @@ -163,28 +199,44 @@ fn exponential( }) } -fn pi(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn pi( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { no_args!(args); Signal::Success(Value { kind: Some(Kind::NumberValue(f64::consts::PI)), }) } -fn euler(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn euler( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { no_args!(args); Signal::Success(Value { kind: Some(Kind::NumberValue(f64::consts::E)), }) } -fn infinity(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn infinity( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { no_args!(args); Signal::Success(Value { kind: Some(Kind::NumberValue(f64::INFINITY)), }) } -fn round_up(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn round_up( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: f64, decimal_places: f64); let factor = 10_f64.powi(decimal_places as i32); Signal::Success(Value { @@ -195,7 +247,7 @@ fn round_up(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> fn round_down( args: &[Argument], _ctx: &mut Context, - _run: &mut dyn FnMut(i64) -> Signal, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, ) -> Signal { args!(args => value: f64, decimal_places: f64); let factor = 10_f64.powi(decimal_places as i32); @@ -204,7 +256,11 @@ fn round_down( }) } -fn round(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn round( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: f64, decimal_places: f64); let factor = 10_f64.powi(decimal_places as i32); Signal::Success(Value { @@ -215,7 +271,7 @@ fn round(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Sig fn square_root( args: &[Argument], _ctx: &mut Context, - _run: &mut dyn FnMut(i64) -> Signal, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, ) -> Signal { args!(args => value: f64); Signal::Success(Value { @@ -223,28 +279,44 @@ fn square_root( }) } -fn root(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn root( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: f64, root: f64); Signal::Success(Value { kind: Some(Kind::NumberValue(value.powf(root))), }) } -fn log(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn log( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: f64, base: f64); Signal::Success(Value { kind: Some(Kind::NumberValue(value.log(base))), }) } -fn ln(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn ln( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: f64); Signal::Success(Value { kind: Some(Kind::NumberValue(value.ln())), }) } -fn from_text(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn from_text( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => string_value: String); match string_value.parse::() { @@ -258,105 +330,171 @@ fn from_text(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> } } -fn as_text(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn as_text( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: f64); Signal::Success(Value { kind: Some(Kind::StringValue(value.to_string())), }) } -fn min(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn min( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => lhs: f64, rhs: f64); Signal::Success(Value { kind: Some(Kind::NumberValue(lhs.min(rhs))), }) } -fn max(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn max( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => lhs: f64, rhs: f64); Signal::Success(Value { kind: Some(Kind::NumberValue(lhs.max(rhs))), }) } -fn negate(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn negate( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: f64); Signal::Success(Value { kind: Some(Kind::NumberValue(-value)), }) } -fn random(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn random( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => min: f64, max: f64); + + let min_i = min.ceil() as i64; + let max_i = max.floor() as i64; + + let value = rand::random_range(min_i..=max_i) as i64; + Signal::Success(Value { - kind: Some(Kind::NumberValue(rand::random_range(min..max))), + kind: Some(Kind::NumberValue(value as f64)), }) } -fn sin(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn sin( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: f64); Signal::Success(Value { kind: Some(Kind::NumberValue(value.sin())), }) } -fn cos(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn cos( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: f64); Signal::Success(Value { kind: Some(Kind::NumberValue(value.cos())), }) } -fn tan(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn tan( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: f64); Signal::Success(Value { kind: Some(Kind::NumberValue(value.tan())), }) } -fn arcsin(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn arcsin( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: f64); Signal::Success(Value { kind: Some(Kind::NumberValue(value.asin())), }) } -fn arccos(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn arccos( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: f64); Signal::Success(Value { kind: Some(Kind::NumberValue(value.acos())), }) } -fn arctan(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn arctan( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: f64); Signal::Success(Value { kind: Some(Kind::NumberValue(value.atan())), }) } -fn sinh(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn sinh( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: f64); Signal::Success(Value { kind: Some(Kind::NumberValue(value.sinh())), }) } -fn cosh(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn cosh( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: f64); Signal::Success(Value { kind: Some(Kind::NumberValue(value.cosh())), }) } -fn clamp(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn clamp( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: f64, min: f64, max: f64); Signal::Success(Value { kind: Some(Kind::NumberValue(value.clamp(min, max))), }) } -fn is_equal(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn is_equal( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => lhs: f64, rhs: f64); Signal::Success(Value { kind: Some(Kind::BoolValue(lhs == rhs)), @@ -407,8 +545,8 @@ mod tests { } } - // dummy runner for handlers that accept `run: &mut dyn FnMut(i64) -> Signal` - fn dummy_run(_: i64) -> Signal { + // dummy runner for handlers that accept `run: &mut dyn FnMut(i64, &mut Context) -> Signal` + fn dummy_run(_: i64, _: &mut Context) -> Signal { Signal::Success(Value { kind: Some(Kind::NullValue(0)), }) diff --git a/taurus/src/implementation/object.rs b/taurus/src/implementation/object.rs index 2cbd292..8e09735 100644 --- a/taurus/src/implementation/object.rs +++ b/taurus/src/implementation/object.rs @@ -21,7 +21,7 @@ pub fn collect_object_functions() -> Vec<(&'static str, HandlerFunctionEntry)> { fn contains_key( args: &[Argument], _ctx: &mut Context, - _run: &mut dyn FnMut(i64) -> Signal, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, ) -> Signal { args!(args => object: Struct, key: String); let contains = object.fields.contains_key(&key); @@ -31,14 +31,14 @@ fn contains_key( }) } -fn size(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn size(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => object: Struct); Signal::Success(Value { kind: Some(Kind::NumberValue(object.fields.len() as f64)), }) } -fn keys(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn keys(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => object: Struct); let keys = object @@ -54,7 +54,7 @@ fn keys(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Sign }) } -fn set(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn set(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => object: Struct, key: String, value: Value); let mut new_object = object.clone(); new_object.fields.insert(key.clone(), value.clone()); @@ -130,8 +130,8 @@ mod tests { }) } - // dummy runner for handlers that accept `run: &mut dyn FnMut(i64) -> Signal` - fn dummy_run(_: i64) -> Signal { + // dummy runner for handlers that accept `run: &mut dyn FnMut(i64, &mut Context) -> Signal` + fn dummy_run(_: i64, _: &mut Context) -> Signal { Signal::Success(Value { kind: Some(Kind::NullValue(0)), }) diff --git a/taurus/src/implementation/text.rs b/taurus/src/implementation/text.rs index 67d7e25..677c71b 100644 --- a/taurus/src/implementation/text.rs +++ b/taurus/src/implementation/text.rs @@ -51,7 +51,7 @@ fn arg_err>(msg: S) -> Signal { )) } -fn as_bytes(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn as_bytes(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => value: String); let bytes: Vec = value @@ -67,7 +67,7 @@ fn as_bytes(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> }) } -fn byte_size(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn byte_size(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => value: String); Signal::Success(Value { kind: Some(Kind::NumberValue(value.len() as f64)), @@ -77,7 +77,7 @@ fn byte_size(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> fn capitalize( args: &[Argument], _ctx: &mut Context, - _run: &mut dyn FnMut(i64) -> Signal, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, ) -> Signal { args!(args => value: String); @@ -101,21 +101,21 @@ fn capitalize( }) } -fn uppercase(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn uppercase(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => value: String); Signal::Success(Value { kind: Some(Kind::StringValue(value.to_uppercase())), }) } -fn lowercase(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn lowercase(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => value: String); Signal::Success(Value { kind: Some(Kind::StringValue(value.to_lowercase())), }) } -fn swapcase(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn swapcase(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => value: String); let swapped = value @@ -136,14 +136,14 @@ fn swapcase(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> }) } -fn trim(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn trim(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => value: String); Signal::Success(Value { kind: Some(Kind::StringValue(value.trim().to_string())), }) } -fn chars(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn chars(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => value: String); let list = value @@ -158,7 +158,7 @@ fn chars(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Sig }) } -fn at(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn at(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => value: String, index: f64); if index < 0.0 { @@ -181,21 +181,21 @@ fn at(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal } } -fn append(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn append(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => value: String, suffix: String); Signal::Success(Value { kind: Some(Kind::StringValue(value + &suffix)), }) } -fn prepend(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn prepend(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => value: String, prefix: String); Signal::Success(Value { kind: Some(Kind::StringValue(prefix + &value)), }) } -fn insert(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn insert(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => value: String, position: f64, text: String); if position < 0.0 { @@ -219,14 +219,14 @@ fn insert(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Si }) } -fn length(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn length(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => value: String); Signal::Success(Value { kind: Some(Kind::NumberValue(value.chars().count() as f64)), }) } -fn remove(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn remove(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => value: String, from: f64, to: f64); if from < 0.0 || to < 0.0 { @@ -261,7 +261,7 @@ fn remove(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Si }) } -fn replace(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn replace(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => value: String, old: String, new: String); let replaced = value.replace(&old, &new); Signal::Success(Value { @@ -272,7 +272,7 @@ fn replace(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> S fn replace_first( args: &[Argument], _ctx: &mut Context, - _run: &mut dyn FnMut(i64) -> Signal, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, ) -> Signal { args!(args => value: String, old: String, new: String); let replaced = value.replacen(&old, &new, 1); @@ -284,7 +284,7 @@ fn replace_first( fn replace_last( args: &[Argument], _ctx: &mut Context, - _run: &mut dyn FnMut(i64) -> Signal, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, ) -> Signal { args!(args => value: String, old: String, new: String); @@ -307,7 +307,7 @@ fn replace_last( }) } -fn hex(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn hex(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => value: String); let hex = value @@ -321,7 +321,7 @@ fn hex(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signa }) } -fn octal(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn octal(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => value: String); let oct = value @@ -335,7 +335,7 @@ fn octal(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Sig }) } -fn index_of(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn index_of(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => value: String, sub: String); match value.find(&sub) { @@ -348,14 +348,14 @@ fn index_of(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> } } -fn contains(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn contains(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => value: String, sub: String); Signal::Success(Value { kind: Some(Kind::BoolValue(value.contains(&sub))), }) } -fn split(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn split(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => value: String, delimiter: String); let parts = value @@ -370,7 +370,7 @@ fn split(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Sig }) } -fn reverse(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn reverse(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => value: String); let reversed = value.chars().rev().collect::(); @@ -382,7 +382,7 @@ fn reverse(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> S fn starts_with( args: &[Argument], _ctx: &mut Context, - _run: &mut dyn FnMut(i64) -> Signal, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, ) -> Signal { args!(args => value: String, prefix: String); Signal::Success(Value { @@ -390,14 +390,14 @@ fn starts_with( }) } -fn ends_with(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn ends_with(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => value: String, suffix: String); Signal::Success(Value { kind: Some(Kind::BoolValue(value.ends_with(&suffix))), }) } -fn to_ascii(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn to_ascii(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => value: String); let ascii = value @@ -415,7 +415,7 @@ fn to_ascii(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> fn from_ascii( args: &[Argument], _ctx: &mut Context, - _run: &mut dyn FnMut(i64) -> Signal, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, ) -> Signal { // Requires a TryFromArg impl for ListValue in your macro system. args!(args => list: ListValue); @@ -440,7 +440,7 @@ fn from_ascii( } // NOTE: "encode"/"decode" currently only support base64. -fn encode(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn encode(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => value: String, encoding: String); let encoded = match encoding.to_lowercase().as_str() { @@ -455,7 +455,7 @@ fn encode(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Si }) } -fn decode(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn decode(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => value: String, encoding: String); let decoded = match encoding.to_lowercase().as_str() { @@ -484,7 +484,7 @@ fn decode(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Si }) } -fn is_equal(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64) -> Signal) -> Signal { +fn is_equal(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { args!(args => lhs: String, rhs: String); Signal::Success(Value { kind: Some(Kind::BoolValue(lhs == rhs)), @@ -560,8 +560,8 @@ mod tests { } } - // dummy runner for handlers that accept `run: &mut dyn FnMut(i64) -> Signal` - fn dummy_run(_: i64) -> Signal { + // dummy runner for handlers that accept `run: &mut dyn FnMut(i64, &mut Context) -> Signal` + fn dummy_run(_: i64, _: &mut Context) -> Signal { Signal::Success(Value { kind: Some(Kind::NullValue(0)), }) diff --git a/taurus/src/main.rs b/taurus/src/main.rs index 53c9db0..b7fe7b9 100644 --- a/taurus/src/main.rs +++ b/taurus/src/main.rs @@ -23,7 +23,7 @@ use tucana::shared::value::Kind; use tucana::shared::{ExecutionFlow, NodeFunction, Value}; fn handle_message(flow: ExecutionFlow, store: &FunctionStore) -> Signal { - let context = Context::default(); + let mut context = Context::default(); let node_functions: HashMap = flow .node_functions @@ -31,7 +31,7 @@ fn handle_message(flow: ExecutionFlow, store: &FunctionStore) -> Signal { .map(|node| (node.database_id, node)) .collect(); - Executor::new(store, node_functions, context).execute(flow.starting_node_id) + Executor::new(store, node_functions).execute(flow.starting_node_id, &mut context) } #[tokio::main] @@ -122,16 +122,37 @@ async fn main() { } }; + let flow_id = flow.flow_id; let value = match handle_message(flow, &store) { - Signal::Failure(error) => error.as_value(), - Signal::Success(v) => v, - Signal::Return(v) => v, - Signal::Respond(v) => v, - Signal::Stop => Value { - kind: Some(Kind::NullValue(0)), - }, + Signal::Failure(error) => { + log::error!( + "RuntimeError occurred, execution failed because: {:?}", + error + ); + error.as_value() + } + Signal::Success(v) => { + log::debug!("Execution ended on a success signal"); + v + } + Signal::Return(v) => { + log::debug!("Execution ended on a return signal"); + v + } + Signal::Respond(v) => { + log::debug!("Execution ended on a respond signal"); + v + } + Signal::Stop => { + log::debug!("Revied stop signal as last signal"); + Value { + kind: Some(Kind::NullValue(0)), + } + } }; + log::info!("For the flow_id {} returing the value {:?}", flow_id, value); + // Send a response to the reply subject if let Some(reply) = msg.reply { match client.publish(reply, value.encode_to_vec().into()).await { From f83029d4d7057767c73df664941e670fc31a2f65 Mon Sep 17 00:00:00 2001 From: Raphael Date: Mon, 2 Feb 2026 08:26:02 +0100 Subject: [PATCH 2/3] feat: added shutdown on sigterm --- taurus/src/main.rs | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/taurus/src/main.rs b/taurus/src/main.rs index b7fe7b9..4ab426b 100644 --- a/taurus/src/main.rs +++ b/taurus/src/main.rs @@ -165,9 +165,19 @@ async fn main() { log::info!("NATS worker loop ended"); }); + #[cfg(unix)] + let sigterm = async { + use tokio::signal::unix::{SignalKind, signal}; + + let mut term = signal(SignalKind::terminate()).expect("failed to install SIGTERM handler"); + term.recv().await; + }; + + #[cfg(not(unix))] + let sigterm = std::future::pending::<()>(); + match health_task { Some(mut health_task) => { - // both are mutable JoinHandle<()> so we can borrow them in select! tokio::select! { _ = &mut worker_task => { log::warn!("NATS worker task finished, shutting down"); @@ -182,6 +192,11 @@ async fn main() { worker_task.abort(); health_task.abort(); } + _ = sigterm => { + log::info!("SIGTERM received, shutting down"); + worker_task.abort(); + health_task.abort(); + } } } None => { @@ -193,6 +208,10 @@ async fn main() { log::info!("Ctrl+C/Exit signal received, shutting down"); worker_task.abort(); } + _ = sigterm => { + log::info!("SIGTERM received, shutting down"); + worker_task.abort(); + } } } } From 8e95c003932f756c7e90f80e4f6381100b2720c3 Mon Sep 17 00:00:00 2001 From: Raphael Date: Mon, 2 Feb 2026 08:27:21 +0100 Subject: [PATCH 3/3] ref: cargo fmt --- taurus/src/context/registry.rs | 7 +- taurus/src/implementation/array.rs | 143 ++++++++++++++++++++----- taurus/src/implementation/boolean.rs | 30 +++++- taurus/src/implementation/control.rs | 24 ++++- taurus/src/implementation/http.rs | 10 +- taurus/src/implementation/object.rs | 18 +++- taurus/src/implementation/text.rs | 150 ++++++++++++++++++++++----- 7 files changed, 312 insertions(+), 70 deletions(-) diff --git a/taurus/src/context/registry.rs b/taurus/src/context/registry.rs index fd1e42b..d402e44 100644 --- a/taurus/src/context/registry.rs +++ b/taurus/src/context/registry.rs @@ -7,8 +7,11 @@ use std::collections::HashMap; /// - For eager params, the executor will already convert them to Argument::Eval(Value). /// - For lazy params, the executor will pass Argument::Thunk(node_id). /// - If a handler wants to execute a lazy arg, it calls run(node_id). -pub type HandlerFn = - fn(args: &[Argument], ctx: &mut Context, run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal; +pub type HandlerFn = fn( + args: &[Argument], + ctx: &mut Context, + run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal; pub struct HandlerFunctionEntry { pub handler: HandlerFn, diff --git a/taurus/src/implementation/array.rs b/taurus/src/implementation/array.rs index 6637637..642d0c1 100644 --- a/taurus/src/implementation/array.rs +++ b/taurus/src/implementation/array.rs @@ -28,10 +28,7 @@ pub fn collect_array_functions() -> Vec<(&'static str, HandlerFunctionEntry)> { ("std::list::index_of", HandlerFn::eager(index_of, 2)), ("std::list::to_unique", HandlerFn::eager(to_unique, 1)), ("std::list::sort", HandlerFn::eager(sort, 2)), - ( - "std::list::sort_reverse", - HandlerFn::eager(sort_reverse, 2), - ), + ("std::list::sort_reverse", HandlerFn::eager(sort_reverse, 2)), ("std::list::reverse", HandlerFn::eager(reverse, 1)), ("std::list::flat", HandlerFn::eager(flat, 1)), ("std::list::min", HandlerFn::eager(min, 1)), @@ -41,7 +38,11 @@ pub fn collect_array_functions() -> Vec<(&'static str, HandlerFunctionEntry)> { ] } -fn at(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn at( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { // array, index args!(args => array: ListValue, index: f64); @@ -61,7 +62,11 @@ fn at(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Cont } } -fn concat(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn concat( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => lhs_v: Value, rhs_v: Value); let Kind::ListValue(lhs) = lhs_v.kind.clone().ok_or(()).unwrap_or(Kind::NullValue(0)) else { @@ -91,7 +96,11 @@ fn concat(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut }) } -fn filter(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn filter( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => array_v: Value, predicate_v: Value); let Kind::ListValue(array) = array_v.kind.ok_or(()).unwrap_or(Kind::NullValue(0)) else { return Signal::Failure(RuntimeError::simple( @@ -132,7 +141,11 @@ fn filter(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut }) } -fn find(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn find( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => array_v: Value, predicate_v: Value); let Kind::ListValue(array) = array_v.kind.ok_or(()).unwrap_or(Kind::NullValue(0)) else { return Signal::Failure(RuntimeError::simple_str( @@ -176,7 +189,11 @@ fn find(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Co } } -fn find_last(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn find_last( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => array_v: Value, predicate_v: Value); let Kind::ListValue(array) = array_v.kind.ok_or(()).unwrap_or(Kind::NullValue(0)) else { return Signal::Failure(RuntimeError::simple_str( @@ -267,7 +284,11 @@ fn find_index( } } -fn first(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn first( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => array: ListValue); match array.values.first() { @@ -279,7 +300,11 @@ fn first(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut C } } -fn last(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn last( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => array: ListValue); match array.values.last() { Some(v) => Signal::Success(v.clone()), @@ -296,14 +321,22 @@ fn last(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Co /// The definition itself takes in an array and a node /// The node itself will be executed on the arrays elements /// If the node is (CONSUMER) resolved it goes in this function --> therefor all code is already executed -fn for_each(_args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn for_each( + _args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { // Already executed by the engine (consumer); return Null Signal::Success(Value { kind: Some(Kind::NullValue(0)), }) } -fn map(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn map( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { // (array, transformed_results[]) args!(args => _array_v: Value, transform_v: Value); let Kind::ListValue(transform_result) = @@ -319,7 +352,11 @@ fn map(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Con }) } -fn push(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn push( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => array_v: Value, item: Value); let Kind::ListValue(mut array) = array_v.kind.ok_or(()).unwrap_or(Kind::NullValue(0)) else { return Signal::Failure(RuntimeError::simple_str( @@ -333,7 +370,11 @@ fn push(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Co }) } -fn pop(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn pop( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => array_v: Value); let Kind::ListValue(mut array) = array_v.kind.ok_or(()).unwrap_or(Kind::NullValue(0)) else { return Signal::Failure(RuntimeError::simple_str( @@ -347,7 +388,11 @@ fn pop(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Con }) } -fn remove(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn remove( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => array_v: Value, item: Value); let Kind::ListValue(mut array) = array_v.kind.ok_or(()).unwrap_or(Kind::NullValue(0)) else { return Signal::Failure(RuntimeError::simple_str( @@ -369,7 +414,11 @@ fn remove(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut } } -fn is_empty(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn is_empty( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => array_v: Value); let Kind::ListValue(array) = array_v.kind.ok_or(()).unwrap_or(Kind::NullValue(0)) else { return Signal::Failure(RuntimeError::simple_str( @@ -382,7 +431,11 @@ fn is_empty(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mu }) } -fn size(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn size( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => array_v: Value); let Kind::ListValue(array) = array_v.kind.ok_or(()).unwrap_or(Kind::NullValue(0)) else { return Signal::Failure(RuntimeError::simple_str( @@ -395,7 +448,11 @@ fn size(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Co }) } -fn index_of(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn index_of( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => array_v: Value, item: Value); let Kind::ListValue(array) = array_v.kind.ok_or(()).unwrap_or(Kind::NullValue(0)) else { return Signal::Failure(RuntimeError::simple_str( @@ -415,7 +472,11 @@ fn index_of(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mu } } -fn to_unique(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn to_unique( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => array_v: Value); let Kind::ListValue(array) = array_v.kind.ok_or(()).unwrap_or(Kind::NullValue(0)) else { return Signal::Failure(RuntimeError::simple_str( @@ -436,7 +497,11 @@ fn to_unique(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &m }) } -fn sort(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn sort( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { // array, resolved comparator yields -1/0/1 sequence args!(args => array_v: Value, cmp_v: Value); let Kind::ListValue(mut arr) = array_v.kind.ok_or(()).unwrap_or(Kind::NullValue(0)) else { @@ -519,7 +584,11 @@ fn sort_reverse( }) } -fn reverse(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn reverse( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => array_v: Value); let Kind::ListValue(mut array) = array_v.kind.ok_or(()).unwrap_or(Kind::NullValue(0)) else { return Signal::Failure(RuntimeError::simple_str( @@ -533,7 +602,11 @@ fn reverse(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut }) } -fn flat(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn flat( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => array_v: Value); let Kind::ListValue(array) = array_v.kind.ok_or(()).unwrap_or(Kind::NullValue(0)) else { return Signal::Failure(RuntimeError::simple_str( @@ -555,7 +628,11 @@ fn flat(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Co }) } -fn min(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn min( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => array: ListValue); let mut nums: Vec = Vec::new(); @@ -576,7 +653,11 @@ fn min(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Con } } -fn max(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn max( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => array: ListValue); let mut nums: Vec = Vec::new(); @@ -597,7 +678,11 @@ fn max(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Con } } -fn sum(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn sum( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => array: ListValue); let mut s = 0.0; @@ -612,7 +697,11 @@ fn sum(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Con }) } -fn join(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn join( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => array: ListValue, separator: String); let mut parts: Vec = Vec::new(); diff --git a/taurus/src/implementation/boolean.rs b/taurus/src/implementation/boolean.rs index 28107f8..b7b5fb4 100644 --- a/taurus/src/implementation/boolean.rs +++ b/taurus/src/implementation/boolean.rs @@ -19,14 +19,22 @@ pub fn collect_boolean_functions() -> Vec<(&'static str, HandlerFunctionEntry)> ] } -fn as_number(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn as_number( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: bool); Signal::Success(Value { kind: Some(Kind::NumberValue((value as i64) as f64)), }) } -fn as_text(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn as_text( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: bool); Signal::Success(Value { kind: Some(Kind::StringValue(value.to_string())), @@ -45,7 +53,11 @@ fn from_number( }) } -fn from_text(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn from_text( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => text: String); match text.to_lowercase().parse::() { @@ -59,14 +71,22 @@ fn from_text(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &m } } -fn is_equal(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn is_equal( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => lhs: bool, rhs: bool); Signal::Success(Value { kind: Some(Kind::BoolValue(lhs == rhs)), }) } -fn negate(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn negate( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: bool); Signal::Success(Value { kind: Some(Kind::BoolValue(!value)), diff --git a/taurus/src/implementation/control.rs b/taurus/src/implementation/control.rs index ca8ce05..e552a7c 100644 --- a/taurus/src/implementation/control.rs +++ b/taurus/src/implementation/control.rs @@ -23,16 +23,28 @@ pub fn collect_control_functions() -> Vec<(&'static str, HandlerFunctionEntry)> ] } -fn stop(_args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn stop( + _args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { Signal::Stop } -fn r#return(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn r#return( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: Value); Signal::Return(value) } -fn r#if(args: &[Argument], ctx: &mut Context, run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn r#if( + args: &[Argument], + ctx: &mut Context, + run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { let [ Argument::Eval(Value { kind: Some(Kind::BoolValue(bool)), @@ -55,7 +67,11 @@ fn r#if(args: &[Argument], ctx: &mut Context, run: &mut dyn FnMut(i64, &mut Cont } } -fn if_else(args: &[Argument], ctx: &mut Context, run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn if_else( + args: &[Argument], + ctx: &mut Context, + run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { let [ Argument::Eval(Value { kind: Some(Kind::BoolValue(bool)), diff --git a/taurus/src/implementation/http.rs b/taurus/src/implementation/http.rs index 905ee40..d593ab5 100644 --- a/taurus/src/implementation/http.rs +++ b/taurus/src/implementation/http.rs @@ -118,10 +118,12 @@ fn create_response( let code = match http_status_code.as_str().parse::() { Ok(c) => c, - Err(_) => return Signal::Failure(RuntimeError::simple_str( - "InvalidArgumentExeption", - "Expected http_status_code to be parsed to float", - )), + Err(_) => { + return Signal::Failure(RuntimeError::simple_str( + "InvalidArgumentExeption", + "Expected http_status_code to be parsed to float", + )); + } }; fields.insert( "status_code".to_string(), diff --git a/taurus/src/implementation/object.rs b/taurus/src/implementation/object.rs index 8e09735..6f8c228 100644 --- a/taurus/src/implementation/object.rs +++ b/taurus/src/implementation/object.rs @@ -31,14 +31,22 @@ fn contains_key( }) } -fn size(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn size( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => object: Struct); Signal::Success(Value { kind: Some(Kind::NumberValue(object.fields.len() as f64)), }) } -fn keys(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn keys( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => object: Struct); let keys = object @@ -54,7 +62,11 @@ fn keys(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Co }) } -fn set(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn set( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => object: Struct, key: String, value: Value); let mut new_object = object.clone(); new_object.fields.insert(key.clone(), value.clone()); diff --git a/taurus/src/implementation/text.rs b/taurus/src/implementation/text.rs index 677c71b..f86a6a8 100644 --- a/taurus/src/implementation/text.rs +++ b/taurus/src/implementation/text.rs @@ -51,7 +51,11 @@ fn arg_err>(msg: S) -> Signal { )) } -fn as_bytes(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn as_bytes( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: String); let bytes: Vec = value @@ -67,7 +71,11 @@ fn as_bytes(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mu }) } -fn byte_size(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn byte_size( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: String); Signal::Success(Value { kind: Some(Kind::NumberValue(value.len() as f64)), @@ -101,21 +109,33 @@ fn capitalize( }) } -fn uppercase(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn uppercase( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: String); Signal::Success(Value { kind: Some(Kind::StringValue(value.to_uppercase())), }) } -fn lowercase(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn lowercase( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: String); Signal::Success(Value { kind: Some(Kind::StringValue(value.to_lowercase())), }) } -fn swapcase(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn swapcase( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: String); let swapped = value @@ -136,14 +156,22 @@ fn swapcase(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mu }) } -fn trim(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn trim( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: String); Signal::Success(Value { kind: Some(Kind::StringValue(value.trim().to_string())), }) } -fn chars(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn chars( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: String); let list = value @@ -158,7 +186,11 @@ fn chars(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut C }) } -fn at(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn at( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: String, index: f64); if index < 0.0 { @@ -181,21 +213,33 @@ fn at(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Cont } } -fn append(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn append( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: String, suffix: String); Signal::Success(Value { kind: Some(Kind::StringValue(value + &suffix)), }) } -fn prepend(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn prepend( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: String, prefix: String); Signal::Success(Value { kind: Some(Kind::StringValue(prefix + &value)), }) } -fn insert(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn insert( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: String, position: f64, text: String); if position < 0.0 { @@ -219,14 +263,22 @@ fn insert(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut }) } -fn length(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn length( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: String); Signal::Success(Value { kind: Some(Kind::NumberValue(value.chars().count() as f64)), }) } -fn remove(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn remove( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: String, from: f64, to: f64); if from < 0.0 || to < 0.0 { @@ -261,7 +313,11 @@ fn remove(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut }) } -fn replace(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn replace( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: String, old: String, new: String); let replaced = value.replace(&old, &new); Signal::Success(Value { @@ -307,7 +363,11 @@ fn replace_last( }) } -fn hex(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn hex( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: String); let hex = value @@ -321,7 +381,11 @@ fn hex(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Con }) } -fn octal(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn octal( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: String); let oct = value @@ -335,7 +399,11 @@ fn octal(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut C }) } -fn index_of(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn index_of( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: String, sub: String); match value.find(&sub) { @@ -348,14 +416,22 @@ fn index_of(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mu } } -fn contains(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn contains( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: String, sub: String); Signal::Success(Value { kind: Some(Kind::BoolValue(value.contains(&sub))), }) } -fn split(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn split( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: String, delimiter: String); let parts = value @@ -370,7 +446,11 @@ fn split(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut C }) } -fn reverse(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn reverse( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: String); let reversed = value.chars().rev().collect::(); @@ -390,14 +470,22 @@ fn starts_with( }) } -fn ends_with(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn ends_with( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: String, suffix: String); Signal::Success(Value { kind: Some(Kind::BoolValue(value.ends_with(&suffix))), }) } -fn to_ascii(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn to_ascii( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: String); let ascii = value @@ -440,7 +528,11 @@ fn from_ascii( } // NOTE: "encode"/"decode" currently only support base64. -fn encode(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn encode( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: String, encoding: String); let encoded = match encoding.to_lowercase().as_str() { @@ -455,7 +547,11 @@ fn encode(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut }) } -fn decode(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn decode( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => value: String, encoding: String); let decoded = match encoding.to_lowercase().as_str() { @@ -484,7 +580,11 @@ fn decode(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut }) } -fn is_equal(args: &[Argument], _ctx: &mut Context, _run: &mut dyn FnMut(i64, &mut Context) -> Signal) -> Signal { +fn is_equal( + args: &[Argument], + _ctx: &mut Context, + _run: &mut dyn FnMut(i64, &mut Context) -> Signal, +) -> Signal { args!(args => lhs: String, rhs: String); Signal::Success(Value { kind: Some(Kind::BoolValue(lhs == rhs)),