use crate::prelude::*;
use serde_json::Map;
use serde_json::Number;
use serde_json::Value;
use std::str::FromStr;
use crate::token::DelimiterKind;
use crate::token::IdentifierKind;
use crate::token::LiteralKind;
use crate::token::TokenKind;
pub fn bytes_to_str(_bytes: &[u8]) -> &str {
unsafe { std::str::from_utf8_unchecked(_bytes) }
}
pub fn bytes_to_string(_bytes: &[u8]) -> String {
unsafe { String::from_utf8_unchecked(_bytes.to_vec()) }
}
pub fn unescape_bytes(_bytes: &[u8]) -> Vec<u8> {
let mut output = Vec::with_capacity(_bytes.len());
let mut chars = _bytes.iter();
while let Some(&c) = chars.next() {
match c {
b'\\' => {
if let Some(&b) = chars.next() {
match b {
b'n' => output.push(b'\n'),
b'r' => output.push(b'\r'),
b't' => output.push(b'\t'),
b'"' => output.push(b),
b'\'' => output.push(b),
b'\\' => output.push(b),
b'`' => output.push(b),
_ => output.push(b),
}
}
}
_ => output.push(c),
}
}
output
}
#[derive(Default, Debug)]
pub struct Parser {
index: usize,
}
impl Parser {
fn index(&self) -> usize {
self.index
}
fn next(&mut self) {
self.index += 1;
}
pub fn new() -> Self {
Parser { index: 0 }
}
pub fn parse(&mut self, tokens: &[TokenKind]) -> Result<Value> {
match tokens.get(self.index()) {
Some(token) => match token {
TokenKind::Identifier(IdentifierKind::String(_)) => {
let mut values = Map::with_capacity(tokens.len());
while tokens.get(self.index()).is_some() {
let key = self.create_key(tokens)?;
self.next();
let value = self.create_value(tokens)?;
self.next();
values.insert(key, value);
}
Ok(Value::Object(values))
}
_ => {
let mut values = Vec::with_capacity(tokens.len());
while tokens.get(self.index()).is_some() {
let value = self.create_value(tokens)?;
self.next();
values.push(value);
}
Ok(Value::Array(values))
}
},
None => Err(Error {
description: "ran out of tokens".to_string(),
}),
}
}
pub fn create_list<'a>(&mut self, tokens: &'a [TokenKind<'a>]) -> Result<Value> {
let mut values = Vec::new();
while let Some(token) = tokens.get(self.index()) {
match token {
TokenKind::Delimiter(DelimiterKind::ArrayTerm(_)) => break,
_ => {
let value = self.create_value(tokens)?;
self.next();
values.push(value);
}
}
}
Ok(Value::Array(values))
}
pub fn create_table<'a>(&mut self, tokens: &'a [TokenKind<'a>]) -> Result<Value> {
let mut values = Map::new();
while let Some(token) = tokens.get(self.index()) {
match token {
TokenKind::Delimiter(DelimiterKind::ObjectTerm(_)) => break,
_ => {
let key = self.create_key(tokens)?;
self.next();
let value = self.create_value(tokens)?;
self.next();
values.insert(key, value);
}
}
}
Ok(Value::Object(values))
}
pub fn create_key<'a>(&mut self, tokens: &'a [TokenKind<'a>]) -> Result<String> {
if let Some(token) = tokens.get(self.index()) {
match token {
TokenKind::Identifier(IdentifierKind::String(t)) => {
let result = bytes_to_string(t.bytes());
Ok(result)
}
token => Err(Error {
description: format!("invalid key '{:?}'", token),
}),
}
} else {
Err(Error {
description: "expected a key".to_string(),
})
}
}
pub fn create_value<'a>(&mut self, tokens: &'a [TokenKind<'a>]) -> Result<Value> {
if let Some(token) = tokens.get(self.index()) {
match token {
TokenKind::Literal(LiteralKind::True(_)) => Ok(Value::Bool(true)),
TokenKind::Literal(LiteralKind::False(_)) => Ok(Value::Bool(false)),
TokenKind::Literal(LiteralKind::String(t)) => {
let bytes_str = t.bytes();
if bytes_str.contains(&b'\\') {
let unescaped = unescape_bytes(bytes_str);
let result = bytes_to_string(&unescaped);
Ok(Value::String(result))
} else {
let result = bytes_to_string(bytes_str);
Ok(Value::String(result))
}
}
TokenKind::Literal(LiteralKind::Number(t)) => {
let num_str = bytes_to_str(t.bytes());
match Number::from_str(num_str) {
Ok(num) => Ok(Value::Number(num)),
Err(e) => Err(Error {
description: e.to_string(),
}),
}
}
TokenKind::Literal(LiteralKind::Null(_)) => Ok(Value::Null),
TokenKind::Delimiter(DelimiterKind::ObjectPrec(_)) => {
self.next();
match self.create_table(tokens) {
Ok(tbl) => Ok(tbl),
Err(e) => Err(Error {
description: format!(
"failed creating a table because of {}",
e.description
),
}),
}
}
TokenKind::Delimiter(DelimiterKind::ArrayPrec(_)) => {
self.next();
match self.create_list(tokens) {
Ok(ls) => Ok(ls),
Err(e) => Err(Error {
description: format!(
"failed creating a list because of {}",
e.description
),
}),
}
}
TokenKind::Delimiter(DelimiterKind::ArrayTerm(ctx)) => Err(Error {
description: format!(
"'{}' is not a valid value ({}:{})",
bytes_to_str(ctx.bytes()),
ctx.location().start().line(),
ctx.location().start().column()
),
}),
TokenKind::Delimiter(DelimiterKind::ObjectTerm(ctx)) => Err(Error {
description: format!(
"'{}' is not a valid value ({}:{})",
bytes_to_str(ctx.bytes()),
ctx.location().start().line(),
ctx.location().start().column()
),
}),
TokenKind::Identifier(IdentifierKind::String(ctx)) => Err(Error {
description: format!(
"'{}' is not a valid value ({}:{})",
bytes_to_str(ctx.bytes()),
ctx.location().start().line(),
ctx.location().start().column()
),
}),
}
} else {
Err(Error {
description: "ran out of tokens".to_string(),
})
}
}
}