use super::{Token, Class};
#[derive(Debug)]
#[derive(PartialEq)]
enum ExpectedClass {
IDENTIFIER,
EQUALS,
NEWLINE,
LITERALORSEPARATOR,
LITERAL,
SEPARATOR,
}
pub fn validate(tree: &Vec<Token>) -> Option<String> {
let mut expected_token: ExpectedClass = ExpectedClass::IDENTIFIER;
let mut i = 0;
let mut line = 1;
while i < tree.len() {
if tree[i].class == Class::NEWLINE && i == 0 {
i = i + 1;
line = line + 1;
continue;
}
if tree[i].class == Class::NEWLINE && expected_token == ExpectedClass::NEWLINE {
i = i + 1;
line = line + 1;
expected_token = ExpectedClass::IDENTIFIER;
continue;
}
if tree[i].class == Class::IDENTIFIER && expected_token == ExpectedClass::IDENTIFIER {
i = i + 1;
if tree.len() - i == 0 {
return Some(format!("Key left undefined on line {}.", line));
}
expected_token = ExpectedClass::EQUALS;
continue;
}
if tree[i].class == Class::EQUALS && expected_token == ExpectedClass::EQUALS {
i = i + 1;
expected_token = ExpectedClass::LITERALORSEPARATOR;
if tree.len() - i == 0 {
return Some(format!("Key left undefined on line {}.", line));
}
continue;
}
if (tree[i].class == Class::LITERAL || tree[i].class == Class::BOOLEAN) && expected_token == ExpectedClass::LITERALORSEPARATOR {
i = i + 1;
expected_token = ExpectedClass::NEWLINE;
continue;
}
if (tree[i].class == Class::LITERAL || tree[i].class == Class::BOOLEAN) && expected_token == ExpectedClass::LITERAL {
i = i + 1;
expected_token = ExpectedClass::SEPARATOR;
continue;
}
if tree[i].class == Class::SEPARATOR && expected_token == ExpectedClass::LITERALORSEPARATOR {
if tree[i].value.clone().unwrap_or("".to_string()) == "[".to_string() {
expected_token = ExpectedClass::LITERAL;
i = i + 1;
if tree.len() - i == 0 {
return Some(format!("Key left undefined on line {}.", line));
}
continue;
} else {
return Some(format!("Invalid use of separator syntax on line {}.", line));
}
}
if tree[i].class == Class::SEPARATOR && expected_token == ExpectedClass::SEPARATOR {
if tree[i].value.clone().unwrap_or("".to_string()) == "]".to_string() {
expected_token = ExpectedClass::NEWLINE;
i = i + 1;
continue;
} else if tree[i].value.clone().unwrap_or("".to_string()) == ",".to_string() {
expected_token = ExpectedClass::LITERAL;
i = i + 1;
continue;
} else {
return Some(format!("Invalid use of separator syntax on line {}.", line));
}
}
if tree[i].value.is_none() {
return Some(format!("{:?} found where {:?} expected at line {}.", tree[i].class, expected_token, line));
} else {
return Some(format!("{:?} {} found where {:?} expected at line {}.", tree[i].class, tree[i].value.clone().unwrap_or("None".to_string()), expected_token, line));
}
}
return None;
}