openapi_types/
error.rs

1use crate::yaml::YamlLoaderError;
2use crate::{http, json_schema, openapi, v3_0};
3use gesha_collections::partial_result::PartialResult;
4use gesha_collections::tracking::{ContextAppendable, ContextBindable};
5use gesha_collections::yaml::YamlError;
6use std::fmt::Debug;
7
8pub type Result<A> = std::result::Result<A, Error>;
9
10pub type Output<A> = PartialResult<A, Error>;
11
12#[derive(Debug)]
13pub enum Error {
14    Enclosed { key: String, cause: Box<Error> },
15    Multiple(Vec<Error>),
16    SpecViolation(SpecViolation),
17    Unsupported(Unsupported),
18    YamlLoader(YamlLoaderError),
19}
20
21impl Error {
22    pub fn multiple(mut causes: Vec<Self>) -> Self {
23        if causes.len() == 1 {
24            causes.remove(0)
25        } else {
26            Self::Multiple(causes)
27        }
28    }
29}
30
31impl From<Vec<Error>> for Error {
32    fn from(mut causes: Vec<Error>) -> Self {
33        if causes.len() == 1 {
34            causes.remove(0)
35        } else {
36            Error::Multiple(causes)
37        }
38    }
39}
40
41impl From<YamlError> for Error {
42    fn from(e: YamlError) -> Self {
43        match e {
44            YamlError::FieldNotExist { field } => {
45                Error::from(openapi::SpecViolation::FieldNotExist { field })
46            }
47            YamlError::TypeMismatch { found, expected } => {
48                Error::from(openapi::SpecViolation::TypeMismatch { found, expected })
49            }
50            YamlError::UnknownType { found } => {
51                Error::Unsupported(Unsupported::UnknownType { found })
52            }
53        }
54    }
55}
56
57impl ContextBindable<String> for Error {
58    fn bind(key: impl Into<String>, causes: Vec<Self>) -> Self {
59        Error::Enclosed {
60            key: key.into(),
61            cause: Box::new(causes.into()),
62        }
63    }
64}
65
66impl ContextAppendable<String> for Error {
67    fn append(key: impl Into<String>, cause: Self) -> Self {
68        Error::Enclosed {
69            key: key.into(),
70            cause: Box::new(cause),
71        }
72    }
73}
74
75#[derive(Clone, Debug, PartialEq)]
76pub enum SpecViolation {
77    Http(http::SpecViolation),
78    JsonSchema(json_schema::SpecViolation),
79
80    /// version independent violations
81    OpenApi(openapi::SpecViolation),
82
83    V3_0(v3_0::SpecViolation),
84}
85
86#[derive(Clone, Debug, PartialEq)]
87pub enum Unsupported {
88    IncompatibleOpenApiVersion { version: String },
89    UnknownType { found: String },
90    Unimplemented { message: String },
91}
92
93impl From<Unsupported> for Error {
94    fn from(unsupported: Unsupported) -> Self {
95        Error::Unsupported(unsupported)
96    }
97}