From fd10e74c98877dd0c935860ca84def83d4c34368 Mon Sep 17 00:00:00 2001 From: raphael-goetz Date: Fri, 17 Oct 2025 13:25:56 +0200 Subject: [PATCH 1/9] ref: switched from result to Signal --- src/configuration.rs | 45 -- src/implementation/array.rs | 414 +++++++----- src/implementation/boolean.rs | 286 +++++--- src/implementation/control.rs | 13 +- src/implementation/http.rs | 15 +- src/implementation/number.rs | 607 +++++++++++------ src/implementation/object.rs | 147 +++-- src/implementation/text.rs | 1148 +++++++++++++++++++++++---------- 8 files changed, 1759 insertions(+), 916 deletions(-) delete mode 100644 src/configuration.rs diff --git a/src/configuration.rs b/src/configuration.rs deleted file mode 100644 index 3ce933c..0000000 --- a/src/configuration.rs +++ /dev/null @@ -1,45 +0,0 @@ -use code0_flow::flow_config::{env_with_default, environment::Environment, mode::Mode}; - -/// Struct for all relevant `Taurus` startup configurations -pub struct Config { - /// Options: - /// `development` (default) - /// `staging` - /// `production` - pub environment: Environment, - - /// Aquila mode - /// - /// Options: - /// `static` (default) - /// `hybrid` - pub mode: Mode, - - pub nats_url: String, - - pub aquila_url: String, - - pub with_health_service: bool, - - pub grpc_host: String, - - pub grpc_port: u16, -} - -/// Implementation for all relevant `Aquila` startup configurations -/// -/// Behavior: -/// Searches for the env. file at root level. Filename: `.env` -impl Config { - pub fn new() -> Self { - Config { - environment: env_with_default("ENVIRONMENT", Environment::Development), - mode: env_with_default("MODE", Mode::STATIC), - nats_url: env_with_default("NATS_URL", String::from("nats://localhost:4222")), - aquila_url: env_with_default("AQUILA_URL", String::from("http://localhost:50051")), - with_health_service: env_with_default("WITH_HEALTH_SERVICE", false), - grpc_host: env_with_default("GRPC_HOST", "127.0.0.1".to_string()), - grpc_port: env_with_default("GRPC_PORT", 50051), - } - } -} diff --git a/src/implementation/array.rs b/src/implementation/array.rs index a4016c8..5e1a0e3 100644 --- a/src/implementation/array.rs +++ b/src/implementation/array.rs @@ -2,6 +2,7 @@ use std::cmp::Ordering; use tucana::shared::{Value, value::Kind}; +use crate::context::signal::Signal; use crate::{context::Context, error::RuntimeError, registry::HandlerFn}; pub fn collect_array_functions() -> Vec<(&'static str, HandlerFn)> { @@ -34,7 +35,7 @@ pub fn collect_array_functions() -> Vec<(&'static str, HandlerFn)> { ] } -fn at(values: &[Value], _ctx: &mut Context) -> Result { +fn at(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::ListValue(array)), @@ -44,7 +45,7 @@ fn at(values: &[Value], _ctx: &mut Context) -> Result { }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected a list and a number as arguments but received {:?}", @@ -55,10 +56,10 @@ fn at(values: &[Value], _ctx: &mut Context) -> Result { let item = array.values[index.clone() as usize].clone(); - Ok(item) + Signal::Success(item) } -fn concat(values: &[Value], _ctx: &mut Context) -> Result { +fn concat(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::ListValue(lhs)), @@ -68,7 +69,7 @@ fn concat(values: &[Value], _ctx: &mut Context) -> Result { }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected two arrays as arguments but received {:?}", values), )); @@ -77,14 +78,14 @@ fn concat(values: &[Value], _ctx: &mut Context) -> Result { let mut result = lhs.values.clone(); result.extend(rhs.values.clone()); - Ok(Value { + Signal::Success(Value { kind: Some(Kind::ListValue(tucana::shared::ListValue { values: result, })), }) } -fn filter(values: &[Value], _ctx: &mut Context) -> Result { +fn filter(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::ListValue(array)), @@ -94,7 +95,7 @@ fn filter(values: &[Value], _ctx: &mut Context) -> Result { }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected two arrays as arguments but received {:?}", values), )); @@ -122,14 +123,14 @@ fn filter(values: &[Value], _ctx: &mut Context) -> Result { }) .collect::>(); - Ok(Value { + Signal::Success(Value { kind: Some(Kind::ListValue(tucana::shared::ListValue { values: new_array, })), }) } -fn find(values: &[Value], _ctx: &mut Context) -> Result { +fn find(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::ListValue(array)), @@ -139,7 +140,7 @@ fn find(values: &[Value], _ctx: &mut Context) -> Result { }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected two arrays as arguments but received {:?}", values), )); @@ -163,15 +164,15 @@ fn find(values: &[Value], _ctx: &mut Context) -> Result { }); match item { - Some(item) => Ok(item), - None => Err(RuntimeError::simple( + Some(item) => Signal::Success(item), + None => Signal::Failure(RuntimeError::simple( "NotFoundError", "No item found that satisfies the predicate".to_string(), )), } } -fn find_last(values: &[Value], _ctx: &mut Context) -> Result { +fn find_last(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::ListValue(array)), @@ -181,7 +182,7 @@ fn find_last(values: &[Value], _ctx: &mut Context) -> Result Result Ok(item), - None => Err(RuntimeError::simple( + Some(item) => Signal::Success(item), + None => Signal::Failure(RuntimeError::simple( "NotFoundError", "No item found that satisfies the predicate".to_string(), )), } } -fn find_index(values: &[Value], _ctx: &mut Context) -> Result { +fn find_index(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::ListValue(array)), @@ -226,7 +227,7 @@ fn find_index(values: &[Value], _ctx: &mut Context) -> Result Result Ok(Value { + Some(_) => Signal::Success(Value { kind: Some(Kind::NumberValue(index as f64)), }), - None => Err(RuntimeError::simple( + None => Signal::Failure(RuntimeError::simple( "NotFoundError", "No item found that satisfies the predicate".to_string(), )), } } -fn first(values: &[Value], _ctx: &mut Context) -> Result { +fn first(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::ListValue(array)), }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected an array as an argument but received {:?}", values), )); }; match array.values.first() { - Some(item) => Ok(item.clone()), - None => Err(RuntimeError::simple_str( + Some(item) => Signal::Success(item.clone()), + None => Signal::Failure(RuntimeError::simple_str( "ArrayEmptyRuntimeError", "This array is empty", )), } } -fn last(values: &[Value], _ctx: &mut Context) -> Result { +fn last(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::ListValue(array)), }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected an array as an argument but received {:?}", values), )); }; match array.values.last() { - Some(item) => Ok(item.clone()), - None => Err(RuntimeError::simple_str( + Some(item) => Signal::Success(item.clone()), + None => Signal::Failure(RuntimeError::simple_str( "ArrayEmptyRuntimeError", "This array is empty", )), @@ -317,8 +318,8 @@ fn last(values: &[Value], _ctx: &mut Context) -> Result { * 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(_values: &[Value], _ctx: &mut Context) -> Result { - Ok(Value { +fn for_each(_values: &[Value], _ctx: &mut Context) -> Signal { + Signal::Success(Value { kind: Some(Kind::NullValue(0)), }) } @@ -332,7 +333,7 @@ fn for_each(_values: &[Value], _ctx: &mut Context) -> Result therefor all code is already executed * The TRANSFORM node is gives a new item as a result */ -fn map(values: &[Value], _ctx: &mut Context) -> Result { +fn map(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::ListValue(_array)), @@ -342,18 +343,18 @@ fn map(values: &[Value], _ctx: &mut Context) -> Result { }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected two arrays as arguments but received {:?}", values), )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::ListValue(transform_result.clone())), }) } -fn push(values: &[Value], _ctx: &mut Context) -> Result { +fn push(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::ListValue(array)), @@ -361,7 +362,7 @@ fn push(values: &[Value], _ctx: &mut Context) -> Result { item, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected an array as an argument but received {:?}", values), )); @@ -369,19 +370,19 @@ fn push(values: &[Value], _ctx: &mut Context) -> Result { let mut new_array = array.clone(); new_array.values.push(item.clone()); - Ok(Value { + Signal::Success(Value { kind: Some(Kind::ListValue(new_array)), }) } -fn pop(values: &[Value], _ctx: &mut Context) -> Result { +fn pop(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::ListValue(array)), }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected an array as an argument but received {:?}", values), )); @@ -389,12 +390,12 @@ fn pop(values: &[Value], _ctx: &mut Context) -> Result { let mut new_array = array.clone(); new_array.values.pop(); - Ok(Value { + Signal::Success(Value { kind: Some(Kind::ListValue(new_array)), }) } -fn remove(values: &[Value], _ctx: &mut Context) -> Result { +fn remove(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::ListValue(array)), @@ -402,7 +403,7 @@ fn remove(values: &[Value], _ctx: &mut Context) -> Result { item, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected an array as an argument but received {:?}", values), )); @@ -413,7 +414,7 @@ fn remove(values: &[Value], _ctx: &mut Context) -> Result { let index = match new_array.values.iter().position(|x| *x == item_clone) { Some(index) => index, None => { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "ValueNotFoundRuntimeError", format!("Item {:?} not found in array", item_clone), )); @@ -422,48 +423,48 @@ fn remove(values: &[Value], _ctx: &mut Context) -> Result { new_array.values.remove(index); - Ok(Value { + Signal::Success(Value { kind: Some(Kind::ListValue(new_array)), }) } -fn is_empty(values: &[Value], _ctx: &mut Context) -> Result { +fn is_empty(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::ListValue(array)), }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected an array as an argument but received {:?}", values), )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::BoolValue(array.values.is_empty())), }) } -fn size(values: &[Value], _ctx: &mut Context) -> Result { +fn size(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::ListValue(array)), }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected an array as an argument but received {:?}", values), )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::NumberValue(array.values.len() as f64)), }) } -fn index_of(values: &[Value], _ctx: &mut Context) -> Result { +fn index_of(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::ListValue(array)), @@ -471,7 +472,7 @@ fn index_of(values: &[Value], _ctx: &mut Context) -> Result item, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected two numbers as arguments but received {:?}", @@ -485,26 +486,26 @@ fn index_of(values: &[Value], _ctx: &mut Context) -> Result let index = match new_array.values.iter().position(|x| *x == item_clone) { Some(index) => index, None => { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "ValueNotFoundRuntimeError", format!("Item {:?} not found in array", item_clone), )); } }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::NumberValue(index as f64)), }) } -fn to_unique(values: &[Value], _ctx: &mut Context) -> Result { +fn to_unique(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::ListValue(array)), }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected an array as an argument but received {:?}", values), )); @@ -518,14 +519,14 @@ fn to_unique(values: &[Value], _ctx: &mut Context) -> Result Result { +fn sort(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::ListValue(array)), @@ -535,7 +536,7 @@ fn sort(values: &[Value], _ctx: &mut Context) -> Result { }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected two arrays as arguments but received {:?}", values), )); @@ -563,14 +564,14 @@ fn sort(values: &[Value], _ctx: &mut Context) -> Result { } }); - Ok(Value { + Signal::Success(Value { kind: Some(Kind::ListValue(tucana::shared::ListValue { values: new_array, })), }) } -fn sort_reverse(values: &[Value], _ctx: &mut Context) -> Result { +fn sort_reverse(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::ListValue(array)), @@ -580,7 +581,7 @@ fn sort_reverse(values: &[Value], _ctx: &mut Context) -> Result Result Result { +fn reverse(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::ListValue(array)), }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected an array as an argument but received {:?}", values), )); @@ -633,21 +634,21 @@ fn reverse(values: &[Value], _ctx: &mut Context) -> Result let mut new_array = array.values.clone(); new_array.reverse(); - Ok(Value { + Signal::Success(Value { kind: Some(Kind::ListValue(tucana::shared::ListValue { values: new_array, })), }) } -fn flat(values: &[Value], _ctx: &mut Context) -> Result { +fn flat(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::ListValue(array)), }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected an array as an argument but received {:?}", values), )); @@ -671,21 +672,21 @@ fn flat(values: &[Value], _ctx: &mut Context) -> Result { .flatten() .collect::>(); - Ok(Value { + Signal::Success(Value { kind: Some(Kind::ListValue(tucana::shared::ListValue { values: flattend, })), }) } -fn min(values: &[Value], _ctx: &mut Context) -> Result { +fn min(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::ListValue(array)), }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected an array of numbers as an argument but received {:?}", @@ -707,24 +708,24 @@ fn min(values: &[Value], _ctx: &mut Context) -> Result { let min = new_array.iter().min_by(|a, b| a.total_cmp(b)); match min { - Some(min) => Ok(Value { + Some(min) => Signal::Success(Value { kind: Some(Kind::NumberValue(min.clone())), }), - None => Err(RuntimeError::simple( + None => Signal::Failure(RuntimeError::simple( "ArrayEmptyRuntimeError", "Array is empty".to_string(), )), } } -fn max(values: &[Value], _ctx: &mut Context) -> Result { +fn max(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::ListValue(array)), }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected an array of numbers as an argument but received {:?}", @@ -746,24 +747,24 @@ fn max(values: &[Value], _ctx: &mut Context) -> Result { let max = new_array.iter().max_by(|a, b| a.total_cmp(b)); match max { - Some(max) => Ok(Value { + Some(max) => Signal::Success(Value { kind: Some(Kind::NumberValue(max.clone())), }), - None => Err(RuntimeError::simple( + None => Signal::Failure(RuntimeError::simple( "ArrayEmptyRuntimeError", "Array is empty".to_string(), )), } } -fn sum(values: &[Value], _ctx: &mut Context) -> Result { +fn sum(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::ListValue(array)), }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected an array of numbers as an argument but received {:?}", @@ -782,12 +783,12 @@ fn sum(values: &[Value], _ctx: &mut Context) -> Result { } }); - Ok(Value { + Signal::Success(Value { kind: Some(Kind::NumberValue(sum)), }) } -fn join(values: &[Value], _ctx: &mut Context) -> Result { +fn join(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::ListValue(array)), @@ -797,7 +798,7 @@ fn join(values: &[Value], _ctx: &mut Context) -> Result { }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected array of text and a text as arguments but received {:?}", @@ -818,7 +819,7 @@ fn join(values: &[Value], _ctx: &mut Context) -> Result { let joined = collector.join(&separator); - Ok(Value { + Signal::Success(Value { kind: Some(Kind::StringValue(joined)), }) } @@ -869,15 +870,24 @@ mod tests { // Test getting first element let values = vec![array.clone(), create_number_value(0.0)]; - let result = at(&values, &mut ctx).unwrap(); - match result.kind { - Some(Kind::NumberValue(val)) => assert_eq!(val, 10.0), + let result = at(&values, &mut ctx); + match result { + Signal::Success(v) => match v.kind { + Some(Kind::NumberValue(val)) => assert_eq!(val, 10.0), + _ => panic!("Expected NumberValue"), + }, _ => panic!("Expected NumberValue"), } // Test getting second element let values = vec![array.clone(), create_number_value(1.0)]; - let result = at(&values, &mut ctx).unwrap(); + let signal = at(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; + match result.kind { Some(Kind::NumberValue(val)) => assert_eq!(val, 20.0), _ => panic!("Expected NumberValue"), @@ -885,7 +895,13 @@ mod tests { // Test getting third element let values = vec![array, create_number_value(2.0)]; - let result = at(&values, &mut ctx).unwrap(); + let signal = at(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; + match result.kind { Some(Kind::NumberValue(val)) => assert_eq!(val, 30.0), _ => panic!("Expected NumberValue"), @@ -900,17 +916,17 @@ mod tests { // Test with wrong number of parameters let values = vec![array.clone()]; let result = at(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong type for first parameter let values = vec![create_string_value("not_array"), create_number_value(0.0)]; let result = at(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong type for second parameter let values = vec![array, create_string_value("not_number")]; let result = at(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -921,7 +937,12 @@ mod tests { let array2 = create_array_value(vec![create_number_value(3.0), create_number_value(4.0)]); let values = vec![array1, array2]; - let result = concat(&values, &mut ctx).unwrap(); + let signal = concat(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; match result.kind { Some(Kind::ListValue(list)) => { @@ -957,17 +978,17 @@ mod tests { // Test with wrong number of parameters let values = vec![array.clone()]; let result = concat(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong type for first parameter let values = vec![create_string_value("not_array"), array.clone()]; let result = concat(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong type for second parameter let values = vec![array, create_number_value(42.0)]; let result = concat(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -986,7 +1007,12 @@ mod tests { ]); let values = vec![array, predicate]; - let result = filter(&values, &mut ctx).unwrap(); + let signal = filter(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; match result.kind { Some(Kind::ListValue(list)) => { @@ -1014,17 +1040,15 @@ mod tests { // Test with wrong number of parameters let values = vec![array.clone()]; let result = filter(&values, &mut ctx); - assert!(result.is_err()); - + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong type for first parameter let values = vec![create_string_value("not_array"), predicate.clone()]; let result = filter(&values, &mut ctx); - assert!(result.is_err()); - + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong type for second parameter let values = vec![array, create_number_value(42.0)]; let result = filter(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -1038,7 +1062,12 @@ mod tests { ]); let values = vec![array]; - let result = first(&values, &mut ctx).unwrap(); + let signal = first(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; match result.kind { Some(Kind::StringValue(val)) => assert_eq!(val, "first"), @@ -1054,17 +1083,15 @@ mod tests { let empty_array = create_array_value(vec![]); let values = vec![empty_array]; let result = first(&values, &mut ctx); - assert!(result.is_err()); - + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong parameter type let values = vec![create_string_value("not_array")]; let result = first(&values, &mut ctx); - assert!(result.is_err()); - + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong number of parameters let values = vec![]; let result = first(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -1078,7 +1105,12 @@ mod tests { ]); let values = vec![array]; - let result = last(&values, &mut ctx).unwrap(); + let signal = last(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; match result.kind { Some(Kind::StringValue(val)) => assert_eq!(val, "last"), @@ -1094,12 +1126,11 @@ mod tests { let empty_array = create_array_value(vec![]); let values = vec![empty_array]; let result = last(&values, &mut ctx); - assert!(result.is_err()); - + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong parameter type let values = vec![create_string_value("not_array")]; let result = last(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -1110,7 +1141,12 @@ mod tests { let new_element = create_number_value(3.0); let values = vec![array, new_element]; - let result = push(&values, &mut ctx).unwrap(); + let signal = push(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; match result.kind { Some(Kind::ListValue(list)) => { @@ -1133,12 +1169,11 @@ mod tests { // Test with wrong number of parameters let values = vec![array.clone()]; let result = push(&values, &mut ctx); - assert!(result.is_err()); - + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong type for first parameter let values = vec![create_string_value("not_array"), create_number_value(42.0)]; let result = push(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -1152,7 +1187,12 @@ mod tests { ]); let values = vec![array]; - let result = pop(&values, &mut ctx).unwrap(); + let signal = pop(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; match result.kind { Some(Kind::ListValue(list)) => { @@ -1179,12 +1219,11 @@ mod tests { // Test with wrong parameter type let values = vec![create_string_value("not_array")]; let result = pop(&values, &mut ctx); - assert!(result.is_err()); - + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong number of parameters let values = vec![]; let result = pop(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -1194,7 +1233,12 @@ mod tests { // Test with empty array let empty_array = create_array_value(vec![]); let values = vec![empty_array]; - let result = is_empty(&values, &mut ctx).unwrap(); + let signal = is_empty(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; match result.kind { Some(Kind::BoolValue(val)) => assert_eq!(val, true), @@ -1204,7 +1248,12 @@ mod tests { // Test with non-empty array let non_empty_array = create_array_value(vec![create_number_value(1.0)]); let values = vec![non_empty_array]; - let result = is_empty(&values, &mut ctx).unwrap(); + let signal = is_empty(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; match result.kind { Some(Kind::BoolValue(val)) => assert_eq!(val, false), @@ -1219,12 +1268,11 @@ mod tests { // Test with wrong parameter type let values = vec![create_string_value("not_array")]; let result = is_empty(&values, &mut ctx); - assert!(result.is_err()); - + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong number of parameters let values = vec![]; let result = is_empty(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -1234,7 +1282,12 @@ mod tests { // Test with empty array let empty_array = create_array_value(vec![]); let values = vec![empty_array]; - let result = size(&values, &mut ctx).unwrap(); + let signal = size(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert_eq!(val, 0.0), @@ -1248,7 +1301,12 @@ mod tests { create_number_value(3.0), ]); let values = vec![array]; - let result = size(&values, &mut ctx).unwrap(); + let signal = size(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert_eq!(val, 3.0), @@ -1263,12 +1321,11 @@ mod tests { // Test with wrong parameter type let values = vec![create_string_value("not_array")]; let result = size(&values, &mut ctx); - assert!(result.is_err()); - + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong number of parameters let values = vec![]; let result = size(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -1282,7 +1339,12 @@ mod tests { ]); let values = vec![array]; - let result = reverse(&values, &mut ctx).unwrap(); + let signal = reverse(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; match result.kind { Some(Kind::ListValue(list)) => { @@ -1313,12 +1375,11 @@ mod tests { // Test with wrong parameter type let values = vec![create_string_value("not_array")]; let result = reverse(&values, &mut ctx); - assert!(result.is_err()); - + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong number of parameters let values = vec![]; let result = reverse(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -1332,7 +1393,12 @@ mod tests { ]); let values = vec![array]; - let result = sum(&values, &mut ctx).unwrap(); + let signal = sum(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert_eq!(val, 7.0), @@ -1346,7 +1412,12 @@ mod tests { let empty_array = create_array_value(vec![]); let values = vec![empty_array]; - let result = sum(&values, &mut ctx).unwrap(); + let signal = sum(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert_eq!(val, 0.0), @@ -1361,12 +1432,11 @@ mod tests { // Test with wrong parameter type let values = vec![create_string_value("not_array")]; let result = sum(&values, &mut ctx); - assert!(result.is_err()); - + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong number of parameters let values = vec![]; let result = sum(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -1381,7 +1451,12 @@ mod tests { let separator = create_string_value(", "); let values = vec![array, separator]; - let result = join(&values, &mut ctx).unwrap(); + let signal = join(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; match result.kind { Some(Kind::StringValue(val)) => assert_eq!(val, "hello, world, test"), @@ -1397,17 +1472,15 @@ mod tests { // Test with wrong number of parameters let values = vec![array.clone()]; let result = join(&values, &mut ctx); - assert!(result.is_err()); - + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong type for first parameter let values = vec![create_string_value("not_array"), create_string_value(",")]; let result = join(&values, &mut ctx); - assert!(result.is_err()); - + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong type for second parameter let values = vec![array, create_number_value(42.0)]; let result = join(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -1422,7 +1495,12 @@ mod tests { ]); let values = vec![array]; - let result = min(&values, &mut ctx).unwrap(); + let signal = min(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert_eq!(val, 1.0), @@ -1438,12 +1516,11 @@ mod tests { let empty_array = create_array_value(vec![]); let values = vec![empty_array]; let result = min(&values, &mut ctx); - assert!(result.is_err()); - + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong parameter type let values = vec![create_string_value("not_array")]; let result = min(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -1458,7 +1535,12 @@ mod tests { ]); let values = vec![array]; - let result = max(&values, &mut ctx).unwrap(); + let signal = max(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert_eq!(val, 8.0), @@ -1474,12 +1556,11 @@ mod tests { let empty_array = create_array_value(vec![]); let values = vec![empty_array]; let result = max(&values, &mut ctx); - assert!(result.is_err()); - + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong parameter type let values = vec![create_string_value("not_array")]; let result = max(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -1495,7 +1576,12 @@ mod tests { let search_element = create_number_value(42.0); let values = vec![array, search_element]; - let result = index_of(&values, &mut ctx).unwrap(); + let signal = index_of(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert_eq!(val, 1.0), // Should return first occurrence @@ -1515,7 +1601,7 @@ mod tests { let values = vec![array, search_element]; let result = index_of(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -1526,12 +1612,11 @@ mod tests { // Test with wrong number of parameters let values = vec![array.clone()]; let result = index_of(&values, &mut ctx); - assert!(result.is_err()); - + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong type for first parameter let values = vec![create_string_value("not_array"), create_number_value(42.0)]; let result = index_of(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -1546,7 +1631,12 @@ mod tests { let item_to_remove = create_string_value("second"); // Remove middle element let values = vec![array, item_to_remove]; - let result = remove(&values, &mut ctx).unwrap(); + let signal = remove(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; match result.kind { Some(Kind::ListValue(list)) => { @@ -1573,16 +1663,14 @@ mod tests { // Test with wrong number of parameters let values = vec![array.clone()]; let result = remove(&values, &mut ctx); - assert!(result.is_err()); - + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong type for first parameter let values = vec![create_string_value("not_array"), create_number_value(0.0)]; let result = remove(&values, &mut ctx); - assert!(result.is_err()); - + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with item not found let values = vec![array, create_number_value(999.0)]; let result = remove(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } } diff --git a/src/implementation/boolean.rs b/src/implementation/boolean.rs index 528b34e..f819a56 100644 --- a/src/implementation/boolean.rs +++ b/src/implementation/boolean.rs @@ -1,5 +1,6 @@ +use crate::context::signal::Signal; use crate::{context::Context, error::RuntimeError, registry::HandlerFn}; -use tucana::shared::{value::Kind, Value}; +use tucana::shared::{Value, value::Kind}; pub fn collect_boolean_functions() -> Vec<(&'static str, HandlerFn)> { vec![ @@ -12,44 +13,50 @@ pub fn collect_boolean_functions() -> Vec<(&'static str, HandlerFn)> { ] } -fn as_number(values: &[Value], _ctx: &mut Context) -> Result { - let [Value { - kind: Some(Kind::BoolValue(value)), - }] = values +fn as_number(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::BoolValue(value)), + }, + ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected a boolean value but received {:?}", values), )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::NumberValue(value.clone() as i64 as f64)), }) } -fn as_text(values: &[Value], _ctx: &mut Context) -> Result { - let [Value { - kind: Some(Kind::BoolValue(value)), - }] = values +fn as_text(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::BoolValue(value)), + }, + ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected a boolean value but received {:?}", values), )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::StringValue(value.to_string())), }) } -fn from_number(values: &[Value], _ctx: &mut Context) -> Result { - let [Value { - kind: Some(Kind::NumberValue(number)), - }] = values +fn from_number(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::NumberValue(number)), + }, + ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected a number value but received {:?}", values), )); @@ -57,17 +64,19 @@ fn from_number(values: &[Value], _ctx: &mut Context) -> Result Result { - let [Value { - kind: Some(Kind::StringValue(text)), - }] = values +fn from_text(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::StringValue(text)), + }, + ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected a string value but received {:?}", values), )); @@ -76,48 +85,53 @@ fn from_text(values: &[Value], _ctx: &mut Context) -> Result value, Err(_) => { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Failed to parse boolean from string: {:?}", text), - )) + )); } }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::BoolValue(bool)), }) } -fn is_equal(values: &[Value], _ctx: &mut Context) -> Result { - let [Value { - kind: Some(Kind::BoolValue(lhs)), - }, Value { - kind: Some(Kind::BoolValue(rhs)), - }] = values +fn is_equal(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::BoolValue(lhs)), + }, + Value { + kind: Some(Kind::BoolValue(rhs)), + }, + ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected two boolean values but received {:?}", values), )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::BoolValue(lhs == rhs)), }) } -fn negate(values: &[Value], _ctx: &mut Context) -> Result { - let [Value { - kind: Some(Kind::BoolValue(value)), - }] = values +fn negate(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::BoolValue(value)), + }, + ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected a boolean value but received {:?}", values), )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::BoolValue(!value)), }) } @@ -126,7 +140,7 @@ fn negate(values: &[Value], _ctx: &mut Context) -> Result { mod tests { use super::*; use crate::context::Context; - use tucana::shared::{value::Kind, Value}; + use tucana::shared::{Value, value::Kind}; // Helper function to create a bool value fn create_bool_value(b: bool) -> Value { @@ -160,7 +174,13 @@ mod tests { // Test true -> 1.0 let values = vec![create_bool_value(true)]; - let result = as_number(&values, &mut ctx).unwrap(); + let signal = as_number(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; + match result.kind { Some(Kind::NumberValue(val)) => assert_eq!(val, 1.0), _ => panic!("Expected NumberValue"), @@ -168,7 +188,12 @@ mod tests { // Test false -> 0.0 let values = vec![create_bool_value(false)]; - let result = as_number(&values, &mut ctx).unwrap(); + let signal = as_number(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert_eq!(val, 0.0), _ => panic!("Expected NumberValue"), @@ -182,27 +207,27 @@ mod tests { // Test with wrong number of parameters (none) let values = vec![]; let result = as_number(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong number of parameters (too many) let values = vec![create_bool_value(true), create_bool_value(false)]; let result = as_number(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong value type (number) let values = vec![create_number_value(5.0)]; let result = as_number(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong value type (string) let values = vec![create_string_value("hello")]; let result = as_number(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with invalid value let values = vec![create_invalid_value()]; let result = as_number(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -211,7 +236,12 @@ mod tests { // Test true -> "true" let values = vec![create_bool_value(true)]; - let result = as_text(&values, &mut ctx).unwrap(); + let signal = as_text(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; + match result.kind { Some(Kind::StringValue(val)) => assert_eq!(val, "true"), _ => panic!("Expected StringValue"), @@ -219,7 +249,12 @@ mod tests { // Test false -> "false" let values = vec![create_bool_value(false)]; - let result = as_text(&values, &mut ctx).unwrap(); + let signal = as_text(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; match result.kind { Some(Kind::StringValue(val)) => assert_eq!(val, "false"), _ => panic!("Expected StringValue"), @@ -233,27 +268,27 @@ mod tests { // Test with wrong number of parameters (none) let values = vec![]; let result = as_text(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong number of parameters (too many) let values = vec![create_bool_value(true), create_bool_value(false)]; let result = as_text(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong value type (number) let values = vec![create_number_value(5.0)]; let result = as_text(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong value type (string) let values = vec![create_string_value("hello")]; let result = as_text(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with invalid value let values = vec![create_invalid_value()]; let result = as_text(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -262,7 +297,11 @@ mod tests { // Test 0.0 -> false let values = vec![create_number_value(0.0)]; - let result = from_number(&values, &mut ctx).unwrap(); + let signal = from_number(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; match result.kind { Some(Kind::BoolValue(val)) => assert_eq!(val, false), _ => panic!("Expected BoolValue"), @@ -270,7 +309,12 @@ mod tests { // Test positive number -> true let values = vec![create_number_value(5.0)]; - let result = from_number(&values, &mut ctx).unwrap(); + let signal = from_number(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; + match result.kind { Some(Kind::BoolValue(val)) => assert_eq!(val, true), _ => panic!("Expected BoolValue"), @@ -278,7 +322,12 @@ mod tests { // Test negative number -> true let values = vec![create_number_value(-3.5)]; - let result = from_number(&values, &mut ctx).unwrap(); + let signal = from_number(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; + match result.kind { Some(Kind::BoolValue(val)) => assert_eq!(val, true), _ => panic!("Expected BoolValue"), @@ -286,7 +335,13 @@ mod tests { // Test -0.0 -> false let values = vec![create_number_value(-0.0)]; - let result = from_number(&values, &mut ctx).unwrap(); + let signal = from_number(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; + match result.kind { Some(Kind::BoolValue(val)) => assert_eq!(val, false), _ => panic!("Expected BoolValue"), @@ -300,27 +355,27 @@ mod tests { // Test with wrong number of parameters (none) let values = vec![]; let result = from_number(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong number of parameters (too many) let values = vec![create_number_value(5.0), create_number_value(3.0)]; let result = from_number(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong value type (bool) let values = vec![create_bool_value(true)]; let result = from_number(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong value type (string) let values = vec![create_string_value("hello")]; let result = from_number(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with invalid value let values = vec![create_invalid_value()]; let result = from_number(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -329,7 +384,11 @@ mod tests { // Test "true" -> true let values = vec![create_string_value("true")]; - let result = from_text(&values, &mut ctx).unwrap(); + let signal = from_text(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; match result.kind { Some(Kind::BoolValue(val)) => assert_eq!(val, true), _ => panic!("Expected BoolValue"), @@ -337,7 +396,11 @@ mod tests { // Test "false" -> false let values = vec![create_string_value("false")]; - let result = from_text(&values, &mut ctx).unwrap(); + let signal = from_text(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; match result.kind { Some(Kind::BoolValue(val)) => assert_eq!(val, false), _ => panic!("Expected BoolValue"), @@ -345,7 +408,11 @@ mod tests { // Test "True" -> true (case insensitive) let values = vec![create_string_value("True")]; - let result = from_text(&values, &mut ctx).unwrap(); + let signal = from_text(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; match result.kind { Some(Kind::BoolValue(val)) => assert_eq!(val, true), _ => panic!("Expected BoolValue"), @@ -353,7 +420,11 @@ mod tests { // Test "FALSE" -> false (case insensitive) let values = vec![create_string_value("FALSE")]; - let result = from_text(&values, &mut ctx).unwrap(); + let signal = from_text(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; match result.kind { Some(Kind::BoolValue(val)) => assert_eq!(val, false), _ => panic!("Expected BoolValue"), @@ -367,42 +438,42 @@ mod tests { // Test with wrong number of parameters (none) let values = vec![]; let result = from_text(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong number of parameters (too many) let values = vec![create_string_value("true"), create_string_value("false")]; let result = from_text(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong value type (bool) let values = vec![create_bool_value(true)]; let result = from_text(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong value type (number) let values = vec![create_number_value(5.0)]; let result = from_text(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with invalid value let values = vec![create_invalid_value()]; let result = from_text(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with unparseable text let values = vec![create_string_value("hello")]; let result = from_text(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with numeric string let values = vec![create_string_value("123")]; let result = from_text(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with empty string let values = vec![create_string_value("")]; let result = from_text(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -411,7 +482,11 @@ mod tests { // Test true == true -> true let values = vec![create_bool_value(true), create_bool_value(true)]; - let result = is_equal(&values, &mut ctx).unwrap(); + let signal = is_equal(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; match result.kind { Some(Kind::BoolValue(val)) => assert_eq!(val, true), _ => panic!("Expected BoolValue"), @@ -419,7 +494,11 @@ mod tests { // Test false == false -> true let values = vec![create_bool_value(false), create_bool_value(false)]; - let result = is_equal(&values, &mut ctx).unwrap(); + let signal = is_equal(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; match result.kind { Some(Kind::BoolValue(val)) => assert_eq!(val, true), _ => panic!("Expected BoolValue"), @@ -427,7 +506,11 @@ mod tests { // Test true == false -> false let values = vec![create_bool_value(true), create_bool_value(false)]; - let result = is_equal(&values, &mut ctx).unwrap(); + let signal = is_equal(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; match result.kind { Some(Kind::BoolValue(val)) => assert_eq!(val, false), _ => panic!("Expected BoolValue"), @@ -435,7 +518,12 @@ mod tests { // Test false == true -> false let values = vec![create_bool_value(false), create_bool_value(true)]; - let result = is_equal(&values, &mut ctx).unwrap(); + let signal = is_equal(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; + match result.kind { Some(Kind::BoolValue(val)) => assert_eq!(val, false), _ => panic!("Expected BoolValue"), @@ -449,12 +537,12 @@ mod tests { // Test with wrong number of parameters (none) let values = vec![]; let result = is_equal(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong number of parameters (one) let values = vec![create_bool_value(true)]; let result = is_equal(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong number of parameters (too many) let values = vec![ @@ -463,26 +551,26 @@ mod tests { create_bool_value(true), ]; let result = is_equal(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong value type (first parameter) let values = vec![create_number_value(5.0), create_bool_value(true)]; let result = is_equal(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong value type (second parameter) let values = vec![create_bool_value(true), create_string_value("hello")]; let result = is_equal(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with invalid values let values = vec![create_invalid_value(), create_bool_value(true)]; let result = is_equal(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); let values = vec![create_bool_value(true), create_invalid_value()]; let result = is_equal(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -491,7 +579,11 @@ mod tests { // Test !true -> false let values = vec![create_bool_value(true)]; - let result = negate(&values, &mut ctx).unwrap(); + let signal = negate(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; match result.kind { Some(Kind::BoolValue(val)) => assert_eq!(val, false), _ => panic!("Expected BoolValue"), @@ -499,7 +591,11 @@ mod tests { // Test !false -> true let values = vec![create_bool_value(false)]; - let result = negate(&values, &mut ctx).unwrap(); + let signal = negate(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success"), + }; match result.kind { Some(Kind::BoolValue(val)) => assert_eq!(val, true), _ => panic!("Expected BoolValue"), @@ -513,26 +609,26 @@ mod tests { // Test with wrong number of parameters (none) let values = vec![]; let result = negate(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong number of parameters (too many) let values = vec![create_bool_value(true), create_bool_value(false)]; let result = negate(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong value type (number) let values = vec![create_number_value(5.0)]; let result = negate(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong value type (string) let values = vec![create_string_value("hello")]; let result = negate(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with invalid value let values = vec![create_invalid_value()]; let result = negate(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } } diff --git a/src/implementation/control.rs b/src/implementation/control.rs index eeb8fe7..15719b6 100644 --- a/src/implementation/control.rs +++ b/src/implementation/control.rs @@ -1,6 +1,7 @@ use tucana::shared::Value; use crate::{context::Context, error::RuntimeError, registry::HandlerFn}; +use crate::context::signal::Signal; pub fn collect_control_functions() -> Vec<(&'static str, HandlerFn)> { vec![ @@ -9,24 +10,24 @@ pub fn collect_control_functions() -> Vec<(&'static str, HandlerFn)> { ] } -fn r#break(values: &[Value], _ctx: &mut Context) -> Result { +fn r#break(values: &[Value], _ctx: &mut Context) -> Signal { let [Value { kind }] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected one generic value but received {:?}", values), )); }; - Ok(Value { kind: kind.clone() }) + Signal::Success(Value { kind: kind.clone() }) } -fn r#return(values: &[Value], _ctx: &mut Context) -> Result { +fn r#return(values: &[Value], _ctx: &mut Context) -> Signal { let [Value { kind }] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected one generic value but received {:?}", values), )); }; - Ok(Value { kind: kind.clone() }) + Signal::Success(Value { kind: kind.clone() }) } diff --git a/src/implementation/http.rs b/src/implementation/http.rs index a09a31f..1c85bfc 100644 --- a/src/implementation/http.rs +++ b/src/implementation/http.rs @@ -1,6 +1,7 @@ use tucana::shared::{Struct, Value}; use tucana::shared::value::Kind; use crate::context::Context; +use crate::context::signal::Signal; use crate::error::RuntimeError; use crate::registry::HandlerFn; @@ -11,7 +12,7 @@ pub fn collect_http_functions() -> Vec<(&'static str, HandlerFn)> { ] } -fn create_request(values: &[Value], _ctx: &mut Context) -> Result { +fn create_request(values: &[Value], _ctx: &mut Context) -> Signal { let [Value { kind: Some(Kind::StringValue(http_method)), }, @@ -24,7 +25,7 @@ fn create_request(values: &[Value], _ctx: &mut Context) -> Result Result Result { +fn create_response(values: &[Value], _ctx: &mut Context) -> Signal { let [Value { kind: Some(Kind::NumberValue(http_status_code)), }, @@ -60,7 +61,7 @@ fn create_response(values: &[Value], _ctx: &mut Context) -> Result Result Vec<(&'static str, HandlerFn)> { @@ -47,7 +48,7 @@ pub fn collect_number_functions() -> Vec<(&'static str, HandlerFn)> { ] } -fn add(values: &[Value], _ctx: &mut Context) -> Result { +fn add(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::NumberValue(lhs)), @@ -57,7 +58,7 @@ fn add(values: &[Value], _ctx: &mut Context) -> Result { }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected two numbers as arguments but received {:?}", @@ -66,12 +67,12 @@ fn add(values: &[Value], _ctx: &mut Context) -> Result { )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::NumberValue(lhs + rhs)), }) } -fn multiply(values: &[Value], _ctx: &mut Context) -> Result { +fn multiply(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::NumberValue(lhs)), @@ -81,7 +82,7 @@ fn multiply(values: &[Value], _ctx: &mut Context) -> Result }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected two numbers as arguments but received {:?}", @@ -90,12 +91,12 @@ fn multiply(values: &[Value], _ctx: &mut Context) -> Result )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::NumberValue(lhs * rhs)), }) } -fn substract(values: &[Value], _ctx: &mut Context) -> Result { +fn substract(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::NumberValue(lhs)), @@ -105,7 +106,7 @@ fn substract(values: &[Value], _ctx: &mut Context) -> Result Result Result { +fn divide(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::NumberValue(lhs)), @@ -129,7 +130,7 @@ fn divide(values: &[Value], _ctx: &mut Context) -> Result { }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected two numbers as arguments but received {:?}", @@ -139,18 +140,18 @@ fn divide(values: &[Value], _ctx: &mut Context) -> Result { }; if rhs == &0.0 { - return Err(RuntimeError::simple_str( + return Signal::Failure(RuntimeError::simple_str( "DivisionByZero", "You cannot divide by zero", )); } - Ok(Value { + Signal::Success(Value { kind: Some(Kind::NumberValue(lhs / rhs)), }) } -fn modulo(values: &[Value], _ctx: &mut Context) -> Result { +fn modulo(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::NumberValue(lhs)), @@ -160,7 +161,7 @@ fn modulo(values: &[Value], _ctx: &mut Context) -> Result { }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected two numbers as arguments but received {:?}", @@ -170,54 +171,54 @@ fn modulo(values: &[Value], _ctx: &mut Context) -> Result { }; if rhs == &0.0 { - return Err(RuntimeError::simple_str( + return Signal::Failure(RuntimeError::simple_str( "DivisionByZero", "You cannot divide by zero", )); } - Ok(Value { + Signal::Success(Value { kind: Some(Kind::NumberValue(lhs % rhs)), }) } -fn abs(values: &[Value], _ctx: &mut Context) -> Result { +fn abs(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::NumberValue(value)), }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected a number as argument but received {:?}", values), )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::NumberValue(value.abs())), }) } -fn is_positive(values: &[Value], _ctx: &mut Context) -> Result { +fn is_positive(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::NumberValue(value)), }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected a number as argument but received {:?}", values), )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::BoolValue(!value.is_sign_negative())), }) } -fn is_greater(values: &[Value], _ctx: &mut Context) -> Result { +fn is_greater(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::NumberValue(lhs)), @@ -227,7 +228,7 @@ fn is_greater(values: &[Value], _ctx: &mut Context) -> Result Result rhs)), }) } -fn is_less(values: &[Value], _ctx: &mut Context) -> Result { +fn is_less(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::NumberValue(lhs)), @@ -251,7 +252,7 @@ fn is_less(values: &[Value], _ctx: &mut Context) -> Result }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected two numbers as arguments but received {:?}", @@ -260,48 +261,48 @@ fn is_less(values: &[Value], _ctx: &mut Context) -> Result )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::BoolValue(lhs < rhs)), }) } -fn is_zero(values: &[Value], _ctx: &mut Context) -> Result { +fn is_zero(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::NumberValue(value)), }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected a number as argument but received {:?}", values), )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::BoolValue(value == &0.0)), }) } -fn square(values: &[Value], _ctx: &mut Context) -> Result { +fn square(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::NumberValue(value)), }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected a number as argument but received {:?}", values), )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::NumberValue(value.powf(2.0))), }) } -fn exponential(values: &[Value], _ctx: &mut Context) -> Result { +fn exponential(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::NumberValue(base)), @@ -311,7 +312,7 @@ fn exponential(values: &[Value], _ctx: &mut Context) -> Result Result Result { - Ok(Value { +fn pi(_values: &[Value], _ctx: &mut Context) -> Signal { + Signal::Success(Value { kind: Some(Kind::NumberValue(f64::consts::PI)), }) } -fn euler(_values: &[Value], _ctx: &mut Context) -> Result { - Ok(Value { +fn euler(_values: &[Value], _ctx: &mut Context) -> Signal { + Signal::Success(Value { kind: Some(Kind::NumberValue(f64::consts::E)), }) } -fn infinity(_values: &[Value], _ctx: &mut Context) -> Result { - Ok(Value { +fn infinity(_values: &[Value], _ctx: &mut Context) -> Signal { + Signal::Success(Value { kind: Some(Kind::NumberValue(f64::INFINITY)), }) } -fn round_up(values: &[Value], _ctx: &mut Context) -> Result { +fn round_up(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::NumberValue(value)), @@ -353,7 +354,7 @@ fn round_up(values: &[Value], _ctx: &mut Context) -> Result }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected two numbers as arguments but received {:?}", @@ -364,12 +365,12 @@ fn round_up(values: &[Value], _ctx: &mut Context) -> Result let factor = 10_f64.powi(decimal_places.clone() as i32); - Ok(Value { + Signal::Success(Value { kind: Some(Kind::NumberValue((value * factor).ceil() / factor)), }) } -fn round_down(values: &[Value], _ctx: &mut Context) -> Result { +fn round_down(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::NumberValue(value)), @@ -379,7 +380,7 @@ fn round_down(values: &[Value], _ctx: &mut Context) -> Result Result Result { +fn round(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::NumberValue(value)), @@ -405,7 +406,7 @@ fn round(values: &[Value], _ctx: &mut Context) -> Result { }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected two numbers as arguments but received {:?}", @@ -416,30 +417,30 @@ fn round(values: &[Value], _ctx: &mut Context) -> Result { let factor = 10_f64.powi(decimal_places.clone() as i32); - Ok(Value { + Signal::Success(Value { kind: Some(Kind::NumberValue((value * factor).round() / factor)), }) } -fn square_root(values: &[Value], _ctx: &mut Context) -> Result { +fn square_root(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::NumberValue(value)), }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected one number as argument but received {:?}", values), )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::NumberValue(value.sqrt())), }) } -fn root(values: &[Value], _ctx: &mut Context) -> Result { +fn root(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::NumberValue(value)), @@ -449,7 +450,7 @@ fn root(values: &[Value], _ctx: &mut Context) -> Result { }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected two numbers as arguments but received {:?}", @@ -458,12 +459,12 @@ fn root(values: &[Value], _ctx: &mut Context) -> Result { )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::NumberValue(value.powf(root.clone()))), }) } -fn log(values: &[Value], _ctx: &mut Context) -> Result { +fn log(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::NumberValue(value)), @@ -473,7 +474,7 @@ fn log(values: &[Value], _ctx: &mut Context) -> Result { }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected two numbers as arguments but received {:?}", @@ -482,37 +483,37 @@ fn log(values: &[Value], _ctx: &mut Context) -> Result { )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::NumberValue(value.log(log.clone()))), }) } -fn ln(values: &[Value], _ctx: &mut Context) -> Result { +fn ln(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::NumberValue(value)), }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected one number as argument but received {:?}", values), )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::NumberValue(value.ln())), }) } -fn from_text(values: &[Value], _ctx: &mut Context) -> Result { +fn from_text(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::StringValue(string_value)), }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected one string as argument but received {:?}", values), )); @@ -521,37 +522,37 @@ fn from_text(values: &[Value], _ctx: &mut Context) -> Result result, Err(_) => { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Failed to parse string as number: {}", string_value), )); } }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::NumberValue(value)), }) } -fn as_text(values: &[Value], _ctx: &mut Context) -> Result { +fn as_text(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::NumberValue(value)), }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected one number as argument but received {:?}", values), )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::StringValue(value.to_string())), }) } -fn min(values: &[Value], _ctx: &mut Context) -> Result { +fn min(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::NumberValue(lhs)), @@ -561,7 +562,7 @@ fn min(values: &[Value], _ctx: &mut Context) -> Result { }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected two numbers as arguments but received {:?}", @@ -570,12 +571,12 @@ fn min(values: &[Value], _ctx: &mut Context) -> Result { )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::NumberValue(lhs.min(rhs.clone()))), }) } -fn max(values: &[Value], _ctx: &mut Context) -> Result { +fn max(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::NumberValue(lhs)), @@ -585,7 +586,7 @@ fn max(values: &[Value], _ctx: &mut Context) -> Result { }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected two numbers as arguments but received {:?}", @@ -594,30 +595,30 @@ fn max(values: &[Value], _ctx: &mut Context) -> Result { )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::NumberValue(lhs.max(rhs.clone()))), }) } -fn negate(values: &[Value], _ctx: &mut Context) -> Result { +fn negate(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::NumberValue(value)), }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected one number as argument but received {:?}", values), )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::NumberValue(-value)), }) } -fn random(values: &[Value], _ctx: &mut Context) -> Result { +fn random(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::NumberValue(min)), @@ -627,7 +628,7 @@ fn random(values: &[Value], _ctx: &mut Context) -> Result { }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected two numbers as arguments but received {:?}", @@ -636,157 +637,157 @@ fn random(values: &[Value], _ctx: &mut Context) -> Result { )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::NumberValue(rand::random_range( min.clone()..max.clone(), ))), }) } -fn sin(values: &[Value], _ctx: &mut Context) -> Result { +fn sin(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::NumberValue(value)), }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected one number as argument but received {:?}", values), )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::NumberValue(value.sin())), }) } -fn cos(values: &[Value], _ctx: &mut Context) -> Result { +fn cos(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::NumberValue(value)), }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected one number as argument but received {:?}", values), )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::NumberValue(value.cos())), }) } -fn tan(values: &[Value], _ctx: &mut Context) -> Result { +fn tan(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::NumberValue(value)), }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected one number as argument but received {:?}", values), )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::NumberValue(value.tan())), }) } -fn arcsin(values: &[Value], _ctx: &mut Context) -> Result { +fn arcsin(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::NumberValue(value)), }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected one number as argument but received {:?}", values), )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::NumberValue(value.asin())), }) } -fn arccos(values: &[Value], _ctx: &mut Context) -> Result { +fn arccos(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::NumberValue(value)), }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected one number as argument but received {:?}", values), )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::NumberValue(value.acos())), }) } -fn arctan(values: &[Value], _ctx: &mut Context) -> Result { +fn arctan(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::NumberValue(value)), }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected one number as argument but received {:?}", values), )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::NumberValue(value.atan())), }) } -fn sinh(values: &[Value], _ctx: &mut Context) -> Result { +fn sinh(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::NumberValue(value)), }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected one number as argument but received {:?}", values), )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::NumberValue(value.sinh())), }) } -fn cosh(values: &[Value], _ctx: &mut Context) -> Result { +fn cosh(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::NumberValue(value)), }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected one number as argument but received {:?}", values), )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::NumberValue(value.cosh())), }) } -fn clamp(values: &[Value], _ctx: &mut Context) -> Result { +fn clamp(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::NumberValue(value)), @@ -799,7 +800,7 @@ fn clamp(values: &[Value], _ctx: &mut Context) -> Result { }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected three numbers as arguments but received {:?}", @@ -808,12 +809,12 @@ fn clamp(values: &[Value], _ctx: &mut Context) -> Result { )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::NumberValue(value.clamp(min.clone(), max.clone()))), }) } -fn is_equal(values: &[Value], _ctx: &mut Context) -> Result { +fn is_equal(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::NumberValue(lhs)), @@ -823,7 +824,7 @@ fn is_equal(values: &[Value], _ctx: &mut Context) -> Result }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected two numbers as arguments but received {:?}", @@ -832,7 +833,7 @@ fn is_equal(values: &[Value], _ctx: &mut Context) -> Result )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::BoolValue(lhs == rhs)), }) } @@ -873,7 +874,12 @@ mod tests { fn test_add_success() { let mut ctx = Context::new(); let values = vec![create_number_value(5.0), create_number_value(3.0)]; - let result = add(&values, &mut ctx).unwrap(); + let signal = add(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert_eq!(val, 8.0), @@ -888,25 +894,29 @@ mod tests { // Test with wrong number of parameters let values = vec![create_number_value(5.0)]; let result = add(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong value types let values = vec![create_string_value("hello"), create_number_value(3.0)]; let result = add(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with invalid values let values = vec![create_invalid_value(), create_number_value(3.0)]; let result = add(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] fn test_multiply_success() { let mut ctx = Context::new(); let values = vec![create_number_value(4.0), create_number_value(2.5)]; - let result = multiply(&values, &mut ctx).unwrap(); + let signal = multiply(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert_eq!(val, 10.0), _ => panic!("Expected NumberValue"), @@ -918,15 +928,19 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_bool_value(true), create_number_value(3.0)]; let result = multiply(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] fn test_substract_success() { let mut ctx = Context::new(); let values = vec![create_number_value(10.0), create_number_value(4.0)]; - let result = substract(&values, &mut ctx).unwrap(); + let signal = substract(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert_eq!(val, 6.0), _ => panic!("Expected NumberValue"), @@ -938,15 +952,19 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_number_value(5.0)]; let result = substract(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] fn test_divide_success() { let mut ctx = Context::new(); let values = vec![create_number_value(15.0), create_number_value(3.0)]; - let result = divide(&values, &mut ctx).unwrap(); + let signal = divide(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert_eq!(val, 5.0), _ => panic!("Expected NumberValue"), @@ -958,7 +976,7 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_number_value(10.0), create_number_value(0.0)]; let result = divide(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -969,15 +987,19 @@ mod tests { create_number_value(2.0), ]; let result = divide(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] fn test_modulo_success() { let mut ctx = Context::new(); let values = vec![create_number_value(10.0), create_number_value(3.0)]; - let result = modulo(&values, &mut ctx).unwrap(); + let signal = modulo(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert_eq!(val, 1.0), _ => panic!("Expected NumberValue"), @@ -989,7 +1011,7 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_number_value(10.0), create_number_value(0.0)]; let result = modulo(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -997,7 +1019,7 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_invalid_value(), create_number_value(3.0)]; let result = modulo(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -1006,7 +1028,12 @@ mod tests { // Test positive number let values = vec![create_number_value(5.0)]; - let result = abs(&values, &mut ctx).unwrap(); + let signal = abs(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert_eq!(val, 5.0), _ => panic!("Expected NumberValue"), @@ -1014,7 +1041,12 @@ mod tests { // Test negative number let values = vec![create_number_value(-7.5)]; - let result = abs(&values, &mut ctx).unwrap(); + let signal = abs(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert_eq!(val, 7.5), _ => panic!("Expected NumberValue"), @@ -1026,7 +1058,7 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_string_value("not_a_number")]; let result = abs(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -1035,7 +1067,12 @@ mod tests { // Test positive number let values = vec![create_number_value(5.0)]; - let result = is_positive(&values, &mut ctx).unwrap(); + let signal = is_positive(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::BoolValue(val)) => assert_eq!(val, true), _ => panic!("Expected BoolValue"), @@ -1043,7 +1080,12 @@ mod tests { // Test negative number let values = vec![create_number_value(-5.0)]; - let result = is_positive(&values, &mut ctx).unwrap(); + let signal = is_positive(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::BoolValue(val)) => assert_eq!(val, false), _ => panic!("Expected BoolValue"), @@ -1051,7 +1093,12 @@ mod tests { // Test zero let values = vec![create_number_value(0.0)]; - let result = is_positive(&values, &mut ctx).unwrap(); + let signal = is_positive(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::BoolValue(val)) => assert_eq!(val, true), _ => panic!("Expected BoolValue"), @@ -1063,7 +1110,7 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_bool_value(true)]; let result = is_positive(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -1072,7 +1119,11 @@ mod tests { // Test greater let values = vec![create_number_value(10.0), create_number_value(5.0)]; - let result = is_greater(&values, &mut ctx).unwrap(); + let signal = is_greater(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::BoolValue(val)) => assert_eq!(val, true), _ => panic!("Expected BoolValue"), @@ -1080,7 +1131,11 @@ mod tests { // Test not greater let values = vec![create_number_value(3.0), create_number_value(7.0)]; - let result = is_greater(&values, &mut ctx).unwrap(); + let signal = is_greater(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::BoolValue(val)) => assert_eq!(val, false), _ => panic!("Expected BoolValue"), @@ -1095,7 +1150,7 @@ mod tests { create_string_value("not_a_number"), ]; let result = is_greater(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -1104,7 +1159,11 @@ mod tests { // Test less let values = vec![create_number_value(3.0), create_number_value(7.0)]; - let result = is_less(&values, &mut ctx).unwrap(); + let signal = is_less(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::BoolValue(val)) => assert_eq!(val, true), _ => panic!("Expected BoolValue"), @@ -1112,7 +1171,11 @@ mod tests { // Test not less let values = vec![create_number_value(10.0), create_number_value(5.0)]; - let result = is_less(&values, &mut ctx).unwrap(); + let signal = is_less(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::BoolValue(val)) => assert_eq!(val, false), _ => panic!("Expected BoolValue"), @@ -1124,7 +1187,7 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_invalid_value(), create_number_value(5.0)]; let result = is_less(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -1133,7 +1196,11 @@ mod tests { // Test zero let values = vec![create_number_value(0.0)]; - let result = is_zero(&values, &mut ctx).unwrap(); + let signal = is_zero(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::BoolValue(val)) => assert_eq!(val, true), _ => panic!("Expected BoolValue"), @@ -1141,7 +1208,11 @@ mod tests { // Test non-zero let values = vec![create_number_value(5.0)]; - let result = is_zero(&values, &mut ctx).unwrap(); + let signal = is_zero(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::BoolValue(val)) => assert_eq!(val, false), _ => panic!("Expected BoolValue"), @@ -1153,15 +1224,19 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_string_value("zero")]; let result = is_zero(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] fn test_square_success() { let mut ctx = Context::new(); let values = vec![create_number_value(4.0)]; - let result = square(&values, &mut ctx).unwrap(); + let signal = square(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert_eq!(val, 16.0), _ => panic!("Expected NumberValue"), @@ -1173,15 +1248,18 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_bool_value(false)]; let result = square(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] fn test_exponential_success() { let mut ctx = Context::new(); let values = vec![create_number_value(2.0), create_number_value(3.0)]; - let result = exponential(&values, &mut ctx).unwrap(); - + let signal = exponential(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert_eq!(val, 8.0), _ => panic!("Expected NumberValue"), @@ -1193,15 +1271,19 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_number_value(2.0)]; let result = exponential(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] fn test_pi_success() { let mut ctx = Context::new(); let values = vec![]; - let result = pi(&values, &mut ctx).unwrap(); + let signal = pi(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => { assert!((val - std::f64::consts::PI).abs() < f64::EPSILON) @@ -1214,8 +1296,12 @@ mod tests { fn test_euler_success() { let mut ctx = Context::new(); let values = vec![]; - let result = euler(&values, &mut ctx).unwrap(); + let signal = euler(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => { assert!((val - std::f64::consts::E).abs() < f64::EPSILON) @@ -1228,8 +1314,12 @@ mod tests { fn test_infinity_success() { let mut ctx = Context::new(); let values = vec![]; - let result = infinity(&values, &mut ctx).unwrap(); + let signal = infinity(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert!(val.is_infinite() && val.is_sign_positive()), _ => panic!("Expected NumberValue"), @@ -1240,8 +1330,12 @@ mod tests { fn test_round_up_success() { let mut ctx = Context::new(); let values = vec![create_number_value(3.14159), create_number_value(2.0)]; - let result = round_up(&values, &mut ctx).unwrap(); + let signal = round_up(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert_eq!(val, 3.15), _ => panic!("Expected NumberValue"), @@ -1253,15 +1347,19 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_string_value("3.14"), create_number_value(2.0)]; let result = round_up(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] fn test_round_down_success() { let mut ctx = Context::new(); let values = vec![create_number_value(3.14159), create_number_value(2.0)]; - let result = round_down(&values, &mut ctx).unwrap(); + let signal = round_down(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert_eq!(val, 3.14), _ => panic!("Expected NumberValue"), @@ -1273,15 +1371,19 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_number_value(3.14), create_invalid_value()]; let result = round_down(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] fn test_round_success() { let mut ctx = Context::new(); let values = vec![create_number_value(3.14159), create_number_value(2.0)]; - let result = round(&values, &mut ctx).unwrap(); + let signal = round(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert_eq!(val, 3.14), _ => panic!("Expected NumberValue"), @@ -1293,15 +1395,19 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_bool_value(true), create_number_value(2.0)]; let result = round(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] fn test_square_root_success() { let mut ctx = Context::new(); let values = vec![create_number_value(16.0)]; - let result = square_root(&values, &mut ctx).unwrap(); + let signal = square_root(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert_eq!(val, 4.0), _ => panic!("Expected NumberValue"), @@ -1313,15 +1419,19 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_string_value("sixteen")]; let result = square_root(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] fn test_root_success() { let mut ctx = Context::new(); let values = vec![create_number_value(8.0), create_number_value(1.0 / 3.0)]; - let result = root(&values, &mut ctx).unwrap(); + let signal = root(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert!((val - 2.0).abs() < 0.001), _ => panic!("Expected NumberValue"), @@ -1333,15 +1443,19 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_number_value(8.0)]; let result = root(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] fn test_log_success() { let mut ctx = Context::new(); let values = vec![create_number_value(100.0), create_number_value(10.0)]; - let result = log(&values, &mut ctx).unwrap(); + let signal = log(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert!((val - 2.0).abs() < f64::EPSILON), _ => panic!("Expected NumberValue"), @@ -1353,15 +1467,19 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_invalid_value(), create_number_value(10.0)]; let result = log(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] fn test_ln_success() { let mut ctx = Context::new(); let values = vec![create_number_value(std::f64::consts::E)]; - let result = ln(&values, &mut ctx).unwrap(); + let signal = ln(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert!((val - 1.0).abs() < f64::EPSILON), _ => panic!("Expected NumberValue"), @@ -1373,15 +1491,19 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_bool_value(true)]; let result = ln(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] fn test_from_text_success() { let mut ctx = Context::new(); let values = vec![create_string_value("42.5")]; - let result = from_text(&values, &mut ctx).unwrap(); + let signal = from_text(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert_eq!(val, 42.5), _ => panic!("Expected NumberValue"), @@ -1395,20 +1517,23 @@ mod tests { // Test with invalid string let values = vec![create_string_value("not_a_number")]; let result = from_text(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong type let values = vec![create_number_value(42.0)]; let result = from_text(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] fn test_as_text_success() { let mut ctx = Context::new(); let values = vec![create_number_value(42.5)]; - let result = as_text(&values, &mut ctx).unwrap(); - + let signal = as_text(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::StringValue(val)) => assert_eq!(val, "42.5"), _ => panic!("Expected StringValue"), @@ -1420,15 +1545,18 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_string_value("already_text")]; let result = as_text(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] fn test_min_success() { let mut ctx = Context::new(); let values = vec![create_number_value(3.0), create_number_value(7.0)]; - let result = min(&values, &mut ctx).unwrap(); - + let signal = min(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert_eq!(val, 3.0), _ => panic!("Expected NumberValue"), @@ -1440,15 +1568,18 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_number_value(3.0), create_bool_value(false)]; let result = min(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] fn test_max_success() { let mut ctx = Context::new(); let values = vec![create_number_value(3.0), create_number_value(7.0)]; - let result = max(&values, &mut ctx).unwrap(); - + let signal = max(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert_eq!(val, 7.0), _ => panic!("Expected NumberValue"), @@ -1460,7 +1591,7 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_string_value("three"), create_number_value(7.0)]; let result = max(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -1469,7 +1600,11 @@ mod tests { // Test positive number let values = vec![create_number_value(5.0)]; - let result = negate(&values, &mut ctx).unwrap(); + let signal = negate(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert_eq!(val, -5.0), _ => panic!("Expected NumberValue"), @@ -1477,7 +1612,11 @@ mod tests { // Test negative number let values = vec![create_number_value(-3.0)]; - let result = negate(&values, &mut ctx).unwrap(); + let signal = negate(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert_eq!(val, 3.0), _ => panic!("Expected NumberValue"), @@ -1489,15 +1628,19 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_invalid_value()]; let result = negate(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] fn test_random_success() { let mut ctx = Context::new(); let values = vec![create_number_value(1.0), create_number_value(10.0)]; - let result = random(&values, &mut ctx).unwrap(); + let signal = random(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => { assert!(val >= 1.0 && val < 10.0); @@ -1511,15 +1654,19 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_number_value(1.0), create_string_value("ten")]; let result = random(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] fn test_sin_success() { let mut ctx = Context::new(); let values = vec![create_number_value(std::f64::consts::PI / 2.0)]; - let result = sin(&values, &mut ctx).unwrap(); + let signal = sin(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert!((val - 1.0).abs() < f64::EPSILON), _ => panic!("Expected NumberValue"), @@ -1531,15 +1678,19 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_bool_value(true)]; let result = sin(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] fn test_cos_success() { let mut ctx = Context::new(); let values = vec![create_number_value(0.0)]; - let result = cos(&values, &mut ctx).unwrap(); + let signal = cos(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert!((val - 1.0).abs() < f64::EPSILON), _ => panic!("Expected NumberValue"), @@ -1551,15 +1702,19 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_string_value("zero")]; let result = cos(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] fn test_tan_success() { let mut ctx = Context::new(); let values = vec![create_number_value(std::f64::consts::PI / 4.0)]; - let result = tan(&values, &mut ctx).unwrap(); + let signal = tan(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert!((val - 1.0).abs() < 0.0001), _ => panic!("Expected NumberValue"), @@ -1571,15 +1726,19 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_invalid_value()]; let result = tan(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] fn test_arcsin_success() { let mut ctx = Context::new(); let values = vec![create_number_value(1.0)]; - let result = arcsin(&values, &mut ctx).unwrap(); + let signal = arcsin(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => { assert!((val - std::f64::consts::PI / 2.0).abs() < f64::EPSILON) @@ -1593,15 +1752,19 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_bool_value(false)]; let result = arcsin(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] fn test_arccos_success() { let mut ctx = Context::new(); let values = vec![create_number_value(1.0)]; - let result = arccos(&values, &mut ctx).unwrap(); + let signal = arccos(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert!(val.abs() < f64::EPSILON), _ => panic!("Expected NumberValue"), @@ -1613,15 +1776,19 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_string_value("one")]; let result = arccos(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] fn test_arctan_success() { let mut ctx = Context::new(); let values = vec![create_number_value(1.0)]; - let result = arctan(&values, &mut ctx).unwrap(); + let signal = arctan(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => { assert!((val - std::f64::consts::PI / 4.0).abs() < f64::EPSILON) @@ -1635,15 +1802,19 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_invalid_value()]; let result = arctan(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] fn test_sinh_success() { let mut ctx = Context::new(); let values = vec![create_number_value(0.0)]; - let result = sinh(&values, &mut ctx).unwrap(); + let signal = sinh(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert!(val.abs() < f64::EPSILON), _ => panic!("Expected NumberValue"), @@ -1655,15 +1826,19 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_bool_value(true)]; let result = sinh(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] fn test_cosh_success() { let mut ctx = Context::new(); let values = vec![create_number_value(0.0)]; - let result = cosh(&values, &mut ctx).unwrap(); + let signal = cosh(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert!((val - 1.0).abs() < f64::EPSILON), _ => panic!("Expected NumberValue"), @@ -1675,7 +1850,7 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_string_value("zero")]; let result = cosh(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -1688,7 +1863,11 @@ mod tests { create_number_value(1.0), create_number_value(10.0), ]; - let result = clamp(&values, &mut ctx).unwrap(); + let signal = clamp(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert_eq!(val, 5.0), _ => panic!("Expected NumberValue"), @@ -1700,7 +1879,11 @@ mod tests { create_number_value(1.0), create_number_value(10.0), ]; - let result = clamp(&values, &mut ctx).unwrap(); + let signal = clamp(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert_eq!(val, 1.0), _ => panic!("Expected NumberValue"), @@ -1712,7 +1895,11 @@ mod tests { create_number_value(1.0), create_number_value(10.0), ]; - let result = clamp(&values, &mut ctx).unwrap(); + let signal = clamp(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert_eq!(val, 10.0), _ => panic!("Expected NumberValue"), @@ -1724,7 +1911,7 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_number_value(5.0), create_string_value("one")]; let result = clamp(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -1733,7 +1920,11 @@ mod tests { // Test equal numbers let values = vec![create_number_value(5.0), create_number_value(5.0)]; - let result = is_equal(&values, &mut ctx).unwrap(); + let signal = is_equal(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::BoolValue(val)) => assert_eq!(val, true), _ => panic!("Expected BoolValue"), @@ -1741,7 +1932,11 @@ mod tests { // Test unequal numbers let values = vec![create_number_value(5.0), create_number_value(3.0)]; - let result = is_equal(&values, &mut ctx).unwrap(); + let signal = is_equal(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::BoolValue(val)) => assert_eq!(val, false), _ => panic!("Expected BoolValue"), @@ -1753,6 +1948,6 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_number_value(5.0), create_bool_value(true)]; let result = is_equal(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } } diff --git a/src/implementation/object.rs b/src/implementation/object.rs index 01b31de..db3864a 100644 --- a/src/implementation/object.rs +++ b/src/implementation/object.rs @@ -1,5 +1,6 @@ use tucana::shared::{Value, value::Kind}; +use crate::context::signal::Signal; use crate::{context::Context, error::RuntimeError, registry::HandlerFn}; pub fn collect_object_functions() -> Vec<(&'static str, HandlerFn)> { @@ -11,7 +12,7 @@ pub fn collect_object_functions() -> Vec<(&'static str, HandlerFn)> { ] } -fn contains_key(values: &[Value], _ctx: &mut Context) -> Result { +fn contains_key(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::StructValue(object)), @@ -21,7 +22,7 @@ fn contains_key(values: &[Value], _ctx: &mut Context) -> Result Result Result { +fn size(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::StructValue(object)), }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected an object as an argument but received {:?}", @@ -52,19 +53,19 @@ fn size(values: &[Value], _ctx: &mut Context) -> Result { ), )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::NumberValue(object.fields.len() as f64)), }) } -fn keys(values: &[Value], _ctx: &mut Context) -> Result { +fn keys(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::StructValue(object)), }, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected an object as an argument but received {:?}", @@ -81,12 +82,12 @@ fn keys(values: &[Value], _ctx: &mut Context) -> Result { }) .collect::>(); - Ok(Value { + Signal::Success(Value { kind: Some(Kind::ListValue(tucana::shared::ListValue { values: keys })), }) } -fn set(values: &[Value], _ctx: &mut Context) -> Result { +fn set(values: &[Value], _ctx: &mut Context) -> Signal { let [ Value { kind: Some(Kind::StructValue(object)), @@ -97,7 +98,7 @@ fn set(values: &[Value], _ctx: &mut Context) -> Result { value, ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected an object as an argument but received {:?}", @@ -109,7 +110,7 @@ fn set(values: &[Value], _ctx: &mut Context) -> Result { let mut new_object = object.clone(); new_object.fields.insert(key.clone(), value.clone()); - Ok(Value { + Signal::Success(Value { kind: Some(Kind::StructValue(new_object)), }) } @@ -175,7 +176,12 @@ mod tests { // Test existing key let values = vec![test_object.clone(), create_string_value("name")]; - let result = contains_key(&values, &mut ctx).unwrap(); + let signal = contains_key(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::BoolValue(val)) => assert_eq!(val, true), @@ -184,7 +190,12 @@ mod tests { // Test non-existing key let values = vec![test_object, create_string_value("nonexistent")]; - let result = contains_key(&values, &mut ctx).unwrap(); + let signal = contains_key(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::BoolValue(val)) => assert_eq!(val, false), @@ -198,7 +209,12 @@ mod tests { let empty_object = create_empty_object(); let values = vec![empty_object, create_string_value("any_key")]; - let result = contains_key(&values, &mut ctx).unwrap(); + let signal = contains_key(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::BoolValue(val)) => assert_eq!(val, false), @@ -213,7 +229,7 @@ mod tests { // Test with wrong number of parameters let values = vec![create_test_object()]; let result = contains_key(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong first parameter type (not an object) let values = vec![ @@ -221,17 +237,17 @@ mod tests { create_string_value("key"), ]; let result = contains_key(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong second parameter type (not a string) let values = vec![create_test_object(), create_number_value(123.0)]; let result = contains_key(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with invalid values let values = vec![create_invalid_value(), create_string_value("key")]; let result = contains_key(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with too many parameters let values = vec![ @@ -240,7 +256,7 @@ mod tests { create_string_value("extra"), ]; let result = contains_key(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -250,7 +266,12 @@ mod tests { // Test with object containing fields let test_object = create_test_object(); let values = vec![test_object]; - let result = size(&values, &mut ctx).unwrap(); + let signal = size(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert_eq!(val, 3.0), // name, age, active @@ -260,7 +281,12 @@ mod tests { // Test with empty object let empty_object = create_empty_object(); let values = vec![empty_object]; - let result = size(&values, &mut ctx).unwrap(); + let signal = size(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::NumberValue(val)) => assert_eq!(val, 0.0), @@ -275,22 +301,22 @@ mod tests { // Test with wrong number of parameters (no parameters) let values = vec![]; let result = size(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong parameter type let values = vec![create_string_value("not_an_object")]; let result = size(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with invalid value let values = vec![create_invalid_value()]; let result = size(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with too many parameters let values = vec![create_test_object(), create_string_value("extra")]; let result = size(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -300,7 +326,12 @@ mod tests { // Test with object containing fields let test_object = create_test_object(); let values = vec![test_object]; - let result = keys(&values, &mut ctx).unwrap(); + let signal = keys(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::ListValue(list)) => { @@ -329,7 +360,12 @@ mod tests { // Test with empty object let empty_object = create_empty_object(); let values = vec![empty_object]; - let result = keys(&values, &mut ctx).unwrap(); + let signal = keys(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::ListValue(list)) => assert_eq!(list.values.len(), 0), @@ -344,22 +380,22 @@ mod tests { // Test with wrong number of parameters let values = vec![]; let result = keys(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong parameter type let values = vec![create_number_value(42.0)]; let result = keys(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with invalid value let values = vec![create_invalid_value()]; let result = keys(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with too many parameters let values = vec![create_test_object(), create_string_value("extra")]; let result = keys(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -373,7 +409,12 @@ mod tests { create_string_value("email"), create_string_value("john@example.com"), ]; - let result = set(&values, &mut ctx).unwrap(); + let signal = set(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::StructValue(struct_val)) => { @@ -398,7 +439,12 @@ mod tests { create_string_value("age"), create_number_value(31.0), ]; - let result = set(&values, &mut ctx).unwrap(); + let signal = set(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::StructValue(struct_val)) => { @@ -427,7 +473,12 @@ mod tests { create_string_value("first_key"), create_bool_value(true), ]; - let result = set(&values, &mut ctx).unwrap(); + let signal = set(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::StructValue(struct_val)) => { @@ -458,7 +509,12 @@ mod tests { let nested_object = create_object_value(nested_fields); let values = vec![test_object, create_string_value("address"), nested_object]; - let result = set(&values, &mut ctx).unwrap(); + let signal = set(&values, &mut ctx); + + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; match result.kind { Some(Kind::StructValue(struct_val)) => { @@ -484,7 +540,7 @@ mod tests { // Test with wrong number of parameters (too few) let values = vec![create_test_object(), create_string_value("key")]; let result = set(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong first parameter type (not an object) let values = vec![ @@ -493,7 +549,7 @@ mod tests { create_string_value("value"), ]; let result = set(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with wrong second parameter type (not a string key) let values = vec![ @@ -502,7 +558,7 @@ mod tests { create_string_value("value"), ]; let result = set(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with invalid values let values = vec![ @@ -511,12 +567,12 @@ mod tests { create_string_value("value"), ]; let result = set(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with no parameters let values = vec![]; let result = set(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); // Test with too many parameters let values = vec![ @@ -526,7 +582,7 @@ mod tests { create_string_value("extra"), ]; let result = set(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -545,7 +601,12 @@ mod tests { create_string_value("new_key"), create_string_value("new_value"), ]; - let _result = set(&values, &mut ctx).unwrap(); + let signal = set(&values, &mut ctx); + + let _value = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; // Verify original object is unchanged match &original_object.kind { diff --git a/src/implementation/text.rs b/src/implementation/text.rs index 4d2a724..9854682 100644 --- a/src/implementation/text.rs +++ b/src/implementation/text.rs @@ -1,6 +1,7 @@ +use crate::context::signal::Signal; use crate::{context::Context, error::RuntimeError, registry::HandlerFn}; use base64::Engine; -use tucana::shared::{value::Kind, ListValue, Value}; +use tucana::shared::{ListValue, Value, value::Kind}; pub fn collect_text_functions() -> Vec<(&'static str, HandlerFn)> { vec![ @@ -37,12 +38,14 @@ pub fn collect_text_functions() -> Vec<(&'static str, HandlerFn)> { ] } -fn as_bytes(values: &[Value], _ctx: &mut Context) -> Result { - let [Value { - kind: Some(Kind::StringValue(value)), - }] = values +fn as_bytes(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::StringValue(value)), + }, + ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected one string as argument but received {:?}", values), )); @@ -56,17 +59,19 @@ fn as_bytes(values: &[Value], _ctx: &mut Context) -> Result }) .collect(); - Ok(Value { + Signal::Success(Value { kind: Some(Kind::ListValue(ListValue { values: bytes })), }) } -fn byte_size(values: &[Value], _ctx: &mut Context) -> Result { - let [Value { - kind: Some(Kind::StringValue(value)), - }] = values +fn byte_size(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::StringValue(value)), + }, + ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected one string as an argument but received {:?}", @@ -75,17 +80,19 @@ fn byte_size(values: &[Value], _ctx: &mut Context) -> Result Result { - let [Value { - kind: Some(Kind::StringValue(value)), - }] = values +fn capitalize(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::StringValue(value)), + }, + ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected one string as an argument but received {:?}", @@ -117,17 +124,19 @@ fn capitalize(values: &[Value], _ctx: &mut Context) -> Result>() .join(" "); - Ok(Value { + Signal::Success(Value { kind: Some(Kind::StringValue(capitalized_value)), }) } -fn uppercase(values: &[Value], _ctx: &mut Context) -> Result { - let [Value { - kind: Some(Kind::StringValue(value)), - }] = values +fn uppercase(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::StringValue(value)), + }, + ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected one string as an argument but received {:?}", @@ -136,17 +145,19 @@ fn uppercase(values: &[Value], _ctx: &mut Context) -> Result Result { - let [Value { - kind: Some(Kind::StringValue(value)), - }] = values +fn lowercase(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::StringValue(value)), + }, + ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected one string as an argument but received {:?}", @@ -155,17 +166,19 @@ fn lowercase(values: &[Value], _ctx: &mut Context) -> Result Result { - let [Value { - kind: Some(Kind::StringValue(value)), - }] = values +fn swapcase(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::StringValue(value)), + }, + ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected one string as an argument but received {:?}", @@ -187,17 +200,19 @@ fn swapcase(values: &[Value], _ctx: &mut Context) -> Result }) .collect(); - Ok(Value { + Signal::Success(Value { kind: Some(Kind::StringValue(swapped)), }) } -fn chars(values: &[Value], _ctx: &mut Context) -> Result { - let [Value { - kind: Some(Kind::StringValue(value)), - }] = values +fn chars(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::StringValue(value)), + }, + ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected one string as an argument but received {:?}", @@ -213,19 +228,22 @@ fn chars(values: &[Value], _ctx: &mut Context) -> Result { }) .collect::>(); - Ok(Value { + Signal::Success(Value { kind: Some(Kind::ListValue(ListValue { values: chars })), }) } -fn at(values: &[Value], _ctx: &mut Context) -> Result { - let [Value { - kind: Some(Kind::StringValue(value)), - }, Value { - kind: Some(Kind::NumberValue(index)), - }] = values +fn at(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::StringValue(value)), + }, + Value { + kind: Some(Kind::NumberValue(index)), + }, + ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected one string followed by one number as arguments but received {:?}", @@ -235,7 +253,7 @@ fn at(values: &[Value], _ctx: &mut Context) -> Result { }; if index < &0.0 { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected a positive number as the second argument but received {}", @@ -248,10 +266,10 @@ fn at(values: &[Value], _ctx: &mut Context) -> Result { let char = value.chars().into_iter().nth(usize_index); match char { - Some(c) => Ok(Value { + Some(c) => Signal::Success(Value { kind: Some(Kind::StringValue(c.to_string())), }), - None => Err(RuntimeError::simple( + None => Signal::Failure(RuntimeError::simple( "IndexOutOfBoundsRuntimeError", format!( "Index {} is out of bounds for string of length {}", @@ -262,12 +280,14 @@ fn at(values: &[Value], _ctx: &mut Context) -> Result { } } -fn trim(values: &[Value], _ctx: &mut Context) -> Result { - let [Value { - kind: Some(Kind::StringValue(value)), - }] = values +fn trim(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::StringValue(value)), + }, + ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected one string as an arguments but received {:?}", @@ -276,37 +296,43 @@ fn trim(values: &[Value], _ctx: &mut Context) -> Result { )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::StringValue(value.trim().to_string())), }) } -fn append(values: &[Value], _ctx: &mut Context) -> Result { - let [Value { - kind: Some(Kind::StringValue(value)), - }, Value { - kind: Some(Kind::StringValue(suffix)), - }] = values +fn append(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::StringValue(value)), + }, + Value { + kind: Some(Kind::StringValue(suffix)), + }, + ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Expected two numbers as argument but received {:?}", values), )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::StringValue(value.clone() + suffix)), }) } -fn prepend(values: &[Value], _ctx: &mut Context) -> Result { - let [Value { - kind: Some(Kind::StringValue(value)), - }, Value { - kind: Some(Kind::StringValue(prefix)), - }] = values +fn prepend(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::StringValue(value)), + }, + Value { + kind: Some(Kind::StringValue(prefix)), + }, + ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected two strings as arguments but received {:?}", @@ -315,21 +341,25 @@ fn prepend(values: &[Value], _ctx: &mut Context) -> Result )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::StringValue(prefix.clone() + value)), }) } -fn insert(values: &[Value], _ctx: &mut Context) -> Result { - let [Value { - kind: Some(Kind::StringValue(value)), - }, Value { - kind: Some(Kind::NumberValue(position)), - }, Value { - kind: Some(Kind::StringValue(text)), - }] = values +fn insert(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::StringValue(value)), + }, + Value { + kind: Some(Kind::NumberValue(position)), + }, + Value { + kind: Some(Kind::StringValue(text)), + }, + ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected string, number, and string as arguments but received {:?}", @@ -342,17 +372,19 @@ fn insert(values: &[Value], _ctx: &mut Context) -> Result { let mut new_value = value.clone(); new_value.insert_str(usize_position, text.as_str()); - Ok(Value { + Signal::Success(Value { kind: Some(Kind::StringValue(new_value)), }) } -fn length(values: &[Value], _ctx: &mut Context) -> Result { - let [Value { - kind: Some(Kind::StringValue(value)), - }] = values +fn length(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::StringValue(value)), + }, + ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected one string as an argument but received {:?}", @@ -361,21 +393,25 @@ fn length(values: &[Value], _ctx: &mut Context) -> Result { )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::NumberValue(value.chars().count() as f64)), }) } -fn remove(values: &[Value], _ctx: &mut Context) -> Result { - let [Value { - kind: Some(Kind::StringValue(value)), - }, Value { - kind: Some(Kind::NumberValue(from)), - }, Value { - kind: Some(Kind::NumberValue(to)), - }] = values +fn remove(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::StringValue(value)), + }, + Value { + kind: Some(Kind::NumberValue(from)), + }, + Value { + kind: Some(Kind::NumberValue(to)), + }, + ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected one string followed by two numbers as arguments but received {:?}", @@ -393,21 +429,25 @@ fn remove(values: &[Value], _ctx: &mut Context) -> Result { .map(|e| e.1) .collect::(); - Ok(Value { + Signal::Success(Value { kind: Some(Kind::StringValue(new)), }) } -fn replace(values: &[Value], _ctx: &mut Context) -> Result { - let [Value { - kind: Some(Kind::StringValue(value)), - }, Value { - kind: Some(Kind::StringValue(old)), - }, Value { - kind: Some(Kind::StringValue(new)), - }] = values +fn replace(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::StringValue(value)), + }, + Value { + kind: Some(Kind::StringValue(old)), + }, + Value { + kind: Some(Kind::StringValue(new)), + }, + ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected three strings as arguments but received {:?}", @@ -418,21 +458,25 @@ fn replace(values: &[Value], _ctx: &mut Context) -> Result let replaced = value.replace(old, new); - Ok(Value { + Signal::Success(Value { kind: Some(Kind::StringValue(replaced)), }) } -fn replace_first(values: &[Value], _ctx: &mut Context) -> Result { - let [Value { - kind: Some(Kind::StringValue(value)), - }, Value { - kind: Some(Kind::StringValue(old)), - }, Value { - kind: Some(Kind::StringValue(new)), - }] = values +fn replace_first(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::StringValue(value)), + }, + Value { + kind: Some(Kind::StringValue(old)), + }, + Value { + kind: Some(Kind::StringValue(new)), + }, + ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected three strings as arguments but received {:?}", @@ -443,21 +487,25 @@ fn replace_first(values: &[Value], _ctx: &mut Context) -> Result Result { - let [Value { - kind: Some(Kind::StringValue(value)), - }, Value { - kind: Some(Kind::StringValue(old)), - }, Value { - kind: Some(Kind::StringValue(new)), - }] = values +fn replace_last(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::StringValue(value)), + }, + Value { + kind: Some(Kind::StringValue(old)), + }, + Value { + kind: Some(Kind::StringValue(new)), + }, + ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected three strings as arguments but received {:?}", @@ -481,17 +529,19 @@ fn replace_last(values: &[Value], _ctx: &mut Context) -> Result Result { - let [Value { - kind: Some(Kind::StringValue(value)), - }] = values +fn hex(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::StringValue(value)), + }, + ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected one string as an argument but received {:?}", @@ -506,17 +556,19 @@ fn hex(values: &[Value], _ctx: &mut Context) -> Result { .map(|byte| format!("{:02x}", byte)) .collect::(); - Ok(Value { + Signal::Success(Value { kind: Some(Kind::StringValue(hex)), }) } -fn octal(values: &[Value], _ctx: &mut Context) -> Result { - let [Value { - kind: Some(Kind::StringValue(value)), - }] = values +fn octal(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::StringValue(value)), + }, + ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected one string as an argument but received {:?}", @@ -531,19 +583,22 @@ fn octal(values: &[Value], _ctx: &mut Context) -> Result { .map(|byte| format!("{:03o}", byte)) .collect::(); - Ok(Value { + Signal::Success(Value { kind: Some(Kind::StringValue(hex)), }) } -fn index_of(values: &[Value], _ctx: &mut Context) -> Result { - let [Value { - kind: Some(Kind::StringValue(value)), - }, Value { - kind: Some(Kind::StringValue(sub_string)), - }] = values +fn index_of(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::StringValue(value)), + }, + Value { + kind: Some(Kind::StringValue(sub_string)), + }, + ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected two strings as arguments but received {:?}", @@ -555,23 +610,26 @@ fn index_of(values: &[Value], _ctx: &mut Context) -> Result let index_option = value.find(sub_string); match index_option { - Some(index) => Ok(Value { + Some(index) => Signal::Success(Value { kind: Some(Kind::NumberValue(index as f64)), }), - None => Ok(Value { + None => Signal::Success(Value { kind: Some(Kind::NumberValue(-1.0)), }), } } -fn contains(values: &[Value], _ctx: &mut Context) -> Result { - let [Value { - kind: Some(Kind::StringValue(value)), - }, Value { - kind: Some(Kind::StringValue(sub_string)), - }] = values +fn contains(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::StringValue(value)), + }, + Value { + kind: Some(Kind::StringValue(sub_string)), + }, + ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected two strings as arguments but received {:?}", @@ -580,19 +638,22 @@ fn contains(values: &[Value], _ctx: &mut Context) -> Result )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::BoolValue(value.contains(sub_string))), }) } -fn split(values: &[Value], _ctx: &mut Context) -> Result { - let [Value { - kind: Some(Kind::StringValue(value)), - }, Value { - kind: Some(Kind::StringValue(delimiter)), - }] = values +fn split(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::StringValue(value)), + }, + Value { + kind: Some(Kind::StringValue(delimiter)), + }, + ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected two strings as arguments but received {:?}", @@ -608,17 +669,19 @@ fn split(values: &[Value], _ctx: &mut Context) -> Result { }) .collect::>(); - Ok(Value { + Signal::Success(Value { kind: Some(Kind::ListValue(ListValue { values: words })), }) } -fn reverse(values: &[Value], _ctx: &mut Context) -> Result { - let [Value { - kind: Some(Kind::StringValue(value)), - }] = values +fn reverse(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::StringValue(value)), + }, + ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected one string as an argument but received {:?}", @@ -629,19 +692,22 @@ fn reverse(values: &[Value], _ctx: &mut Context) -> Result let reversed = value.chars().rev().collect::(); - Ok(Value { + Signal::Success(Value { kind: Some(Kind::StringValue(reversed)), }) } -fn starts_with(values: &[Value], _ctx: &mut Context) -> Result { - let [Value { - kind: Some(Kind::StringValue(value)), - }, Value { - kind: Some(Kind::StringValue(prefix)), - }] = values +fn starts_with(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::StringValue(value)), + }, + Value { + kind: Some(Kind::StringValue(prefix)), + }, + ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected two strings as arguments but received {:?}", @@ -650,19 +716,22 @@ fn starts_with(values: &[Value], _ctx: &mut Context) -> Result Result { - let [Value { - kind: Some(Kind::StringValue(value)), - }, Value { - kind: Some(Kind::StringValue(suffix)), - }] = values +fn ends_with(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::StringValue(value)), + }, + Value { + kind: Some(Kind::StringValue(suffix)), + }, + ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected two strings as arguments but received {:?}", @@ -671,17 +740,19 @@ fn ends_with(values: &[Value], _ctx: &mut Context) -> Result Result { - let [Value { - kind: Some(Kind::StringValue(value)), - }] = values +fn to_ascii(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::StringValue(value)), + }, + ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected one string as an argument but received {:?}", @@ -697,19 +768,21 @@ fn to_ascii(values: &[Value], _ctx: &mut Context) -> Result }) .collect::>(); - Ok(Value { + Signal::Success(Value { kind: Some(Kind::ListValue(ListValue { values: ascii_value, })), }) } -fn from_ascii(values: &[Value], _ctx: &mut Context) -> Result { - let [Value { - kind: Some(Kind::ListValue(list)), - }] = values +fn from_ascii(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::ListValue(list)), + }, + ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected a list of numbers as an argument but received {:?}", @@ -738,10 +811,10 @@ fn from_ascii(values: &[Value], _ctx: &mut Context) -> Result>(); match string { - Some(string) => Ok(Value { + Some(string) => Signal::Success(Value { kind: Some(Kind::StringValue(string)), }), - None => Err(RuntimeError::simple( + None => Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", "Expected a list of numbers between 0 and 127".to_string(), )), @@ -750,14 +823,17 @@ fn from_ascii(values: &[Value], _ctx: &mut Context) -> Result Result { - let [Value { - kind: Some(Kind::StringValue(value)), - }, Value { - kind: Some(Kind::StringValue(encoding)), - }] = values +fn encode(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::StringValue(value)), + }, + Value { + kind: Some(Kind::StringValue(encoding)), + }, + ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected two strings as arguments but received {:?}", @@ -769,26 +845,29 @@ fn encode(values: &[Value], _ctx: &mut Context) -> Result { let encoded_string = match encoding.clone().to_lowercase().as_str() { "base64" => base64::prelude::BASE64_STANDARD.encode(value), _ => { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Unsupported encoding: {}", encoding), - )) + )); } }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::StringValue(encoded_string)), }) } -fn decode(values: &[Value], _ctx: &mut Context) -> Result { - let [Value { - kind: Some(Kind::StringValue(value)), - }, Value { - kind: Some(Kind::StringValue(encoding)), - }] = values +fn decode(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::StringValue(value)), + }, + Value { + kind: Some(Kind::StringValue(encoding)), + }, + ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected two strings as arguments but received {:?}", @@ -802,40 +881,43 @@ fn decode(values: &[Value], _ctx: &mut Context) -> Result { Ok(bytes) => match String::from_utf8(bytes) { Ok(string) => string, Err(err) => { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "DecodeError", format!("Failed to decode base64 string: {:?}", err), - )) + )); } }, Err(err) => { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "DecodeError", format!("Failed to decode base64 string: {:?}", err), - )) + )); } }, _ => { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!("Unsupported decoding: {}", encoding), - )) + )); } }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::StringValue(decoded_string)), }) } -fn is_equal(values: &[Value], _ctx: &mut Context) -> Result { - let [Value { - kind: Some(Kind::StringValue(lhs)), - }, Value { - kind: Some(Kind::StringValue(rhs)), - }] = values +fn is_equal(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::StringValue(lhs)), + }, + Value { + kind: Some(Kind::StringValue(rhs)), + }, + ] = values else { - return Err(RuntimeError::simple( + return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", format!( "Expected two strings as arguments but received {:?}", @@ -844,7 +926,7 @@ fn is_equal(values: &[Value], _ctx: &mut Context) -> Result )); }; - Ok(Value { + Signal::Success(Value { kind: Some(Kind::BoolValue(lhs == rhs)), }) } @@ -853,7 +935,7 @@ fn is_equal(values: &[Value], _ctx: &mut Context) -> Result mod tests { use super::*; use crate::context::Context; - use tucana::shared::{value::Kind, ListValue, Value}; + use tucana::shared::{ListValue, Value, value::Kind}; // Helper function to create a string value fn create_string_value(s: &str) -> Value { @@ -887,7 +969,11 @@ mod tests { fn test_as_bytes_valid() { let mut ctx = Context::new(); let values = vec![create_string_value("hello")]; - let result = as_bytes(&values, &mut ctx).unwrap(); + let signal = as_bytes(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; if let Value { kind: Some(Kind::ListValue(list)), @@ -908,7 +994,11 @@ mod tests { fn test_as_bytes_empty_string() { let mut ctx = Context::new(); let values = vec![create_string_value("")]; - let result = as_bytes(&values, &mut ctx).unwrap(); + let signal = as_bytes(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; if let Value { kind: Some(Kind::ListValue(list)), @@ -925,14 +1015,18 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_number_value(123.0)]; let result = as_bytes(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] fn test_byte_size_valid() { let mut ctx = Context::new(); let values = vec![create_string_value("hello")]; - let result = byte_size(&values, &mut ctx).unwrap(); + let signal = byte_size(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_number_value(5.0)); } @@ -940,7 +1034,11 @@ mod tests { fn test_byte_size_empty() { let mut ctx = Context::new(); let values = vec![create_string_value("")]; - let result = byte_size(&values, &mut ctx).unwrap(); + let signal = byte_size(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_number_value(0.0)); } @@ -948,7 +1046,11 @@ mod tests { fn test_byte_size_unicode() { let mut ctx = Context::new(); let values = vec![create_string_value("café")]; - let result = byte_size(&values, &mut ctx).unwrap(); + let signal = byte_size(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_number_value(5.0)); // 'é' is 2 bytes in UTF-8 } @@ -956,7 +1058,11 @@ mod tests { fn test_capitalize_valid() { let mut ctx = Context::new(); let values = vec![create_string_value("hello world")]; - let result = capitalize(&values, &mut ctx).unwrap(); + let signal = capitalize(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("Hello World")); } @@ -964,7 +1070,11 @@ mod tests { fn test_capitalize_empty() { let mut ctx = Context::new(); let values = vec![create_string_value("")]; - let result = capitalize(&values, &mut ctx).unwrap(); + let signal = capitalize(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("")); } @@ -972,7 +1082,11 @@ mod tests { fn test_capitalize_single_char() { let mut ctx = Context::new(); let values = vec![create_string_value("a")]; - let result = capitalize(&values, &mut ctx).unwrap(); + let signal = capitalize(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("A")); } @@ -980,7 +1094,11 @@ mod tests { fn test_uppercase_valid() { let mut ctx = Context::new(); let values = vec![create_string_value("Hello World")]; - let result = uppercase(&values, &mut ctx).unwrap(); + let signal = uppercase(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("HELLO WORLD")); } @@ -988,7 +1106,11 @@ mod tests { fn test_uppercase_already_upper() { let mut ctx = Context::new(); let values = vec![create_string_value("HELLO")]; - let result = uppercase(&values, &mut ctx).unwrap(); + let signal = uppercase(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("HELLO")); } @@ -996,7 +1118,11 @@ mod tests { fn test_lowercase_valid() { let mut ctx = Context::new(); let values = vec![create_string_value("Hello World")]; - let result = lowercase(&values, &mut ctx).unwrap(); + let signal = lowercase(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("hello world")); } @@ -1004,7 +1130,11 @@ mod tests { fn test_lowercase_already_lower() { let mut ctx = Context::new(); let values = vec![create_string_value("hello")]; - let result = lowercase(&values, &mut ctx).unwrap(); + let signal = lowercase(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("hello")); } @@ -1012,7 +1142,11 @@ mod tests { fn test_swapcase_valid() { let mut ctx = Context::new(); let values = vec![create_string_value("Hello World")]; - let result = swapcase(&values, &mut ctx).unwrap(); + let signal = swapcase(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("hELLO wORLD")); } @@ -1020,7 +1154,11 @@ mod tests { fn test_swapcase_mixed() { let mut ctx = Context::new(); let values = vec![create_string_value("HeLLo123")]; - let result = swapcase(&values, &mut ctx).unwrap(); + let signal = swapcase(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("hEllO123")); } @@ -1028,7 +1166,11 @@ mod tests { fn test_chars_valid() { let mut ctx = Context::new(); let values = vec![create_string_value("abc")]; - let result = chars(&values, &mut ctx).unwrap(); + let signal = chars(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; if let Value { kind: Some(Kind::ListValue(list)), @@ -1047,7 +1189,11 @@ mod tests { fn test_chars_empty() { let mut ctx = Context::new(); let values = vec![create_string_value("")]; - let result = chars(&values, &mut ctx).unwrap(); + let signal = chars(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; if let Value { kind: Some(Kind::ListValue(list)), @@ -1063,7 +1209,11 @@ mod tests { fn test_at_valid() { let mut ctx = Context::new(); let values = vec![create_string_value("hello"), create_number_value(1.0)]; - let result = at(&values, &mut ctx).unwrap(); + let signal = at(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("e")); } @@ -1071,7 +1221,11 @@ mod tests { fn test_at_first_char() { let mut ctx = Context::new(); let values = vec![create_string_value("hello"), create_number_value(0.0)]; - let result = at(&values, &mut ctx).unwrap(); + let signal = at(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("h")); } @@ -1080,7 +1234,7 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_string_value("hello"), create_number_value(10.0)]; let result = at(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -1088,14 +1242,18 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_string_value("hello"), create_number_value(-1.0)]; let result = at(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] fn test_trim_valid() { let mut ctx = Context::new(); let values = vec![create_string_value(" hello world ")]; - let result = trim(&values, &mut ctx).unwrap(); + let signal = trim(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("hello world")); } @@ -1103,7 +1261,11 @@ mod tests { fn test_trim_no_whitespace() { let mut ctx = Context::new(); let values = vec![create_string_value("hello")]; - let result = trim(&values, &mut ctx).unwrap(); + let signal = trim(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("hello")); } @@ -1111,7 +1273,11 @@ mod tests { fn test_append_valid() { let mut ctx = Context::new(); let values = vec![create_string_value("hello"), create_string_value(" world")]; - let result = append(&values, &mut ctx).unwrap(); + let signal = append(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("hello world")); } @@ -1119,7 +1285,11 @@ mod tests { fn test_append_empty_suffix() { let mut ctx = Context::new(); let values = vec![create_string_value("hello"), create_string_value("")]; - let result = append(&values, &mut ctx).unwrap(); + let signal = append(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("hello")); } @@ -1127,7 +1297,11 @@ mod tests { fn test_prepend_valid() { let mut ctx = Context::new(); let values = vec![create_string_value("world"), create_string_value("hello ")]; - let result = prepend(&values, &mut ctx).unwrap(); + let signal = prepend(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("hello world")); } @@ -1135,7 +1309,11 @@ mod tests { fn test_prepend_empty_prefix() { let mut ctx = Context::new(); let values = vec![create_string_value("hello"), create_string_value("")]; - let result = prepend(&values, &mut ctx).unwrap(); + let signal = prepend(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("hello")); } @@ -1147,7 +1325,11 @@ mod tests { create_number_value(2.0), create_string_value("XXX"), ]; - let result = insert(&values, &mut ctx).unwrap(); + let signal = insert(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("heXXXllo")); } @@ -1159,7 +1341,11 @@ mod tests { create_number_value(0.0), create_string_value("XXX"), ]; - let result = insert(&values, &mut ctx).unwrap(); + let signal = insert(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("XXXhello")); } @@ -1171,7 +1357,11 @@ mod tests { create_number_value(5.0), create_string_value("XXX"), ]; - let result = insert(&values, &mut ctx).unwrap(); + let signal = insert(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("helloXXX")); } @@ -1179,7 +1369,11 @@ mod tests { fn test_length_valid() { let mut ctx = Context::new(); let values = vec![create_string_value("hello")]; - let result = length(&values, &mut ctx).unwrap(); + let signal = length(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_number_value(5.0)); } @@ -1187,7 +1381,11 @@ mod tests { fn test_length_empty() { let mut ctx = Context::new(); let values = vec![create_string_value("")]; - let result = length(&values, &mut ctx).unwrap(); + let signal = length(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_number_value(0.0)); } @@ -1195,7 +1393,11 @@ mod tests { fn test_length_unicode() { let mut ctx = Context::new(); let values = vec![create_string_value("café")]; - let result = length(&values, &mut ctx).unwrap(); + let signal = length(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_number_value(4.0)); // 4 characters } @@ -1207,7 +1409,11 @@ mod tests { create_number_value(2.0), create_number_value(7.0), ]; - let result = remove(&values, &mut ctx).unwrap(); + let signal = remove(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("heorld")); } @@ -1219,7 +1425,11 @@ mod tests { create_number_value(0.0), create_number_value(2.0), ]; - let result = remove(&values, &mut ctx).unwrap(); + let signal = remove(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("llo")); } @@ -1231,7 +1441,11 @@ mod tests { create_string_value("hello"), create_string_value("hi"), ]; - let result = replace(&values, &mut ctx).unwrap(); + let signal = replace(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("hi world hi")); } @@ -1243,7 +1457,11 @@ mod tests { create_string_value("xyz"), create_string_value("abc"), ]; - let result = replace(&values, &mut ctx).unwrap(); + let signal = replace(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("hello world")); } @@ -1255,7 +1473,11 @@ mod tests { create_string_value("hello"), create_string_value("hi"), ]; - let result = replace_first(&values, &mut ctx).unwrap(); + let signal = replace_first(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("hi world hello")); } @@ -1267,7 +1489,11 @@ mod tests { create_string_value("hello"), create_string_value("hi"), ]; - let result = replace_last(&values, &mut ctx).unwrap(); + let signal = replace_last(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("hello world hi")); } @@ -1279,7 +1505,11 @@ mod tests { create_string_value("xyz"), create_string_value("abc"), ]; - let result = replace_last(&values, &mut ctx).unwrap(); + let signal = replace_last(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("hello world")); } @@ -1287,7 +1517,11 @@ mod tests { fn test_hex_valid() { let mut ctx = Context::new(); let values = vec![create_string_value("hello")]; - let result = hex(&values, &mut ctx).unwrap(); + let signal = hex(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("68656c6c6f")); } @@ -1295,7 +1529,11 @@ mod tests { fn test_hex_empty() { let mut ctx = Context::new(); let values = vec![create_string_value("")]; - let result = hex(&values, &mut ctx).unwrap(); + let signal = hex(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("")); } @@ -1303,7 +1541,11 @@ mod tests { fn test_octal_valid() { let mut ctx = Context::new(); let values = vec![create_string_value("A")]; - let result = octal(&values, &mut ctx).unwrap(); + let signal = octal(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("101")); // 'A' is 65 in ASCII, 101 in octal } @@ -1314,7 +1556,11 @@ mod tests { create_string_value("hello world"), create_string_value("world"), ]; - let result = index_of(&values, &mut ctx).unwrap(); + let signal = index_of(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_number_value(6.0)); } @@ -1325,7 +1571,11 @@ mod tests { create_string_value("hello world"), create_string_value("xyz"), ]; - let result = index_of(&values, &mut ctx).unwrap(); + let signal = index_of(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_number_value(-1.0)); } @@ -1336,7 +1586,11 @@ mod tests { create_string_value("hello world"), create_string_value("hello"), ]; - let result = index_of(&values, &mut ctx).unwrap(); + let signal = index_of(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_number_value(0.0)); } @@ -1347,7 +1601,11 @@ mod tests { create_string_value("hello world"), create_string_value("world"), ]; - let result = contains(&values, &mut ctx).unwrap(); + let signal = contains(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_bool_value(true)); } @@ -1358,7 +1616,11 @@ mod tests { create_string_value("hello world"), create_string_value("xyz"), ]; - let result = contains(&values, &mut ctx).unwrap(); + let signal = contains(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_bool_value(false)); } @@ -1369,7 +1631,11 @@ mod tests { create_string_value("hello,world,test"), create_string_value(","), ]; - let result = split(&values, &mut ctx).unwrap(); + let signal = split(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; if let Value { kind: Some(Kind::ListValue(list)), @@ -1388,7 +1654,11 @@ mod tests { fn test_split_no_delimiter() { let mut ctx = Context::new(); let values = vec![create_string_value("hello"), create_string_value(",")]; - let result = split(&values, &mut ctx).unwrap(); + let signal = split(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; if let Value { kind: Some(Kind::ListValue(list)), @@ -1405,7 +1675,11 @@ mod tests { fn test_reverse_valid() { let mut ctx = Context::new(); let values = vec![create_string_value("hello")]; - let result = reverse(&values, &mut ctx).unwrap(); + let signal = reverse(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("olleh")); } @@ -1413,7 +1687,11 @@ mod tests { fn test_reverse_empty() { let mut ctx = Context::new(); let values = vec![create_string_value("")]; - let result = reverse(&values, &mut ctx).unwrap(); + let signal = reverse(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("")); } @@ -1421,7 +1699,11 @@ mod tests { fn test_reverse_palindrome() { let mut ctx = Context::new(); let values = vec![create_string_value("aba")]; - let result = reverse(&values, &mut ctx).unwrap(); + let signal = reverse(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("aba")); } @@ -1430,7 +1712,7 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_string_value("aba")]; let result = encode(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -1438,14 +1720,18 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_string_value("aba"), create_string_value("gug")]; let result = encode(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] fn test_encode_correct() { let mut ctx = Context::new(); let values = vec![create_string_value("hello"), create_string_value("BASE64")]; - let result = encode(&values, &mut ctx).unwrap(); + let signal = encode(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!( result, Value { @@ -1459,7 +1745,7 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_string_value("aba")]; let result = decode(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -1467,7 +1753,7 @@ mod tests { let mut ctx = Context::new(); let values = vec![create_string_value("aba"), create_string_value("gug")]; let result = decode(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -1477,7 +1763,11 @@ mod tests { create_string_value("aGVsbG8="), create_string_value("BASE64"), ]; - let result = decode(&values, &mut ctx).unwrap(); + let signal = decode(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!( result, Value { @@ -1493,7 +1783,11 @@ mod tests { create_string_value("hello world"), create_string_value("hello"), ]; - let result = starts_with(&values, &mut ctx).unwrap(); + let signal = starts_with(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_bool_value(true)); } @@ -1504,7 +1798,11 @@ mod tests { create_string_value("hello world"), create_string_value("world"), ]; - let result = starts_with(&values, &mut ctx).unwrap(); + let signal = starts_with(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_bool_value(false)); } @@ -1515,7 +1813,11 @@ mod tests { create_string_value("hello world"), create_string_value("world"), ]; - let result = ends_with(&values, &mut ctx).unwrap(); + let signal = ends_with(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_bool_value(true)); } @@ -1526,7 +1828,11 @@ mod tests { create_string_value("hello world"), create_string_value("hello"), ]; - let result = ends_with(&values, &mut ctx).unwrap(); + let signal = ends_with(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_bool_value(false)); } @@ -1534,7 +1840,11 @@ mod tests { fn test_to_ascii_valid() { let mut ctx = Context::new(); let values = vec![create_string_value("AB")]; - let result = to_ascii(&values, &mut ctx).unwrap(); + let signal = to_ascii(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; if let Value { kind: Some(Kind::ListValue(list)), @@ -1557,7 +1867,11 @@ mod tests { create_number_value(67.0), // 'C' ]; let values = vec![create_list_value(ascii_values)]; - let result = from_ascii(&values, &mut ctx).unwrap(); + let signal = from_ascii(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("ABC")); } @@ -1565,7 +1879,11 @@ mod tests { fn test_from_ascii_empty_list() { let mut ctx = Context::new(); let values = vec![create_list_value(vec![])]; - let result = from_ascii(&values, &mut ctx).unwrap(); + let signal = from_ascii(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("")); } @@ -1578,7 +1896,7 @@ mod tests { ]; let values = vec![create_list_value(ascii_values)]; let result = from_ascii(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -1590,7 +1908,7 @@ mod tests { ]; let values = vec![create_list_value(ascii_values)]; let result = from_ascii(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] @@ -1602,14 +1920,18 @@ mod tests { ]; let values = vec![create_list_value(ascii_values)]; let result = from_ascii(&values, &mut ctx); - assert!(result.is_err()); + assert_eq!(result, Signal::Failure(RuntimeError::default())); } #[test] fn test_is_equal_true() { let mut ctx = Context::new(); let values = vec![create_string_value("hello"), create_string_value("hello")]; - let result = is_equal(&values, &mut ctx).unwrap(); + let signal = is_equal(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_bool_value(true)); } @@ -1617,7 +1939,11 @@ mod tests { fn test_is_equal_false() { let mut ctx = Context::new(); let values = vec![create_string_value("hello"), create_string_value("world")]; - let result = is_equal(&values, &mut ctx).unwrap(); + let signal = is_equal(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_bool_value(false)); } @@ -1625,7 +1951,11 @@ mod tests { fn test_is_equal_empty_strings() { let mut ctx = Context::new(); let values = vec![create_string_value(""), create_string_value("")]; - let result = is_equal(&values, &mut ctx).unwrap(); + let signal = is_equal(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_bool_value(true)); } @@ -1637,19 +1967,58 @@ mod tests { // Test functions that expect 1 string argument let invalid_values = vec![create_number_value(123.0)]; - assert!(as_bytes(&invalid_values, &mut ctx).is_err()); - assert!(byte_size(&invalid_values, &mut ctx).is_err()); - assert!(capitalize(&invalid_values, &mut ctx).is_err()); - assert!(uppercase(&invalid_values, &mut ctx).is_err()); - assert!(lowercase(&invalid_values, &mut ctx).is_err()); - assert!(swapcase(&invalid_values, &mut ctx).is_err()); - assert!(chars(&invalid_values, &mut ctx).is_err()); - assert!(trim(&invalid_values, &mut ctx).is_err()); - assert!(length(&invalid_values, &mut ctx).is_err()); - assert!(reverse(&invalid_values, &mut ctx).is_err()); - assert!(hex(&invalid_values, &mut ctx).is_err()); - assert!(octal(&invalid_values, &mut ctx).is_err()); - assert!(to_ascii(&invalid_values, &mut ctx).is_err()); + assert_eq!( + as_bytes(&invalid_values, &mut ctx), + Signal::Failure(RuntimeError::default()) + ); + assert_eq!( + byte_size(&invalid_values, &mut ctx), + Signal::Failure(RuntimeError::default()) + ); + assert_eq!( + capitalize(&invalid_values, &mut ctx), + Signal::Failure(RuntimeError::default()) + ); + assert_eq!( + uppercase(&invalid_values, &mut ctx), + Signal::Failure(RuntimeError::default()) + ); + assert_eq!( + lowercase(&invalid_values, &mut ctx), + Signal::Failure(RuntimeError::default()) + ); + assert_eq!( + swapcase(&invalid_values, &mut ctx), + Signal::Failure(RuntimeError::default()) + ); + assert_eq!( + chars(&invalid_values, &mut ctx), + Signal::Failure(RuntimeError::default()) + ); + assert_eq!( + trim(&invalid_values, &mut ctx), + Signal::Failure(RuntimeError::default()) + ); + assert_eq!( + length(&invalid_values, &mut ctx), + Signal::Failure(RuntimeError::default()) + ); + assert_eq!( + reverse(&invalid_values, &mut ctx), + Signal::Failure(RuntimeError::default()) + ); + assert_eq!( + hex(&invalid_values, &mut ctx), + Signal::Failure(RuntimeError::default()) + ); + assert_eq!( + octal(&invalid_values, &mut ctx), + Signal::Failure(RuntimeError::default()) + ); + assert_eq!( + to_ascii(&invalid_values, &mut ctx), + Signal::Failure(RuntimeError::default()) + ); } #[test] @@ -1659,14 +2028,38 @@ mod tests { // Test functions that expect 2 string arguments let invalid_values = vec![create_string_value("hello"), create_number_value(123.0)]; - assert!(append(&invalid_values, &mut ctx).is_err()); - assert!(prepend(&invalid_values, &mut ctx).is_err()); - assert!(index_of(&invalid_values, &mut ctx).is_err()); - assert!(contains(&invalid_values, &mut ctx).is_err()); - assert!(split(&invalid_values, &mut ctx).is_err()); - assert!(starts_with(&invalid_values, &mut ctx).is_err()); - assert!(ends_with(&invalid_values, &mut ctx).is_err()); - assert!(is_equal(&invalid_values, &mut ctx).is_err()); + assert_eq!( + append(&invalid_values, &mut ctx), + Signal::Failure(RuntimeError::default()) + ); + assert_eq!( + prepend(&invalid_values, &mut ctx), + Signal::Failure(RuntimeError::default()) + ); + assert_eq!( + index_of(&invalid_values, &mut ctx), + Signal::Failure(RuntimeError::default()) + ); + assert_eq!( + contains(&invalid_values, &mut ctx), + Signal::Failure(RuntimeError::default()) + ); + assert_eq!( + split(&invalid_values, &mut ctx), + Signal::Failure(RuntimeError::default()) + ); + assert_eq!( + starts_with(&invalid_values, &mut ctx), + Signal::Failure(RuntimeError::default()) + ); + assert_eq!( + ends_with(&invalid_values, &mut ctx), + Signal::Failure(RuntimeError::default()) + ); + assert_eq!( + is_equal(&invalid_values, &mut ctx), + Signal::Failure(RuntimeError::default()) + ); } #[test] @@ -1676,7 +2069,10 @@ mod tests { // Test functions that expect string and number let invalid_values = vec![create_number_value(123.0), create_string_value("test")]; - assert!(at(&invalid_values, &mut ctx).is_err()); + assert_eq!( + at(&invalid_values, &mut ctx), + Signal::Failure(RuntimeError::default()) + ); } #[test] @@ -1690,11 +2086,26 @@ mod tests { create_number_value(123.0), ]; - assert!(insert(&invalid_values, &mut ctx).is_err()); - assert!(remove(&invalid_values, &mut ctx).is_err()); - assert!(replace(&invalid_values, &mut ctx).is_err()); - assert!(replace_first(&invalid_values, &mut ctx).is_err()); - assert!(replace_last(&invalid_values, &mut ctx).is_err()); + assert_eq!( + insert(&invalid_values, &mut ctx), + Signal::Failure(RuntimeError::default()) + ); + assert_eq!( + remove(&invalid_values, &mut ctx), + Signal::Failure(RuntimeError::default()) + ); + assert_eq!( + replace(&invalid_values, &mut ctx), + Signal::Failure(RuntimeError::default()) + ); + assert_eq!( + replace_first(&invalid_values, &mut ctx), + Signal::Failure(RuntimeError::default()) + ); + assert_eq!( + replace_last(&invalid_values, &mut ctx), + Signal::Failure(RuntimeError::default()) + ); } #[test] @@ -1710,11 +2121,23 @@ mod tests { create_string_value("test4"), ]; - assert!(as_bytes(&empty_values, &mut ctx).is_err()); - assert!(as_bytes(&too_many_values, &mut ctx).is_err()); + assert_eq!( + as_bytes(&empty_values, &mut ctx), + Signal::Failure(RuntimeError::default()) + ); + assert_eq!( + as_bytes(&too_many_values, &mut ctx), + Signal::Failure(RuntimeError::default()) + ); - assert!(append(&empty_values, &mut ctx).is_err()); - assert!(append(&too_many_values, &mut ctx).is_err()); + assert_eq!( + append(&empty_values, &mut ctx), + Signal::Failure(RuntimeError::default()) + ); + assert_eq!( + append(&too_many_values, &mut ctx), + Signal::Failure(RuntimeError::default()) + ); } #[test] @@ -1725,25 +2148,40 @@ mod tests { let long_string = "a".repeat(1000); let values = vec![create_string_value(&long_string)]; - assert!(length(&values, &mut ctx).is_ok()); - assert!(reverse(&values, &mut ctx).is_ok()); - assert!(uppercase(&values, &mut ctx).is_ok()); + assert_eq!(length(&values, &mut ctx), Signal::Success(Value::default())); + assert_eq!( + reverse(&values, &mut ctx), + Signal::Success(Value::default()) + ); + assert_eq!( + uppercase(&values, &mut ctx), + Signal::Success(Value::default()) + ); // Test with special characters let special_string = "!@#$%^&*(){}[]|\\:;\"'<>,.?/~`"; let values = vec![create_string_value(special_string)]; - assert!(length(&values, &mut ctx).is_ok()); - assert!(reverse(&values, &mut ctx).is_ok()); - assert!(uppercase(&values, &mut ctx).is_ok()); + assert_eq!(length(&values, &mut ctx), Signal::Success(Value::default())); + assert_eq!( + uppercase(&values, &mut ctx), + Signal::Success(Value::default()) + ); + assert_eq!( + reverse(&values, &mut ctx), + Signal::Success(Value::default()) + ); // Test with unicode characters let unicode_string = "🦀🚀✨🎉"; let values = vec![create_string_value(unicode_string)]; - assert!(length(&values, &mut ctx).is_ok()); - assert!(reverse(&values, &mut ctx).is_ok()); - assert!(chars(&values, &mut ctx).is_ok()); + assert_eq!(length(&values, &mut ctx), Signal::Success(Value::default())); + assert_eq!( + reverse(&values, &mut ctx), + Signal::Success(Value::default()) + ); + assert_eq!(chars(&values, &mut ctx), Signal::Success(Value::default())); } #[test] @@ -1759,7 +2197,7 @@ mod tests { create_string_value("X"), ]; let result = insert(&values, &mut ctx); - assert!(result.is_ok(), "Insert at position {} should work", i); + assert_eq!(result, Signal::Success(Value::default())); } // Test remove with edge cases @@ -1768,7 +2206,11 @@ mod tests { create_number_value(0.0), create_number_value(0.0), // Remove nothing ]; - let result = remove(&values, &mut ctx).unwrap(); + let signal = remove(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("hello")); // Test remove entire string @@ -1777,7 +2219,11 @@ mod tests { create_number_value(0.0), create_number_value(5.0), ]; - let result = remove(&values, &mut ctx).unwrap(); + let signal = remove(&values, &mut ctx); + let result = match signal { + Signal::Success(v) => v, + _ => panic!("Expected Success!"), + }; assert_eq!(result, create_string_value("")); } } From 0c9767dfb6c1c056e771f3f1d714063135d0f1d2 Mon Sep 17 00:00:00 2001 From: raphael-goetz Date: Fri, 17 Oct 2025 13:26:34 +0200 Subject: [PATCH 2/9] ref: moved config into its own file --- src/config/mod.rs | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 src/config/mod.rs diff --git a/src/config/mod.rs b/src/config/mod.rs new file mode 100644 index 0000000..9ec5fd9 --- /dev/null +++ b/src/config/mod.rs @@ -0,0 +1,47 @@ +use code0_flow::flow_config::env_with_default; +use code0_flow::flow_config::environment::Environment; +use code0_flow::flow_config::mode::Mode; + +/// Struct for all relevant `Taurus` startup configurations +pub struct Config { + /// Options: + /// `development` (default) + /// `staging` + /// `production` + pub environment: Environment, + + /// Aquila mode + /// + /// Options: + /// `static` (default) + /// `hybrid` + pub mode: Mode, + + pub nats_url: String, + + pub aquila_url: String, + + pub with_health_service: bool, + + pub grpc_host: String, + + pub grpc_port: u16, +} + +/// Implementation for all relevant `Aquila` startup configurations +/// +/// Behavior: +/// Searches for the env. file at root level. Filename: `.env` +impl Config { + pub fn new() -> Self { + Config { + environment: env_with_default("ENVIRONMENT", Environment::Development), + mode: env_with_default("MODE", Mode::STATIC), + nats_url: env_with_default("NATS_URL", String::from("nats://localhost:4222")), + aquila_url: env_with_default("AQUILA_URL", String::from("http://localhost:50051")), + with_health_service: env_with_default("WITH_HEALTH_SERVICE", false), + grpc_host: env_with_default("GRPC_HOST", "127.0.0.1".to_string()), + grpc_port: env_with_default("GRPC_PORT", 50051), + } + } +} From dc122b01ed71030b5eb93c3451dd68e7a9bee96d Mon Sep 17 00:00:00 2001 From: raphael-goetz Date: Fri, 17 Oct 2025 13:26:55 +0200 Subject: [PATCH 3/9] feat: added signal to replace primitive result --- src/context/context.rs | 3 +++ src/context/mod.rs | 3 +++ src/context/signal.rs | 22 ++++++++++++++++++++++ src/registry/mod.rs | 5 +++-- 4 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 src/context/context.rs create mode 100644 src/context/signal.rs diff --git a/src/context/context.rs b/src/context/context.rs new file mode 100644 index 0000000..a55a20a --- /dev/null +++ b/src/context/context.rs @@ -0,0 +1,3 @@ +pub struct Context { + +} \ No newline at end of file diff --git a/src/context/mod.rs b/src/context/mod.rs index e858586..da946de 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -1,3 +1,6 @@ +pub mod signal; +pub mod context; + use crate::error::RuntimeError; use std::{ collections::{HashMap, VecDeque}, diff --git a/src/context/signal.rs b/src/context/signal.rs new file mode 100644 index 0000000..3f09ceb --- /dev/null +++ b/src/context/signal.rs @@ -0,0 +1,22 @@ +use tucana::shared::Value; +use crate::error::RuntimeError; + +#[derive(Debug)] +pub enum Signal { + Success(Value), + Failure(RuntimeError), + Return(Value), + Stop +} + +impl PartialEq for Signal { + fn eq(&self, other: &Self) -> bool { + matches!( + (self, other), + (Signal::Success(_), Signal::Success(_)) + | (Signal::Failure(_), Signal::Failure(_)) + | (Signal::Return(_), Signal::Return(_)) + | (Signal::Stop, Signal::Stop) + ) + } +} \ No newline at end of file diff --git a/src/registry/mod.rs b/src/registry/mod.rs index 973f524..b9bd037 100644 --- a/src/registry/mod.rs +++ b/src/registry/mod.rs @@ -1,8 +1,9 @@ -use crate::{context::Context, error::RuntimeError}; +use crate::{context::Context}; use std::collections::HashMap; use tucana::shared::Value; +use crate::context::signal::Signal; -pub type HandlerFn = fn(&[Value], &mut Context) -> Result; +pub type HandlerFn = fn(&[Value], &mut Context) -> Signal; /// Holds all registered handlers. pub struct FunctionStore { From cf0b020bbefae019528540dcda7a2d6391c2b3c8 Mon Sep 17 00:00:00 2001 From: raphael-goetz Date: Fri, 17 Oct 2025 13:39:50 +0200 Subject: [PATCH 4/9] feat: wip new execution logic --- src/executor/mod.rs | 104 ++++++++++++++++++++++++++++++++ src/main.rs | 141 ++++---------------------------------------- 2 files changed, 117 insertions(+), 128 deletions(-) create mode 100644 src/executor/mod.rs diff --git a/src/executor/mod.rs b/src/executor/mod.rs new file mode 100644 index 0000000..16fdfa1 --- /dev/null +++ b/src/executor/mod.rs @@ -0,0 +1,104 @@ +use crate::context::Context; +use crate::context::signal::Signal; +use crate::error::RuntimeError; +use crate::registry::FunctionStore; +use std::collections::HashMap; +use tucana::shared::{NodeFunction, NodeParameter}; + +pub struct Executor<'a> { + functions: &'a FunctionStore, + nodes: HashMap, + context: Context, +} + +type HandleNodeParameterFn = fn(&mut Executor, node_parameter: &NodeParameter) -> Signal; + +impl<'a> Executor<'a> { + + pub fn new(functions: &'a FunctionStore, nodes: HashMap, context: Context) -> Self { + Executor { + functions, + nodes, + context + } + } + + + pub fn execute(&mut self, starting_node_id: i64) -> 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( + "NodeNotFound", + "The node with the id was not found", + )); + } + Some(n) => n.clone(), + }; + + let mut parameters = Vec::new(); + + for node_parameter in &node.parameters { + match Executor::handle_node_parameter(self, node_parameter) { + Signal::Success(value) | Signal::Return(value) => { + parameters.push(value.clone()) + } + Signal::Failure(error) => return Signal::Failure(error), + Signal::Stop => return Signal::Stop, + } + } + + let execution_result = match self.functions.get(node.runtime_function_id.as_str()) { + Some(handler) => handler(¶meters, &mut self.context), + None => { + return Signal::Failure(RuntimeError::simple_str( + "FunctionNotFound", + "The function was not found", + )); + } + }; + + match execution_result { + Signal::Success(value) => { + if let Some(next_node_id) = node.next_node_id { + current_node_id = next_node_id; + continue; + } else { + return Signal::Success(value); + } + } + Signal::Failure(runtime_error) => return Signal::Failure(runtime_error), + Signal::Return(value) => return Signal::Return(value), + Signal::Stop => return Signal::Stop, + } + } + } + + fn handle_node_parameter(&mut self, node_parameter: &NodeParameter) -> Signal { + let node_value = match &node_parameter.value { + Some(v) => v, + None => { + return Signal::Failure(RuntimeError::simple_str( + "NodeValueNotFound", + "An error occurred while executing a flow!", + )); + } + }; + + let value = match &node_value.value { + Some(v) => v, + None => return Signal::Failure(RuntimeError::simple_str("NodeValueNotFound", "An error occurred while executing a flow!")) + }; + + match value { + tucana::shared::node_value::Value::LiteralValue(value) => return Signal::Success(value.clone()), + tucana::shared::node_value::Value::ReferenceValue(_reference_value) => todo!("implement reference values!"), + tucana::shared::node_value::Value::NodeFunctionId(id) => { + return Executor::execute(self, *id) + }, + } + } +} + diff --git a/src/main.rs b/src/main.rs index 4b4ad7b..cdd1989 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,14 +1,15 @@ -mod configuration; pub mod context; pub mod error; pub mod implementation; pub mod registry; +mod executor; +mod config; -use crate::configuration::Config; +use crate::context::signal::Signal; +use crate::executor::Executor; use crate::implementation::collect; use code0_flow::flow_config::load_env_file; -use context::{Context, ContextEntry, ContextResult}; -use error::RuntimeError; +use context::Context; use futures_lite::StreamExt; use log::error; use prost::Message; @@ -16,139 +17,23 @@ use registry::FunctionStore; use std::collections::HashMap; use tonic_health::pb::health_server::HealthServer; use tucana::shared::value::Kind; -use tucana::shared::{ExecutionFlow, ListValue, NodeFunction, Value}; - -fn handle_node_function( - function: NodeFunction, - node_functions: &HashMap, - store: &FunctionStore, - context: &mut Context, -) -> Result { - let runtime_function = match store.get(function.runtime_function_id.as_str()) { - Some(fc) => fc, - None => todo!("Retrun if no funtion is present"), - }; - - let mut parameter_collection: Vec = vec![]; - for parameter in function.parameters { - if let Some(node_value) = parameter.value { - if let Some(value) = node_value.value { - match value { - // Its just a normal value, directly a paramter - tucana::shared::node_value::Value::LiteralValue(v) => { - parameter_collection.push(v) - } - // Its a reference to an already executed function that returns value is the parameter of this function - tucana::shared::node_value::Value::ReferenceValue(reference) => { - let optional_value = context.get(&reference); - - // Look if its even present - let context_result = match optional_value { - Some(context_result) => context_result, - None => { - todo!("Required function that holds the parameter wasnt executed") - } - }; - - // A reference is present. Look up the real value - match context_result { - // The reference is a exeuction result of a node - ContextResult::NodeExecutionResult(node_result) => match node_result { - Ok(value) => { - parameter_collection.push(value.clone()); - } - Err(err) => return Err(err), - }, - // The reference is a parameter of a node - ContextResult::ParameterResult(parameter_result) => { - parameter_collection.push(parameter_result.clone()); - } - } - } - - // Its another function, that result is a direct parameter to this function - tucana::shared::node_value::Value::NodeFunctionId(another_node_function) => { - // As this is another new indent, a new context will be opened - - let function_result = match node_functions.get(&another_node_function) { - Some(function_result) => { - context.next_context(); - handle_node_function(function_result.clone(), node_functions, store, context ) - }, - None => { - todo!("Handle node not found. This should normally not happen") - } - }; - - - let entry = ContextEntry::new( - Result::Ok(function_result.clone()?), - parameter_collection.clone(), - ); - - context.write_to_current_context(entry); - } - } - } - } - - let result = runtime_function(¶meter_collection, context); - - // Result will be added to the current context - let entry = ContextEntry::new(result.clone(), parameter_collection.clone()); - context.write_to_current_context(entry); - - // Check if there is a next node, if not then this was the last one - match function.next_node_id { - Some(next_node_function_id) => { - let node = match node_functions.get(&next_node_function_id) { - Some(node) => node, - None => todo!("Handle node not found. This should normally not happen"), - }; - - // Increment the context node! - context.next_node(); - - return handle_node_function(node.clone(), node_functions, store, context); - } - None => { - if context.is_end() { - return result; - } - - context.leave_context(); - } - } - } - - Err(RuntimeError::default()) -} +use tucana::shared::{ExecutionFlow, NodeFunction, Value}; +use crate::config::Config; fn handle_message(flow: ExecutionFlow, store: &FunctionStore) -> Option { - let mut context = Context::new(); + let context = Context::new(); let node_functions: HashMap = flow .node_functions .into_iter() .map(|node| return (node.database_id, node)) .collect(); - - if let Some(node) = node_functions.get(&flow.starting_node_id) { - return match handle_node_function(node.clone(), &node_functions, store, &mut context) { - Ok(result) => { - println!( - "Execution completed successfully: The value is {:?}", - result - ); - Some(result) - } - Err(runtime_error) => { - println!("Runtime Error: {:?}", runtime_error); - None - } - }; + + let mut executor = Executor::new(store, node_functions, context); + match executor.execute(flow.starting_node_id) { + Signal::Success(v) => Some(v.clone()), + _ => None } - None } #[tokio::main] From ca6f8cfa7a6d8208ef2d56b85d3491d4199e11b5 Mon Sep 17 00:00:00 2001 From: raphael-goetz Date: Fri, 17 Oct 2025 14:10:23 +0200 Subject: [PATCH 5/9] feat: added respond signal --- src/context/signal.rs | 17 ++++++++++++++++- src/executor/mod.rs | 2 ++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/context/signal.rs b/src/context/signal.rs index 3f09ceb..b12f0d7 100644 --- a/src/context/signal.rs +++ b/src/context/signal.rs @@ -3,9 +3,23 @@ use crate::error::RuntimeError; #[derive(Debug)] pub enum Signal { + // Will be signaled if a function has been executed successfully Success(Value), + // Will be signaled if + // - a function recieves wrong parameter + // - a function throws an error + // - taurus itself throwns an error + // - will stop the execution of the flow completly Failure(RuntimeError), + // Will be signaled if the `return` function has been executed + // - will break the current context and return the value to the upper node Return(Value), + // Will be signaled if the `respond` function has been executed + // - will stop the execution of the flow completly + // - will return the value to the adapter + Respond(Value), + // Will be signaled if the `stop` function has been executed + // - will stop the execution of the flow completly Stop } @@ -17,6 +31,7 @@ impl PartialEq for Signal { | (Signal::Failure(_), Signal::Failure(_)) | (Signal::Return(_), Signal::Return(_)) | (Signal::Stop, Signal::Stop) + | (Signal::Respond(_), Signal::Respond(_)) ) } -} \ No newline at end of file +} diff --git a/src/executor/mod.rs b/src/executor/mod.rs index 16fdfa1..97db411 100644 --- a/src/executor/mod.rs +++ b/src/executor/mod.rs @@ -47,6 +47,7 @@ impl<'a> Executor<'a> { } Signal::Failure(error) => return Signal::Failure(error), Signal::Stop => return Signal::Stop, + Signal::Respond(value) => return Signal::Respond(value) } } @@ -71,6 +72,7 @@ impl<'a> Executor<'a> { } Signal::Failure(runtime_error) => return Signal::Failure(runtime_error), Signal::Return(value) => return Signal::Return(value), + Signal::Respond(value) => return Signal::Respond(value), Signal::Stop => return Signal::Stop, } } From 4d2a2403dd862446aab737b3da59c2cea772b3dc Mon Sep 17 00:00:00 2001 From: raphael-goetz Date: Fri, 17 Oct 2025 14:10:40 +0200 Subject: [PATCH 6/9] feat: added new stop, return and respond logic --- src/implementation/control.rs | 15 +--- src/implementation/http.rs | 161 ++++++++++++++++++++++++++-------- src/main.rs | 11 +-- 3 files changed, 134 insertions(+), 53 deletions(-) diff --git a/src/implementation/control.rs b/src/implementation/control.rs index 15719b6..6217615 100644 --- a/src/implementation/control.rs +++ b/src/implementation/control.rs @@ -5,20 +5,13 @@ use crate::context::signal::Signal; pub fn collect_control_functions() -> Vec<(&'static str, HandlerFn)> { vec![ - ("std::control::break", r#break), + ("std::control::stop", stop), ("std::control::return", r#return), ] } -fn r#break(values: &[Value], _ctx: &mut Context) -> Signal { - let [Value { kind }] = values else { - return Signal::Failure(RuntimeError::simple( - "InvalidArgumentRuntimeError", - format!("Expected one generic value but received {:?}", values), - )); - }; - - Signal::Success(Value { kind: kind.clone() }) +fn stop(_values: &[Value], _ctx: &mut Context) -> Signal { + Signal::Stop } fn r#return(values: &[Value], _ctx: &mut Context) -> Signal { @@ -29,5 +22,5 @@ fn r#return(values: &[Value], _ctx: &mut Context) -> Signal { )); }; - Signal::Success(Value { kind: kind.clone() }) + Signal::Return(Value { kind: kind.clone() }) } diff --git a/src/implementation/http.rs b/src/implementation/http.rs index 1c85bfc..a8ec723 100644 --- a/src/implementation/http.rs +++ b/src/implementation/http.rs @@ -1,84 +1,171 @@ -use tucana::shared::{Struct, Value}; -use tucana::shared::value::Kind; use crate::context::Context; use crate::context::signal::Signal; use crate::error::RuntimeError; use crate::registry::HandlerFn; +use tucana::shared::value::Kind; +use tucana::shared::{Struct, Value}; pub fn collect_http_functions() -> Vec<(&'static str, HandlerFn)> { vec![ ("http::request::create", create_request), ("http::response::create", create_response), + ("http::control::respond", respond), ] } +fn respond(values: &[Value], _ctx: &mut Context) -> Signal { + let [ + Value { + kind: Some(Kind::StructValue(struct_val)), + }, + ] = values + else { + return Signal::Failure(RuntimeError::simple( + "InvalidArgumentRuntimeError", + format!("Expected exactly one response struct, got {:?}", values), + )); + }; + + let fields = &struct_val.fields; + + let Some(headers_val) = fields.get("headers") else { + return Signal::Failure(RuntimeError::simple( + "InvalidArgumentRuntimeError", + "Missing 'headers' field".to_string(), + )); + }; + + let Some(status_code_val) = fields.get("status_code") else { + return Signal::Failure(RuntimeError::simple( + "InvalidArgumentRuntimeError", + "Missing 'status_code' field".to_string(), + )); + }; + + let Some(payload_val) = fields.get("payload") else { + return Signal::Failure(RuntimeError::simple( + "InvalidArgumentRuntimeError", + "Missing 'payload' field".to_string(), + )); + }; + + let Some(Kind::StructValue(_headers_struct)) = &headers_val.kind else { + return Signal::Failure(RuntimeError::simple( + "InvalidArgumentRuntimeError", + "Expected 'headers' to be StructValue".to_string(), + )); + }; + + let Some(Kind::StringValue(_status_code_str)) = &status_code_val.kind else { + return Signal::Failure(RuntimeError::simple( + "InvalidArgumentRuntimeError", + "Expected 'status_code' to be StringValue".to_string(), + )); + }; + + let Some(_payload_kind) = &payload_val.kind else { + return Signal::Failure(RuntimeError::simple( + "InvalidArgumentRuntimeError", + "Expected 'payload' to have a value".to_string(), + )); + }; + + Signal::Respond(Value { + kind: Some(Kind::StructValue(struct_val.clone())), + }) +} + fn create_request(values: &[Value], _ctx: &mut Context) -> Signal { - let [Value { - kind: Some(Kind::StringValue(http_method)), - }, - Value { - kind: Some(Kind::StructValue(headers)), - }, - Value { - kind: Some(Kind::StringValue(http_url)), - }, - payload + let [ + Value { + kind: Some(Kind::StringValue(http_method)), + }, + Value { + kind: Some(Kind::StructValue(headers)), + }, + Value { + kind: Some(Kind::StringValue(http_url)), + }, + payload, ] = values else { return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", - format!("Expected [method, headers, url, payload] but received {:?}", values), + format!( + "Expected [method, headers, url, payload] but received {:?}", + values + ), )); }; let mut fields = std::collections::HashMap::new(); - fields.insert("method".to_string(), Value { - kind: Some(Kind::StringValue(http_method.clone())), - }); + fields.insert( + "method".to_string(), + Value { + kind: Some(Kind::StringValue(http_method.clone())), + }, + ); - fields.insert("url".to_string(), Value { - kind: Some(Kind::StringValue(http_url.clone())), - }); + fields.insert( + "url".to_string(), + Value { + kind: Some(Kind::StringValue(http_url.clone())), + }, + ); - fields.insert("headers".to_string(),Value { - kind: Some(Kind::StructValue(headers.clone())), - }); + fields.insert( + "headers".to_string(), + Value { + kind: Some(Kind::StructValue(headers.clone())), + }, + ); fields.insert("body".to_string(), payload.clone()); - Signal::Success(Value { + Signal::Success(Value { kind: Some(Kind::StructValue(Struct { fields })), }) } fn create_response(values: &[Value], _ctx: &mut Context) -> Signal { - let [Value { - kind: Some(Kind::NumberValue(http_status_code)), - }, - Value { - kind: Some(Kind::StructValue(headers)), - }, - payload + let [ + Value { + kind: Some(Kind::NumberValue(http_status_code)), + }, + Value { + kind: Some(Kind::StructValue(headers)), + }, + payload, ] = values else { return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", - format!("Expected [http_status_code, headers, payload] but received {:?}", values), + format!( + "Expected [http_status_code, headers, payload] but received {:?}", + values + ), )); }; let mut fields = std::collections::HashMap::new(); - fields.insert("method".to_string(), Value { - kind: Some(Kind::NumberValue(http_status_code.clone())), - }); + fields.insert( + "status_code".to_string(), + Value { + kind: Some(Kind::NumberValue(http_status_code.clone())), + }, + ); - fields.insert("headers".to_string(),Value { - kind: Some(Kind::StructValue(headers.clone())), - }); + fields.insert( + "headers".to_string(), + Value { + kind: Some(Kind::StructValue(headers.clone())), + }, + ); fields.insert("body".to_string(), payload.clone()); Signal::Success(Value { kind: Some(Kind::StructValue(Struct { fields })), }) } + diff --git a/src/main.rs b/src/main.rs index cdd1989..7ac9a98 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,11 @@ +mod config; pub mod context; pub mod error; +mod executor; pub mod implementation; pub mod registry; -mod executor; -mod config; +use crate::config::Config; use crate::context::signal::Signal; use crate::executor::Executor; use crate::implementation::collect; @@ -18,7 +19,6 @@ use std::collections::HashMap; use tonic_health::pb::health_server::HealthServer; use tucana::shared::value::Kind; use tucana::shared::{ExecutionFlow, NodeFunction, Value}; -use crate::config::Config; fn handle_message(flow: ExecutionFlow, store: &FunctionStore) -> Option { let context = Context::new(); @@ -28,11 +28,12 @@ fn handle_message(flow: ExecutionFlow, store: &FunctionStore) -> Option { .into_iter() .map(|node| return (node.database_id, node)) .collect(); - + let mut executor = Executor::new(store, node_functions, context); match executor.execute(flow.starting_node_id) { Signal::Success(v) => Some(v.clone()), - _ => None + Signal::Respond(v) => Some(v.clone()), + _ => None, } } From ecb40bb0d91c42e400f9d100c93008699f7482b8 Mon Sep 17 00:00:00 2001 From: raphael-goetz Date: Mon, 20 Oct 2025 17:29:06 +0200 Subject: [PATCH 7/9] fix: propper field names --- src/implementation/http.rs | 6 +++--- src/main.rs | 19 ++++++++++++++++--- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/implementation/http.rs b/src/implementation/http.rs index a8ec723..e3c51a5 100644 --- a/src/implementation/http.rs +++ b/src/implementation/http.rs @@ -56,10 +56,10 @@ fn respond(values: &[Value], _ctx: &mut Context) -> Signal { )); }; - let Some(Kind::StringValue(_status_code_str)) = &status_code_val.kind else { + let Some(Kind::NumberValue(_status_code_str)) = &status_code_val.kind else { return Signal::Failure(RuntimeError::simple( "InvalidArgumentRuntimeError", - "Expected 'status_code' to be StringValue".to_string(), + "Expected 'status_code' to be NumberValue".to_string(), )); }; @@ -162,7 +162,7 @@ fn create_response(values: &[Value], _ctx: &mut Context) -> Signal { kind: Some(Kind::StructValue(headers.clone())), }, ); - fields.insert("body".to_string(), payload.clone()); + fields.insert("payload".to_string(), payload.clone()); Signal::Success(Value { kind: Some(Kind::StructValue(Struct { fields })), diff --git a/src/main.rs b/src/main.rs index 7ac9a98..2dbab8e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -33,6 +33,10 @@ fn handle_message(flow: ExecutionFlow, store: &FunctionStore) -> Option { match executor.execute(flow.starting_node_id) { Signal::Success(v) => Some(v.clone()), Signal::Respond(v) => Some(v.clone()), + Signal::Failure(error ) => { + log::error!("{:?}", error); + None + } _ => None, } } @@ -92,9 +96,18 @@ async fn main() { } }; - let value = handle_message(flow, &store).unwrap_or_else(|| Value { - kind: Some(Kind::NullValue(0)), - }); + let value = match handle_message(flow, &store) { + None => { + log::error!("Failed to handle message"); + Value { + kind: Some(Kind::NullValue(0)), + } + } + Some(v) => { + log::info!("Handled message successfully"); + v + } + }; // Send a response to the reply subject if let Some(reply) = msg.reply { From 3c71b22252af9a41e692394ef38dc74b2b172f4c Mon Sep 17 00:00:00 2001 From: raphael-goetz Date: Sun, 2 Nov 2025 11:13:39 +0100 Subject: [PATCH 8/9] feat: added to_value function to error --- src/error/mod.rs | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/error/mod.rs b/src/error/mod.rs index 3465554..4dbf6e2 100644 --- a/src/error/mod.rs +++ b/src/error/mod.rs @@ -1,7 +1,10 @@ +use std::collections::HashMap; use std::{ error::Error, fmt::{Display, Formatter}, }; +use tucana::shared::value::Kind::{StringValue, StructValue}; +use tucana::shared::{Struct, Value}; #[derive(Debug, Default, Clone)] pub struct RuntimeError { @@ -38,8 +41,37 @@ impl RuntimeError { pub fn simple(name: &str, message: String) -> Self { Self { name: name.to_string(), - message: message, + message, suggestion: None, } } + + pub fn as_value(&self) -> Value { + let suggestion = match self.suggestion { + Some(ref s) => Value { + kind: Some(StringValue(s.clone())), + }, + None => Value { kind: None }, + }; + + Value { + kind: Some(StructValue(Struct { + fields: HashMap::from([ + ( + String::from("name"), + Value { + kind: Some(StringValue(self.name.clone())), + }, + ), + ( + String::from("message"), + Value { + kind: Some(StringValue(self.message.clone())), + }, + ), + (String::from("suggestion"), suggestion), + ]), + })), + } + } } From e77e94661863daf3d0231d2fff676ddb9c463fca Mon Sep 17 00:00:00 2001 From: raphael-goetz Date: Sun, 2 Nov 2025 11:15:09 +0100 Subject: [PATCH 9/9] feat: handled all possible signal returns --- src/context/context.rs | 4 +--- src/context/mod.rs | 13 ++++++++----- src/context/signal.rs | 8 ++++---- src/executor/mod.rs | 32 ++++++++++++++++++++------------ src/implementation/array.rs | 8 ++++---- src/implementation/boolean.rs | 2 +- src/implementation/control.rs | 2 +- src/implementation/http.rs | 3 +-- src/implementation/mod.rs | 2 +- src/implementation/number.rs | 22 ++++++++++------------ src/implementation/text.rs | 18 +++++++++--------- src/main.rs | 34 +++++++++++----------------------- src/registry/mod.rs | 10 ++++++++-- 13 files changed, 79 insertions(+), 79 deletions(-) diff --git a/src/context/context.rs b/src/context/context.rs index a55a20a..10bdeb7 100644 --- a/src/context/context.rs +++ b/src/context/context.rs @@ -1,3 +1 @@ -pub struct Context { - -} \ No newline at end of file +pub struct Context {} diff --git a/src/context/mod.rs b/src/context/mod.rs index da946de..659afab 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -1,5 +1,5 @@ -pub mod signal; pub mod context; +pub mod signal; use crate::error::RuntimeError; use std::{ @@ -26,10 +26,7 @@ pub struct ContextEntry { impl ContextEntry { pub fn new(result: NodeResult, parameter: Vec) -> Self { - ContextEntry { - result: result, - parameter: parameter, - } + ContextEntry { result, parameter } } } @@ -53,6 +50,12 @@ pub struct Context { context_history: VecDeque<(i32, i32)>, } +impl Default for Context { + fn default() -> Self { + Self::new() + } +} + impl Context { /// Create a new, empty context. pub fn new() -> Self { diff --git a/src/context/signal.rs b/src/context/signal.rs index b12f0d7..9e0cf30 100644 --- a/src/context/signal.rs +++ b/src/context/signal.rs @@ -1,5 +1,5 @@ -use tucana::shared::Value; use crate::error::RuntimeError; +use tucana::shared::Value; #[derive(Debug)] pub enum Signal { @@ -15,12 +15,12 @@ pub enum Signal { // - will break the current context and return the value to the upper node Return(Value), // Will be signaled if the `respond` function has been executed - // - will stop the execution of the flow completly + // - will stop the execution of the flow completly // - will return the value to the adapter Respond(Value), // Will be signaled if the `stop` function has been executed - // - will stop the execution of the flow completly - Stop + // - will stop the execution of the flow completly + Stop, } impl PartialEq for Signal { diff --git a/src/executor/mod.rs b/src/executor/mod.rs index 97db411..cf3f844 100644 --- a/src/executor/mod.rs +++ b/src/executor/mod.rs @@ -14,16 +14,18 @@ pub struct Executor<'a> { type HandleNodeParameterFn = fn(&mut Executor, node_parameter: &NodeParameter) -> Signal; impl<'a> Executor<'a> { - - pub fn new(functions: &'a FunctionStore, nodes: HashMap, context: Context) -> Self { + pub fn new( + functions: &'a FunctionStore, + nodes: HashMap, + context: Context, + ) -> Self { Executor { functions, nodes, - context + context, } } - pub fn execute(&mut self, starting_node_id: i64) -> Signal { let mut current_node_id = starting_node_id; @@ -47,7 +49,7 @@ impl<'a> Executor<'a> { } Signal::Failure(error) => return Signal::Failure(error), Signal::Stop => return Signal::Stop, - Signal::Respond(value) => return Signal::Respond(value) + Signal::Respond(value) => return Signal::Respond(value), } } @@ -91,16 +93,22 @@ impl<'a> Executor<'a> { let value = match &node_value.value { Some(v) => v, - None => return Signal::Failure(RuntimeError::simple_str("NodeValueNotFound", "An error occurred while executing a flow!")) + None => { + return Signal::Failure(RuntimeError::simple_str( + "NodeValueNotFound", + "An error occurred while executing a flow!", + )); + } }; match value { - tucana::shared::node_value::Value::LiteralValue(value) => return Signal::Success(value.clone()), - tucana::shared::node_value::Value::ReferenceValue(_reference_value) => todo!("implement reference values!"), - tucana::shared::node_value::Value::NodeFunctionId(id) => { - return Executor::execute(self, *id) - }, + tucana::shared::node_value::Value::LiteralValue(value) => { + Signal::Success(value.clone()) + } + tucana::shared::node_value::Value::ReferenceValue(_reference_value) => { + todo!("implement reference values!") + } + tucana::shared::node_value::Value::NodeFunctionId(id) => Executor::execute(self, *id), } } } - diff --git a/src/implementation/array.rs b/src/implementation/array.rs index 5e1a0e3..58591a3 100644 --- a/src/implementation/array.rs +++ b/src/implementation/array.rs @@ -54,7 +54,7 @@ fn at(values: &[Value], _ctx: &mut Context) -> Signal { )); }; - let item = array.values[index.clone() as usize].clone(); + let item = array.values[*index as usize].clone(); Signal::Success(item) } @@ -709,7 +709,7 @@ fn min(values: &[Value], _ctx: &mut Context) -> Signal { match min { Some(min) => Signal::Success(Value { - kind: Some(Kind::NumberValue(min.clone())), + kind: Some(Kind::NumberValue(*min)), }), None => Signal::Failure(RuntimeError::simple( "ArrayEmptyRuntimeError", @@ -748,7 +748,7 @@ fn max(values: &[Value], _ctx: &mut Context) -> Signal { match max { Some(max) => Signal::Success(Value { - kind: Some(Kind::NumberValue(max.clone())), + kind: Some(Kind::NumberValue(*max)), }), None => Signal::Failure(RuntimeError::simple( "ArrayEmptyRuntimeError", @@ -817,7 +817,7 @@ fn join(values: &[Value], _ctx: &mut Context) -> Signal { } }); - let joined = collector.join(&separator); + let joined = collector.join(separator); Signal::Success(Value { kind: Some(Kind::StringValue(joined)), diff --git a/src/implementation/boolean.rs b/src/implementation/boolean.rs index f819a56..4adf8c5 100644 --- a/src/implementation/boolean.rs +++ b/src/implementation/boolean.rs @@ -27,7 +27,7 @@ fn as_number(values: &[Value], _ctx: &mut Context) -> Signal { }; Signal::Success(Value { - kind: Some(Kind::NumberValue(value.clone() as i64 as f64)), + kind: Some(Kind::NumberValue(*value as i64 as f64)), }) } diff --git a/src/implementation/control.rs b/src/implementation/control.rs index 6217615..be49084 100644 --- a/src/implementation/control.rs +++ b/src/implementation/control.rs @@ -1,7 +1,7 @@ use tucana::shared::Value; -use crate::{context::Context, error::RuntimeError, registry::HandlerFn}; use crate::context::signal::Signal; +use crate::{context::Context, error::RuntimeError, registry::HandlerFn}; pub fn collect_control_functions() -> Vec<(&'static str, HandlerFn)> { vec![ diff --git a/src/implementation/http.rs b/src/implementation/http.rs index e3c51a5..d1605e0 100644 --- a/src/implementation/http.rs +++ b/src/implementation/http.rs @@ -152,7 +152,7 @@ fn create_response(values: &[Value], _ctx: &mut Context) -> Signal { fields.insert( "status_code".to_string(), Value { - kind: Some(Kind::NumberValue(http_status_code.clone())), + kind: Some(Kind::NumberValue(*http_status_code)), }, ); @@ -168,4 +168,3 @@ fn create_response(values: &[Value], _ctx: &mut Context) -> Signal { kind: Some(Kind::StructValue(Struct { fields })), }) } - diff --git a/src/implementation/mod.rs b/src/implementation/mod.rs index 4666337..caa93b9 100644 --- a/src/implementation/mod.rs +++ b/src/implementation/mod.rs @@ -3,10 +3,10 @@ use crate::registry::HandlerFn; mod array; mod boolean; mod control; +mod http; mod number; mod object; mod text; -mod http; pub fn collect() -> Vec<(&'static str, HandlerFn)> { let mut result = vec![]; diff --git a/src/implementation/number.rs b/src/implementation/number.rs index dc9aac8..a5dcd67 100644 --- a/src/implementation/number.rs +++ b/src/implementation/number.rs @@ -322,7 +322,7 @@ fn exponential(values: &[Value], _ctx: &mut Context) -> Signal { }; Signal::Success(Value { - kind: Some(Kind::NumberValue(base.powf(exponent.clone()))), + kind: Some(Kind::NumberValue(base.powf(*exponent))), }) } @@ -363,7 +363,7 @@ fn round_up(values: &[Value], _ctx: &mut Context) -> Signal { )); }; - let factor = 10_f64.powi(decimal_places.clone() as i32); + let factor = 10_f64.powi(*decimal_places as i32); Signal::Success(Value { kind: Some(Kind::NumberValue((value * factor).ceil() / factor)), @@ -389,7 +389,7 @@ fn round_down(values: &[Value], _ctx: &mut Context) -> Signal { )); }; - let factor = 10_f64.powi(decimal_places.clone() as i32); + let factor = 10_f64.powi(*decimal_places as i32); Signal::Success(Value { kind: Some(Kind::NumberValue((value * factor).floor() / factor)), @@ -415,7 +415,7 @@ fn round(values: &[Value], _ctx: &mut Context) -> Signal { )); }; - let factor = 10_f64.powi(decimal_places.clone() as i32); + let factor = 10_f64.powi(*decimal_places as i32); Signal::Success(Value { kind: Some(Kind::NumberValue((value * factor).round() / factor)), @@ -460,7 +460,7 @@ fn root(values: &[Value], _ctx: &mut Context) -> Signal { }; Signal::Success(Value { - kind: Some(Kind::NumberValue(value.powf(root.clone()))), + kind: Some(Kind::NumberValue(value.powf(*root))), }) } @@ -484,7 +484,7 @@ fn log(values: &[Value], _ctx: &mut Context) -> Signal { }; Signal::Success(Value { - kind: Some(Kind::NumberValue(value.log(log.clone()))), + kind: Some(Kind::NumberValue(value.log(*log))), }) } @@ -572,7 +572,7 @@ fn min(values: &[Value], _ctx: &mut Context) -> Signal { }; Signal::Success(Value { - kind: Some(Kind::NumberValue(lhs.min(rhs.clone()))), + kind: Some(Kind::NumberValue(lhs.min(*rhs))), }) } @@ -596,7 +596,7 @@ fn max(values: &[Value], _ctx: &mut Context) -> Signal { }; Signal::Success(Value { - kind: Some(Kind::NumberValue(lhs.max(rhs.clone()))), + kind: Some(Kind::NumberValue(lhs.max(*rhs))), }) } @@ -638,9 +638,7 @@ fn random(values: &[Value], _ctx: &mut Context) -> Signal { }; Signal::Success(Value { - kind: Some(Kind::NumberValue(rand::random_range( - min.clone()..max.clone(), - ))), + kind: Some(Kind::NumberValue(rand::random_range(*min..*max))), }) } @@ -810,7 +808,7 @@ fn clamp(values: &[Value], _ctx: &mut Context) -> Signal { }; Signal::Success(Value { - kind: Some(Kind::NumberValue(value.clamp(min.clone(), max.clone()))), + kind: Some(Kind::NumberValue(value.clamp(*min, *max))), }) } diff --git a/src/implementation/text.rs b/src/implementation/text.rs index 9854682..85f8854 100644 --- a/src/implementation/text.rs +++ b/src/implementation/text.rs @@ -109,10 +109,10 @@ fn capitalize(values: &[Value], _ctx: &mut Context) -> Signal { } if word.len() == 1 { - return String::from(word.to_uppercase()); + return word.to_uppercase(); } - let first = word.chars().nth(0); + let first = word.chars().next(); if first.is_some() { let first = first.unwrap(); @@ -262,8 +262,8 @@ fn at(values: &[Value], _ctx: &mut Context) -> Signal { )); } - let usize_index = index.clone() as usize; - let char = value.chars().into_iter().nth(usize_index); + let usize_index = *index as usize; + let char = value.chars().nth(usize_index); match char { Some(c) => Signal::Success(Value { @@ -368,7 +368,7 @@ fn insert(values: &[Value], _ctx: &mut Context) -> Signal { )); }; - let usize_position = position.clone() as usize; + let usize_position = *position as usize; let mut new_value = value.clone(); new_value.insert_str(usize_position, text.as_str()); @@ -420,12 +420,12 @@ fn remove(values: &[Value], _ctx: &mut Context) -> Signal { )); }; - let chars = value.chars().into_iter().collect::>(); + let chars = value.chars().collect::>(); let new = chars .into_iter() .enumerate() - .filter(|&(i, _)| i < from.clone() as usize || i >= to.clone() as usize) + .filter(|&(i, _)| i < *from as usize || i >= *to as usize) .map(|e| e.1) .collect::(); @@ -799,8 +799,8 @@ fn from_ascii(values: &[Value], _ctx: &mut Context) -> Signal { kind: Some(Kind::NumberValue(number)), } = number_value { - if number >= &0.0 && number <= &127.0 { - Some(number.clone() as u8 as char) + if (&0.0..=&127.0).contains(&number) { + Some(*number as u8 as char) } else { None } diff --git a/src/main.rs b/src/main.rs index 2dbab8e..1300e01 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,25 +20,16 @@ use tonic_health::pb::health_server::HealthServer; use tucana::shared::value::Kind; use tucana::shared::{ExecutionFlow, NodeFunction, Value}; -fn handle_message(flow: ExecutionFlow, store: &FunctionStore) -> Option { +fn handle_message(flow: ExecutionFlow, store: &FunctionStore) -> Signal { let context = Context::new(); let node_functions: HashMap = flow .node_functions .into_iter() - .map(|node| return (node.database_id, node)) + .map(|node| (node.database_id, node)) .collect(); - let mut executor = Executor::new(store, node_functions, context); - match executor.execute(flow.starting_node_id) { - Signal::Success(v) => Some(v.clone()), - Signal::Respond(v) => Some(v.clone()), - Signal::Failure(error ) => { - log::error!("{:?}", error); - None - } - _ => None, - } + Executor::new(store, node_functions, context).execute(flow.starting_node_id) } #[tokio::main] @@ -80,7 +71,7 @@ async fn main() { println!("Health server started at {}", address); } - let _ = match client + match client .queue_subscribe(String::from("execution.*"), "taurus".into()) .await { @@ -97,16 +88,13 @@ async fn main() { }; let value = match handle_message(flow, &store) { - None => { - log::error!("Failed to handle message"); - Value { - kind: Some(Kind::NullValue(0)), - } - } - Some(v) => { - log::info!("Handled message successfully"); - v - } + 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)), + }, }; // Send a response to the reply subject diff --git a/src/registry/mod.rs b/src/registry/mod.rs index b9bd037..b523129 100644 --- a/src/registry/mod.rs +++ b/src/registry/mod.rs @@ -1,7 +1,7 @@ -use crate::{context::Context}; +use crate::context::Context; +use crate::context::signal::Signal; use std::collections::HashMap; use tucana::shared::Value; -use crate::context::signal::Signal; pub type HandlerFn = fn(&[Value], &mut Context) -> Signal; @@ -10,6 +10,12 @@ pub struct FunctionStore { functions: HashMap, } +impl Default for FunctionStore { + fn default() -> Self { + Self::new() + } +} + impl FunctionStore { /// Create a new, empty store. pub fn new() -> Self {