use crate::{CompiledNode, Engine, Result};
use crate::arena::{ContextStack, DataValue};
use bumpalo::Bump;
#[inline]
pub(crate) fn evaluate_type<'a>(
args: &'a [CompiledNode],
ctx: &mut ContextStack<'a>,
engine: &Engine,
arena: &'a Bump,
) -> Result<&'a DataValue<'a>> {
if args.is_empty() {
return Ok(crate::arena::singletons::singleton_type_name("null"));
}
let av = engine.dispatch_node(&args[0], ctx, arena)?;
#[cfg(feature = "datetime")]
{
if let DataValue::Object(pairs) = av {
if pairs.iter().any(|(k, _)| *k == "datetime") {
return Ok(crate::arena::singletons::singleton_type_name("datetime"));
}
if pairs.iter().any(|(k, _)| *k == "timestamp") {
return Ok(crate::arena::singletons::singleton_type_name("duration"));
}
}
}
let type_str: &'static str = match av {
DataValue::Null => "null",
DataValue::Bool(_) => "boolean",
DataValue::Number(_) => "number",
DataValue::String(s) => classify_string(s),
DataValue::Array(_) => "array",
DataValue::Object(_) => "object",
#[cfg(feature = "datetime")]
DataValue::DateTime(_) => "datetime",
#[cfg(feature = "datetime")]
DataValue::Duration(_) => "duration",
};
Ok(crate::arena::singletons::singleton_type_name(type_str))
}
#[inline]
fn classify_string(s: &str) -> &'static str {
#[cfg(feature = "datetime")]
{
if s.contains('T') && s.contains(':') && (s.contains('Z') || s.contains('+')) {
return "datetime";
}
if s.chars().any(|c| matches!(c, 'd' | 'h' | 'm' | 's'))
&& s.chars().any(|c| c.is_ascii_digit())
&& !s.contains(' ')
{
return "duration";
}
"string"
}
#[cfg(not(feature = "datetime"))]
{
let _ = s;
"string"
}
}