use std::{error, fmt, io};
use base64::DecodeError as Base64DecodeError;
use prost::DecodeError as ProstDecodeError;
use crate::BitBrokerMessage;
#[derive(Debug)]
pub enum Error {
Io(io::Error),
DecodeError(Base64DecodeError),
UnexpectedOperation((u8, u8)),
BrokerError(&'static str),
ProstError(ProstDecodeError),
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Io(err) => write!(f, "IO error: {err}"),
Self::DecodeError(err) => write!(f, "Decode error: {err}"),
Self::UnexpectedOperation((opcode, operand)) => {
write!(f, "Unexpected operation '{opcode:0X}|{operand:0X}")
}
Self::BrokerError(msg) => write!(f, "Broker error: {msg}"),
Self::ProstError(err) => write!(f, "Proto decode error: {err}"),
}
}
}
impl error::Error for Error {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match self {
Self::Io(err) => err.source(),
Self::DecodeError(err) => err.source(),
_ => None,
}
}
}
impl From<io::Error> for Error {
fn from(value: io::Error) -> Self {
Self::Io(value)
}
}
impl From<Base64DecodeError> for Error {
fn from(value: Base64DecodeError) -> Self {
Self::DecodeError(value)
}
}
impl From<ProstDecodeError> for Error {
fn from(value: ProstDecodeError) -> Self {
Self::ProstError(value)
}
}
impl From<BitBrokerMessage> for Error {
fn from(value: BitBrokerMessage) -> Self {
let (opcode, operand) = value.codes();
Self::UnexpectedOperation((*opcode, *operand))
}
}