From 8ce5d01727402074f36de13845b569f0962cda09 Mon Sep 17 00:00:00 2001 From: Tobie Morgan Hitchcock Date: Wed, 8 Jun 2022 19:50:29 +0100 Subject: [PATCH] Improve graph traversal expression parsing code --- lib/src/sql/graph.rs | 91 +++++++++++--------------------------------- 1 file changed, 22 insertions(+), 69 deletions(-) diff --git a/lib/src/sql/graph.rs b/lib/src/sql/graph.rs index 8fb05304..190b0eb1 100644 --- a/lib/src/sql/graph.rs +++ b/lib/src/sql/graph.rs @@ -1,10 +1,10 @@ use crate::sql::comment::mightbespace; use crate::sql::comment::shouldbespace; +use crate::sql::cond::{cond, Cond}; use crate::sql::dir::{dir, Dir}; use crate::sql::error::IResult; use crate::sql::idiom::{idiom, Idiom}; use crate::sql::table::{table, tables, Tables}; -use crate::sql::value::{value, Value}; use nom::branch::alt; use nom::bytes::complete::tag_no_case; use nom::character::complete::char; @@ -17,7 +17,7 @@ use std::fmt; pub struct Graph { pub dir: Dir, pub what: Tables, - pub cond: Option, + pub cond: Option, pub alias: Option, } @@ -36,7 +36,7 @@ impl fmt::Display for Graph { _ => write!(f, "{}", self.what), }?; if let Some(ref v) = self.cond { - write!(f, " WHERE {}", v)? + write!(f, " {}", v)? } if let Some(ref v) = self.alias { write!(f, " AS {}", v)? @@ -47,17 +47,12 @@ impl fmt::Display for Graph { } pub fn graph(i: &str) -> IResult<&str, Graph> { - alt((graph_in, graph_out, graph_both))(i) -} - -fn graph_in(i: &str) -> IResult<&str, Graph> { - let (i, _) = char('<')(i)?; - let (i, _) = char('-')(i)?; + let (i, dir) = dir(i)?; let (i, (what, cond, alias)) = alt((simple, custom))(i)?; Ok(( i, Graph { - dir: Dir::In, + dir, what, cond, alias, @@ -65,83 +60,41 @@ fn graph_in(i: &str) -> IResult<&str, Graph> { )) } -fn graph_out(i: &str) -> IResult<&str, Graph> { - let (i, _) = char('-')(i)?; - let (i, _) = char('>')(i)?; - let (i, (what, cond, alias)) = alt((simple, custom))(i)?; - Ok(( - i, - Graph { - dir: Dir::Out, - what, - cond, - alias, - }, - )) -} - -fn graph_both(i: &str) -> IResult<&str, Graph> { - let (i, _) = char('<')(i)?; - let (i, _) = char('-')(i)?; - let (i, _) = char('>')(i)?; - let (i, (what, cond, alias)) = alt((simple, custom))(i)?; - Ok(( - i, - Graph { - dir: Dir::Both, - what, - cond, - alias, - }, - )) -} - -fn simple(i: &str) -> IResult<&str, (Tables, Option, Option)> { - let (i, w) = alt((any, single))(i)?; +fn simple(i: &str) -> IResult<&str, (Tables, Option, Option)> { + let (i, w) = alt((any, one))(i)?; Ok((i, (w, None, None))) } -fn custom(i: &str) -> IResult<&str, (Tables, Option, Option)> { +fn custom(i: &str) -> IResult<&str, (Tables, Option, Option)> { let (i, _) = char('(')(i)?; let (i, _) = mightbespace(i)?; - let (i, w) = alt((any, multi))(i)?; - let (i, c) = opt(cond)(i)?; - let (i, a) = opt(alias)(i)?; + let (i, w) = alt((any, tables))(i)?; + let (i, c) = opt(|i| { + let (i, _) = shouldbespace(i)?; + let (i, v) = cond(i)?; + Ok((i, v)) + })(i)?; + let (i, a) = opt(|i| { + let (i, _) = shouldbespace(i)?; + let (i, _) = tag_no_case("AS")(i)?; + let (i, _) = shouldbespace(i)?; + let (i, v) = idiom(i)?; + Ok((i, v)) + })(i)?; let (i, _) = mightbespace(i)?; let (i, _) = char(')')(i)?; Ok((i, (w, c, a))) } -fn single(i: &str) -> IResult<&str, Tables> { +fn one(i: &str) -> IResult<&str, Tables> { let (i, v) = table(i)?; Ok((i, Tables::from(v))) } -fn multi(i: &str) -> IResult<&str, Tables> { - let (i, v) = tables(i)?; - Ok((i, Tables::from(v))) -} - fn any(i: &str) -> IResult<&str, Tables> { map(char('?'), |_| Tables::default())(i) } -fn cond(i: &str) -> IResult<&str, Value> { - let (i, _) = shouldbespace(i)?; - let (i, _) = tag_no_case("WHERE")(i)?; - let (i, _) = shouldbespace(i)?; - let (i, v) = value(i)?; - Ok((i, v)) -} - -fn alias(i: &str) -> IResult<&str, Idiom> { - let (i, _) = shouldbespace(i)?; - let (i, _) = tag_no_case("AS")(i)?; - let (i, _) = shouldbespace(i)?; - let (i, v) = idiom(i)?; - Ok((i, v)) -} - #[cfg(test)] mod tests {