use crate::eval::evaluate_expr;
use crate::eval::functions::EvalCtx;
use crate::parser::ast::Expr;
use crate::types::{ErrorKind, Value};
pub fn count_fn(args: &[Value]) -> Value {
let n = args.iter().filter(|v| matches!(v, Value::Number(_))).count();
Value::Number(n as f64)
}
pub fn counta_fn(args: &[Value]) -> Value {
let n = args.iter().filter(|v| !matches!(v, Value::Empty)).count();
Value::Number(n as f64)
}
pub fn count_lazy_fn(args: &[Expr], ctx: &mut EvalCtx<'_>) -> Value {
if args.is_empty() {
return Value::Error(ErrorKind::NA);
}
let mut n = 0usize;
for arg in args {
match evaluate_expr(arg, ctx) {
Value::Number(_) => n += 1,
Value::Bool(_) => n += 1,
Value::Text(s) if s.parse::<f64>().is_ok() => n += 1,
_ => {}
}
}
Value::Number(n as f64)
}
pub fn counta_lazy_fn(args: &[Expr], ctx: &mut EvalCtx<'_>) -> Value {
if args.is_empty() {
return Value::Error(ErrorKind::NA);
}
let mut n = 0usize;
for arg in args {
if !matches!(evaluate_expr(arg, ctx), Value::Empty) {
n += 1;
}
}
Value::Number(n as f64)
}
#[cfg(test)]
mod tests;