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::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<Value>,
|
||||
pub cond: Option<Cond>,
|
||||
pub alias: Option<Idiom>,
|
||||
}
|
||||
|
||||
|
@ -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<Value>, Option<Idiom>)> {
|
||||
let (i, w) = alt((any, single))(i)?;
|
||||
fn simple(i: &str) -> IResult<&str, (Tables, Option<Cond>, Option<Idiom>)> {
|
||||
let (i, w) = alt((any, one))(i)?;
|
||||
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, _) = 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 {
|
||||
|
||||
|
|
Loading…
Reference in a new issue