use alloc::{boxed::Box, format, string::String};
use core::fmt::Debug;
use super::round::Protocol;
use crate::session::EchoRoundError;
#[derive(displaydoc::Display, Debug, Clone)]
#[displaydoc("Local error: {0}")]
pub struct LocalError(String);
impl LocalError {
pub fn new(message: impl Into<String>) -> Self {
Self(message.into())
}
}
#[derive(displaydoc::Display, Debug, Clone)]
#[displaydoc("Remote error: {0}")]
pub struct RemoteError(String);
impl RemoteError {
pub fn new(message: impl Into<String>) -> Self {
Self(message.into())
}
}
#[derive(Debug)]
pub struct ReceiveError<Id, P: Protocol<Id>>(pub(crate) ReceiveErrorType<Id, P>);
#[derive(Debug)]
pub(crate) enum ReceiveErrorType<Id, P: Protocol<Id>> {
Local(LocalError),
InvalidDirectMessage(DirectMessageError),
InvalidEchoBroadcast(EchoBroadcastError),
InvalidNormalBroadcast(NormalBroadcastError),
Protocol(P::ProtocolError),
Unprovable(RemoteError),
Echo(Box<EchoRoundError<Id>>),
}
impl<Id, P: Protocol<Id>> ReceiveError<Id, P> {
pub fn local(message: impl Into<String>) -> Self {
Self(ReceiveErrorType::Local(LocalError::new(message.into())))
}
pub fn unprovable(message: impl Into<String>) -> Self {
Self(ReceiveErrorType::Unprovable(RemoteError::new(message.into())))
}
pub fn protocol(error: P::ProtocolError) -> Self {
Self(ReceiveErrorType::Protocol(error))
}
pub(crate) fn map<T, F>(self, f: F) -> ReceiveError<Id, T>
where
F: Fn(P::ProtocolError) -> T::ProtocolError,
T: Protocol<Id>,
{
ReceiveError(self.0.map::<T, F>(f))
}
}
impl<Id, P: Protocol<Id>> ReceiveErrorType<Id, P> {
pub(crate) fn map<T, F>(self, f: F) -> ReceiveErrorType<Id, T>
where
F: Fn(P::ProtocolError) -> T::ProtocolError,
T: Protocol<Id>,
{
match self {
Self::Local(err) => ReceiveErrorType::Local(err),
Self::InvalidDirectMessage(err) => ReceiveErrorType::InvalidDirectMessage(err),
Self::InvalidEchoBroadcast(err) => ReceiveErrorType::InvalidEchoBroadcast(err),
Self::InvalidNormalBroadcast(err) => ReceiveErrorType::InvalidNormalBroadcast(err),
Self::Unprovable(err) => ReceiveErrorType::Unprovable(err),
Self::Echo(err) => ReceiveErrorType::Echo(err),
Self::Protocol(err) => ReceiveErrorType::Protocol(f(err)),
}
}
}
impl<Id, P> From<LocalError> for ReceiveError<Id, P>
where
P: Protocol<Id>,
{
fn from(error: LocalError) -> Self {
Self(ReceiveErrorType::Local(error))
}
}
impl<Id, P> From<RemoteError> for ReceiveError<Id, P>
where
P: Protocol<Id>,
{
fn from(error: RemoteError) -> Self {
Self(ReceiveErrorType::Unprovable(error))
}
}
impl<Id, P> From<EchoRoundError<Id>> for ReceiveError<Id, P>
where
P: Protocol<Id>,
{
fn from(error: EchoRoundError<Id>) -> Self {
Self(ReceiveErrorType::Echo(Box::new(error)))
}
}
impl<Id, P> From<DirectMessageError> for ReceiveError<Id, P>
where
P: Protocol<Id>,
{
fn from(error: DirectMessageError) -> Self {
Self(ReceiveErrorType::InvalidDirectMessage(error))
}
}
impl<Id, P> From<EchoBroadcastError> for ReceiveError<Id, P>
where
P: Protocol<Id>,
{
fn from(error: EchoBroadcastError) -> Self {
Self(ReceiveErrorType::InvalidEchoBroadcast(error))
}
}
impl<Id, P> From<NormalBroadcastError> for ReceiveError<Id, P>
where
P: Protocol<Id>,
{
fn from(error: NormalBroadcastError) -> Self {
Self(ReceiveErrorType::InvalidNormalBroadcast(error))
}
}
#[derive(Debug, Clone)]
pub enum MessageValidationError {
Local(LocalError),
InvalidEvidence(String),
}
#[derive(displaydoc::Display, Debug, Clone)]
#[displaydoc("Deserialization error: {0}")]
pub struct DeserializationError(String);
impl DeserializationError {
pub fn new(message: impl Into<String>) -> Self {
Self(message.into())
}
}
impl From<LocalError> for MessageValidationError {
fn from(error: LocalError) -> Self {
Self::Local(error)
}
}
#[derive(Debug, Clone)]
pub enum ProtocolValidationError {
Local(LocalError),
InvalidEvidence(String),
}
impl From<DirectMessageError> for ProtocolValidationError {
fn from(error: DirectMessageError) -> Self {
Self::InvalidEvidence(format!("Failed to deserialize direct message: {error:?}"))
}
}
impl From<EchoBroadcastError> for ProtocolValidationError {
fn from(error: EchoBroadcastError) -> Self {
Self::InvalidEvidence(format!("Failed to deserialize echo broadcast: {error:?}"))
}
}
impl From<NormalBroadcastError> for ProtocolValidationError {
fn from(error: NormalBroadcastError) -> Self {
Self::InvalidEvidence(format!("Failed to deserialize normal broadcast: {error:?}"))
}
}
impl From<LocalError> for ProtocolValidationError {
fn from(error: LocalError) -> Self {
Self::Local(error)
}
}
#[derive(displaydoc::Display, Debug, Clone)]
#[displaydoc("Direct message error: {0}")]
pub struct DirectMessageError(String);
impl From<String> for DirectMessageError {
fn from(message: String) -> Self {
Self(message)
}
}
#[derive(displaydoc::Display, Debug, Clone)]
#[displaydoc("Echo broadcast error: {0}")]
pub struct EchoBroadcastError(String);
impl From<String> for EchoBroadcastError {
fn from(message: String) -> Self {
Self(message)
}
}
#[derive(displaydoc::Display, Debug, Clone)]
#[displaydoc("Normal broadcast error: {0}")]
pub struct NormalBroadcastError(String);
impl From<String> for NormalBroadcastError {
fn from(message: String) -> Self {
Self(message)
}
}