use alloc::string::String;
use core::str;
use crate::number::{self, Number};
use crate::scan::Scan;
use crate::{skip, text};
use crate::{Error, ErrorKind};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Kind {
Object,
Array,
String,
Number,
Bool,
Null,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Value<'s> {
String(&'s str),
Number(Number<'s>),
Bool(bool),
Null,
Array,
Object,
}
pub const DEFAULT_DEPTH_LIMIT: usize = 128;
#[derive(Clone, Debug)]
pub struct Cursor<'a> {
text: &'a str,
scan: Scan<'a>,
depth_limit: usize,
}
impl<'a> Cursor<'a> {
#[inline]
pub fn new(text: &'a str) -> Self {
Cursor {
text,
scan: Scan::new(text.as_bytes()),
depth_limit: DEFAULT_DEPTH_LIMIT,
}
}
#[inline]
pub fn from_bytes(bytes: &'a [u8]) -> Result<Self, Error> {
str::from_utf8(bytes)
.map(Self::new)
.map_err(|e| Error::new(ErrorKind::Utf8, e.valid_up_to()))
}
#[inline]
pub fn with_depth_limit(mut self, limit: usize) -> Self {
self.depth_limit = limit;
self
}
#[inline]
pub fn position(&self) -> usize {
self.scan.at
}
#[inline]
pub fn peek(&mut self) -> Result<Kind, Error> {
Ok(match self.scan.next_byte()? {
b'{' => Kind::Object,
b'[' => Kind::Array,
b'"' => Kind::String,
b'-' | b'0'..=b'9' => Kind::Number,
b't' | b'f' => Kind::Bool,
b'n' => Kind::Null,
_ => return Err(self.scan.err(ErrorKind::Expected("a value"))),
})
}
#[inline]
pub fn value<'s>(&mut self, buf: &'s mut String) -> Result<Value<'s>, Error>
where
'a: 's,
{
Ok(match self.scan.next_byte()? {
b'"' => Value::String(self.string_at(buf)?),
b'-' | b'0'..=b'9' => Value::Number(self.number_at()?),
b'{' => Value::Object,
b'[' => Value::Array,
b't' => self.scan.literal(b"true", "`true`").map(|()| Value::Bool(true))?,
b'f' => self.scan.literal(b"false", "`false`").map(|()| Value::Bool(false))?,
b'n' => self.scan.literal(b"null", "`null`").map(|()| Value::Null)?,
_ => return Err(self.scan.err(ErrorKind::Expected("a value"))),
})
}
#[inline]
pub fn first_key<'s>(&mut self, buf: &'s mut String) -> Result<Option<&'s str>, Error>
where
'a: 's,
{
self.scan.expect(b'{', "`{`")?;
match self.scan.next_byte()? {
b'}' => {
self.scan.at += 1;
Ok(None)
}
b'"' => self.key(buf).map(Some),
_ => Err(self.scan.err(ErrorKind::Expected("a key or `}`"))),
}
}
#[inline]
pub fn next_key<'s>(&mut self, buf: &'s mut String) -> Result<Option<&'s str>, Error>
where
'a: 's,
{
match self.scan.next_byte()? {
b',' => {
self.scan.at += 1;
match self.scan.next_byte()? {
b'"' => self.key(buf).map(Some),
_ => Err(self.scan.err(ErrorKind::Expected("a key"))),
}
}
b'}' => {
self.scan.at += 1;
Ok(None)
}
_ => Err(self.scan.err(ErrorKind::Expected("`,` or `}`"))),
}
}
#[inline]
pub fn first_item(&mut self) -> Result<bool, Error> {
self.scan.expect(b'[', "`[`")?;
if self.scan.next_byte()? == b']' {
self.scan.at += 1;
Ok(false)
} else {
Ok(true)
}
}
#[inline]
pub fn next_item(&mut self) -> Result<bool, Error> {
match self.scan.next_byte()? {
b',' => {
self.scan.at += 1;
Ok(true)
}
b']' => {
self.scan.at += 1;
Ok(false)
}
_ => Err(self.scan.err(ErrorKind::Expected("`,` or `]`"))),
}
}
#[inline]
pub fn string<'s>(&mut self, buf: &'s mut String) -> Result<&'s str, Error>
where
'a: 's,
{
if self.scan.next_byte()? != b'"' {
return Err(self.scan.err(ErrorKind::Expected("a string")));
}
self.string_at(buf)
}
#[inline]
pub fn number(&mut self) -> Result<Number<'a>, Error> {
match self.scan.next_byte()? {
b'-' | b'0'..=b'9' => self.number_at(),
_ => Err(self.scan.err(ErrorKind::Expected("a number"))),
}
}
#[inline]
pub fn bool(&mut self) -> Result<bool, Error> {
match self.scan.next_byte()? {
b't' => self.scan.literal(b"true", "`true`").map(|()| true),
b'f' => self.scan.literal(b"false", "`false`").map(|()| false),
_ => Err(self.scan.err(ErrorKind::Expected("`true` or `false`"))),
}
}
#[inline]
pub fn null(&mut self) -> Result<(), Error> {
if self.scan.next_byte()? != b'n' {
return Err(self.scan.err(ErrorKind::Expected("`null`")));
}
self.scan.literal(b"null", "`null`")
}
#[inline]
pub fn skip(&mut self) -> Result<(), Error> {
skip::skip::<false>(&mut self.scan, self.depth_limit)
}
#[inline]
pub fn finish(&mut self) -> Result<(), Error> {
self.scan.finish()
}
#[inline(always)]
fn number_at(&mut self) -> Result<Number<'a>, Error> {
let start = self.scan.at;
let (end, parts) = number::read::<true>(self.scan.bytes, start)?;
self.scan.at = end;
Ok(Number::new(self.text, start, end, parts))
}
#[inline(always)]
fn string_at<'s>(&mut self, buf: &'s mut String) -> Result<&'s str, Error>
where
'a: 's,
{
let (end, borrowed) = text::read(self.text, self.scan.at, buf)?;
self.scan.at = end;
Ok(match borrowed {
Some(text) => text,
None => buf.as_str(),
})
}
#[inline]
fn key<'s>(&mut self, buf: &'s mut String) -> Result<&'s str, Error>
where
'a: 's,
{
let key = self.string_at(buf)?;
self.scan.expect(b':', "`:`")?;
Ok(key)
}
}