Skip to content

Commit 01e1153

Browse files
committed
add tests
1 parent 5da3a60 commit 01e1153

File tree

3 files changed

+114
-16
lines changed

3 files changed

+114
-16
lines changed

src/parser/macros2.rs

Lines changed: 60 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::parser::model2::{Filter, FilterAtom, FnArg, Literal, SingularQuery, Test};
1+
use crate::parser::model2::{Comparable, Filter, FilterAtom, FnArg, Literal, Segment, SingularQuery, Test};
22

33
#[macro_export]
44
macro_rules! lit {
@@ -46,7 +46,7 @@ macro_rules! q_segment {
4646
}
4747
#[macro_export]
4848
macro_rules! singular_query {
49-
(@$($segment:tt)*) => {
49+
(@ $($segment:tt)*) => {
5050
SingularQuery::Current(q_segments!($($segment)*))
5151
};
5252
($($segment:tt)*) => {
@@ -115,14 +115,14 @@ macro_rules! test {
115115

116116
#[macro_export]
117117
macro_rules! or {
118-
($($items:expr)*) => {
118+
($($items:expr),*) => {
119119
Filter::Or(vec![ $($items),* ])
120120
};
121121
}
122122

123123
#[macro_export]
124124
macro_rules! and {
125-
($($items:expr)*) => {
125+
($($items:expr),*) => {
126126
Filter::And(vec![ $($items),* ])
127127
};
128128
}
@@ -136,19 +136,71 @@ macro_rules! atom {
136136
FilterAtom::filter($filter, false)
137137
};
138138
(t! $filter:expr) => {
139-
FilterAtom::filter($filter, true)
139+
FilterAtom::test($filter, true)
140140
};
141141
(t $filter:expr) => {
142142
FilterAtom::filter($filter, false)
143143
};
144-
($lhs:expr, $s:ident, $rhs:expr) => {
144+
($lhs:expr, $s:expr, $rhs:expr) => {
145145
FilterAtom::Comparison(Box::new(cmp!($lhs, $s, $rhs)))
146146
};
147147
}
148148

149149
#[macro_export]
150150
macro_rules! cmp {
151-
($lhs:expr, $s:ident, $rhs:expr) => {
152-
Comparison::try_new($lhs, stringify!($s), $rhs).unwrap()
151+
($lhs:expr, $op:expr , $rhs:expr) => {
152+
Comparison::try_new($op, $lhs, $rhs).unwrap()
153153
}
154+
}
155+
156+
#[macro_export]
157+
macro_rules! comparable {
158+
($lit:expr) => {
159+
Comparable::Literal($lit)
160+
};
161+
(f $func:expr) => {
162+
Comparable::Function($func)
163+
};
164+
(> $sq:expr) => {
165+
Comparable::SingularQuery($sq)
166+
};
167+
}
168+
169+
#[macro_export]
170+
macro_rules! selector {
171+
(*) => {
172+
Selector::Wildcard
173+
};
174+
(?$filter:expr) => {
175+
Selector::Filter($filter)
176+
};
177+
($name:ident) => {
178+
Selector::Name(stringify!($name).to_string())
179+
};
180+
([$name:ident]) => {
181+
Selector::Name(format!("\"{}\"", stringify!($name)))
182+
};
183+
([$index:expr]) => {
184+
Selector::Index($index)
185+
};
186+
}
187+
188+
#[macro_export]
189+
macro_rules! segment {
190+
(..) => {
191+
Segment::Descendant
192+
};
193+
($selector:expr) => {
194+
Segment::Selector($selector)
195+
};
196+
($($selectors:expr),*) => {
197+
Segment::Selectors(vec![$($selectors),*])
198+
};
199+
}
200+
201+
#[macro_export]
202+
macro_rules! jq {
203+
($($segment:expr),*) => {
204+
JpQuery::new(vec![$($segment),*])
205+
};
154206
}

src/parser/parser2.rs

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::parser::model2::{Comparable, Comparison, Filter, FilterAtom, FnArg, J
55
use crate::path::JsonLike;
66
use pest::iterators::{Pair, Pairs};
77
use pest::Parser;
8+
use crate::JsonPath;
89

910
#[derive(Parser)]
1011
#[grammar = "parser/grammar/json_path_9535.pest"]
@@ -14,6 +15,20 @@ const MIN_VAL: i64 = -9007199254740991; // Minimum safe integer value in JavaScr
1415

1516
pub(super) type Parsed<T> = Result<T, JsonPathParserError>;
1617

18+
/// Parses a string into a [JsonPath].
19+
///
20+
/// # Errors
21+
///
22+
/// Returns a variant of [crate::JsonPathParserError] if the parsing operation failed.
23+
pub fn parse_json_path(jp_str: &str) -> Parsed<JpQuery>
24+
{
25+
JSPathParser::parse(Rule::main, jp_str)
26+
.map_err(Box::new)?
27+
.next()
28+
.ok_or(JsonPathParserError::UnexpectedPestOutput)
29+
.and_then(jp_query)
30+
}
31+
1732
pub fn jp_query(rule: Pair<Rule>) -> Parsed<JpQuery> {
1833
Ok(JpQuery::new(segments(rule)?))
1934
}
@@ -32,7 +47,7 @@ pub fn segment(rule: Pair<Rule>) -> Parsed<Segment> {
3247
let next = next_down(child)?;
3348
match next.as_rule() {
3449
Rule::wildcard_selector => Ok(Segment::Selector(Selector::Wildcard)),
35-
Rule::member_name_shorthand => Ok(Segment::name(next.as_str())),
50+
Rule::member_name_shorthand => Ok(Segment::name(next.as_str().trim())),
3651
Rule::bracketed_selection => {
3752
let mut selectors = vec![];
3853
for r in next.into_inner() {
@@ -58,7 +73,7 @@ pub fn segment(rule: Pair<Rule>) -> Parsed<Segment> {
5873
pub fn selector(rule: Pair<Rule>) -> Parsed<Selector> {
5974
let child = next_down(rule)?;
6075
match child.as_rule() {
61-
Rule::name_selector => Ok(Selector::Name(child.as_str().to_string())),
76+
Rule::name_selector => Ok(Selector::Name(child.as_str().trim().to_string())),
6277
Rule::wildcard_selector => Ok(Selector::Wildcard),
6378
Rule::index_selector => Ok(Selector::Index(
6479
child.as_str().parse::<i64>().map_err(|e| (e, "int"))?,
@@ -67,7 +82,7 @@ pub fn selector(rule: Pair<Rule>) -> Parsed<Selector> {
6782
let (start, end, step) = slice_selector(child)?;
6883
Ok(Selector::Slice(start, end, step))
6984
}
70-
Rule::filter_selector => Ok(Selector::Filter(logical_expr(child)?)),
85+
Rule::filter_selector => Ok(Selector::Filter(logical_expr(next_down(child)?)?)),
7186
_ => Err(child.into()),
7287
}
7388
}
@@ -76,7 +91,7 @@ pub fn function_expr(rule: Pair<Rule>) -> Parsed<TestFunction> {
7691
let mut elems = rule.into_inner();
7792
let name = elems
7893
.next()
79-
.map(|e| e.as_str())
94+
.map(|e| e.as_str().trim())
8095
.ok_or(JsonPathParserError::empty("function expression"))?
8196
;
8297
let mut args = vec![];
@@ -125,7 +140,7 @@ pub fn singular_query_segments(rule: Pair<Rule>) -> Parsed<Vec<SingularQuerySegm
125140
for r in rule.into_inner() {
126141
match r.as_rule() {
127142
Rule::name_segment => {
128-
segments.push(SingularQuerySegment::Name(next_down(r)?.as_str().to_string()));
143+
segments.push(SingularQuerySegment::Name(next_down(r)?.as_str().trim().to_string()));
129144
}
130145
Rule::index_segment => {
131146
segments.push(SingularQuerySegment::Index(
@@ -195,6 +210,7 @@ pub fn comp_expr(rule:Pair<Rule>) -> Parsed<Comparison> {
195210

196211
pub fn literal(rule: Pair<Rule>) -> Parsed<Literal> {
197212
fn parse_number(num: &str) -> Parsed<Literal> {
213+
let num = num.trim();
198214
if num.contains('.') {
199215
Ok(Literal::Float(num.parse::<f64>().map_err(|e| (e, num))?))
200216
} else {
@@ -223,6 +239,7 @@ pub fn literal(rule: Pair<Rule>) -> Parsed<Literal> {
223239

224240
pub fn filter_atom(pair: Pair<Rule>) -> Parsed<FilterAtom> {
225241
let rule = next_down(pair)?;
242+
226243
match rule.as_rule() {
227244
Rule::paren_expr => {
228245
let mut not = false;

src/parser/tests.rs

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
use crate::parser::model2::JpQuery;
2+
use crate::parser::model2::{Comparable, Filter};
3+
use crate::parser::model2::Comparison;
4+
use crate::parser::model2::FilterAtom;
5+
use crate::parser::model2::Segment;
6+
use crate::parser::model2::Selector;
17
use crate::parser::model2::Test;
28
use crate::parser::model2::FnArg;
39
use crate::parser::model2::TestFunction;
@@ -8,8 +14,8 @@ use std::fmt::Debug;
814
use pest::error::Error;
915
use pest::iterators::Pair;
1016
use pest::Parser;
11-
use crate::{lit, q_segments, q_segment, singular_query, slice, test_fn, arg, test};
12-
use crate::parser::parser2::{function_expr, literal, singular_query, singular_query_segments, slice_selector, Rule};
17+
use crate::{lit, q_segments, q_segment, singular_query, slice, test_fn, arg, test, segment, selector, atom, cmp, comparable, jq, filter, or, and};
18+
use crate::parser::parser2::{filter_atom, function_expr, jp_query, literal, singular_query, singular_query_segments, slice_selector, Rule};
1319
use std::panic;
1420

1521
struct TestPair<T> {
@@ -140,6 +146,29 @@ fn function_expr_test(){
140146
.assert("length(true)", test_fn!(length arg!(lit!(b true))))
141147
.assert("search(@, \"abc\")",
142148
test_fn!(search arg!(t test!(@ ) ), arg!(lit!(s "\"abc\""))))
143-
.assert("count(@.a)", test_fn!(count arg!(t test!(@ ))))
149+
.assert("count(@.a)", test_fn!(count arg!(t test!(@ segment!(selector!(a))))))
144150
;
145151
}
152+
153+
#[test]
154+
fn atom_test(){
155+
TestPair::new(Rule::atom_expr,filter_atom)
156+
.assert("1 > 2", atom!(comparable!(lit!(i 1)), ">" , comparable!(lit!(i 2))))
157+
.assert("!(@.a ==1 || @.b == 2)", atom!(! or!(
158+
and!( Filter::Atom(atom!(comparable!(> singular_query!(@ a)),"==", comparable!(lit!(i 1))))),
159+
and!( Filter::Atom(atom!(comparable!(> singular_query!(@ b)),"==", comparable!(lit!(i 2)))))
160+
)
161+
))
162+
;
163+
}
164+
165+
#[test]
166+
fn jq_test(){
167+
let atom = Filter::Atom(atom!(comparable!(> singular_query!(@ a b)), ">", comparable!(lit!(i 1))));
168+
TestPair::new(Rule::jp_query,jp_query)
169+
.assert("$.a.b[[email protected] > 1]",jq!(
170+
segment!(selector!(a)),segment!(selector!(b)),
171+
segment!(selector!(? or!(and!(atom))))
172+
) )
173+
;
174+
}

0 commit comments

Comments
 (0)