poem_openapi/types/
error.rs

1use std::{fmt::Display, marker::PhantomData};
2
3use serde_json::Value;
4
5use super::Type;
6
7/// An error parsing an schema.
8///
9/// This type is generic over T as it uses T's type name when converting to a
10/// regular error.
11#[derive(Debug)]
12pub struct ParseError<T> {
13    message: String,
14    phantom: PhantomData<T>,
15}
16
17impl<T: Type, E: Display> From<E> for ParseError<T> {
18    fn from(error: E) -> Self {
19        Self::custom(error)
20    }
21}
22
23impl<T: Type> ParseError<T> {
24    fn new(message: String) -> Self {
25        Self {
26            message,
27            phantom: PhantomData,
28        }
29    }
30
31    /// The expected input type did not match the actual input type.
32    #[must_use]
33    pub fn expected_type(actual: Value) -> Self {
34        Self::new(format!(
35            r#"Expected input type "{}", found {}."#,
36            T::name(),
37            actual
38        ))
39    }
40
41    /// Type A expects an input value.
42    #[must_use]
43    pub fn expected_input() -> Self {
44        Self::new(format!(r#"Type "{}" expects an input value."#, T::name()))
45    }
46
47    /// A custom error message.
48    ///
49    /// Any type that implements `Display` is automatically converted to this if
50    /// you use the `?` operator.
51    #[must_use]
52    pub fn custom(msg: impl Display) -> Self {
53        Self::new(format!(r#"failed to parse "{}": {}"#, T::name(), msg))
54    }
55
56    /// Propagate the error message to a different type.
57    pub fn propagate<U: Type>(self) -> ParseError<U> {
58        if T::name() != U::name() {
59            ParseError::new(format!(
60                r#"{} (occurred while parsing "{}")"#,
61                self.message,
62                U::name()
63            ))
64        } else {
65            ParseError::new(self.message)
66        }
67    }
68
69    /// Consume this error and convert it into a message.
70    pub fn into_message(self) -> String {
71        self.message
72    }
73
74    /// Return the error message.
75    pub fn message(&self) -> &str {
76        &self.message
77    }
78}
79
80/// An error parsing a value of type `T`.
81pub type ParseResult<T> = Result<T, ParseError<T>>;