use crate::types::{ErrorKind, Value};
pub fn mina_fn(args: &[Value]) -> Value {
if args.is_empty() {
return Value::Error(ErrorKind::NA);
}
if let Some(r) = super::stat_helpers::zoned_extreme(args, true) {
return r;
}
let mut result: Option<f64> = None;
let mut skipped_sparkline = false;
let mut saw_date = false;
for arg in args {
match arg {
Value::Sparkline(_) => skipped_sparkline = true,
Value::Number(n) => {
result = Some(result.map_or(*n, |cur: f64| cur.min(*n)));
}
Value::Date(n) => {
saw_date = true;
result = Some(result.map_or(*n, |cur: f64| cur.min(*n)));
}
Value::Bool(b) => {
let n = if *b { 1.0 } else { 0.0 };
result = Some(result.map_or(n, |cur: f64| cur.min(n)));
}
Value::Text(_) => return Value::Error(ErrorKind::Value),
Value::Empty => {}
Value::Array(inner) => {
if inner.is_empty() {
return Value::Error(ErrorKind::Ref);
}
if let Err(e) =
fold_array_min(inner, &mut result, &mut skipped_sparkline, &mut saw_date)
{
return e;
}
}
Value::Error(e) => return Value::Error(e.clone()),
Value::ErrorMsg(e, m) => return Value::ErrorMsg(e.clone(), m.clone()),
Value::Zoned(_) => {}
}
}
match result {
Some(n) if saw_date => Value::Date(n),
Some(n) => Value::Number(n),
None if skipped_sparkline => Value::Number(0.0),
None if super::stat_helpers::is_blank_only_array(args) => Value::Number(0.0),
None => Value::Error(ErrorKind::NA),
}
}
fn fold_array_min(
arr: &[Value],
result: &mut Option<f64>,
skipped_sparkline: &mut bool,
saw_date: &mut bool,
) -> Result<(), Value> {
for v in arr {
let n = match v {
Value::Sparkline(_) => {
*skipped_sparkline = true;
continue;
}
Value::Number(n) => *n,
Value::Date(n) => {
*saw_date = true;
*n
}
Value::Bool(b) => if *b { 1.0 } else { 0.0 },
Value::Text(_) => 0.0,
Value::Empty => continue,
Value::Array(inner) => {
fold_array_min(inner, result, skipped_sparkline, saw_date)?;
continue;
}
Value::Error(e) => return Err(Value::Error(e.clone())),
Value::ErrorMsg(e, m) => return Err(Value::ErrorMsg(e.clone(), m.clone())),
Value::Zoned(_) => continue,
};
*result = Some(result.map_or(n, |cur: f64| cur.min(n)));
}
Ok(())
}
#[cfg(test)]
mod tests;