use aura_lang::eval::value::Value;
use aura_lang::eval::{Interpreter, Options};
use aura_lang::lexer::Lexer;
use aura_lang::parser::Parser;
use aura_lang::source::SourceCache;
use aura_lang::span::Span;
const RULES: &str = r#"
# Routing rules. Editing this changes behaviour with no rebuild.
pub def route(path, method)
backend: cond
path.starts_with("/api") -> "api-cluster"
method == "POST" -> "write-pool"
else -> "static"
end
timeout_ms: cond
path.starts_with("/api") -> 5000
else -> 1000
end
end
version: "rules-v3"
"#;
fn main() {
let cache = SourceCache::new();
let (id, src) = cache.add("rules.aura".into(), RULES.to_string());
let tokens = Lexer::new(src, id).tokenize().expect("rules.aura lexes");
let module = Parser::new(tokens)
.parse_module()
.expect("rules.aura parses");
let mut interp = Interpreter::new(Options {
strict: false,
dry_run: false,
});
let exported = interp.eval_module(&module).expect("rules.aura evaluates");
let Value::Object(top) = &exported else {
panic!("a module evaluates to an object");
};
println!("rules version: {:?}", top.get("version").expect("version"));
let route = top.get("route").expect("`pub def route`").clone();
let span = Span::new(id, 0, 0);
for (path, method) in [
("/api/orders", "GET"),
("/img/logo.png", "GET"),
("/submit", "POST"),
] {
let decision = interp
.call_value(&route, &[Value::str(path), Value::str(method)], span)
.expect("route() is callable");
let Value::Object(fields) = &decision else {
panic!("route() returns an object");
};
let backend = fields.get("backend").expect("backend");
let timeout = fields.get("timeout_ms").expect("timeout_ms");
println!("{path:16} {method:5} -> {backend:?}, timeout {timeout:?}");
let expected = match (path, method) {
("/api/orders", _) => ("api-cluster", 5000),
(_, "POST") => ("write-pool", 1000),
_ => ("static", 1000),
};
assert_eq!(*backend, Value::str(expected.0), "backend for {path}");
assert_eq!(*timeout, Value::Int(expected.1), "timeout for {path}");
}
println!("\nall decisions matched — the script drove them, not this binary");
}