jsona_schema/
error.rs

1use jsona::{
2    dom::{Keys, Node},
3    error::ErrorObject,
4    util::mapper::Mapper,
5};
6use thiserror::Error;
7
8pub type SchemaResult<T> = std::result::Result<T, Vec<SchemaError>>;
9
10pub const ERROR_SOURCE: &str = "schema";
11
12#[derive(Clone, Debug, Error)]
13pub enum SchemaError {
14    #[error("conflict def {name}")]
15    ConflictDef { keys: Keys, name: String },
16    #[error("unknown ref {name}")]
17    UnknownRef { keys: Keys, name: String },
18    #[error("the type is unexpected")]
19    UnexpectedType { keys: Keys },
20    #[error("the schema type is not match value type")]
21    UnmatchedSchemaType { keys: Keys },
22    #[error("invalid schema value, {error}")]
23    InvalidSchemaValue { keys: Keys, error: String },
24    #[error("invalid compound value")]
25    InvalidCompoundValue { keys: Keys },
26}
27
28impl SchemaError {
29    pub fn keys(&self) -> &Keys {
30        match self {
31            SchemaError::ConflictDef { keys, .. } => keys,
32            SchemaError::UnknownRef { keys, .. } => keys,
33            SchemaError::UnexpectedType { keys } => keys,
34            SchemaError::UnmatchedSchemaType { keys } => keys,
35            SchemaError::InvalidSchemaValue { keys, .. } => keys,
36            SchemaError::InvalidCompoundValue { keys } => keys,
37        }
38    }
39
40    pub fn append_keys(self, prefix_keys: &Keys) -> Self {
41        match self {
42            SchemaError::ConflictDef { keys, name } => SchemaError::ConflictDef {
43                keys: prefix_keys.extend(keys),
44                name,
45            },
46            SchemaError::UnknownRef { keys, name } => SchemaError::UnknownRef {
47                keys: prefix_keys.extend(keys),
48                name,
49            },
50            SchemaError::UnexpectedType { keys } => SchemaError::UnexpectedType {
51                keys: prefix_keys.extend(keys),
52            },
53            SchemaError::UnmatchedSchemaType { keys } => SchemaError::UnmatchedSchemaType {
54                keys: prefix_keys.extend(keys),
55            },
56            SchemaError::InvalidSchemaValue { keys, error } => SchemaError::InvalidSchemaValue {
57                keys: prefix_keys.extend(keys),
58                error,
59            },
60            SchemaError::InvalidCompoundValue { keys } => SchemaError::UnmatchedSchemaType {
61                keys: prefix_keys.extend(keys),
62            },
63        }
64    }
65
66    pub fn to_error_object(&self, node: &Node, mapper: &Mapper) -> ErrorObject {
67        let message = self.to_string();
68        let (kind, range) = match self {
69            SchemaError::ConflictDef { keys, .. } => {
70                ("ConflictDef", keys.mapper_range(node, mapper))
71            }
72            SchemaError::UnknownRef { keys, .. } => ("UnknownRef", keys.mapper_range(node, mapper)),
73            SchemaError::UnexpectedType { keys } => {
74                ("UnexpectedType", keys.mapper_range(node, mapper))
75            }
76            SchemaError::UnmatchedSchemaType { keys } => {
77                ("UnmatchedSchemaType", keys.mapper_range(node, mapper))
78            }
79            SchemaError::InvalidSchemaValue { keys, .. } => {
80                ("InvalidSchemaValue", keys.mapper_range(node, mapper))
81            }
82            SchemaError::InvalidCompoundValue { keys } => {
83                ("InvalidCompoundValue", keys.mapper_range(node, mapper))
84            }
85        };
86        ErrorObject::new(ERROR_SOURCE, kind, message, range)
87    }
88}