use crate::token::Expect;
use crate::{num, str, Error, LexAlloc};
use alloc::vec::Vec;
use core::{convert::AsRef, fmt};
#[derive(Debug)]
pub enum Value<Num, Str> {
Null,
Bool(bool),
Number((Num, num::Parts)),
String(Str),
Array(Vec<Self>),
Object(Vec<(Str, Self)>),
}
impl<NumL: PartialEq<NumR>, NumR, StrL: PartialEq<StrR>, StrR> PartialEq<Value<NumR, StrR>>
for Value<NumL, StrL>
{
fn eq(&self, other: &Value<NumR, StrR>) -> bool {
use Value::*;
match (self, other) {
(Null, Null) => true,
(Bool(l), Bool(r)) => l == r,
(Number((nl, pl)), Number((nr, pr))) => nl == nr && pl == pr,
(String(l), String(r)) => l == r,
(Array(l), Array(r)) => l == r,
(Object(l), Object(r)) => {
let mut lr = l.iter().zip(r.iter());
l.len() == r.len() && lr.all(|((kl, vl), (kr, vr))| kl == kr && vl == vr)
}
_ => false,
}
}
}
impl<Num: AsRef<str>, Str: AsRef<str>> fmt::Display for Value<Num, Str> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use Value::*;
match self {
Null => "null".fmt(f),
Bool(b) => b.fmt(f),
Number((n, _)) => n.as_ref().fmt(f),
String(s) => str::Display::new(s.as_ref()).fmt(f),
Array(a) => {
"[".fmt(f)?;
let mut iter = a.iter();
iter.next().iter().try_for_each(|v| write!(f, "{}", v))?;
iter.try_for_each(|v| write!(f, ",{}", v))?;
"]".fmt(f)
}
Object(o) => {
"{".fmt(f)?;
let mut iter = o.iter().map(|(k, v)| (str::Display::new(k.as_ref()), v));
iter.next()
.iter()
.try_for_each(|(k, v)| write!(f, "{}:{}", k, v))?;
iter.try_for_each(|(k, v)| write!(f, ",{}:{}", k, v))?;
"}".fmt(f)
}
}
}
}
fn parse<L: LexAlloc>(
next: u8,
lexer: &mut L,
f: impl Fn(u8, &mut L) -> Result<Value<L::Num, L::Str>, Error>,
) -> Result<Value<L::Num, L::Str>, Error> {
let nob = |o: Option<bool>| o.map(Value::Bool).unwrap_or(Value::Null);
match next {
b'a'..=b'z' => Ok(lexer.null_or_bool().map(nob).ok_or(Expect::Value)?),
b'0'..=b'9' | b'-' => Ok(Value::Number(lexer.num_string().validated()?)),
b'"' => Ok(Value::String(lexer.discarded().str_string()?)),
b'[' => Ok(Value::Array({
let mut arr = Vec::new();
lexer.discarded().seq(b']', L::ws_peek, |next, lexer| {
arr.push(f(next, lexer)?);
Ok::<_, Error>(())
})?;
arr
})),
b'{' => Ok(Value::Object({
let mut obj = Vec::new();
lexer.discarded().seq(b'}', L::ws_peek, |next, lexer| {
lexer.expect(|_| Some(next), b'"').ok_or(Expect::String)?;
let key = lexer.str_string().map_err(Error::Str)?;
lexer.expect(L::ws_peek, b':').ok_or(Expect::Colon)?;
let value = f(lexer.ws_peek().ok_or(Expect::Value)?, lexer)?;
obj.push((key, value));
Ok::<_, Error>(())
})?;
obj
})),
_ => Err(Expect::Value)?,
}
}
pub fn parse_unbounded<L: LexAlloc>(
next: u8,
lexer: &mut L,
) -> Result<Value<L::Num, L::Str>, Error> {
parse(next, lexer, parse_unbounded)
}
pub fn parse_bounded<L: LexAlloc>(
depth: usize,
next: u8,
lexer: &mut L,
) -> Result<Value<L::Num, L::Str>, Error> {
let d = depth.checked_sub(1).ok_or(Error::Depth)?;
parse(next, lexer, |next, lexer| parse_bounded(d, next, lexer))
}