mod error;
mod json;
mod scanner;
use json::general_tokens::*;
use json::{StackTokens, JSON};
use scanner::Scanner;
mod validate_true;
use validate_true::validate_true;
mod validate_false;
use validate_false::validate_false;
mod validate_null;
use validate_null::validate_null;
mod validate_number;
use validate_number::validate_number;
mod validate_string;
use validate_string::validate_string;
mod validate_begin_array;
use validate_begin_array::validate_begin_array;
mod validate_end_array;
use validate_end_array::validate_end_array;
mod validate_value_separator;
use validate_value_separator::validate_value_separator;
mod validate_begin_object;
use validate_begin_object::validate_begin_object;
mod validate_end_object;
use validate_end_object::validate_end_object;
mod validate_name_separator;
use validate_name_separator::validate_name_separator;
pub use error::{Error, ErrorType};
pub fn validate(code: &str) -> Vec<Error> {
let mut scanner = Scanner::new(code);
let mut json_document = JSON::new();
if scanner
.peek()
.filter(|(_, first_character)| first_character == &'\u{feff}')
.is_some()
{
scanner.next();
}
while let Some((current_index, current_character)) = scanner.next() {
match current_character {
SPACE | NEW_LINE | CARRIAGE_RETURN | HORIZONTAL_TAB => continue,
't' => {
if validate_true(&mut json_document, &mut scanner).is_err() {
return json_document.errors;
}
}
'f' => {
if validate_false(&mut json_document, &mut scanner).is_err() {
return json_document.errors;
}
}
'n' => {
if validate_null(&mut json_document, &mut scanner).is_err() {
return json_document.errors;
}
}
'0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '-' => {
if validate_number(&mut json_document, &mut scanner).is_err() {
return json_document.errors;
}
}
QUOTATION_MARK => {
if validate_string(&mut json_document, &mut scanner).is_err() {
return json_document.errors;
}
}
BEGIN_ARRAY => {
if validate_begin_array(&mut json_document, &mut scanner).is_err() {
return json_document.errors;
}
}
END_ARRAY => {
if validate_end_array(&mut json_document, &mut scanner).is_err() {
return json_document.errors;
}
}
VALUE_SEPARATOR => {
if validate_value_separator(&mut json_document, &mut scanner).is_err() {
return json_document.errors;
}
}
BEGIN_OBJECT => {
if validate_begin_object(&mut json_document, &mut scanner).is_err() {
return json_document.errors;
}
}
END_OBJECT => {
if validate_end_object(&mut json_document, &mut scanner).is_err() {
return json_document.errors;
}
}
NAME_SEPARATOR => {
if validate_name_separator(&mut json_document, &mut scanner).is_err() {
return json_document.errors;
}
}
_ => {
let err = Error::new(ErrorType::E106, current_index, current_index + 1);
json_document.errors.push(err);
return json_document.errors;
}
}
}
if json_document.last_parsed_token.is_none() {
let last_parsed_index = scanner.current().index;
let err = Error::new(ErrorType::E100, last_parsed_index, last_parsed_index + 1);
json_document.errors.push(err);
}
if let Some(token) = json_document.stack.pop() {
match token {
StackTokens::BeginArray => {
let last_parsed_index = scanner.current().index;
let err = Error::new(ErrorType::E127, last_parsed_index, last_parsed_index + 1);
json_document.errors.push(err);
}
StackTokens::BeginObject => {
let last_parsed_index = scanner.current().index;
let err = Error::new(ErrorType::E128, last_parsed_index, last_parsed_index + 1);
json_document.errors.push(err);
}
StackTokens::NameSeparator => {
let last_parsed_index = scanner.current().index;
let err = Error::new(ErrorType::E141, last_parsed_index, last_parsed_index + 1);
json_document.errors.push(err);
}
}
}
json_document.errors
}