use crate::error::{Error, ErrorType};
use crate::json::{ParseTokens, StackTokens, JSON};
use crate::scanner::Scanner;
fn validate(json_document: &mut JSON, scanner: &mut Scanner) -> Result<(), ()> {
let mut num: Vec<char> = Vec::new();
let next: Option<(usize, char)> = None;
let index_start = scanner.current().index;
num.push(scanner.current().character);
if scanner.current().character == '0' {
let peek = scanner.peek();
if peek
.filter(|(_, character)| character.is_ascii_digit())
.is_some()
{
let last_parsed_index = peek.unwrap().0;
let err = Error::new(ErrorType::E111, index_start, last_parsed_index + 1);
json_document.errors.push(err);
return Err(());
}
}
if scanner.current().character == '-' {
let peek = scanner.peek();
if peek.is_none() {
let last_parsed_index = scanner.current().index;
let err = Error::new(ErrorType::E110, index_start, last_parsed_index + 1);
json_document.errors.push(err);
return Err(());
}
if !peek.unwrap().1.is_ascii_digit() {
let last_parsed_index = peek.unwrap().0;
let err = Error::new(ErrorType::E110, index_start, last_parsed_index + 1);
json_document.errors.push(err);
return Err(());
}
if peek.unwrap().1 == '0' {
scanner.next();
num.push(scanner.current().character);
let peek = scanner.peek();
if peek
.filter(|(_, character)| character.is_ascii_digit())
.is_some()
{
let last_parsed_index = peek.unwrap().0;
let err = Error::new(ErrorType::E111, index_start, last_parsed_index + 1);
json_document.errors.push(err);
return Err(());
}
}
}
while scanner
.peek()
.filter(|(_, character)| character.is_ascii_digit())
.is_some()
{
scanner.next();
num.push(scanner.current().character);
}
if scanner
.peek()
.filter(|(_, character)| character == &'.')
.is_some()
{
scanner.next();
num.push(scanner.current().character);
let peek = scanner.peek();
if peek.is_none() {
let last_parsed_index = scanner.current().index;
let err = Error::new(ErrorType::E110, index_start, last_parsed_index + 1);
json_document.errors.push(err);
return Err(());
}
if !peek.unwrap().1.is_ascii_digit() {
let last_parsed_index = peek.unwrap().0;
let err = Error::new(ErrorType::E110, index_start, last_parsed_index + 1);
json_document.errors.push(err);
return Err(());
}
while scanner
.peek()
.filter(|(_, character)| character.is_ascii_digit())
.is_some()
{
scanner.next();
num.push(scanner.current().character);
}
}
if scanner
.peek()
.filter(|(_, character)| character == &'e' || character == &'E')
.is_some()
{
scanner.next();
num.push(scanner.current().character);
if scanner
.peek()
.filter(|(_, character)| character == &'+' || character == &'-')
.is_some()
{
scanner.next();
num.push(scanner.current().character);
}
let peek = scanner.peek();
if peek.is_none() {
let last_parsed_index = scanner.current().index;
let err = Error::new(ErrorType::E110, index_start, last_parsed_index + 1);
json_document.errors.push(err);
return Err(());
}
if !peek.unwrap().1.is_ascii_digit() {
let last_parsed_index = peek.unwrap().0;
let err = Error::new(ErrorType::E110, index_start, last_parsed_index + 1);
json_document.errors.push(err);
return Err(());
}
while scanner
.peek()
.filter(|(_, character)| character.is_ascii_digit())
.is_some()
{
scanner.next();
num.push(scanner.current().character);
}
}
match num.iter().collect::<String>().parse::<f64>() {
Ok(num) => {
if num < core::f64::MIN || num > core::f64::MAX {
if next.is_none() {
let last_parsed_index = scanner.current().index;
let err = Error::new(ErrorType::E112, index_start, last_parsed_index + 1);
json_document.errors.push(err);
} else {
let last_parsed_index = next.unwrap().0;
let err = Error::new(ErrorType::E112, index_start, last_parsed_index + 1);
json_document.errors.push(err);
}
Err(())
} else {
json_document.last_parsed_token = Some(ParseTokens::Number);
Ok(())
}
}
Err(_) => {
if next.is_none() {
let last_parsed_index = scanner.current().index;
let err = Error::new(ErrorType::E113, index_start, last_parsed_index + 1);
json_document.errors.push(err);
} else {
let last_parsed_index = next.unwrap().0;
let err = Error::new(ErrorType::E113, index_start, last_parsed_index + 1);
json_document.errors.push(err);
}
Err(())
}
}
}
pub fn validate_number(
json_document: &mut JSON,
scanner: &mut Scanner,
) -> Result<(), ()> {
match &json_document.last_parsed_token {
Some(last_parsed_token) => match last_parsed_token {
ParseTokens::BeginArray => validate(json_document, scanner),
ParseTokens::ValueSeparator | ParseTokens::BeginObject => {
if json_document
.stack
.last()
.unwrap_or(&StackTokens::BeginArray)
== &StackTokens::BeginObject
{
let last_parsed_index = scanner.current().index;
let err = Error::new(ErrorType::E137, last_parsed_index, last_parsed_index + 1);
json_document.errors.push(err);
Err(())
} else {
validate(json_document, scanner)
}
}
ParseTokens::NameSeparator => {
json_document.stack.pop();
json_document.object_has_valid_member = true;
validate(json_document, scanner)
}
_ => {
let last_parsed_index = scanner.current().index;
let err = Error::new(ErrorType::E109, last_parsed_index, last_parsed_index + 1);
json_document.errors.push(err);
Err(())
}
},
None => {
json_document.root_value_parsed = true;
validate(json_document, scanner)
}
}
}