use crate::protocol::{Protocol, ProtocolDescription};
pub trait WalkerError<'value, 'ctx: 'value> {
fn wrong_visit<P: Protocol<'value, 'ctx>>() -> Self;
fn needs_hint() -> Self;
}
pub trait VisitorError<'value, 'ctx: 'value> {
fn wrong_hint<P: Protocol<'value, 'ctx>>() -> Self;
}
#[derive(thiserror::Error, Debug)]
pub enum UniError<WalkerErr, VisitorErr> {
#[error(transparent)]
Walker(WalkerErr),
#[error(transparent)]
Visitor(VisitorErr),
}
#[derive(thiserror::Error, Debug)]
#[error("{message}")]
pub struct BasicError {
message: &'static str,
}
impl BasicError {
pub fn new(message: &'static str) -> Self {
Self { message }
}
pub fn message(&self) -> &'static str {
self.message
}
}
impl<'value, 'ctx: 'value> WalkerError<'value, 'ctx> for BasicError {
fn wrong_visit<P: Protocol<'value, 'ctx>>() -> Self {
Self::new("wrong protocol for visit")
}
fn needs_hint() -> Self {
Self::new("walker needs hint from visitor")
}
}
impl<'value, 'ctx: 'value> VisitorError<'value, 'ctx> for BasicError {
fn wrong_hint<P: Protocol<'value, 'ctx>>() -> Self {
Self::new("wrong protocol for hint")
}
}
/// Error wrapper that adds a missing variant.
#[derive(thiserror::Error, Debug)]
pub enum Missing<E> {
/// The value was never visted.
#[error("value is missing after walking")]
Missing,
/// Another error.
#[error(transparent)]
Error(#[from] E),
}
impl<'value, 'ctx: 'value, E: VisitorError<'value, 'ctx>> VisitorError<'value, 'ctx>
for Missing<E>
{
fn wrong_hint<P: Protocol<'value, 'ctx>>() -> Self {
E::wrong_hint::<P>().into()
}
}
#[derive(thiserror::Error, Debug)]
pub enum WrongProtocol<E> {
/// The wrong protocol was given in a query.
#[error("wrong protocol, expected: `{expected}`, got: `{got}`")]
WrongProtocol {
expected: ProtocolDescription,
got: ProtocolDescription,
},
/// Another error.
#[error(transparent)]
Error(#[from] E),
}
impl<'value, 'ctx: 'value, E: VisitorError<'value, 'ctx>> VisitorError<'value, 'ctx>
for WrongProtocol<E>
{
fn wrong_hint<P: Protocol<'value, 'ctx>>() -> Self {
E::wrong_hint::<P>().into()
}
}