mirror of
https://github.com/fluencelabs/jsonpath
synced 2025-06-17 10:01:29 +00:00
필터에 중첩된 상대경로 잘못찾는 문제 수정
This commit is contained in:
@ -196,7 +196,7 @@ enum ExprTerm<'a> {
|
|||||||
String(String),
|
String(String),
|
||||||
Number(Number),
|
Number(Number),
|
||||||
Bool(bool),
|
Bool(bool),
|
||||||
Json(Option<FilterKey>, Vec<&'a Value>),
|
Json(Option<Vec<&'a Value>>, Option<FilterKey>, Vec<&'a Value>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ExprTerm<'a> {
|
impl<'a> ExprTerm<'a> {
|
||||||
@ -209,20 +209,20 @@ impl<'a> ExprTerm<'a> {
|
|||||||
match &self {
|
match &self {
|
||||||
ExprTerm::String(s1) => match &other {
|
ExprTerm::String(s1) => match &other {
|
||||||
ExprTerm::String(s2) => ExprTerm::Bool(cmp_fn.cmp_string(s1, s2)),
|
ExprTerm::String(s2) => ExprTerm::Bool(cmp_fn.cmp_string(s1, s2)),
|
||||||
ExprTerm::Json(_, _) => other.cmp(&self, reverse_cmp_fn, cmp_fn),
|
ExprTerm::Json(_, _, _) => other.cmp(&self, reverse_cmp_fn, cmp_fn),
|
||||||
_ => ExprTerm::Bool(cmp_fn.default()),
|
_ => ExprTerm::Bool(cmp_fn.default()),
|
||||||
},
|
},
|
||||||
ExprTerm::Number(n1) => match &other {
|
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::Json(_, _, _) => other.cmp(&self, reverse_cmp_fn, cmp_fn),
|
||||||
_ => ExprTerm::Bool(cmp_fn.default()),
|
_ => ExprTerm::Bool(cmp_fn.default()),
|
||||||
},
|
},
|
||||||
ExprTerm::Bool(b1) => match &other {
|
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::Json(_, _, _) => other.cmp(&self, reverse_cmp_fn, cmp_fn),
|
||||||
_ => ExprTerm::Bool(cmp_fn.default()),
|
_ => ExprTerm::Bool(cmp_fn.default()),
|
||||||
},
|
},
|
||||||
ExprTerm::Json(fk1, vec1) => {
|
ExprTerm::Json(rel, fk1, vec1) => {
|
||||||
let ret: Vec<&Value> = match &other {
|
let ret: Vec<&Value> = match &other {
|
||||||
ExprTerm::String(s2) => vec1
|
ExprTerm::String(s2) => vec1
|
||||||
.iter()
|
.iter()
|
||||||
@ -272,13 +272,15 @@ impl<'a> ExprTerm<'a> {
|
|||||||
})
|
})
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect(),
|
.collect(),
|
||||||
ExprTerm::Json(_, vec2) => cmp_fn.cmp_json(vec1, vec2),
|
ExprTerm::Json(_, _, vec2) => cmp_fn.cmp_json(vec1, vec2),
|
||||||
};
|
};
|
||||||
|
|
||||||
if ret.is_empty() {
|
if ret.is_empty() {
|
||||||
ExprTerm::Bool(cmp_fn.default())
|
ExprTerm::Bool(cmp_fn.default())
|
||||||
|
} else if let Some(rel) = rel {
|
||||||
|
ExprTerm::Json(Some(rel.to_vec()), None, ret)
|
||||||
} else {
|
} else {
|
||||||
ExprTerm::Json(None, ret)
|
ExprTerm::Json(None, None, ret)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -360,7 +362,7 @@ impl<'a> Into<ExprTerm<'a>> for &Vec<&'a Value> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprTerm::Json(None, self.to_vec())
|
ExprTerm::Json(None, None, self.to_vec())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -584,10 +586,27 @@ impl<'a, 'b> Selector<'a, 'b> {
|
|||||||
debug!("in_filter 1.: {:?}", v);
|
debug!("in_filter 1.: {:?}", v);
|
||||||
|
|
||||||
match v {
|
match v {
|
||||||
ExprTerm::Json(_, vec) => {
|
ExprTerm::Json(rel, fk, vec) => {
|
||||||
let mut tmp = Vec::new();
|
let mut tmp = Vec::new();
|
||||||
let filter_key = fun(&vec, &mut tmp);
|
let filter_key = if let Some(FilterKey::String(key)) = fk {
|
||||||
self.terms.push(Some(ExprTerm::Json(Some(filter_key), tmp)));
|
fun(
|
||||||
|
&vec.iter()
|
||||||
|
.map(|v| match v {
|
||||||
|
Value::Object(map) if map.contains_key(&key) => {
|
||||||
|
map.get(&key).unwrap()
|
||||||
|
}
|
||||||
|
_ => v,
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
&mut tmp,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
fun(&vec, &mut tmp)
|
||||||
|
};
|
||||||
|
|
||||||
|
let parent = if rel.is_some() { rel } else { Some(vec) };
|
||||||
|
self.terms
|
||||||
|
.push(Some(ExprTerm::Json(parent, Some(filter_key), tmp)));
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
@ -598,7 +617,8 @@ impl<'a, 'b> Selector<'a, 'b> {
|
|||||||
if let Some(current) = &self.current {
|
if let Some(current) = &self.current {
|
||||||
let mut tmp = Vec::new();
|
let mut tmp = Vec::new();
|
||||||
let filter_key = fun(current, &mut tmp);
|
let filter_key = fun(current, &mut tmp);
|
||||||
self.terms.push(Some(ExprTerm::Json(Some(filter_key), tmp)));
|
self.terms
|
||||||
|
.push(Some(ExprTerm::Json(None, Some(filter_key), tmp)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -803,9 +823,11 @@ impl<'a, 'b> Selector<'a, 'b> {
|
|||||||
ExprTerm::String(key) => {
|
ExprTerm::String(key) => {
|
||||||
self.next_from_current_with_str(&[key]);
|
self.next_from_current_with_str(&[key]);
|
||||||
}
|
}
|
||||||
ExprTerm::Json(_, v) => {
|
ExprTerm::Json(rel, _, v) => {
|
||||||
if v.is_empty() {
|
if v.is_empty() {
|
||||||
self.current = Some(vec![&Value::Null]);
|
self.current = Some(vec![&Value::Null]);
|
||||||
|
} else if let Some(vec) = rel {
|
||||||
|
self.current = Some(vec);
|
||||||
} else {
|
} else {
|
||||||
self.current = Some(v);
|
self.current = Some(v);
|
||||||
}
|
}
|
||||||
@ -883,6 +905,7 @@ impl<'a, 'b> Selector<'a, 'b> {
|
|||||||
let right = match self.terms.pop() {
|
let right = match self.terms.pop() {
|
||||||
Some(Some(right)) => right,
|
Some(Some(right)) => right,
|
||||||
Some(None) => ExprTerm::Json(
|
Some(None) => ExprTerm::Json(
|
||||||
|
None,
|
||||||
None,
|
None,
|
||||||
match &self.current {
|
match &self.current {
|
||||||
Some(current) => current.to_vec(),
|
Some(current) => current.to_vec(),
|
||||||
@ -895,6 +918,7 @@ impl<'a, 'b> Selector<'a, 'b> {
|
|||||||
let left = match self.terms.pop() {
|
let left = match self.terms.pop() {
|
||||||
Some(Some(left)) => left,
|
Some(Some(left)) => left,
|
||||||
Some(None) => ExprTerm::Json(
|
Some(None) => ExprTerm::Json(
|
||||||
|
None,
|
||||||
None,
|
None,
|
||||||
match &self.current {
|
match &self.current {
|
||||||
Some(current) => current.to_vec(),
|
Some(current) => current.to_vec(),
|
||||||
@ -1027,7 +1051,11 @@ pub struct SelectorMut {
|
|||||||
value: Option<Value>,
|
value: Option<Value>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn replace_value<F: FnMut(Value) -> Option<Value>>(mut tokens: Vec<String>, value: &mut Value, fun: &mut F) {
|
fn replace_value<F: FnMut(Value) -> Option<Value>>(
|
||||||
|
mut tokens: Vec<String>,
|
||||||
|
value: &mut Value,
|
||||||
|
fun: &mut F,
|
||||||
|
) {
|
||||||
let mut target = value;
|
let mut target = value;
|
||||||
|
|
||||||
let last_index = tokens.len() - 1;
|
let last_index = tokens.len() - 1;
|
||||||
|
@ -663,3 +663,43 @@ fn all_filter() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn current_path() {
|
||||||
|
setup();
|
||||||
|
select_and_then_compare(
|
||||||
|
"$.a[?(@.b.c == 1)]",
|
||||||
|
json!({
|
||||||
|
"a": {
|
||||||
|
"b": {
|
||||||
|
"c": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
json!([
|
||||||
|
{
|
||||||
|
"b" : {
|
||||||
|
"c" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
|
||||||
|
select_and_then_compare(
|
||||||
|
"$.a[?(@.b.c)]",
|
||||||
|
json!({
|
||||||
|
"a": {
|
||||||
|
"b": {
|
||||||
|
"c": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
json!([
|
||||||
|
{
|
||||||
|
"b" : {
|
||||||
|
"c" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
}
|
Reference in New Issue
Block a user