use energyml_core::value::{FieldValue, Reflect, Scalar};
use energyml_domain::values;
use crate::error::{Error, Result};
use crate::source::ValueSource;
pub fn read_doubles(array: &dyn Reflect, source: &dyn ValueSource, at: &str) -> Result<Vec<f64>> {
let values = values::read(array, source, at)?;
values.to_f64().ok_or_else(|| {
Error::malformed(
at,
format!("`{}` holds text, not numbers", array.type_info().name),
)
})
}
pub fn read_integers(array: &dyn Reflect, source: &dyn ValueSource, at: &str) -> Result<Vec<i64>> {
match values::read(array, source, at)? {
values::Values::Integer(v) => Ok(v),
other => other
.to_f64()
.map(|v| v.into_iter().map(|x| x as i64).collect())
.ok_or_else(|| {
Error::malformed(
at,
format!("`{}` holds text, not numbers", array.type_info().name),
)
}),
}
}
pub fn read_flags(array: &dyn Reflect, source: &dyn ValueSource, at: &str) -> Result<Vec<bool>> {
match values::read(array, source, at)? {
values::Values::Boolean(flags) => Ok(flags),
other => Ok(other
.to_f64()
.map(|v| v.into_iter().map(|x| x != 0.0).collect())
.unwrap_or_default()),
}
}
pub fn count(array: &dyn Reflect, source: &dyn ValueSource, at: &str) -> Result<usize> {
Ok(values::count(array, source, at)?)
}
pub(crate) fn scalar_f64(object: &dyn Reflect, field: &str) -> Option<f64> {
match object.field(field)? {
FieldValue::Scalar(Scalar::Double(v)) => Some(v),
FieldValue::Scalar(Scalar::Int(v)) => Some(v as f64),
FieldValue::Scalar(Scalar::UInt(v)) => Some(v as f64),
_ => None,
}
}
pub(crate) fn scalar_i64(object: &dyn Reflect, field: &str) -> Option<i64> {
match object.field(field)? {
FieldValue::Scalar(Scalar::Int(v)) => Some(v),
FieldValue::Scalar(Scalar::UInt(v)) => i64::try_from(v).ok(),
FieldValue::Scalar(Scalar::Double(v)) => Some(v as i64),
_ => None,
}
}