use crate::{DataType, GetParameterValue, SetParameterValue};
pub fn encode_parameter_value<V>(data_type: u32, value: &V) -> Vec<u8>
where
V: SetParameterValue,
{
let Ok(dtype) = DataType::try_from(data_type as i32) else {
return Vec::new();
};
match dtype {
DataType::Bool => value.to_bytes_as_bool(),
DataType::Int8 => value.to_bytes_as_i8(),
DataType::Uint8 => value.to_bytes_as_u8(),
DataType::Int16 => value.to_bytes_as_i16(),
DataType::Uint16 => value.to_bytes_as_u16(),
DataType::Int32 => value.to_bytes_as_i32(),
DataType::Uint32 => value.to_bytes_as_u32(),
DataType::Int64 => value.to_bytes_as_i64(),
DataType::Uint64 => value.to_bytes_as_u64(),
DataType::Float => value.to_bytes_as_f32(),
DataType::Double => value.to_bytes_as_f64(),
DataType::String => value.to_bytes_as_string(),
_ => Vec::new(),
}
}
pub fn decode_parameter_value<V>(data_type: u32, bytes: &[u8]) -> V
where
V: GetParameterValue + Default,
{
let Ok(dtype) = DataType::try_from(data_type as i32) else {
return V::default();
};
match dtype {
DataType::Bool => {
return V::from_bytes_as_bool(bytes).unwrap();
}
DataType::Int8 => {
return V::from_bytes_as_i8(bytes).unwrap();
}
DataType::Uint8 => {
return V::from_bytes_as_u8(bytes).unwrap();
}
DataType::Int16 => {
return V::from_bytes_as_i16(bytes).unwrap();
}
DataType::Uint16 => {
return V::from_bytes_as_u16(bytes).unwrap();
}
DataType::Int32 => {
return V::from_bytes_as_i32(bytes).unwrap();
}
DataType::Uint32 => {
return V::from_bytes_as_u32(bytes).unwrap();
}
DataType::Int64 => {
return V::from_bytes_as_i64(bytes).unwrap();
}
DataType::Uint64 => {
return V::from_bytes_as_u64(bytes).unwrap();
}
DataType::Float => {
return V::from_bytes_as_f32(bytes).unwrap();
}
DataType::Double => {
return V::from_bytes_as_f64(bytes).unwrap();
}
DataType::String => {
return V::from_bytes_as_string(bytes).unwrap();
}
_ => {}
}
V::default()
}
#[cfg(test)]
mod tests {
use super::*;
const UNSUPPORTED: &[DataType] = &[
DataType::Undefined,
DataType::Char,
DataType::Bytes,
DataType::UserType,
];
#[test]
fn encode_unsupported_dtypes_return_empty_vec() {
for &dtype in UNSUPPORTED {
let bytes = encode_parameter_value(dtype as u32, &42i32);
assert!(bytes.is_empty(), "{dtype:?} must fall through to empty");
}
}
#[test]
fn decode_unsupported_dtypes_return_default() {
for &dtype in UNSUPPORTED {
let value: i32 = decode_parameter_value(dtype as u32, &[]);
assert_eq!(value, 0, "{dtype:?} must fall through to Default");
}
}
#[test]
fn encode_out_of_range_dtype_does_not_panic() {
let bytes = encode_parameter_value(u32::MAX, &42i32);
assert!(bytes.is_empty());
}
#[test]
fn decode_out_of_range_dtype_returns_default() {
let value: i32 = decode_parameter_value(u32::MAX, &[]);
assert_eq!(value, 0);
}
}