jsonpath-rust 1.0.4

The library provides the basic functionality to find the set of the data according to the filtering query.
Documentation
main = ${ SOI ~ jp_query ~ EOI }
jp_query = {root ~ segments}
segments = !{(S ~ segment)*}
segment = { child_segment | descendant_segment }
child_segment = { bracketed_selection | ("." ~ (wildcard_selector | member_name_shorthand)) }
bracketed_selection = { "[" ~ S ~ selector ~ (S ~ "," ~ S ~ selector)* ~ S ~ "]" }
descendant_segment = { ".."  ~ (bracketed_selection | wildcard_selector | member_name_shorthand)}
selector = {name_selector | wildcard_selector | slice_selector| index_selector | filter_selector}

root = _{"$"}
name_selector = {string}
wildcard_selector   = {"*"}
index_selector   = {int}
int = { "0" | ("-"? ~ safe_int) }
step = {":" ~ S ~ int?}
start = {int}
end = {int}
slice_selector = { start? ~ S ~ ":" ~ S ~ end? ~ S ~ step? }
filter_selector = {"?"~ S ~ logical_expr}
logical_expr = {logical_expr_and ~ S ~ ("||" ~ S ~ logical_expr_and)*}
logical_expr_and = {atom_expr ~ S ~ ("&&" ~ S ~ atom_expr)*}
atom_expr = {paren_expr | comp_expr| test_expr}
paren_expr = {not_op? ~ S ~ "(" ~ S ~ logical_expr ~ S ~ ")"}
comp_expr = { comparable ~ S ~ comp_op ~ S ~ comparable }
test_expr = {not_op? ~ S ~ test}
test = {rel_query | jp_query | function_expr}
rel_query = {curr ~ S ~ segments}
function_expr = { ( function_name_one_arg ~ one_arg ) | ( function_name_two_arg ~ two_arg ) }
function_name_one_arg = { "length" | "value" | "count" }
function_name_two_arg = { "search" | "match" |  "in" | "nin" | "none_of" | "any_of" | "subset_of" }
function_argument = { literal | test | logical_expr }
one_arg = _{ "(" ~ S ~ function_argument ~ S ~ ")" }
two_arg = _{ "(" ~ S ~ function_argument ~ S ~ "," ~ S ~ function_argument ~ S ~ ")" }
comparable = { literal | singular_query | function_expr }
literal = { number | string | bool | null }
bool = {"true" | "false"}
null = {"null"}
singular_query = { rel_singular_query | abs_singular_query }
rel_singular_query = { curr ~ singular_query_segments }
abs_singular_query = { root ~ singular_query_segments }
singular_query_segments = { (S ~ (name_segment | index_segment))* }
name_segment = { ("[" ~ name_selector ~ "]") | ("." ~ member_name_shorthand) }
index_segment = { "[" ~ index_selector ~ "]" }
comp_op = { "==" | "!=" | "<=" | ">=" | "<" | ">" }

LCALPHA = { 'a'..'z' }


string = { "\"" ~ double_quoted* ~ "\"" | "\'" ~ single_quoted* ~ "\'" }
double_quoted = _{ unescaped | "\'" | ESC ~ "\"" | ESC ~ escapable }
single_quoted = _{ unescaped | "\"" | ESC ~ "\'" | ESC ~ escapable }
escapable = _{
    "b" | "f" | "n" | "r" | "t" | "/" | "\\" | ("u" ~ hexchar)
}

member_name_shorthand = { name_first ~ name_char* }
name_first = { ALPHA | "_" | '\u{0080}'..'\u{D7FF}' | '\u{E000}'..'\u{10FFFF}' }
name_char = { name_first | DIGIT }
not_op = {"!"}
curr = _{"@"}
ESC = _{ "\\" }
unescaped = _{
    '\u{0020}'..'\u{0021}' |
    '\u{0023}'..'\u{0026}' |
    '\u{0028}'..'\u{005B}' |
    '\u{005D}'..'\u{D7FF}' |
    '\u{E000}'..'\u{10FFFF}'
}

S = _{ WHITESPACE* }
hexchar = _{ non_surrogate | (high_surrogate ~ "\\" ~ "u" ~ low_surrogate) }
number = { (int | "-0") ~ frac? ~ exp? }
frac = { "." ~ DIGIT+ }
exp = { ("e" | "E") ~ ("-" | "+")? ~ DIGIT+ }
non_surrogate = _{ (DIGIT | "A" | "B" | "C" | "E" | "F") ~ HEXDIG{3} | ("D" ~ ('0'..'7') ~ HEXDIG{2}) }

high_surrogate = _{ "D" ~ ("8" | "9" | "A" | "B") ~ HEXDIG{2} }

low_surrogate = _{ "D" ~ ("C" | "D" | "E" | "F") ~ HEXDIG{2} }

HEXDIG = _{ DIGIT | "A" | "B" | "C" | "D" | "E" | "F" }
DIGIT = _{ ASCII_DIGIT }
DIGIT1 = _{ ASCII_NONZERO_DIGIT}
ALPHA = { ASCII_ALPHA }
WHITESPACE = _{ " " | "\t" | "\r\n" | "\n" | "\r"}

// Matches any number less than 9007199254740991 early escape for any number <= 999999999999999
safe_int = _{
    (
     DIGIT1 ~ DIGIT{0,14} ~ !ASCII_DIGIT // 1 to 15 digits (well below the max)
    | '1'..'8' ~ ASCII_DIGIT{15}
    | "900"  ~ '0'..'6' ~ ASCII_DIGIT{12}
    | "90070"             ~ ASCII_DIGIT{11}
    | "90071"  ~ '0'..'8' ~ ASCII_DIGIT{10}
    | "900719"  ~ '0'..'8' ~ ASCII_DIGIT{9}
    | "9007199"  ~ '0'..'1' ~ ASCII_DIGIT{8}
    | "90071992"  ~ '0'..'4' ~ ASCII_DIGIT{7}
    | "900719925"  ~ '0'..'3' ~ ASCII_DIGIT{6}
    | "9007199254"  ~ '0'..'6' ~ ASCII_DIGIT{5}
    | "90071992547"  ~ '0'..'3' ~ ASCII_DIGIT{4}
    | "9007199254740"  ~ '0'..'8' ~ ASCII_DIGIT{2}
    | "90071992547409"  ~ '0'..'8' ~ ASCII_DIGIT
    | "900719925474099"  ~ '0'..'1'
    ) ~ !ASCII_DIGIT
}