use crate::ast::TypeExpr;
use super::signatures;
use super::{BuiltinMetadata, BuiltinSignature, Ty, TyExt};
pub fn lookup(name: &str) -> Option<&'static BuiltinSignature> {
for sig in harn_builtin_registry::installed_signatures() {
if sig.name == name {
return Some(*sig);
}
}
for group in signatures::groups() {
for sig in group {
if sig.name == name {
return Some(sig);
}
}
}
None
}
pub fn is_builtin(name: &str) -> bool {
lookup(name).is_some()
}
pub fn iter_builtin_names() -> impl Iterator<Item = &'static str> {
let installed = harn_builtin_registry::installed_signatures();
let installed_names: std::collections::HashSet<&'static str> =
installed.iter().map(|s| s.name).collect();
installed.iter().map(|s| s.name).chain(
signatures::groups()
.into_iter()
.flat_map(|g| g.iter())
.filter(move |s| !installed_names.contains(s.name))
.map(|s| s.name),
)
}
pub fn static_signature_names() -> impl Iterator<Item = &'static str> {
signatures::groups()
.into_iter()
.flat_map(|g| g.iter())
.map(|s| s.name)
}
pub fn iter_builtin_metadata() -> impl Iterator<Item = BuiltinMetadata> {
let installed = harn_builtin_registry::installed_signatures();
let installed_names: std::collections::HashSet<&'static str> =
installed.iter().map(|s| s.name).collect();
installed
.iter()
.map(|sig| BuiltinMetadata {
name: sig.name,
return_types: builtin_return_type_names(sig),
})
.chain(
signatures::groups()
.into_iter()
.flat_map(|g| g.iter())
.filter(move |s| !installed_names.contains(s.name))
.map(|sig| BuiltinMetadata {
name: sig.name,
return_types: builtin_return_type_names(sig),
}),
)
}
pub fn builtin_return_type(name: &str) -> Option<TypeExpr> {
let sig = lookup(name)?;
if sig.returns.is_any() {
return None;
}
Some(sig.returns.to_type_expr())
}
pub fn is_untyped_boundary_source(name: &str) -> bool {
matches!(
name,
"json_parse"
| "json_extract"
| "yaml_parse"
| "toml_parse"
| "llm_call"
| "llm_call_safe"
| "llm_completion"
| "http_get"
| "http_post"
| "http_put"
| "http_patch"
| "http_delete"
| "http_download"
| "http_request"
| "http_session_request"
| "http_stream_info"
| "sse_receive"
| "sse_server_mock_receive"
| "sse_server_response"
| "sse_server_status"
| "websocket_accept"
| "websocket_receive"
| "host_call"
| "connector_call"
| "host_tool_call"
| "mcp_call"
)
}
fn builtin_return_type_names(sig: &BuiltinSignature) -> &'static [&'static str] {
match &sig.returns {
Ty::Named(name) => match *name {
"bool" => &["bool"],
"bytes" => &["bytes"],
"dict" => &["dict"],
"float" => &["float"],
"int" => &["int"],
"list" => &["list"],
"nil" => &["nil"],
"string" => &["string"],
_ => &[],
},
Ty::Union(members) => match *members {
[Ty::Named("string"), Ty::Named("nil")] => &["string", "nil"],
[Ty::Named("nil"), Ty::Named("string")] => &["string", "nil"],
[Ty::Named("int"), Ty::Named("nil")] => &["int", "nil"],
[Ty::Named("nil"), Ty::Named("int")] => &["int", "nil"],
[Ty::Named("dict"), Ty::Named("nil")] => &["dict", "nil"],
[Ty::Named("nil"), Ty::Named("dict")] => &["dict", "nil"],
[Ty::Named("bytes"), Ty::Named("nil")] => &["bytes", "nil"],
[Ty::Named("nil"), Ty::Named("bytes")] => &["bytes", "nil"],
_ => &[],
},
Ty::Never => &["never"],
_ => &[],
}
}