use std::io;
use try_from::TryFrom;
use {
DataType, DataValue, HasDataType, HasStorageType,
IsModuleChannelReference, IsParameterMask, ModuleChannelReference,
StorageType,
};
#[derive(Clone, Debug, PartialEq)]
pub enum ParameterValue<M: IsParameterMask, R: IsModuleChannelReference> {
Boolean(bool),
Int8(i8),
Int16(i16),
Int32(i32),
Int64(i64),
UInt8(u8),
UInt16(u16),
UInt32(u32),
UInt64(u64),
ParameterMask(M),
BooleanChannel(R),
Int8Channel(R),
Int16Channel(R),
Int32Channel(R),
Int64Channel(R),
UInt8Channel(R),
UInt16Channel(R),
UInt32Channel(R),
UInt64Channel(R),
ParameterMaskChannel(R),
}
impl TryFrom<(u8, u64)> for ParameterValueRaw {
type Err = io::Error;
fn try_from(value: (u8, u64)) -> io::Result<Self> {
let (tag, data) = value;
match tag {
0x00 => Ok(ParameterValue::Boolean(data > 0u64)),
0x01 => Ok(ParameterValue::Int8(data as i8)),
0x02 => Ok(ParameterValue::Int16(data as i16)),
0x03 => Ok(ParameterValue::Int32(data as i32)),
0x04 => Ok(ParameterValue::Int64(data as i64)),
0x05 => Ok(ParameterValue::UInt8(data as u8)),
0x06 => Ok(ParameterValue::UInt16(data as u16)),
0x07 => Ok(ParameterValue::UInt32(data as u32)),
0x08 => Ok(ParameterValue::UInt64(data as u64)),
0x09 => Ok(ParameterValue::ParameterMask(data as u64)),
0x10 => Ok(ParameterValue::BooleanChannel(data.into())),
0x11 => Ok(ParameterValue::Int8Channel(data.into())),
0x12 => Ok(ParameterValue::Int16Channel(data.into())),
0x13 => Ok(ParameterValue::Int32Channel(data.into())),
0x14 => Ok(ParameterValue::Int64Channel(data.into())),
0x15 => Ok(ParameterValue::UInt8Channel(data.into())),
0x16 => Ok(ParameterValue::UInt16Channel(data.into())),
0x17 => Ok(ParameterValue::UInt32Channel(data.into())),
0x18 => Ok(ParameterValue::UInt64Channel(data.into())),
0x19 => Ok(ParameterValue::ParameterMaskChannel(data.into())),
_ => Err(io::Error::new(
io::ErrorKind::InvalidData,
format!("Invalid ParameterValue enum tag {}", tag),
)),
}
}
}
impl<M: IsParameterMask, R: IsModuleChannelReference> From<DataValue<M>>
for ParameterValue<M, R>
{
fn from(v: DataValue<M>) -> ParameterValue<M, R> {
use ParameterValue::*;
match v {
DataValue::Boolean(v) => Boolean(v),
DataValue::Int8(v) => Int8(v),
DataValue::Int16(v) => Int16(v),
DataValue::Int32(v) => Int32(v),
DataValue::Int64(v) => Int64(v),
DataValue::UInt8(v) => UInt8(v),
DataValue::UInt16(v) => UInt16(v),
DataValue::UInt32(v) => UInt32(v),
DataValue::UInt64(v) => UInt64(v),
DataValue::ParameterMask(v) => ParameterMask(v),
}
}
}
pub type ParameterValueRaw = ParameterValue<u64, ModuleChannelReference>;
impl<M: IsParameterMask, R: IsModuleChannelReference> HasDataType
for ParameterValue<M, R>
{
fn data_type(&self) -> DataType {
use ParameterValue::*;
match *self {
Boolean(_) | BooleanChannel(_) => DataType::Boolean,
Int8(_) | Int8Channel(_) => DataType::Int8,
Int16(_) | Int16Channel(_) => DataType::Int16,
Int32(_) | Int32Channel(_) => DataType::Int32,
Int64(_) | Int64Channel(_) => DataType::Int64,
UInt8(_) | UInt8Channel(_) => DataType::UInt8,
UInt16(_) | UInt16Channel(_) => DataType::UInt16,
UInt32(_) | UInt32Channel(_) => DataType::UInt32,
UInt64(_) | UInt64Channel(_) => DataType::UInt64,
ParameterMask(_) | ParameterMaskChannel(_) => {
DataType::ParameterMask
}
}
}
}
impl<M: IsParameterMask, R: IsModuleChannelReference> HasStorageType
for ParameterValue<M, R>
{
fn storage_type(&self) -> StorageType {
use ParameterValue::*;
use StorageType::*;
match *self {
Boolean(_) | Int8(_) | Int16(_) | Int32(_) | Int64(_)
| UInt8(_) | UInt16(_) | UInt32(_) | UInt64(_)
| ParameterMask(_) => Fixed,
BooleanChannel(_)
| Int8Channel(_)
| Int16Channel(_)
| Int32Channel(_)
| Int64Channel(_)
| UInt8Channel(_)
| UInt16Channel(_)
| UInt32Channel(_)
| UInt64Channel(_)
| ParameterMaskChannel(_) => Channel,
}
}
}
impl<M: IsParameterMask, R: IsModuleChannelReference> From<bool>
for ParameterValue<M, R>
{
fn from(v: bool) -> ParameterValue<M, R> {
ParameterValue::Boolean(v)
}
}
impl<M: IsParameterMask, R: IsModuleChannelReference> From<i8>
for ParameterValue<M, R>
{
fn from(v: i8) -> ParameterValue<M, R> {
ParameterValue::Int8(v)
}
}
impl<M: IsParameterMask, R: IsModuleChannelReference> From<i16>
for ParameterValue<M, R>
{
fn from(v: i16) -> ParameterValue<M, R> {
ParameterValue::Int16(v)
}
}
impl<M: IsParameterMask, R: IsModuleChannelReference> From<i32>
for ParameterValue<M, R>
{
fn from(v: i32) -> ParameterValue<M, R> {
ParameterValue::Int32(v)
}
}
impl<M: IsParameterMask, R: IsModuleChannelReference> From<i64>
for ParameterValue<M, R>
{
fn from(v: i64) -> ParameterValue<M, R> {
ParameterValue::Int64(v)
}
}
impl<M: IsParameterMask, R: IsModuleChannelReference> From<u8>
for ParameterValue<M, R>
{
fn from(v: u8) -> ParameterValue<M, R> {
ParameterValue::UInt8(v)
}
}
impl<M: IsParameterMask, R: IsModuleChannelReference> From<u16>
for ParameterValue<M, R>
{
fn from(v: u16) -> ParameterValue<M, R> {
ParameterValue::UInt16(v)
}
}
impl<M: IsParameterMask, R: IsModuleChannelReference> From<u32>
for ParameterValue<M, R>
{
fn from(v: u32) -> ParameterValue<M, R> {
ParameterValue::UInt32(v)
}
}
impl<M: IsParameterMask, R: IsModuleChannelReference> From<u64>
for ParameterValue<M, R>
{
fn from(v: u64) -> ParameterValue<M, R> {
ParameterValue::UInt64(v)
}
}