use std::{fmt::Display, marker::PhantomData};
use serde_json::Value;
use super::Type;
#[derive(Debug)]
pub struct ParseError<T> {
message: String,
phantom: PhantomData<T>,
}
impl<T: Type, E: Display> From<E> for ParseError<T> {
fn from(error: E) -> Self {
Self::custom(error)
}
}
impl<T: Type> ParseError<T> {
fn new(message: String) -> Self {
Self {
message,
phantom: PhantomData,
}
}
#[must_use]
pub fn expected_type(actual: Value) -> Self {
Self::new(format!(
r#"Expected input type "{}", found {}."#,
T::name(),
actual
))
}
#[must_use]
pub fn expected_input() -> Self {
Self::new(format!(r#"Type "{}" expects an input value."#, T::name()))
}
#[must_use]
pub fn custom(msg: impl Display) -> Self {
Self::new(format!(r#"failed to parse "{}": {}"#, T::name(), msg))
}
pub fn propagate<U: Type>(self) -> ParseError<U> {
if T::name() != U::name() {
ParseError::new(format!(
r#"{} (occurred while parsing "{}")"#,
self.message,
U::name()
))
} else {
ParseError::new(self.message)
}
}
pub fn into_message(self) -> String {
self.message
}
}
pub type ParseResult<T> = Result<T, ParseError<T>>;