apply clippy lints

This commit is contained in:
freestrings
2019-06-25 18:58:25 +09:00
parent f5717d6d26
commit b910ed35f9
9 changed files with 401 additions and 412 deletions

View File

@ -17,13 +17,13 @@ fn to_f64(n: &Number) -> f64 {
}
trait Cmp {
fn cmp_bool(&self, v1: &bool, v2: &bool) -> bool;
fn cmp_bool(&self, v1: bool, v2: bool) -> bool;
fn cmp_f64(&self, v1: &f64, v2: &f64) -> bool;
fn cmp_f64(&self, v1: f64, v2: f64) -> bool;
fn cmp_string(&self, v1: &String, v2: &String) -> bool;
fn cmp_string(&self, v1: &str, v2: &str) -> bool;
fn cmp_json<'a>(&self, v1: &Vec<&'a Value>, v2: &Vec<&'a Value>) -> Vec<&'a Value>;
fn cmp_json<'a>(&self, v1: &[&'a Value], v2: &[&'a Value]) -> Vec<&'a Value>;
fn default(&self) -> bool {
false
@ -33,59 +33,59 @@ trait Cmp {
struct CmpEq;
impl Cmp for CmpEq {
fn cmp_bool(&self, v1: &bool, v2: &bool) -> bool {
fn cmp_bool(&self, v1: bool, v2: bool) -> bool {
v1 == v2
}
fn cmp_f64(&self, v1: &f64, v2: &f64) -> bool {
fn cmp_f64(&self, v1: f64, v2: f64) -> bool {
(v1 - v2).abs() == 0_f64
}
fn cmp_string(&self, v1: &str, v2: &str) -> bool {
v1 == v2
}
fn cmp_string(&self, v1: &String, v2: &String) -> bool {
v1 == v2
}
fn cmp_json<'a>(&self, v1: &Vec<&'a Value>, v2: &Vec<&'a Value>) -> Vec<&'a Value> {
v1.intersect(v2.to_vec())
fn cmp_json<'a>(&self, v1: &[&'a Value], v2: &[&'a Value]) -> Vec<&'a Value> {
v1.to_vec().intersect(v2.to_vec())
}
}
struct CmpNe;
impl Cmp for CmpNe {
fn cmp_bool(&self, v1: &bool, v2: &bool) -> bool {
fn cmp_bool(&self, v1: bool, v2: bool) -> bool {
v1 != v2
}
fn cmp_f64(&self, v1: &f64, v2: &f64) -> bool {
fn cmp_f64(&self, v1: f64, v2: f64) -> bool {
(v1 - v2).abs() != 0_f64
}
fn cmp_string(&self, v1: &str, v2: &str) -> bool {
v1 != v2
}
fn cmp_string(&self, v1: &String, v2: &String) -> bool {
v1 != v2
}
fn cmp_json<'a>(&self, v1: &Vec<&'a Value>, v2: &Vec<&'a Value>) -> Vec<&'a Value> {
v1.intersect_if(v2.to_vec(), |a, b| a != b)
fn cmp_json<'a>(&self, v1: &[&'a Value], v2: &[&'a Value]) -> Vec<&'a Value> {
v1.to_vec().intersect_if(v2.to_vec(), |a, b| a != b)
}
}
struct CmpGt;
impl Cmp for CmpGt {
fn cmp_bool(&self, v1: &bool, v2: &bool) -> bool {
fn cmp_bool(&self, v1: bool, v2: bool) -> bool {
v1 & !v2
}
fn cmp_f64(&self, v1: f64, v2: f64) -> bool {
v1 > v2
}
fn cmp_f64(&self, v1: &f64, v2: &f64) -> bool {
fn cmp_string(&self, v1: &str, v2: &str) -> bool {
v1 > v2
}
fn cmp_string(&self, v1: &String, v2: &String) -> bool {
v1 > v2
}
fn cmp_json<'a>(&self, _: &Vec<&'a Value>, _: &Vec<&'a Value>) -> Vec<&'a Value> {
fn cmp_json<'a>(&self, _: &[&'a Value], _: &[&'a Value]) -> Vec<&'a Value> {
Vec::new()
}
}
@ -93,19 +93,19 @@ impl Cmp for CmpGt {
struct CmpGe;
impl Cmp for CmpGe {
fn cmp_bool(&self, v1: &bool, v2: &bool) -> bool {
fn cmp_bool(&self, v1: bool, v2: bool) -> bool {
v1 >= v2
}
fn cmp_f64(&self, v1: &f64, v2: &f64) -> bool {
fn cmp_f64(&self, v1: f64, v2: f64) -> bool {
v1 >= v2
}
fn cmp_string(&self, v1: &String, v2: &String) -> bool {
fn cmp_string(&self, v1: &str, v2: &str) -> bool {
v1 >= v2
}
fn cmp_json<'a>(&self, _: &Vec<&'a Value>, _: &Vec<&'a Value>) -> Vec<&'a Value> {
fn cmp_json<'a>(&self, _: &[&'a Value], _: &[&'a Value]) -> Vec<&'a Value> {
Vec::new()
}
}
@ -113,19 +113,19 @@ impl Cmp for CmpGe {
struct CmpLt;
impl Cmp for CmpLt {
fn cmp_bool(&self, v1: &bool, v2: &bool) -> bool {
fn cmp_bool(&self, v1: bool, v2: bool) -> bool {
!v1 & v2
}
fn cmp_f64(&self, v1: f64, v2: f64) -> bool {
v1 < v2
}
fn cmp_f64(&self, v1: &f64, v2: &f64) -> bool {
fn cmp_string(&self, v1: &str, v2: &str) -> bool {
v1 < v2
}
fn cmp_string(&self, v1: &String, v2: &String) -> bool {
v1 < v2
}
fn cmp_json<'a>(&self, _: &Vec<&'a Value>, _: &Vec<&'a Value>) -> Vec<&'a Value> {
fn cmp_json<'a>(&self, _: &[&'a Value], _: &[&'a Value]) -> Vec<&'a Value> {
Vec::new()
}
}
@ -133,19 +133,19 @@ impl Cmp for CmpLt {
struct CmpLe;
impl Cmp for CmpLe {
fn cmp_bool(&self, v1: &bool, v2: &bool) -> bool {
fn cmp_bool(&self, v1: bool, v2: bool) -> bool {
v1 <= v2
}
fn cmp_f64(&self, v1: &f64, v2: &f64) -> bool {
fn cmp_f64(&self, v1: f64, v2: f64) -> bool {
v1 <= v2
}
fn cmp_string(&self, v1: &String, v2: &String) -> bool {
fn cmp_string(&self, v1: &str, v2: &str) -> bool {
v1 <= v2
}
fn cmp_json<'a>(&self, _: &Vec<&'a Value>, _: &Vec<&'a Value>) -> Vec<&'a Value> {
fn cmp_json<'a>(&self, _: &[&'a Value], _: &[&'a Value]) -> Vec<&'a Value> {
Vec::new()
}
}
@ -153,40 +153,40 @@ impl Cmp for CmpLe {
struct CmpAnd;
impl Cmp for CmpAnd {
fn cmp_bool(&self, v1: &bool, v2: &bool) -> bool {
*v1 && *v2
fn cmp_bool(&self, v1: bool, v2: bool) -> bool {
v1 && v2
}
fn cmp_f64(&self, v1: &f64, v2: &f64) -> bool {
v1 > &0_f64 && v2 > &0_f64
fn cmp_f64(&self, v1: f64, v2: f64) -> bool {
v1 > 0_f64 && v2 > 0_f64
}
fn cmp_string(&self, v1: &String, v2: &String) -> bool {
fn cmp_string(&self, v1: &str, v2: &str) -> bool {
!v1.is_empty() && !v2.is_empty()
}
fn cmp_json<'a>(&self, v1: &Vec<&'a Value>, v2: &Vec<&'a Value>) -> Vec<&'a Value> {
v1.intersect(v2.to_vec())
fn cmp_json<'a>(&self, v1: &[&'a Value], v2: &[&'a Value]) -> Vec<&'a Value> {
v1.to_vec().intersect(v2.to_vec())
}
}
struct CmpOr;
impl Cmp for CmpOr {
fn cmp_bool(&self, v1: &bool, v2: &bool) -> bool {
*v1 || *v2
fn cmp_bool(&self, v1: bool, v2: bool) -> bool {
v1 || v2
}
fn cmp_f64(&self, v1: &f64, v2: &f64) -> bool {
v1 > &0_f64 || v2 > &0_f64
fn cmp_f64(&self, v1: f64, v2: f64) -> bool {
v1 > 0_f64 || v2 > 0_f64
}
fn cmp_string(&self, v1: &String, v2: &String) -> bool {
fn cmp_string(&self, v1: &str, v2: &str) -> bool {
!v1.is_empty() || !v2.is_empty()
}
fn cmp_json<'a>(&self, v1: &Vec<&'a Value>, v2: &Vec<&'a Value>) -> Vec<&'a Value> {
v1.union(v2.to_vec())
fn cmp_json<'a>(&self, v1: &[&'a Value], v2: &[&'a Value]) -> Vec<&'a Value> {
v1.to_vec().union(v2.to_vec())
}
}
@ -212,12 +212,12 @@ impl<'a> ExprTerm<'a> {
_ => ExprTerm::Bool(cmp_fn.default()),
},
ExprTerm::Number(n1) => match &other {
ExprTerm::Number(n2) => ExprTerm::Bool(cmp_fn.cmp_f64(&to_f64(n1), &to_f64(n2))),
ExprTerm::Number(n2) => ExprTerm::Bool(cmp_fn.cmp_f64(to_f64(n1), to_f64(n2))),
ExprTerm::Json(_, _) => other.cmp(&self, reverse_cmp_fn, cmp_fn),
_ => ExprTerm::Bool(cmp_fn.default()),
},
ExprTerm::Bool(b1) => match &other {
ExprTerm::Bool(b2) => ExprTerm::Bool(cmp_fn.cmp_bool(b1, b2)),
ExprTerm::Bool(b2) => ExprTerm::Bool(cmp_fn.cmp_bool(*b1, *b2)),
ExprTerm::Json(_, _) => other.cmp(&self, reverse_cmp_fn, cmp_fn),
_ => ExprTerm::Bool(cmp_fn.default()),
},
@ -237,39 +237,39 @@ impl<'a> ExprTerm<'a> {
}
_ => cmp_fn.default(),
})
.map(|v| *v)
.cloned()
.collect(),
ExprTerm::Number(n2) => vec1
.iter()
.filter(|v1| match v1 {
Value::Number(n1) => cmp_fn.cmp_f64(&to_f64(n1), &to_f64(n2)),
Value::Number(n1) => cmp_fn.cmp_f64(to_f64(n1), to_f64(n2)),
Value::Object(map1) => {
if let Some(FilterKey::String(k)) = fk1 {
if let Some(Value::Number(n1)) = map1.get(k) {
return cmp_fn.cmp_f64(&to_f64(n1), &to_f64(n2));
return cmp_fn.cmp_f64(to_f64(n1), to_f64(n2));
}
}
cmp_fn.default()
}
_ => cmp_fn.default(),
})
.map(|v| *v)
.cloned()
.collect(),
ExprTerm::Bool(b2) => vec1
.iter()
.filter(|v1| match v1 {
Value::Bool(b1) => cmp_fn.cmp_bool(b1, b2),
Value::Bool(b1) => cmp_fn.cmp_bool(*b1, *b2),
Value::Object(map1) => {
if let Some(FilterKey::String(k)) = fk1 {
if let Some(Value::Bool(b1)) = map1.get(k) {
return cmp_fn.cmp_bool(b1, b2);
return cmp_fn.cmp_bool(*b1, *b2);
}
}
cmp_fn.default()
}
_ => cmp_fn.default(),
})
.map(|v| *v)
.cloned()
.collect(),
ExprTerm::Json(_, vec2) => cmp_fn.cmp_json(vec1, vec2),
};
@ -363,12 +363,7 @@ impl<'a> Into<ExprTerm<'a>> for &Vec<&'a Value> {
}
}
fn walk_all_with_str<'a>(
vec: &Vec<&'a Value>,
tmp: &mut Vec<&'a Value>,
key: &str,
is_filter: bool,
) {
fn walk_all_with_str<'a>(vec: &[&'a Value], tmp: &mut Vec<&'a Value>, key: &str, is_filter: bool) {
if is_filter {
walk(vec, tmp, &|v| match v {
Value::Object(map) if map.contains_key(key) => Some(vec![v]),
@ -385,7 +380,7 @@ fn walk_all_with_str<'a>(
}
}
fn walk_all<'a>(vec: &Vec<&'a Value>, tmp: &mut Vec<&'a Value>) {
fn walk_all<'a>(vec: &[&'a Value], tmp: &mut Vec<&'a Value>) {
walk(vec, tmp, &|v| match v {
Value::Array(vec) => Some(vec.iter().collect()),
Value::Object(map) => {
@ -399,7 +394,7 @@ fn walk_all<'a>(vec: &Vec<&'a Value>, tmp: &mut Vec<&'a Value>) {
});
}
fn walk<'a, F>(vec: &Vec<&'a Value>, tmp: &mut Vec<&'a Value>, fun: &F)
fn walk<'a, F>(vec: &[&'a Value], tmp: &mut Vec<&'a Value>, fun: &F)
where
F: Fn(&Value) -> Option<Vec<&Value>>,
{
@ -431,11 +426,11 @@ where
}
}
fn abs_index(n: &isize, len: usize) -> usize {
if n < &0_isize {
fn abs_index(n: isize, len: usize) -> usize {
if n < 0_isize {
(n + len as isize) as usize
} else {
*n as usize
n as usize
}
}
@ -469,7 +464,7 @@ impl fmt::Display for JsonPathError {
}
}
#[derive(Debug)]
#[derive(Debug, Default)]
pub struct Selector<'a, 'b> {
node: Option<Node>,
node_ref: Option<&'b Node>,
@ -482,15 +477,7 @@ pub struct Selector<'a, 'b> {
impl<'a, 'b> Selector<'a, 'b> {
pub fn new() -> Self {
Selector {
node: None,
node_ref: None,
value: None,
tokens: Vec::new(),
terms: Vec::new(),
current: None,
selectors: Vec::new(),
}
Selector::default()
}
pub fn str_path(&mut self, path: &str) -> Result<&mut Self, JsonPathError> {
@ -500,7 +487,7 @@ impl<'a, 'b> Selector<'a, 'b> {
self.node_ref.take();
}
self.node = Some(Parser::compile(path).map_err(|e| JsonPathError::Path(e))?);
self.node = Some(Parser::compile(path).map_err(JsonPathError::Path)?);
Ok(self)
}
@ -593,8 +580,8 @@ impl<'a, 'b> Selector<'a, 'b> {
}
fn in_filter<F: Fn(&Vec<&'a Value>, &mut Vec<&'a Value>) -> FilterKey>(&mut self, fun: F) {
match self.terms.pop() {
Some(peek) => match peek {
if let Some(peek) = self.terms.pop() {
match peek {
Some(v) => {
debug!("in_filter 1.: {:?}", v);
@ -616,8 +603,7 @@ impl<'a, 'b> Selector<'a, 'b> {
self.terms.push(Some(ExprTerm::Json(Some(filter_key), tmp)));
}
}
},
_ => {}
}
}
}
@ -672,7 +658,7 @@ impl<'a, 'b> Selector<'a, 'b> {
let mut tmp = Vec::new();
for c in current {
if let Value::Array(vec) = c {
let index = abs_index(&(index as isize), vec.len());
let index = abs_index(index as isize, vec.len());
if let Some(v) = c.get(index) {
tmp.push(v);
}
@ -687,19 +673,16 @@ impl<'a, 'b> Selector<'a, 'b> {
);
}
fn next_from_current_with_str(&mut self, keys: &Vec<String>) {
fn next_from_current_with_str(&mut self, keys: &[String]) {
if let Some(current) = self.current.take() {
let mut tmp = Vec::new();
for c in current {
match c {
Value::Object(map) => {
for key in keys {
if let Some(v) = map.get(key) {
tmp.push(v)
}
if let Value::Object(map) = c {
for key in keys {
if let Some(v) = map.get(key) {
tmp.push(v)
}
}
_ => {}
}
}
self.current = Some(tmp);
@ -752,12 +735,8 @@ impl<'a, 'b> Selector<'a, 'b> {
}
debug!("all_from_current_with_str: {}, {:?}", key, self.current);
}
}
impl<'a, 'b> NodeVisitor for Selector<'a, 'b> {
fn visit_token(&mut self, token: &ParseToken) {
debug!("token: {:?}, stack: {:?}", token, self.tokens);
fn compute_absolute_path_filter(&mut self, token: &ParseToken) -> bool {
if !self.selectors.is_empty() {
match token {
ParseToken::Absolute | ParseToken::Relative | ParseToken::Filter(_) => {
@ -781,240 +760,262 @@ impl<'a, 'b> NodeVisitor for Selector<'a, 'b> {
if let Some(selector) = self.selectors.last_mut() {
selector.visit_token(token);
true
} else {
false
}
}
}
impl<'a, 'b> Selector<'a, 'b> {
fn visit_absolute(&mut self) {
if self.current.is_some() {
let mut selector = Selector::default();
if let Some(value) = self.value {
selector.value = Some(value);
selector.current = Some(vec![value]);
self.selectors.push(selector);
}
return;
}
if let Some(v) = &self.value {
self.current = Some(vec![v]);
}
}
fn visit_relative(&mut self) {
if let Some(ParseToken::Array) = self.tokens.last() {
let array_token = self.tokens.pop();
if let Some(ParseToken::Leaves) = self.tokens.last() {
self.tokens.pop();
self.all_from_current();
}
self.tokens.push(array_token.unwrap());
}
self.new_filter_context();
}
fn visit_array_eof(&mut self) {
if let Some(Some(e)) = self.terms.pop() {
match e {
ExprTerm::Number(n) => {
self.next_from_current_with_num(to_f64(&n));
}
ExprTerm::String(key) => {
self.next_from_current_with_str(&[key]);
}
ExprTerm::Json(_, v) => {
if v.is_empty() {
self.current = Some(vec![&Value::Null]);
} else {
self.current = Some(v);
}
}
ExprTerm::Bool(false) => {
self.current = Some(vec![&Value::Null]);
}
_ => {}
}
}
self.tokens.pop();
}
fn visit_all(&mut self) {
if let Some(ParseToken::Array) = self.tokens.last() {
self.tokens.pop();
}
match self.tokens.last() {
Some(ParseToken::Leaves) => {
self.tokens.pop();
self.all_from_current();
}
Some(ParseToken::In) => {
self.tokens.pop();
self.next_all_from_current();
}
_ => {
self.next_all_from_current();
}
}
}
fn visit_key(&mut self, key: &str) {
if let Some(ParseToken::Array) = self.tokens.last() {
self.terms.push(Some(ExprTerm::String(key.to_string())));
return;
}
if let Some(t) = self.tokens.pop() {
if self.terms.is_empty() {
match t {
ParseToken::Leaves => self.all_from_current_with_str(key),
ParseToken::In => self.next_from_current_with_str(&[key.to_string()]),
_ => {}
}
} else {
match t {
ParseToken::Leaves => {
self.all_in_filter_with_str(key);
}
ParseToken::In => {
self.next_in_filter_with_str(key);
}
_ => {}
}
}
}
}
fn visit_keys(&mut self, keys: &[String]) {
if !self.terms.is_empty() {
unimplemented!("keys in filter");
}
if let Some(ParseToken::Array) = self.tokens.pop() {
self.next_from_current_with_str(keys);
} else {
unreachable!();
}
}
fn visit_filter(&mut self, ft: &FilterToken) {
let right = match self.terms.pop() {
Some(Some(right)) => right,
Some(None) => ExprTerm::Json(
None,
match &self.current {
Some(current) => current.to_vec(),
_ => unreachable!(),
},
),
_ => panic!("empty term right"),
};
let left = match self.terms.pop() {
Some(Some(left)) => left,
Some(None) => ExprTerm::Json(
None,
match &self.current {
Some(current) => current.to_vec(),
_ => unreachable!(),
},
),
_ => panic!("empty term left"),
};
let mut ret = None;
match ft {
FilterToken::Equal => left.eq(&right, &mut ret),
FilterToken::NotEqual => left.ne(&right, &mut ret),
FilterToken::Greater => left.gt(&right, &mut ret),
FilterToken::GreaterOrEqual => left.ge(&right, &mut ret),
FilterToken::Little => left.lt(&right, &mut ret),
FilterToken::LittleOrEqual => left.le(&right, &mut ret),
FilterToken::And => left.and(&right, &mut ret),
FilterToken::Or => left.or(&right, &mut ret),
};
if let Some(e) = ret {
self.terms.push(Some(e));
}
}
fn visit_range(&mut self, from: &Option<isize>, to: &Option<isize>, step: &Option<usize>) {
if !self.terms.is_empty() {
unimplemented!("range syntax in filter");
}
if let Some(ParseToken::Array) = self.tokens.pop() {
let mut tmp = Vec::new();
if let Some(current) = &self.current {
for v in current {
if let Value::Array(vec) = v {
let from = if let Some(from) = from {
abs_index(*from, vec.len())
} else {
0
};
let to = if let Some(to) = to {
abs_index(*to, vec.len())
} else {
vec.len()
};
for i in (from..to).step_by(match step {
Some(step) => *step,
_ => 1,
}) {
if let Some(v) = vec.get(i) {
tmp.push(v);
}
}
}
}
}
self.current = Some(tmp);
} else {
unreachable!();
}
}
fn visit_union(&mut self, indices: &[isize]) {
if !self.terms.is_empty() {
unimplemented!("union syntax in filter");
}
if let Some(ParseToken::Array) = self.tokens.pop() {
let mut tmp = Vec::new();
if let Some(current) = &self.current {
for v in current {
if let Value::Array(vec) = v {
for i in indices {
if let Some(v) = vec.get(abs_index(*i, vec.len())) {
tmp.push(v);
}
}
}
}
}
self.current = Some(tmp);
} else {
unreachable!();
}
}
}
impl<'a, 'b> NodeVisitor for Selector<'a, 'b> {
fn visit_token(&mut self, token: &ParseToken) {
debug!("token: {:?}, stack: {:?}", token, self.tokens);
if self.compute_absolute_path_filter(token) {
return;
}
match token {
ParseToken::Absolute => {
if self.current.is_some() {
let mut selector = Selector::new();
if let Some(value) = self.value {
selector.value = Some(value);
selector.current = Some(vec![value]);
self.selectors.push(selector);
}
return;
}
match &self.value {
Some(v) => self.current = Some(vec![v]),
_ => {}
}
}
ParseToken::Relative => {
if let Some(ParseToken::Array) = self.tokens.last() {
let array_token = self.tokens.pop();
if let Some(ParseToken::Leaves) = self.tokens.last() {
self.tokens.pop();
self.all_from_current();
}
self.tokens.push(array_token.unwrap());
}
self.new_filter_context();
}
ParseToken::Absolute => self.visit_absolute(),
ParseToken::Relative => self.visit_relative(),
ParseToken::In | ParseToken::Leaves | ParseToken::Array => {
self.tokens.push(token.clone());
}
ParseToken::ArrayEof => {
if let Some(Some(e)) = self.terms.pop() {
match e {
ExprTerm::Number(n) => {
self.next_from_current_with_num(to_f64(&n));
}
ExprTerm::String(key) => {
self.next_from_current_with_str(&vec![key]);
}
ExprTerm::Json(_, v) => {
if v.is_empty() {
self.current = Some(vec![&Value::Null]);
} else {
self.current = Some(v);
}
}
ExprTerm::Bool(false) => {
self.current = Some(vec![&Value::Null]);
}
_ => {}
}
}
self.tokens.pop();
}
ParseToken::All => {
match self.tokens.last() {
Some(ParseToken::Array) => {
self.tokens.pop();
}
_ => {}
}
match self.tokens.last() {
Some(ParseToken::Leaves) => {
self.tokens.pop();
self.all_from_current();
}
Some(ParseToken::In) => {
self.tokens.pop();
self.next_all_from_current();
}
_ => {
self.next_all_from_current();
}
}
}
ParseToken::ArrayEof => self.visit_array_eof(),
ParseToken::All => self.visit_all(),
ParseToken::Bool(b) => {
self.terms.push(Some(ExprTerm::Bool(*b)));
}
ParseToken::Key(key) => {
if let Some(ParseToken::Array) = self.tokens.last() {
self.terms.push(Some(ExprTerm::String(key.clone())));
return;
}
match self.tokens.pop() {
Some(t) => {
if self.terms.is_empty() {
match t {
ParseToken::Leaves => self.all_from_current_with_str(key.as_str()),
ParseToken::In => {
self.next_from_current_with_str(&vec![key.clone()])
}
_ => {}
}
} else {
match t {
ParseToken::Leaves => {
self.all_in_filter_with_str(key.as_str());
}
ParseToken::In => {
self.next_in_filter_with_str(key.as_str());
}
_ => {}
}
}
}
_ => {}
}
}
ParseToken::Keys(keys) => {
if !self.terms.is_empty() {
unimplemented!("keys in filter");
}
if let Some(ParseToken::Array) = self.tokens.pop() {
self.next_from_current_with_str(keys);
} else {
unreachable!();
}
}
ParseToken::Key(key) => self.visit_key(key),
ParseToken::Keys(keys) => self.visit_keys(keys),
ParseToken::Number(v) => {
self.terms
.push(Some(ExprTerm::Number(Number::from_f64(*v).unwrap())));
}
ParseToken::Filter(ref ft) => {
let ref right = match self.terms.pop() {
Some(Some(right)) => right,
Some(None) => ExprTerm::Json(
None,
match &self.current {
Some(current) => current.to_vec(),
_ => unreachable!(),
},
),
_ => panic!("empty term right"),
};
let left = match self.terms.pop() {
Some(Some(left)) => left,
Some(None) => ExprTerm::Json(
None,
match &self.current {
Some(current) => current.to_vec(),
_ => unreachable!(),
},
),
_ => panic!("empty term left"),
};
let mut ret = None;
match ft {
FilterToken::Equal => left.eq(right, &mut ret),
FilterToken::NotEqual => left.ne(right, &mut ret),
FilterToken::Greater => left.gt(right, &mut ret),
FilterToken::GreaterOrEqual => left.ge(right, &mut ret),
FilterToken::Little => left.lt(right, &mut ret),
FilterToken::LittleOrEqual => left.le(right, &mut ret),
FilterToken::And => left.and(right, &mut ret),
FilterToken::Or => left.or(right, &mut ret),
};
if let Some(e) = ret {
self.terms.push(Some(e));
}
}
ParseToken::Range(from, to, step) => {
if !self.terms.is_empty() {
unimplemented!("range syntax in filter");
}
if let Some(ParseToken::Array) = self.tokens.pop() {
let mut tmp = Vec::new();
if let Some(current) = &self.current {
for v in current {
if let Value::Array(vec) = v {
let from = if let Some(from) = from {
abs_index(from, vec.len())
} else {
0
};
let to = if let Some(to) = to {
abs_index(to, vec.len())
} else {
vec.len()
};
for i in (from..to).step_by(match step {
Some(step) => *step,
_ => 1,
}) {
if let Some(v) = vec.get(i) {
tmp.push(v);
}
}
}
}
}
self.current = Some(tmp);
} else {
unreachable!();
}
}
ParseToken::Union(indices) => {
if !self.terms.is_empty() {
unimplemented!("union syntax in filter");
}
if let Some(ParseToken::Array) = self.tokens.pop() {
let mut tmp = Vec::new();
if let Some(current) = &self.current {
for v in current {
if let Value::Array(vec) = v {
for i in indices {
if let Some(v) = vec.get(abs_index(i, vec.len())) {
tmp.push(v);
}
}
}
}
}
self.current = Some(tmp);
} else {
unreachable!();
}
}
ParseToken::Filter(ref ft) => self.visit_filter(ft),
ParseToken::Range(from, to, step) => self.visit_range(from, to, step),
ParseToken::Union(indices) => self.visit_union(indices),
ParseToken::Eof => {
debug!("visit_token eof");
}
@ -1022,6 +1023,7 @@ impl<'a, 'b> NodeVisitor for Selector<'a, 'b> {
}
}
#[derive(Default)]
pub struct SelectorMut {
path: Option<Node>,
value: Option<Value>,
@ -1072,14 +1074,11 @@ fn replace_value<F: FnMut(&Value) -> Value>(tokens: Vec<String>, value: &mut Val
impl SelectorMut {
pub fn new() -> Self {
SelectorMut {
path: None,
value: None,
}
Self::default()
}
pub fn str_path(&mut self, path: &str) -> Result<&mut Self, JsonPathError> {
self.path = Some(Parser::compile(path).map_err(|e| JsonPathError::Path(e))?);
self.path = Some(Parser::compile(path).map_err(JsonPathError::Path)?);
Ok(self)
}
@ -1139,7 +1138,7 @@ impl SelectorMut {
_ => {}
}
return false;
false
}
let mut visited = HashSet::new();
@ -1165,7 +1164,7 @@ impl SelectorMut {
fn select(&self) -> Result<Vec<&Value>, JsonPathError> {
if let Some(node) = &self.path {
let mut selector = Selector::new();
let mut selector = Selector::default();
selector.compiled_path(&node);
if let Some(value) = &self.value {