use std::fmt;
use nom::{
error::{convert_error, VerboseError, VerboseErrorKind},
Finish,
};
mod parse;
#[derive(Clone, Debug, PartialEq)]
pub enum JsonValue {
Null,
Bool(bool),
String(String),
Array(Vec<JsonValue>),
Number(f32),
Object(Vec<(JsonValue, JsonValue)>),
}
#[derive(Clone, Debug, PartialEq)]
pub struct Error<'a> {
pub errors: Vec<(&'a str, VerboseErrorKind)>,
data: &'a str,
raw_error: VerboseError<&'a str>,
}
impl<'a> std::error::Error for Error<'a> {}
impl<'a> fmt::Display for Error<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(f, "{}", convert_error(self.data, self.raw_error.clone()))
}
}
impl<'a> Error<'a> {
fn from_raw(data: &'a str, raw: VerboseError<&'a str>) -> Self {
Self {
errors: raw.clone().errors,
data,
raw_error: raw,
}
}
}
impl JsonValue {
#[allow(clippy::should_implement_trait)]
pub fn from_str(s: &str) -> Result<Self, Error> {
parse(s)
}
}
pub fn parse(s: &str) -> Result<JsonValue, Error> {
parse::nom_parse(s)
.finish()
.map(|(_, val)| val)
.map_err(|e| Error::from_raw(s, e))
}
pub fn parse_null(s: &str) -> Result<JsonValue, Error> {
parse::nom_null(s)
.finish()
.map(|(_, val)| val)
.map_err(|e| Error::from_raw(s, e))
}
pub fn parse_bool(s: &str) -> Result<JsonValue, Error> {
parse::nom_bool(s)
.finish()
.map(|(_, val)| val)
.map_err(|e| Error::from_raw(s, e))
}
pub fn parse_string(s: &str) -> Result<JsonValue, Error> {
parse::nom_string(s)
.finish()
.map(|(_, val)| val)
.map_err(|e| Error::from_raw(s, e))
}
pub fn parse_array(s: &str) -> Result<JsonValue, Error> {
parse::nom_array(s)
.finish()
.map(|(_, val)| val)
.map_err(|e| Error::from_raw(s, e))
}
pub fn parse_number(s: &str) -> Result<JsonValue, Error> {
parse::nom_number(s)
.finish()
.map(|(_, val)| val)
.map_err(|e| Error::from_raw(s, e))
}
pub fn parse_object(s: &str) -> Result<JsonValue, Error> {
parse::nom_object(s)
.finish()
.map(|(_, val)| val)
.map_err(|e| Error::from_raw(s, e))
}