jsona 0.6.0

A JSONA parser, analyzer and formatter library
Documentation
use crate::dom::DomError;
use crate::util::mapper::{Mapper, Range};
use serde::{Deserialize, Serialize};
use thiserror::Error;

#[derive(Debug, Clone, Error)]
pub enum Error {
    #[error("invalid syntax")]
    InvalidSyntax { errors: Vec<crate::parser::Error> },
    #[error("invalid dom")]
    InvalidDom { errors: Vec<DomError> },
}

const ERROR_SOURCE: &str = "jsona";

impl Error {
    pub fn to_error_objects(&self, mapper: &Mapper) -> Vec<ErrorObject> {
        match self {
            Error::InvalidSyntax { errors } => errors
                .iter()
                .map(|err| {
                    let message = err.to_string();
                    let range = mapper.range(err.range);
                    ErrorObject::new(ERROR_SOURCE, "InvalidSyntax", message, range)
                })
                .collect(),
            Error::InvalidDom { errors } => errors
                .iter()
                .flat_map(|err| {
                    let message = err.to_string();
                    match err {
                        DomError::ConflictingKeys { key, other_key } => {
                            let key_range = key.mapper_range(mapper);
                            let other_key_range = other_key.mapper_range(mapper);
                            vec![
                                ErrorObject::new(
                                    ERROR_SOURCE,
                                    "ConflictingKeys",
                                    message.clone(),
                                    key_range,
                                ),
                                ErrorObject::new(
                                    ERROR_SOURCE,
                                    "ConflictingKeys",
                                    message,
                                    other_key_range,
                                ),
                            ]
                        }
                        DomError::InvalidNode { syntax } => {
                            let range = mapper.range(syntax.text_range());
                            vec![ErrorObject::new(
                                ERROR_SOURCE,
                                "InvalidNode",
                                message,
                                range,
                            )]
                        }
                        DomError::InvalidNumber { syntax } => {
                            let range = mapper.range(syntax.text_range());
                            vec![ErrorObject::new(
                                ERROR_SOURCE,
                                "InvalidNumber",
                                message,
                                range,
                            )]
                        }
                        DomError::InvalidString { syntax } => {
                            let range = mapper.range(syntax.text_range());
                            vec![ErrorObject::new(
                                ERROR_SOURCE,
                                "InvalidString",
                                message,
                                range,
                            )]
                        }
                    }
                })
                .collect(),
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct ErrorObject {
    pub source: String,
    pub kind: String,
    pub message: String,
    pub range: Option<Range>,
}

impl ErrorObject {
    pub fn new(source: &str, kind: &str, message: String, range: Option<Range>) -> Self {
        Self {
            source: source.to_string(),
            kind: kind.into(),
            message,
            range,
        }
    }
}