use super::DataValue;
#[inline]
pub(crate) fn coerce_to_number_cfg(v: &DataValue<'_>, engine: &crate::Engine) -> Option<f64> {
match v {
DataValue::Number(n) => Some(n.as_f64()),
DataValue::String(s) => {
if s.is_empty() && engine.config().numeric_coercion.empty_string_to_zero {
Some(0.0)
} else {
s.parse().ok()
}
}
DataValue::Bool(b) if engine.config().numeric_coercion.bool_to_number => {
Some(if *b { 1.0 } else { 0.0 })
}
DataValue::Null if engine.config().numeric_coercion.null_to_zero => Some(0.0),
_ => None,
}
}
#[inline]
pub(crate) fn try_coerce_to_integer_cfg(v: &DataValue<'_>, engine: &crate::Engine) -> Option<i64> {
match v {
DataValue::Number(n) => n.as_i64(),
DataValue::String(s) => {
if s.is_empty() && engine.config().numeric_coercion.empty_string_to_zero {
Some(0)
} else {
s.parse().ok()
}
}
DataValue::Bool(b) if engine.config().numeric_coercion.bool_to_number => {
Some(if *b { 1 } else { 0 })
}
DataValue::Null if engine.config().numeric_coercion.null_to_zero => Some(0),
_ => None,
}
}
#[cfg(feature = "datetime")]
pub(crate) fn coerce_to_number(v: &DataValue<'_>) -> Option<f64> {
match v {
DataValue::Number(n) => Some(n.as_f64()),
DataValue::Bool(true) => Some(1.0),
DataValue::Bool(false) => Some(0.0),
DataValue::Null => Some(0.0),
DataValue::String(s) => {
let t = s.trim();
if t.is_empty() {
Some(0.0)
} else {
t.parse().ok()
}
}
DataValue::Array(items) => match items.len() {
0 => Some(0.0),
1 => coerce_to_number(&items[0]),
_ => None,
},
DataValue::Object(_) => None,
#[cfg(feature = "datetime")]
DataValue::DateTime(_) | DataValue::Duration(_) => None,
}
}