Improve graph traversal expression parsing code
This commit is contained in:
parent
1333ecf0df
commit
8ce5d01727
1 changed files with 22 additions and 69 deletions
|
@ -1,10 +1,10 @@
|
||||||
use crate::sql::comment::mightbespace;
|
use crate::sql::comment::mightbespace;
|
||||||
use crate::sql::comment::shouldbespace;
|
use crate::sql::comment::shouldbespace;
|
||||||
|
use crate::sql::cond::{cond, Cond};
|
||||||
use crate::sql::dir::{dir, Dir};
|
use crate::sql::dir::{dir, Dir};
|
||||||
use crate::sql::error::IResult;
|
use crate::sql::error::IResult;
|
||||||
use crate::sql::idiom::{idiom, Idiom};
|
use crate::sql::idiom::{idiom, Idiom};
|
||||||
use crate::sql::table::{table, tables, Tables};
|
use crate::sql::table::{table, tables, Tables};
|
||||||
use crate::sql::value::{value, Value};
|
|
||||||
use nom::branch::alt;
|
use nom::branch::alt;
|
||||||
use nom::bytes::complete::tag_no_case;
|
use nom::bytes::complete::tag_no_case;
|
||||||
use nom::character::complete::char;
|
use nom::character::complete::char;
|
||||||
|
@ -17,7 +17,7 @@ use std::fmt;
|
||||||
pub struct Graph {
|
pub struct Graph {
|
||||||
pub dir: Dir,
|
pub dir: Dir,
|
||||||
pub what: Tables,
|
pub what: Tables,
|
||||||
pub cond: Option<Value>,
|
pub cond: Option<Cond>,
|
||||||
pub alias: Option<Idiom>,
|
pub alias: Option<Idiom>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ impl fmt::Display for Graph {
|
||||||
_ => write!(f, "{}", self.what),
|
_ => write!(f, "{}", self.what),
|
||||||
}?;
|
}?;
|
||||||
if let Some(ref v) = self.cond {
|
if let Some(ref v) = self.cond {
|
||||||
write!(f, " WHERE {}", v)?
|
write!(f, " {}", v)?
|
||||||
}
|
}
|
||||||
if let Some(ref v) = self.alias {
|
if let Some(ref v) = self.alias {
|
||||||
write!(f, " AS {}", v)?
|
write!(f, " AS {}", v)?
|
||||||
|
@ -47,17 +47,12 @@ impl fmt::Display for Graph {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn graph(i: &str) -> IResult<&str, Graph> {
|
pub fn graph(i: &str) -> IResult<&str, Graph> {
|
||||||
alt((graph_in, graph_out, graph_both))(i)
|
let (i, dir) = dir(i)?;
|
||||||
}
|
|
||||||
|
|
||||||
fn graph_in(i: &str) -> IResult<&str, Graph> {
|
|
||||||
let (i, _) = char('<')(i)?;
|
|
||||||
let (i, _) = char('-')(i)?;
|
|
||||||
let (i, (what, cond, alias)) = alt((simple, custom))(i)?;
|
let (i, (what, cond, alias)) = alt((simple, custom))(i)?;
|
||||||
Ok((
|
Ok((
|
||||||
i,
|
i,
|
||||||
Graph {
|
Graph {
|
||||||
dir: Dir::In,
|
dir,
|
||||||
what,
|
what,
|
||||||
cond,
|
cond,
|
||||||
alias,
|
alias,
|
||||||
|
@ -65,81 +60,39 @@ fn graph_in(i: &str) -> IResult<&str, Graph> {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn graph_out(i: &str) -> IResult<&str, Graph> {
|
fn simple(i: &str) -> IResult<&str, (Tables, Option<Cond>, Option<Idiom>)> {
|
||||||
let (i, _) = char('-')(i)?;
|
let (i, w) = alt((any, one))(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<Value>, Option<Idiom>)> {
|
|
||||||
let (i, w) = alt((any, single))(i)?;
|
|
||||||
Ok((i, (w, None, None)))
|
Ok((i, (w, None, None)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn custom(i: &str) -> IResult<&str, (Tables, Option<Value>, Option<Idiom>)> {
|
fn custom(i: &str) -> IResult<&str, (Tables, Option<Cond>, Option<Idiom>)> {
|
||||||
let (i, _) = char('(')(i)?;
|
let (i, _) = char('(')(i)?;
|
||||||
let (i, _) = mightbespace(i)?;
|
let (i, _) = mightbespace(i)?;
|
||||||
let (i, w) = alt((any, multi))(i)?;
|
let (i, w) = alt((any, tables))(i)?;
|
||||||
let (i, c) = opt(cond)(i)?;
|
let (i, c) = opt(|i| {
|
||||||
let (i, a) = opt(alias)(i)?;
|
|
||||||
let (i, _) = mightbespace(i)?;
|
|
||||||
let (i, _) = char(')')(i)?;
|
|
||||||
Ok((i, (w, c, a)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn single(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, _) = shouldbespace(i)?;
|
||||||
let (i, _) = tag_no_case("WHERE")(i)?;
|
let (i, v) = cond(i)?;
|
||||||
let (i, _) = shouldbespace(i)?;
|
|
||||||
let (i, v) = value(i)?;
|
|
||||||
Ok((i, v))
|
Ok((i, v))
|
||||||
}
|
})(i)?;
|
||||||
|
let (i, a) = opt(|i| {
|
||||||
fn alias(i: &str) -> IResult<&str, Idiom> {
|
|
||||||
let (i, _) = shouldbespace(i)?;
|
let (i, _) = shouldbespace(i)?;
|
||||||
let (i, _) = tag_no_case("AS")(i)?;
|
let (i, _) = tag_no_case("AS")(i)?;
|
||||||
let (i, _) = shouldbespace(i)?;
|
let (i, _) = shouldbespace(i)?;
|
||||||
let (i, v) = idiom(i)?;
|
let (i, v) = idiom(i)?;
|
||||||
Ok((i, v))
|
Ok((i, v))
|
||||||
|
})(i)?;
|
||||||
|
let (i, _) = mightbespace(i)?;
|
||||||
|
let (i, _) = char(')')(i)?;
|
||||||
|
Ok((i, (w, c, a)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn one(i: &str) -> IResult<&str, Tables> {
|
||||||
|
let (i, v) = table(i)?;
|
||||||
|
Ok((i, Tables::from(v)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn any(i: &str) -> IResult<&str, Tables> {
|
||||||
|
map(char('?'), |_| Tables::default())(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
Loading…
Reference in a new issue