use serde_json::Value;
use super::{logic, Data, Expression};
pub fn compute(args: &[Expression], data: &Data) -> Value {
let a = match args.get(0).map(|arg| arg.compute(data)) {
Some(val) => logic::coerce_to_str(&val),
None => String::from("undefined"),
};
let b = args
.get(1)
.map(|arg| arg.compute(data))
.and_then(|val| logic::coerce_to_f64(&val))
.map(|f| f as i64)
.unwrap_or(0);
let c = args
.get(2)
.map(|arg| arg.compute(data))
.and_then(|val| logic::coerce_to_f64(&val))
.map(|f| f as i64);
let len = a.len() as i64;
let start = if b >= 0 {
b
} else {
std::cmp::max(len + b, 0)
};
let iter = a.chars().skip(start as usize);
let s = match c {
Some(c) => {
let limit = if c >= 0 {
c
} else {
let len_after_start = len - start;
std::cmp::max(len_after_start - c.abs(), 0)
};
iter.take(limit as usize).collect()
}
None => iter.collect(),
};
Value::String(s)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::compute_const;
use serde_json::json;
#[test]
fn basic() {
assert_eq!(compute_const!(), json!("undefined"));
assert_eq!(compute_const!(json!(true)), json!("true"));
assert_eq!(compute_const!(json!("jsonlogic")), json!("jsonlogic"));
assert_eq!(
compute_const!(json!("jsonlogic"), json!(0)),
json!("jsonlogic")
);
assert_eq!(compute_const!(json!("jsonlogic"), json!(4)), json!("logic"));
assert_eq!(
compute_const!(json!("jsonlogic"), json!(-5)),
json!("logic")
);
assert_eq!(
compute_const!(json!("jsonlogic"), json!(-50)),
json!("jsonlogic")
);
assert_eq!(compute_const!(json!("y̆"), json!(0), json!(1)), json!("y"));
assert_eq!(
compute_const!(json!("hallo"), json!(2), json!(2)),
json!("ll")
);
assert_eq!(compute_const!(json!("äüö"), json!(1), json!(1)), json!("ü"));
assert_eq!(
compute_const!(json!("jsonlogic"), json!(4), json!(-2)),
json!("log")
);
assert_eq!(
compute_const!(json!("jsonlogic"), json!(4), json!(-3)),
json!("lo")
);
assert_eq!(
compute_const!(json!("jsonlogic"), json!(4), json!(-4)),
json!("l")
);
assert_eq!(
compute_const!(json!("jsonlogic"), json!(4), json!(-5)),
json!("")
);
assert_eq!(
compute_const!(json!("jsonlogic"), json!(4), json!(-6)),
json!("")
);
assert_eq!(
compute_const!(json!("jsonlogic"), json!(3), json!(-2)),
json!("nlog")
);
assert_eq!(
compute_const!(json!("jsonlogic"), json!(4), json!(-20)),
json!("")
);
}
}