Skip to content

Commit d96315c

Browse files
committed
refactor(core): move files around
1 parent 7ec5ab6 commit d96315c

File tree

5 files changed

+197
-161
lines changed

5 files changed

+197
-161
lines changed
Lines changed: 12 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -1,160 +1,20 @@
1-
use std::error::Error;
2-
31
use nom::{
42
branch::alt,
5-
bytes::complete::{tag, tag_no_case, take_until, take_while, take_while1},
3+
bytes::complete::{tag, tag_no_case, take_until, take_while1},
64
character::{
75
complete::{char, space0},
86
streaming::space1,
97
},
10-
combinator::{fail, into, success, value},
11-
error::context,
8+
combinator::{fail, value},
129
multi::{many0, many1},
13-
sequence::{delimited, preceded, terminated, tuple},
14-
IResult, Parser,
10+
sequence::{delimited, terminated, tuple},
11+
IResult,
1512
};
1613

17-
// ============================================================
18-
// Query
19-
// ============================================================
20-
21-
#[derive(PartialEq, Eq, Clone, Debug)]
22-
pub enum CompareOperator {
23-
Less,
24-
LessEqual,
25-
Equal,
26-
NotEqual,
27-
Greater,
28-
GreaterEqual,
29-
}
14+
use super::query::CompareOperator;
3015

3116
#[derive(Clone, Debug)]
32-
pub enum Query {
33-
Keyword(String),
34-
Filter {
35-
key: String,
36-
op: CompareOperator,
37-
value: String,
38-
},
39-
Property {
40-
key: String,
41-
op: CompareOperator,
42-
value: String,
43-
},
44-
And(Vec<Query>),
45-
Or(Vec<Query>),
46-
Not(Box<Query>),
47-
}
48-
49-
#[derive(Debug)]
50-
pub struct InvalidSearchError;
51-
52-
impl<T: Error> From<T> for InvalidSearchError {
53-
fn from(_: T) -> Self {
54-
Self
55-
}
56-
}
57-
58-
pub fn parse(input: &str) -> Result<Query, InvalidSearchError> {
59-
let (remaining, expr) = parse_expr(input)?;
60-
61-
if !remaining.is_empty() {
62-
Err(InvalidSearchError)
63-
} else {
64-
Ok(expr.try_into()?)
65-
}
66-
}
67-
68-
enum ParseState {
69-
Normal,
70-
Not,
71-
And,
72-
Or,
73-
}
74-
75-
impl TryFrom<Expr> for Query {
76-
type Error = InvalidSearchError;
77-
78-
fn try_from(value: Expr) -> Result<Self, InvalidSearchError> {
79-
expr_to_query(value)
80-
}
81-
}
82-
83-
fn expr_to_query(expr: Expr) -> Result<Query, InvalidSearchError> {
84-
println!("Expr: {:?}", expr);
85-
86-
match expr {
87-
Expr::Sequence(mut seq) if seq.len() == 1 => Ok(expr_to_query(seq.pop().unwrap())?),
88-
Expr::Sequence(mut seq) => {
89-
let has_or = seq.iter().find(|expr| matches!(expr, Expr::Or)).is_some();
90-
91-
if has_or {
92-
let mut root: Vec<Query> = Vec::new();
93-
let mut current: Vec<Query> = Vec::new();
94-
95-
// let not_state =
96-
97-
for expr in seq.into_iter() {}
98-
99-
Ok(Query::Or(vec![]))
100-
} else {
101-
let mut root: Vec<Query> = Vec::new();
102-
let mut not_state = false;
103-
104-
for expr in seq.into_iter() {
105-
if not_state {
106-
root.push(Query::Not(Box::new(expr_to_query(expr)?)));
107-
not_state = false;
108-
} else if matches!(expr, Expr::Not) {
109-
not_state = true;
110-
} else if matches!(expr, Expr::And) {
111-
// Do nothing.
112-
} else {
113-
root.push(expr_to_query(expr)?);
114-
}
115-
}
116-
117-
Ok(vec_to_and_query(root))
118-
}
119-
}
120-
Expr::String(string) => Ok(Query::Keyword(string)),
121-
Expr::Filter { key, op, value } => Ok(Query::Filter { key, op, value }),
122-
Expr::Property { key, op, value } => Ok(Query::Property { key, op, value }),
123-
x => {
124-
println!("Not recognized: {:?}", x);
125-
Err(InvalidSearchError)
126-
} // _ => Err(InvalidSearchError),
127-
}
128-
}
129-
130-
fn vec_to_and_query(vec: Vec<Query>) -> Query {
131-
if vec.len() == 1 {
132-
vec.into_iter().next().unwrap()
133-
} else {
134-
Query::And(vec)
135-
}
136-
}
137-
138-
#[cfg(test)]
139-
mod tests {
140-
use super::*;
141-
142-
#[test]
143-
fn asdf() {
144-
let input = "aaa && (bb && !cc)";
145-
146-
println!("Result: {:?}", parse(input));
147-
148-
panic!();
149-
}
150-
}
151-
152-
// ============================================================
153-
// Expr
154-
// ============================================================
155-
156-
#[derive(Clone, Debug)]
157-
enum Expr {
17+
pub enum Expr {
15818
String(String),
15919
Not,
16020
And,
@@ -172,7 +32,7 @@ enum Expr {
17232
Sequence(Vec<Expr>),
17333
}
17434

175-
fn parse_expr(input: &str) -> IResult<&str, Expr> {
35+
pub fn parse_expr(input: &str) -> IResult<&str, Expr> {
17636
let (remaining, output) = many0(alt((parse_paren, parse_seq)))(input)?;
17737

17838
Ok((remaining, Expr::Sequence(output)))
@@ -204,28 +64,24 @@ fn parse_single(input: &str) -> IResult<&str, Expr> {
20464
}
20565

20666
fn parse_not_expr(input: &str) -> IResult<&str, Expr> {
207-
let (remaining, _) = alt((
208-
terminated(tag("!"), space0),
209-
terminated(tag_no_case("NOT"), space1),
210-
))(input)?;
67+
let (remaining, _) =
68+
alt((terminated(tag("!"), space0), terminated(tag("not"), space1)))(input)?;
21169

21270
Ok((remaining, Expr::Not))
21371
}
21472

21573
fn parse_and_expr(input: &str) -> IResult<&str, Expr> {
21674
let (remaining, _) = alt((
21775
terminated(tag("&&"), space0),
218-
terminated(tag_no_case("AND"), space1),
76+
terminated(tag("and"), space1),
21977
))(input)?;
22078

22179
Ok((remaining, Expr::And))
22280
}
22381

22482
fn parse_or_expr(input: &str) -> IResult<&str, Expr> {
225-
let (remaining, _) = alt((
226-
terminated(tag("||"), space0),
227-
terminated(tag_no_case("OR"), space1),
228-
))(input)?;
83+
let (remaining, _) =
84+
alt((terminated(tag("||"), space0), terminated(tag("or"), space1)))(input)?;
22985

23086
Ok((remaining, Expr::Or))
23187
}

crates/core/src/search/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
mod expr;
2+
3+
mod parser;
4+
pub use parser::{parse, InvalidSearchError};
5+
6+
mod query;
7+
pub use query::{CompareOperator, Query};

crates/core/src/search/parser.rs

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
use std::error::Error;
2+
3+
use super::{
4+
expr::{parse_expr, Expr},
5+
query::Query,
6+
};
7+
8+
#[derive(Debug)]
9+
pub struct InvalidSearchError;
10+
11+
impl<T: Error> From<T> for InvalidSearchError {
12+
fn from(_: T) -> Self {
13+
Self
14+
}
15+
}
16+
17+
pub fn parse(input: &str) -> Result<Query, InvalidSearchError> {
18+
let (remaining, expr) = parse_expr(input)?;
19+
20+
if !remaining.is_empty() {
21+
Err(InvalidSearchError)
22+
} else {
23+
Ok(expr_to_query(expr)?)
24+
}
25+
}
26+
27+
fn expr_to_query(expr: Expr) -> Result<Query, InvalidSearchError> {
28+
match expr {
29+
Expr::Sequence(mut seq) if seq.len() == 1 => Ok(expr_to_query(seq.pop().unwrap())?),
30+
Expr::Sequence(seq) => {
31+
let has_or = seq.iter().find(|expr| matches!(expr, Expr::Or)).is_some();
32+
33+
if has_or {
34+
let mut root: Vec<Query> = Vec::new();
35+
let mut current: Vec<Query> = Vec::new();
36+
let mut not_state = false;
37+
38+
for expr in seq.into_iter() {
39+
if not_state {
40+
current.push(Query::Not(Box::new(expr_to_query(expr)?)));
41+
not_state = false;
42+
} else if matches!(expr, Expr::Not) {
43+
not_state = true
44+
} else if matches!(expr, Expr::And) {
45+
// Do nothing.
46+
} else if matches!(expr, Expr::Or) {
47+
root.push(vec_to_and_query(current));
48+
current = Vec::new();
49+
} else {
50+
current.push(expr_to_query(expr)?);
51+
}
52+
}
53+
54+
if !current.is_empty() {
55+
root.push(vec_to_and_query(current));
56+
}
57+
58+
Ok(vec_to_or_query(root))
59+
} else {
60+
let mut root: Vec<Query> = Vec::new();
61+
let mut not_state = false;
62+
63+
for expr in seq.into_iter() {
64+
if not_state {
65+
root.push(Query::Not(Box::new(expr_to_query(expr)?)));
66+
not_state = false;
67+
} else if matches!(expr, Expr::Not) {
68+
not_state = true;
69+
} else if matches!(expr, Expr::And) {
70+
// Do nothing.
71+
} else {
72+
root.push(expr_to_query(expr)?);
73+
}
74+
}
75+
76+
Ok(vec_to_and_query(root))
77+
}
78+
}
79+
Expr::String(string) => Ok(Query::Keyword(string)),
80+
Expr::Filter { key, op, value } => Ok(Query::Filter { key, op, value }),
81+
Expr::Property { key, op, value } => Ok(Query::Property { key, op, value }),
82+
x => {
83+
println!("Not recognized: {:?}", x);
84+
Err(InvalidSearchError)
85+
}
86+
}
87+
}
88+
89+
fn parse_filter_query(expr: Expr) -> Query {
90+
match expr {
91+
Expr::Filter { key, op, value } => Query::Filter {
92+
key: key,
93+
op: op,
94+
value: value,
95+
},
96+
_ => unreachable!(),
97+
}
98+
}
99+
100+
fn vec_to_and_query(vec: Vec<Query>) -> Query {
101+
if vec.len() == 1 {
102+
vec.into_iter().next().unwrap()
103+
} else {
104+
Query::And(vec)
105+
}
106+
}
107+
108+
fn vec_to_or_query(vec: Vec<Query>) -> Query {
109+
if vec.len() == 1 {
110+
vec.into_iter().next().unwrap()
111+
} else {
112+
Query::Or(vec)
113+
}
114+
}
115+
116+
#[cfg(test)]
117+
mod tests {
118+
use super::*;
119+
120+
#[test]
121+
fn basic() {
122+
assert_eq!(parse("aa").unwrap(), Query::Keyword("aa".to_string()));
123+
124+
assert_eq!(
125+
parse(r#""aa bb""#).unwrap(),
126+
Query::Keyword("aa bb".to_string())
127+
);
128+
129+
assert_eq!(parse("key = value"))
130+
}
131+
}

crates/core/src/search/query.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#[derive(PartialEq, Eq, Clone, Debug)]
2+
pub enum CompareOperator {
3+
Less,
4+
LessEqual,
5+
Equal,
6+
NotEqual,
7+
Greater,
8+
GreaterEqual,
9+
}
10+
11+
#[derive(Clone, PartialEq, Eq, Debug)]
12+
pub enum Query {
13+
Keyword(String),
14+
Filter {
15+
key: String,
16+
op: CompareOperator,
17+
value: String,
18+
},
19+
Property {
20+
key: String,
21+
op: CompareOperator,
22+
value: String,
23+
},
24+
And(Vec<Query>),
25+
Or(Vec<Query>),
26+
Not(Box<Query>),
27+
}
28+
29+
#[derive(Clone, PartialEq, Eq, Debug)]
30+
pub enum FilterKey {
31+
Has,
32+
ChildCount,
33+
LinkCount,
34+
ParentCount,
35+
CreateTime,
36+
}

0 commit comments

Comments
 (0)