use crate::{FoxError, FoxVariables};
use crate::fox_variables::VariableSpec;
pub struct PvPower;
impl VariableSpec for PvPower {
type Value = f64;
const VARIABLE: FoxVariables = FoxVariables::PvPower;
fn into(raw: f64) -> Result<Self::Value, FoxError> {
Ok(raw)
}
}
pub struct LoadsPower;
impl VariableSpec for LoadsPower {
type Value = f64;
const VARIABLE: FoxVariables = FoxVariables::LoadsPower;
fn into(raw: f64) -> Result<Self::Value, FoxError> {
Ok(raw)
}
}
pub struct SoC;
impl VariableSpec for SoC {
type Value = u8;
const VARIABLE: FoxVariables = FoxVariables::SoC;
fn into(raw: f64) -> Result<Self::Value, FoxError> {
try_f64_to_u8_percentage(raw).map_err(|e| FoxError::VariableConversionError {
variable: Self::VARIABLE.as_str(),
value: raw.to_string(),
error: e.to_string(),
})
}
}
pub struct SoH;
impl VariableSpec for SoH {
type Value = u8;
const VARIABLE: FoxVariables = FoxVariables::SOH;
fn into(raw: f64) -> Result<Self::Value, FoxError> {
try_f64_to_u8_percentage(raw).map_err(|e| FoxError::VariableConversionError {
variable: Self::VARIABLE.as_str(),
value: raw.to_string(),
error: e.to_string(),
})
}
}
pub struct BatTemperature;
impl VariableSpec for BatTemperature {
type Value = f64;
const VARIABLE: FoxVariables = FoxVariables::BatTemperature;
fn into(raw: f64) -> Result<Self::Value, FoxError> {
Ok(raw)
}
}
pub struct RunningState;
impl VariableSpec for RunningState {
type Value = i64;
const VARIABLE: FoxVariables = FoxVariables::RunningState;
fn into(raw: f64) -> Result<Self::Value, FoxError> {
try_f64_to_i64(raw).map_err(|e| FoxError::VariableConversionError {
variable: Self::VARIABLE.as_str(),
value: raw.to_string(),
error: e.to_string(),
})
}
}
fn try_f64_to_u8_percentage(x: f64) -> Result<u8, &'static str> {
if !x.is_finite() {
return Err("value is NaN or infinite");
}
let y = x.round();
if !(0.0..=100.0).contains(&y) {
return Err("value out of range for u8 percentage after rounding");
}
Ok(y as u8)
}
fn try_f64_to_i64(x: f64) -> Result<i64, &'static str> {
if !x.is_finite() {
return Err("value is NaN or infinite");
}
let y = x.round();
Ok(y as i64)
}