xio_common 0.12.0

XIO commonly used functionality
Documentation
use crate::base::{DataType, DataValue, DataValueRaw, HasDataType};
use crate::{
    error, DataTypeReaderExt, DataTypeWriterExt, Endian, ReadExt, Result,
    TryInto, WithFixedPayloadLength, WriteExt,
};
use snafu::ResultExt;
use std::io::{Read, Write};

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

pub(crate) trait DataValueWriterExt: Write {
    fn write_data_value(&mut self, r: &DataValueRaw) -> Result<()> {
        let v = vec![r.clone()];
        self.write_data_values(&v)
    }

    fn write_data_values(
        &mut self,
        values: &[DataValueRaw],
    ) -> Result<()> {
        for value in values {
            self.write_data_type(value.data_type())?;
        }
        for value in values {
            match *value {
                DataValue::Boolean(ref v) => {
                    self.write_u64::<Endian>(*v as u64)
                }
                DataValue::Int8(ref v) => {
                    self.write_u64::<Endian>(*v as u64)
                }
                DataValue::Int16(ref v) => {
                    self.write_u64::<Endian>(*v as u64)
                }
                DataValue::Int32(ref v) => {
                    self.write_u64::<Endian>(*v as u64)
                }
                DataValue::Int64(ref v) => self.write_i64::<Endian>(*v),
                DataValue::UInt8(ref v) => {
                    self.write_u64::<Endian>(u64::from(*v))
                }
                DataValue::UInt16(ref v) => {
                    self.write_u64::<Endian>(u64::from(*v))
                }
                DataValue::UInt32(ref v) => {
                    self.write_u64::<Endian>(u64::from(*v))
                }
                DataValue::UInt64(ref v) => self.write_u64::<Endian>(*v),
                DataValue::ParameterMask(ref v) => {
                    self.write_u64::<Endian>(*v)
                }
            }?;
        }
        Ok(())
    }
}

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

pub(crate) trait DataValueReaderExt: Read {
    fn read_data_value(&mut self) -> Result<DataValueRaw> {
        Ok(self.read_data_values(1usize)?.into_iter().next().unwrap())
    }

    fn read_data_values(
        &mut self,
        count: usize,
    ) -> Result<Vec<DataValueRaw>> {
        let tags = self.read_data_types(count)?;

        tags.into_iter()
            .map(|tag| {
                let value = self.read_u64::<Endian>()?;
                Ok((tag, value).try_into().context(error::Io)?)
            })
            .collect::<Result<Vec<DataValueRaw>>>()
    }
}

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