use core::convert::Infallible;
use core::fmt::Debug;
use tokio::sync::mpsc::error::SendError;
use tokio::sync::oneshot::error::RecvError;
pub use self::decode::Decode;
pub use self::status::Status;
pub use self::value_error::ValueError;
use crate::frame::parameters::configuration::version;
use crate::frame::parameters::utilities::invalid_command;
use crate::parameters::utilities;
use crate::{Parameters, Response, ember, ezsp};
mod decode;
mod status;
mod value_error;
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error(transparent)]
Io(#[from] std::io::Error),
#[error(transparent)]
Decode(#[from] Decode),
#[error(transparent)]
Status(#[from] Status),
#[error("Unexpected response: {0:?}")]
UnexpectedResponse(Box<Parameters>),
#[error(transparent)]
ValueError(#[from] ValueError),
#[error("Invalid command: {0}")]
InvalidCommand(invalid_command::Response),
#[error(
"Protocol negotiation failed: {desired:#04X} (desired) != {negotiated_version:#04X} (negotiated)",
negotiated_version = .negotiated.protocol_version()
)]
ProtocolVersionMismatch {
desired: u8,
negotiated: version::Response,
},
#[error("No matching source endpoint found: {0}")]
NoMatchingSourceEndpoint(u16),
#[error("Receive error: {0}")]
RecvError(#[from] RecvError),
#[error("Send error")]
SendError,
#[error("NCP is not configured")]
NotConfigured,
#[error("Response channel is closed")]
ChannelClosed,
#[error("Transaction queue is full.")]
TransactionQueueFull,
#[error("No endpoints provided.")]
NoEndpoints,
}
impl From<Result<ezsp::Status, u8>> for Error {
fn from(status: Result<ezsp::Status, u8>) -> Self {
Self::Status(status.into())
}
}
impl From<Result<ember::Status, u8>> for Error {
fn from(status: Result<ember::Status, u8>) -> Self {
Self::Status(status.into())
}
}
impl From<Result<silizium::Status, u32>> for Error {
fn from(status: Result<silizium::Status, u32>) -> Self {
Self::Status(status.into())
}
}
impl From<ezsp::Status> for Error {
fn from(status: ezsp::Status) -> Self {
Self::Status(status.into())
}
}
impl From<ember::Status> for Error {
fn from(status: ember::Status) -> Self {
Self::Status(status.into())
}
}
impl From<silizium::Status> for Error {
fn from(status: silizium::Status) -> Self {
Self::Status(status.into())
}
}
impl From<Parameters> for Error {
fn from(parameters: Parameters) -> Self {
if let Parameters::Response(Response::Utilities(utilities::Response::InvalidCommand(
invalid_command,
))) = parameters
{
Self::InvalidCommand(*invalid_command)
} else {
Self::UnexpectedResponse(parameters.into())
}
}
}
impl From<invalid_command::Response> for Error {
fn from(response: invalid_command::Response) -> Self {
Self::InvalidCommand(response)
}
}
impl From<Infallible> for Error {
fn from(infallible: Infallible) -> Self {
match infallible {}
}
}
impl<T> From<SendError<T>> for Error {
fn from(_: SendError<T>) -> Self {
Self::SendError
}
}