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 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}