use crate::ParamVal;
use core::convert::TryFrom;
use core::convert::TryInto;
#[derive(Debug, PartialEq)]
pub enum TryIntoParamValError {
UnexpectedType,
}
impl TryFrom<ParamVal> for bool {
type Error = TryIntoParamValError;
fn try_from(param_val: ParamVal) -> Result<Self, Self::Error> {
if let ParamVal::Bool(b) = param_val {
Ok(b)
} else {
Err(TryIntoParamValError::UnexpectedType)
}
}
}
impl TryFrom<ParamVal> for f64 {
type Error = TryIntoParamValError;
fn try_from(param_val: ParamVal) -> Result<Self, Self::Error> {
if let ParamVal::Float(f) = param_val {
Ok(f)
} else {
Err(TryIntoParamValError::UnexpectedType)
}
}
}
impl TryFrom<ParamVal> for i64 {
type Error = TryIntoParamValError;
fn try_from(param_val: ParamVal) -> Result<Self, Self::Error> {
if let ParamVal::Int(i) = param_val {
Ok(i)
} else {
Err(TryIntoParamValError::UnexpectedType)
}
}
}
impl TryFrom<ParamVal> for String {
type Error = TryIntoParamValError;
fn try_from(param_val: ParamVal) -> Result<Self, Self::Error> {
if let ParamVal::Str(s) = param_val {
Ok(s)
} else {
Err(TryIntoParamValError::UnexpectedType)
}
}
}
impl<T> TryFrom<ParamVal> for Vec<T>
where
T: TryFrom<ParamVal, Error = TryIntoParamValError>,
{
type Error = TryIntoParamValError;
fn try_from(value: ParamVal) -> Result<Self, Self::Error> {
if let ParamVal::Array(array) = value {
array
.into_iter()
.map(|sub_val| sub_val.try_into())
.collect()
} else {
Err(Self::Error::UnexpectedType)
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use core::convert::TryInto;
#[test]
fn array_conversion() {
let left =
ParamVal::Array(vec![ParamVal::Int(1), ParamVal::Int(2), ParamVal::Int(3)]).try_into();
let right = Ok(vec![1, 2, 3]);
assert_eq!(left, right);
}
#[test]
fn bool_conversion() {
let left = ParamVal::Bool(true).try_into();
let right = Ok(true);
assert_eq!(left, right)
}
#[test]
fn float_conversion() {
let left: Result<f64, _> = ParamVal::Float(1.0).try_into();
let right: Result<f64, _> = Ok(1.0);
assert_eq!(left, right)
}
#[test]
fn int_conversion() {
let left: Result<i64, _> = ParamVal::Int(-1).try_into();
let right: Result<i64, _> = Ok(-1);
assert_eq!(left, right)
}
#[test]
fn str_conversion() {
let left: Result<String, _> = ParamVal::Str("hello".into()).try_into();
let right: Result<String, _> = Ok("hello".into());
assert_eq!(left, right)
}
}