use hamelin_lib::func::defs::{
UnaryMinus, UnaryPlus, UnaryRangePostfix, UnaryRangePrefix, UnaryRangePrefixInclusive,
};
use crate::registry::EvalRegistry;
use crate::value::{DecimalValue, RangeValue, Value};
pub fn register(registry: &mut EvalRegistry) {
registry.register_eval::<UnaryMinus>(|mut bindings| {
let x = bindings.take()?;
match x {
Value::Int(i) => i
.checked_neg()
.map(Value::Int)
.ok_or_else(|| anyhow::anyhow!("integer overflow: cannot negate {}", i)),
Value::Double(d) => Ok(Value::Double(-d)),
Value::Rows(r) => r
.checked_neg()
.map(Value::Rows)
.ok_or_else(|| anyhow::anyhow!("integer overflow: cannot negate {} rows", r)),
Value::Decimal(d) => d
.unscaled
.checked_neg()
.map(|unscaled| Value::Decimal(DecimalValue::new(unscaled, d.scale)))
.ok_or_else(|| anyhow::anyhow!("decimal overflow: cannot negate {:?}", d)),
Value::Interval(i) => i
.checked_mul(-1)
.map(Value::Interval)
.ok_or_else(|| anyhow::anyhow!("interval overflow: cannot negate {:?}", i)),
Value::CalendarInterval(months) => months
.checked_neg()
.map(Value::CalendarInterval)
.ok_or_else(|| {
anyhow::anyhow!(
"calendar interval overflow: cannot negate {} months",
months
)
}),
Value::Null => Ok(Value::Null),
_ => anyhow::bail!("UnaryMinus not supported for {:?}", x),
}
});
registry.register_eval::<UnaryPlus>(|mut bindings| {
let x = bindings.take()?;
match x {
Value::Int(_)
| Value::Double(_)
| Value::Rows(_)
| Value::Decimal(_)
| Value::Interval(_)
| Value::CalendarInterval(_)
| Value::Null => Ok(x),
_ => anyhow::bail!("UnaryPlus not supported for {:?}", x),
}
});
registry.register_eval::<UnaryRangePrefix>(|mut bindings| {
let x = bindings.take()?;
Ok(Value::Range(Box::new(RangeValue {
lower: None,
upper: Some(x),
})))
});
registry.register_eval::<UnaryRangePostfix>(|mut bindings| {
let x = bindings.take()?;
Ok(Value::Range(Box::new(RangeValue {
lower: Some(x),
upper: None,
})))
});
registry.register_eval::<UnaryRangePrefixInclusive>(|mut bindings| {
let x = bindings.take()?;
Ok(Value::Range(Box::new(RangeValue {
lower: None,
upper: Some(x),
})))
});
}