Skip to content

Commit d2b0f60

Browse files
committed
feat: made func registration static
1 parent f5c8526 commit d2b0f60

8 files changed

Lines changed: 5037 additions & 0 deletions

File tree

crates/taurus-core/src/runtime/functions/array.rs

Lines changed: 1703 additions & 0 deletions
Large diffs are not rendered by default.

crates/taurus-core/src/runtime/functions/boolean.rs

Lines changed: 414 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
//! Control-flow handlers (`if`, `if_else`, `return`, `stop`).
2+
//!
3+
//! `if`/`if_else` execute branch nodes via runtime callbacks and forward their resulting signals.
4+
//! This is required for block-style return semantics where `return` exits only the current call frame.
5+
6+
use crate::handler::argument::Argument;
7+
use crate::handler::argument::ParameterNode::{Eager, Lazy};
8+
use crate::handler::macros::args;
9+
use crate::handler::registry::FunctionRegistration;
10+
use crate::runtime::execution::value_store::ValueStore;
11+
use crate::types::errors::runtime_error::RuntimeError;
12+
use crate::types::signal::Signal;
13+
use tucana::shared::Value;
14+
use tucana::shared::value::Kind;
15+
16+
pub(crate) const FUNCTIONS: &[FunctionRegistration] = &[
17+
FunctionRegistration::eager("std::control::stop", stop, 0),
18+
FunctionRegistration::eager("std::control::return", r#return, 1),
19+
FunctionRegistration::modes("std::control::if", r#if, &[Eager, Lazy]),
20+
FunctionRegistration::modes("std::control::if_else", if_else, &[Eager, Lazy, Lazy]),
21+
];
22+
23+
fn stop(
24+
_args: &[Argument],
25+
_ctx: &mut ValueStore,
26+
_run: &mut dyn FnMut(i64, &mut ValueStore) -> Signal,
27+
) -> Signal {
28+
Signal::Stop
29+
}
30+
31+
fn r#return(
32+
args: &[Argument],
33+
_ctx: &mut ValueStore,
34+
_run: &mut dyn FnMut(i64, &mut ValueStore) -> Signal,
35+
) -> Signal {
36+
args!(args => value: Value);
37+
// The executor decides how far this return unwinds (one frame).
38+
Signal::Return(value)
39+
}
40+
41+
fn r#if(
42+
args: &[Argument],
43+
ctx: &mut ValueStore,
44+
run: &mut dyn FnMut(i64, &mut ValueStore) -> Signal,
45+
) -> Signal {
46+
let [
47+
Argument::Eval(Value {
48+
kind: Some(Kind::BoolValue(bool)),
49+
}),
50+
Argument::Thunk(if_pointer),
51+
] = args
52+
else {
53+
return Signal::Failure(RuntimeError::new(
54+
"T-RT-000000",
55+
"InvalidArgumentRuntimeError",
56+
format!("Expected a bool value but received {:?}", args),
57+
));
58+
};
59+
60+
if *bool {
61+
// Branch execution is delegated to the executor through `run`.
62+
ctx.push_runtime_trace_label("branch=if".to_string());
63+
run(*if_pointer, ctx)
64+
} else {
65+
Signal::Success(Value {
66+
kind: Some(Kind::NullValue(0)),
67+
})
68+
}
69+
}
70+
71+
fn if_else(
72+
args: &[Argument],
73+
ctx: &mut ValueStore,
74+
run: &mut dyn FnMut(i64, &mut ValueStore) -> Signal,
75+
) -> Signal {
76+
let [
77+
Argument::Eval(Value {
78+
kind: Some(Kind::BoolValue(bool)),
79+
}),
80+
Argument::Thunk(if_pointer),
81+
Argument::Thunk(else_pointer),
82+
] = args
83+
else {
84+
return Signal::Failure(RuntimeError::new(
85+
"T-RT-000000",
86+
"InvalidArgumentRuntimeError",
87+
format!("Expected a bool value but received {:?}", args),
88+
));
89+
};
90+
91+
if *bool {
92+
ctx.push_runtime_trace_label("branch=if".to_string());
93+
run(*if_pointer, ctx)
94+
} else {
95+
ctx.push_runtime_trace_label("branch=else".to_string());
96+
run(*else_pointer, ctx)
97+
}
98+
}
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
//! HTTP and REST-oriented helper handlers.
2+
//!
3+
//! These functions build/validate plain struct payloads that the runtime treats as regular values.
4+
5+
use crate::handler::argument::Argument;
6+
use crate::handler::macros::args;
7+
use crate::handler::registry::FunctionRegistration;
8+
use crate::runtime::execution::value_store::ValueStore;
9+
use crate::types::errors::runtime_error::RuntimeError;
10+
use crate::types::signal::Signal;
11+
use tucana::shared::helper::value::ToValue;
12+
use tucana::shared::value::Kind;
13+
use tucana::shared::{Struct, Value};
14+
15+
pub(crate) const FUNCTIONS: &[FunctionRegistration] = &[
16+
FunctionRegistration::eager("http::request::create", create_request, 4),
17+
FunctionRegistration::eager("http::response::create", create_response, 3),
18+
FunctionRegistration::eager("rest::control::respond", respond, 1),
19+
];
20+
21+
fn fail(category: &str, message: impl Into<String>) -> Signal {
22+
Signal::Failure(RuntimeError::new("T-HTTP-000000", category, message))
23+
}
24+
25+
fn respond(
26+
args: &[Argument],
27+
_ctx: &mut ValueStore,
28+
_run: &mut dyn FnMut(i64, &mut ValueStore) -> Signal,
29+
) -> Signal {
30+
args!(args => struct_val: Struct);
31+
32+
let fields = &struct_val.fields;
33+
34+
let Some(headers_val) = fields.get("headers") else {
35+
return Signal::Failure(RuntimeError::new(
36+
"T-RT-000000",
37+
"InvalidArgumentRuntimeError",
38+
"Missing 'headers' field".to_string(),
39+
));
40+
};
41+
42+
let Some(status_code_val) = fields.get("http_status_code") else {
43+
return fail(
44+
"InvalidArgumentRuntimeError",
45+
"Missing 'http_status_code' field",
46+
);
47+
};
48+
49+
let Some(payload_val) = fields.get("payload") else {
50+
return Signal::Failure(RuntimeError::new(
51+
"T-RT-000000",
52+
"InvalidArgumentRuntimeError",
53+
"Missing 'payload' field".to_string(),
54+
));
55+
};
56+
57+
let Some(Kind::StructValue(_headers_struct)) = &headers_val.kind else {
58+
return fail(
59+
"InvalidArgumentRuntimeError",
60+
"Expected 'headers' to be StructValue",
61+
);
62+
};
63+
64+
let Some(Kind::NumberValue(_status_code_str)) = &status_code_val.kind else {
65+
return Signal::Failure(RuntimeError::new(
66+
"T-RT-000000",
67+
"InvalidArgumentRuntimeError",
68+
"Expected 'status_code' to be NumberValue".to_string(),
69+
));
70+
};
71+
72+
let Some(_payload_kind) = &payload_val.kind else {
73+
return Signal::Failure(RuntimeError::new(
74+
"T-RT-000000",
75+
"InvalidArgumentRuntimeError",
76+
"Expected 'payload' to have a value".to_string(),
77+
));
78+
};
79+
80+
// `Respond` is a control signal; the executor can still continue with `next` if present.
81+
Signal::Respond(Value {
82+
kind: Some(Kind::StructValue(struct_val.clone())),
83+
})
84+
}
85+
86+
fn create_request(
87+
args: &[Argument],
88+
_ctx: &mut ValueStore,
89+
_run: &mut dyn FnMut(i64, &mut ValueStore) -> Signal,
90+
) -> Signal {
91+
args!(args => http_method: String, headers: Struct, http_url: String, payload: Value);
92+
let mut fields = std::collections::HashMap::new();
93+
94+
fields.insert(String::from("http_method"), http_method.to_value());
95+
fields.insert(String::from("url"), http_url.to_value());
96+
fields.insert(String::from("payload"), payload.clone());
97+
fields.insert(
98+
String::from("headers"),
99+
Value {
100+
kind: Some(Kind::StructValue(headers.clone())),
101+
},
102+
);
103+
104+
Signal::Success(Value {
105+
kind: Some(Kind::StructValue(Struct { fields })),
106+
})
107+
}
108+
109+
fn create_response(
110+
args: &[Argument],
111+
_ctx: &mut ValueStore,
112+
_run: &mut dyn FnMut(i64, &mut ValueStore) -> Signal,
113+
) -> Signal {
114+
args!(args => http_status_code: i64, headers: Struct, payload: Value);
115+
let mut fields = std::collections::HashMap::new();
116+
117+
fields.insert(
118+
String::from("http_status_code"),
119+
http_status_code.to_value(),
120+
);
121+
fields.insert(String::from("payload"), payload.clone());
122+
123+
fields.insert(
124+
String::from("headers"),
125+
Value {
126+
kind: Some(Kind::StructValue(headers.clone())),
127+
},
128+
);
129+
130+
Signal::Success(Value {
131+
kind: Some(Kind::StructValue(Struct { fields })),
132+
})
133+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//! Built-in runtime function catalog.
2+
//!
3+
//! Each submodule registers handler implementations under stable runtime ids.
4+
5+
use crate::handler::registry::FunctionRegistration;
6+
7+
mod array;
8+
mod boolean;
9+
mod control;
10+
mod http;
11+
mod number;
12+
mod object;
13+
mod text;
14+
15+
pub const ALL_FUNCTION_SETS: &[&[FunctionRegistration]] = &[
16+
array::FUNCTIONS,
17+
number::FUNCTIONS,
18+
boolean::FUNCTIONS,
19+
text::FUNCTIONS,
20+
object::FUNCTIONS,
21+
control::FUNCTIONS,
22+
http::FUNCTIONS,
23+
];

0 commit comments

Comments
 (0)