#![cfg_attr(not(feature = "all-operators"), allow(dead_code, unused_imports))]
use crate::node::{CompileCtx, CompiledNode};
use crate::operators::meta::{HookArgs, Hooked};
#[cfg(any(feature = "error-handling", feature = "tensor", feature = "datetime"))]
use datavalue::OwnedDataValue;
use super::missing::{compile_missing, compile_missing_some};
use super::operator;
#[inline]
fn or_generic(node: Option<CompiledNode>, args: Box<[CompiledNode]>) -> Hooked {
match node {
Some(node) => Hooked::Node(node),
None => Hooked::Generic(args),
}
}
pub(crate) fn val(args: Box<[CompiledNode]>, hook: HookArgs<'_>) -> Hooked {
let node = if hook.op_name == "var" {
operator::try_compile_var(&args, hook.ctx)
} else {
operator::try_compile_val(&args, hook.ctx)
};
or_generic(node, args)
}
#[cfg(feature = "ext-control")]
pub(crate) fn exists(args: Box<[CompiledNode]>, hook: HookArgs<'_>) -> Hooked {
let node = operator::try_compile_exists(&args, hook.ctx);
or_generic(node, args)
}
pub(crate) fn missing(args: Box<[CompiledNode]>, hook: HookArgs<'_>) -> Hooked {
Hooked::Node(compile_missing(args, hook.ctx))
}
pub(crate) fn missing_some(args: Box<[CompiledNode]>, hook: HookArgs<'_>) -> Hooked {
Hooked::Node(compile_missing_some(args, hook.ctx))
}
#[cfg(feature = "error-handling")]
pub(crate) fn throw_literal(args: Box<[CompiledNode]>, hook: HookArgs<'_>) -> Hooked {
let [
CompiledNode::Value {
value: OwnedDataValue::String(s),
..
},
] = &*args
else {
return Hooked::Generic(args);
};
Hooked::Node(CompiledNode::Throw(Box::new(
crate::node::CompiledThrowData {
id: Some(hook.ctx.next_id()),
error: OwnedDataValue::Object(vec![(
"type".to_string(),
OwnedDataValue::String(s.clone()),
)]),
},
)))
}
#[cfg(feature = "datetime")]
pub(crate) fn timezone_literal(args: Box<[CompiledNode]>, hook: HookArgs<'_>) -> Hooked {
let Some(CompiledNode::Value {
value: OwnedDataValue::String(s),
..
}) = args.get(2)
else {
return Hooked::Generic(args);
};
if s.parse::<chrono_tz::Tz>().is_ok() {
return Hooked::Generic(args);
}
Hooked::Node(super::walker::invalid_args_marker(
hook.opcode,
hook.args_value,
hook.ctx,
))
}
#[cfg(feature = "tensor")]
pub(crate) fn tensor_wire_body(
args_value: &OwnedDataValue,
ctx: &mut CompileCtx,
) -> Option<CompiledNode> {
let OwnedDataValue::Object(fields) = args_value else {
return None;
};
if !is_tensor_wire_body(fields) {
return None;
}
let body = CompiledNode::compile_time_value(Some(ctx.next_id()), args_value.clone());
Some(CompiledNode::BuiltinOperator {
id: Some(ctx.next_id()),
opcode: crate::OpCode::TensorMake,
args: Box::new([body]),
predicate_hint: None,
iter_arg_kind: crate::operators::array::IterArgKind::General,
})
}
#[cfg(feature = "tensor")]
pub(crate) fn is_tensor_wire_body(fields: &[(String, OwnedDataValue)]) -> bool {
if fields.len() != 3 {
return false;
}
let get = |k: &str| fields.iter().find(|(n, _)| n == k).map(|(_, v)| v);
matches!(get("dtype"), Some(OwnedDataValue::String(_)))
&& matches!(get("data"), Some(OwnedDataValue::String(_)))
&& matches!(get("shape"), Some(OwnedDataValue::Array(dims))
if dims.iter().all(|d| matches!(d, OwnedDataValue::Number(_))))
}