jsona/
error.rs

1use crate::dom::DomError;
2use crate::util::mapper::{Mapper, Range};
3use serde::{Deserialize, Serialize};
4use thiserror::Error;
5
6#[derive(Debug, Clone, Error)]
7pub enum Error {
8    #[error("invalid syntax")]
9    InvalidSyntax { errors: Vec<crate::parser::Error> },
10    #[error("invalid dom")]
11    InvalidDom { errors: Vec<DomError> },
12}
13
14const ERROR_SOURCE: &str = "jsona";
15
16impl Error {
17    pub fn to_error_objects(&self, mapper: &Mapper) -> Vec<ErrorObject> {
18        match self {
19            Error::InvalidSyntax { errors } => errors
20                .iter()
21                .map(|err| {
22                    let message = err.to_string();
23                    let range = mapper.range(err.range);
24                    ErrorObject::new(ERROR_SOURCE, "InvalidSyntax", message, range)
25                })
26                .collect(),
27            Error::InvalidDom { errors } => errors
28                .iter()
29                .flat_map(|err| {
30                    let message = err.to_string();
31                    match err {
32                        DomError::ConflictingKeys { key, other_key } => {
33                            let key_range = key.mapper_range(mapper);
34                            let other_key_range = other_key.mapper_range(mapper);
35                            vec![
36                                ErrorObject::new(
37                                    ERROR_SOURCE,
38                                    "ConflictingKeys",
39                                    message.clone(),
40                                    key_range,
41                                ),
42                                ErrorObject::new(
43                                    ERROR_SOURCE,
44                                    "ConflictingKeys",
45                                    message,
46                                    other_key_range,
47                                ),
48                            ]
49                        }
50                        DomError::InvalidNode { syntax } => {
51                            let range = mapper.range(syntax.text_range());
52                            vec![ErrorObject::new(
53                                ERROR_SOURCE,
54                                "InvalidNode",
55                                message,
56                                range,
57                            )]
58                        }
59                        DomError::InvalidNumber { syntax } => {
60                            let range = mapper.range(syntax.text_range());
61                            vec![ErrorObject::new(
62                                ERROR_SOURCE,
63                                "InvalidNumber",
64                                message,
65                                range,
66                            )]
67                        }
68                        DomError::InvalidString { syntax } => {
69                            let range = mapper.range(syntax.text_range());
70                            vec![ErrorObject::new(
71                                ERROR_SOURCE,
72                                "InvalidString",
73                                message,
74                                range,
75                            )]
76                        }
77                    }
78                })
79                .collect(),
80        }
81    }
82}
83
84#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
85pub struct ErrorObject {
86    pub source: String,
87    pub kind: String,
88    pub message: String,
89    pub range: Option<Range>,
90}
91
92impl ErrorObject {
93    pub fn new(source: &str, kind: &str, message: String, range: Option<Range>) -> Self {
94        Self {
95            source: source.to_string(),
96            kind: kind.into(),
97            message,
98            range,
99        }
100    }
101}