use crate::payload::Violation;
use crate::port::{ReadError, SendError, ServeError};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Contract {
InvalidValue(Violation),
PreconditionFailed,
ContractBroken,
UnknownInteraction,
}
#[non_exhaustive]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Transport {
Timeout,
Undelivered,
Down,
Corrupt,
Busy,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum CallError {
Contract(Contract),
Transport(Transport),
}
#[non_exhaustive]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ClientError {
Send(SendError),
Call(CallError),
Read(ReadError),
}
impl From<SendError> for ClientError {
fn from(error: SendError) -> Self {
ClientError::Send(error)
}
}
impl From<CallError> for ClientError {
fn from(error: CallError) -> Self {
ClientError::Call(error)
}
}
impl From<ReadError> for ClientError {
fn from(error: ReadError) -> Self {
ClientError::Read(error)
}
}
#[non_exhaustive]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ProviderError {
Serve(ServeError),
Claim(ReadError),
}
impl From<ServeError> for ProviderError {
fn from(error: ServeError) -> Self {
ProviderError::Serve(error)
}
}
impl From<ReadError> for ProviderError {
fn from(error: ReadError) -> Self {
ProviderError::Claim(error)
}
}
#[cfg(test)]
mod tests {
use super::{CallError, ClientError, Contract, ProviderError, Transport};
use crate::port::{ReadError, SendError, ServeError};
fn owns_nothing<T: Copy + Eq + core::fmt::Debug + 'static>() {}
#[test]
fn every_error_is_copy_and_owns_nothing() {
owns_nothing::<Contract>();
owns_nothing::<Transport>();
owns_nothing::<CallError>();
owns_nothing::<ClientError>();
owns_nothing::<ProviderError>();
}
#[test]
fn each_inner_error_converts_into_its_own_client_variant() {
fn send() -> Result<(), ClientError> {
Err(SendError::Busy)?
}
fn call() -> Result<(), ClientError> {
Err(CallError::Transport(Transport::Timeout))?
}
fn read() -> Result<(), ClientError> {
Err(ReadError::Detached)?
}
assert_eq!(send(), Err(ClientError::Send(SendError::Busy)));
assert_eq!(
call(),
Err(ClientError::Call(CallError::Transport(Transport::Timeout)))
);
assert_eq!(read(), Err(ClientError::Read(ReadError::Detached)));
}
#[test]
fn each_inner_error_converts_into_its_own_provider_variant() {
fn serve() -> Result<(), ProviderError> {
Err(ServeError::NotOwner)?
}
fn claim() -> Result<(), ProviderError> {
Err(ReadError::Detached)?
}
assert_eq!(serve(), Err(ProviderError::Serve(ServeError::NotOwner)));
assert_eq!(claim(), Err(ProviderError::Claim(ReadError::Detached)));
}
}