use byteorder::{ReadBytesExt, WriteBytesExt};
use std::io;
use std::io::{Read, Write};
use base::ErrorCode;
use {Endian, PreliminaryTryFrom, WithFixedPayloadLength};
impl WithFixedPayloadLength for ErrorCode {
const FIXED_PAYLOAD_LENGTH: u16 = u16::FIXED_PAYLOAD_LENGTH;
}
impl PreliminaryTryFrom<u16> for ErrorCode {
type Error = io::Error;
fn try_from(value: u16) -> io::Result<Self> {
match value {
0x0000 => Ok(ErrorCode::Success),
0x0001 => Ok(ErrorCode::Failure),
0x0002 => Ok(ErrorCode::MessageConstructionError),
0x0003 => Ok(ErrorCode::InvalidOptions),
0x0011 => Ok(ErrorCode::OutOfSequence),
0x0012 => Ok(ErrorCode::PayloadTooBig),
0x0020 => Ok(ErrorCode::UnknownMessage),
0x0021 => Ok(ErrorCode::InvalidLength),
0x0100 => Ok(ErrorCode::NonExistingIndex),
0x0101 => Ok(ErrorCode::InvalidCount),
0x0102 => Ok(ErrorCode::UnsupportedType),
0x0103 => Ok(ErrorCode::UnsupportedValue),
0x0104 => Ok(ErrorCode::TypeValueMismatch),
0x0105 => Ok(ErrorCode::InvalidOperation),
0x0106 => Ok(ErrorCode::ExhaustedResources),
0x0107 => Ok(ErrorCode::InvalidState),
0x0108 => Ok(ErrorCode::InsufficientPermission),
0x0109 => Ok(ErrorCode::ProgrammingMistake),
_ => Err(io::Error::new(
io::ErrorKind::InvalidData,
format!("Invalid ErrorCode enum value {}", value),
)),
}
}
}
pub(crate) trait ErrorCodeWriterExt: Write {
fn write_error_code(
&mut self,
error_code: &ErrorCode,
) -> io::Result<()> {
self.write_u16::<Endian>(*error_code as u16)?;
Ok(())
}
}
impl<B: Write + ?Sized> ErrorCodeWriterExt for B {}
pub(crate) trait ErrorCodeReaderExt: Read {
fn read_error_code(&mut self) -> io::Result<ErrorCode> {
let value = self.read_u16::<Endian>()?;
ErrorCode::try_from(value)
}
}
impl<B: Read + ?Sized> ErrorCodeReaderExt for B {}