use regex::Regex;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
const RE_INT_VALUE: &str = r"^-?[0-9]+$";
const RE_FLOAT_VALUE: &str = r"^-?[0-9]+\.[0-9]+$";
use crate::proto::mavlink_messages_v1 as proto;
use crate::protocol::errors::{ParseError, ProtoImportError};
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum Value {
IntValue(i128),
FloatValue(f64),
MaxValue,
}
impl Value {
pub fn to_proto(&self) -> proto::Value {
proto::Value {
value: Some(match self {
Value::IntValue(val) => proto::value::Value::IntValue(*val as i64),
Value::FloatValue(val) => {
proto::value::Value::FloatValue(proto::value::FloatValue {
value: Some(if val.is_nan() {
proto::value::float_value::Value::Nan(proto::value::NaN {})
} else {
proto::value::float_value::Value::Data(*val)
}),
})
}
Value::MaxValue => proto::value::Value::MaxValue(proto::value::Max {}),
}),
}
}
pub fn from_proto(proto: proto::Value) -> Result<Self, ProtoImportError> {
Ok(match proto.value {
None => return Err(ProtoImportError::ValueValueIsNone),
Some(value) => match value {
proto::value::Value::IntValue(val) => Value::IntValue(val as i128),
proto::value::Value::FloatValue(val) => match val.value {
None => return Err(ProtoImportError::ValueFloatValueIsNone),
Some(fvalue) => match fvalue {
proto::value::float_value::Value::Nan(_) => Value::FloatValue(f64::NAN),
proto::value::float_value::Value::Data(val) => Value::FloatValue(val),
},
},
proto::value::Value::MaxValue(_) => Value::MaxValue,
},
})
}
pub fn parse(str: &str) -> Result<Self, ParseError> {
let re_int = Regex::new(RE_INT_VALUE).unwrap();
let re_float = Regex::new(RE_FLOAT_VALUE).unwrap();
Ok(match str {
"NaN" => Self::FloatValue(f64::NAN),
"NAN" => Self::FloatValue(f64::NAN),
val if re_int.is_match(str) => {
Self::IntValue(val.parse::<i128>().map_err(ParseError::ValueIntError)?)
}
val if re_float.is_match(str) => {
Self::FloatValue(val.parse::<f64>().map_err(ParseError::ValueFloatError)?)
}
&_ => return Err(ParseError::InvalidValue(str.to_string())),
})
}
}