pub mod parser_error;
pub mod node_type;
pub mod node;
use parser_error::ParserError;
use node_type::NodeType;
use node::Node;
struct ParserResult {
pub node_type: NodeType,
pub value: Option<String>
}
fn parse_input_str(input_str: &str) -> Result<ParserResult, ParserError> {
if input_str.len() == 1 && input_str == "." {
Ok(ParserResult {
node_type: NodeType::Identity,
value: None
})
}
else if input_str.starts_with(".") && input_str.len() > 1 {
Ok(ParserResult {
node_type: NodeType::ObjectIdentifierIndex,
value: Some(input_str.replace(".", ""))
})
}
else {
Err(ParserError::new("Invalid Syntax. Expected <filter>"))
}
}
pub fn to_ast(filter: &str) -> Result<Node, ParserError> {
if filter.len() == 0 {
return Err(ParserError::new("Cannot parse empty string. Expected <filter>"))
}
let mut children = vec!();
let parser_result = parse_input_str(filter)?;
children.push(Node::new(parser_result.node_type, None, parser_result.value));
Ok(Node::new(NodeType::Program, Some(children), None))
}
#[cfg(test)]
mod tests {
use crate::to_ast;
use crate::NodeType;
#[test]
fn identity_filter_produces_root_node() {
let ast = to_ast(".").unwrap();
assert_eq!(ast.node_type, NodeType::Program);
}
#[test]
fn identity_filter_produces_identity_node() {
let ast = to_ast(".").unwrap();
let children = ast.children.unwrap();
let child_node = children.get(0).unwrap();
assert_eq!(child_node.node_type, NodeType::Identity);
}
#[test]
fn identity_filter_produces_identity_node_has_no_value() {
let ast = to_ast(".").unwrap();
let children = ast.children.unwrap();
let child_node = children.get(0).unwrap();
assert_eq!(child_node.value, None);
}
#[test]
fn handles_empty_string_produces_error() {
let ast = to_ast("");
assert_eq!(ast.is_err(), true);
}
#[test]
fn handles_empty_string_error_has_error_message() {
let ast = to_ast("");
assert_eq!(ast.unwrap_err().message(), "Cannot parse empty string. Expected <filter>");
}
#[test]
fn handles_invalid_syntax() {
let ast = to_ast("banana");
assert_eq!(ast.unwrap_err().message(), "Invalid Syntax. Expected <filter>");
}
#[test]
fn simple_object_identifier_index_has_correct_type() {
let ast = to_ast(".foo").unwrap();
let child = &ast.children.unwrap()[0];
assert_eq!(child.node_type, NodeType::ObjectIdentifierIndex);
}
#[test]
fn simple_object_identifier_index_has_correct_identifier() {
let ast = to_ast(".foo").unwrap();
let child = &ast.children.unwrap()[0];
assert_eq!(child.value, Some("foo".to_string()));
}
}