use crate::dot::{Graph, SubGraph};
use crate::parser::ident::ident;
use crate::parser::statement::statements;
use crate::parser::symbols::{graph_type, id, space, strict_symbol, subgraph_symbol};
use pom::parser::{call, Parser};
use std::char;
pub fn graph<'a>() -> Parser<'a, char, Graph> {
let pattern = strict_symbol().opt() - space() + graph_type().opt() - space() + id().opt()
- space()
+ call(statements);
pattern.map(|(((strict, graph_type), id), statements)| Graph {
strict: strict.is_some(),
graph_type,
id,
statements,
})
}
pub fn sub_graph<'a>() -> Parser<'a, char, SubGraph> {
((subgraph_symbol() * space() * ident().opt()).opt() - space() + call(statements)).map(
|(id, statements)| SubGraph {
id: id.unwrap_or_else(|| None),
statements,
},
)
}
#[cfg(test)]
mod test {
#[cfg(test)]
mod graph {
use super::super::*;
use crate::dot::{Attribute, Graph, GraphType, Statement};
use pretty_assertions::assert_eq;
#[test]
fn test() {
let input1: Vec<char> = "strict digraph cool_graph { a=b; \"b\"=\"c\"; c=d }"
.chars()
.collect();
let res1 = Graph {
strict: true,
graph_type: Some(GraphType::Digraph),
id: Some("cool_graph".to_string()),
statements: vec![
Statement::IdPair(Attribute {
key: "a".to_string(),
value: "b".to_string(),
}),
Statement::IdPair(Attribute {
key: "b".to_string(),
value: "c".to_string(),
}),
Statement::IdPair(Attribute {
key: "c".to_string(),
value: "d".to_string(),
}),
],
};
match graph().parse(&input1) {
Ok(r) => assert_eq!(r, res1),
Err(e) => panic!(format!(
"failed with input: {:?} and error: {:?}",
input1, e
)),
};
}
}
#[cfg(test)]
mod sub_graph {
use super::super::*;
use crate::dot::{Attribute, Statement};
use pretty_assertions::assert_eq;
#[test]
fn mixed_tokens() {
let input1: Vec<char> = "subgraph awesome_subgraph_id { a=b; c=d }"
.chars()
.collect();
let res1 = SubGraph {
id: Some("awesome_subgraph_id".to_string()),
statements: vec![
Statement::IdPair(Attribute {
key: "a".to_string(),
value: "b".to_string(),
}),
Statement::IdPair(Attribute {
key: "c".to_string(),
value: "d".to_string(),
}),
],
};
match sub_graph().parse(&input1) {
Ok(r) => assert_eq!(r, res1),
Err(e) => panic!(format!(
"failed with input: {:?} and error: {:?}",
input1, e
)),
};
let input2: Vec<char> = "subgraph { a=b; c=d }".chars().collect();
let res2 = SubGraph {
id: None,
statements: vec![
Statement::IdPair(Attribute {
key: "a".to_string(),
value: "b".to_string(),
}),
Statement::IdPair(Attribute {
key: "c".to_string(),
value: "d".to_string(),
}),
],
};
match sub_graph().parse(&input2) {
Ok(r) => assert_eq!(r, res2),
Err(e) => panic!(format!(
"failed with input: {:?} and error: {:?}",
input2, e
)),
};
let input3: Vec<char> = "{ a=b; c=d }".chars().collect();
let res3 = SubGraph {
id: None,
statements: vec![
Statement::IdPair(Attribute {
key: "a".to_string(),
value: "b".to_string(),
}),
Statement::IdPair(Attribute {
key: "c".to_string(),
value: "d".to_string(),
}),
],
};
match sub_graph().parse(&input3) {
Ok(r) => assert_eq!(r, res3),
Err(e) => panic!(format!(
"failed with input: {:?} and error: {:?}",
input2, e
)),
};
let i = "subraph awesome_subgraph_id [a=b]";
let input4: Vec<char> = i.chars().collect();
if sub_graph().parse(&input4).is_ok() {
panic!("Should have failed with input {:?}, passed instead.", i)
}
}
}
}