xio_common 0.5.0

XIO commonly used functionality
Documentation
use byteorder::{ReadBytesExt, WriteBytesExt};
use std::io;
use std::io::{Read, Write};
use base::{DataValue,DataValueRaw};
use {Endian, PreliminaryTryFrom,
     PreliminaryTryInto, WithFixedPayloadLength};

impl WithFixedPayloadLength for DataValueRaw {
    const FIXED_PAYLOAD_LENGTH: u16 =
        u8::FIXED_PAYLOAD_LENGTH + u64::FIXED_PAYLOAD_LENGTH;
}

impl PreliminaryTryFrom<(u8, u64)> for DataValueRaw {
    type Error = io::Error;
    fn try_from(value: (u8, u64)) -> io::Result<Self> {
        let (tag, data) = value;
        match tag {
            0 => Ok(DataValue::Boolean(data > 0u64)),
            1 => Ok(DataValue::Int8(data as i8)),
            2 => Ok(DataValue::Int16(data as i16)),
            3 => Ok(DataValue::Int32(data as i32)),
            4 => Ok(DataValue::Int64(data as i64)),
            5 => Ok(DataValue::UInt8(data as u8)),
            6 => Ok(DataValue::UInt16(data as u16)),
            7 => Ok(DataValue::UInt32(data as u32)),
            8 => Ok(DataValue::UInt64(data as u64)),
            9 => Ok(DataValue::ParameterMask(data as u64)),
            _ => Err(io::Error::new(
                io::ErrorKind::InvalidData,
                format!("Invalid DataValue enum tag {}", tag),
            )),
        }
    }
}

pub(crate) trait DataValueWriterExt: Write {
    fn write_data_value(&mut self, r: &DataValueRaw) -> io::Result<()> {
        match *r {
            DataValue::Boolean(v) => {
                self.write_u8(0u8)?;
                self.write_u64::<Endian>(v as u64)?;
            }
            DataValue::Int8(v) => {
                self.write_u8(1u8)?;
                self.write_u64::<Endian>(v as u64)?;
            }
            DataValue::Int16(v) => {
                self.write_u8(2u8)?;
                self.write_u64::<Endian>(v as u64)?;
            }
            DataValue::Int32(v) => {
                self.write_u8(3u8)?;
                self.write_u64::<Endian>(v as u64)?;
            }
            DataValue::Int64(v) => {
                self.write_u8(4u8)?;
                self.write_i64::<Endian>(v)?;
            }
            DataValue::UInt8(v) => {
                self.write_u8(5u8)?;
                self.write_u64::<Endian>(u64::from(v))?;
            }
            DataValue::UInt16(v) => {
                self.write_u8(6u8)?;
                self.write_u64::<Endian>(u64::from(v))?;
            }
            DataValue::UInt32(v) => {
                self.write_u8(7u8)?;
                self.write_u64::<Endian>(u64::from(v))?;
            }
            DataValue::UInt64(v) => {
                self.write_u8(8u8)?;
                self.write_u64::<Endian>(v)?;
            }
            DataValue::ParameterMask(v) => {
                self.write_u8(9u8)?;
                self.write_u64::<Endian>(v)?;
            }
        }
        Ok(())
    }
}

impl<B: Write + ?Sized> DataValueWriterExt for B {}

pub(crate) trait DataValueReaderExt: Read {
    fn read_data_value(&mut self) -> io::Result<DataValueRaw> {
        let tag = self.read_u8()?;
        let value = self.read_u64::<Endian>()?;
        Ok((tag, value).try_into()?)
    }
}

impl<B: Read + ?Sized> DataValueReaderExt for B {}