Skip to content

Commit

Permalink
no longer require explicit generic argument for query
Browse files Browse the repository at this point in the history
Signed-off-by: Runji Wang <wangrunji0408@163.com>
  • Loading branch information
wangrunji0408 committed Nov 21, 2023
1 parent a725f46 commit d0af9ce
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 18 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use sql_json_path::JsonPath;
let json = json!({"a": 1});
let path = JsonPath::new("$.a").unwrap();

let nodes = path.query::<Value>(&json).unwrap();
let nodes = path.query(&json).unwrap();
assert_eq!(nodes.len(), 1);
assert_eq!(nodes[0].to_string(), "1");
```
Expand Down
24 changes: 10 additions & 14 deletions src/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,49 +127,45 @@ impl Truth {

impl JsonPath {
/// Evaluate the JSON path against the given JSON value.
pub fn query<'a, T: Json>(&self, value: T::Borrowed<'a>) -> Result<Vec<Cow<'a, T>>> {
pub fn query<'a, T: JsonRef<'a>>(&self, value: T) -> Result<Vec<Cow<'a, T::Owned>>> {
Evaluator {
root: value,
current: value,
vars: T::Borrowed::null(),
array: T::Borrowed::null(),
vars: T::null(),
array: T::null(),
mode: self.mode,
}
.eval_expr_or_predicate(&self.expr)
}

/// Evaluate the JSON path against the given JSON value with variables.
pub fn query_with_vars<'a, T: Json>(
pub fn query_with_vars<'a, T: JsonRef<'a>>(
&self,
value: T::Borrowed<'a>,
vars: T::Borrowed<'a>,
) -> Result<Vec<Cow<'a, T>>> {
value: T,
vars: T,
) -> Result<Vec<Cow<'a, T::Owned>>> {
if !vars.is_object() {
return Err(Error::VarsNotObject);
}
Evaluator {
root: value,
current: value,
vars,
array: T::Borrowed::null(),
array: T::null(),
mode: self.mode,
}
.eval_expr_or_predicate(&self.expr)
}

/// Checks whether the JSON path returns any item for the specified JSON value.
pub fn exists<T: Json>(&self, value: T::Borrowed<'_>) -> Result<bool> {
pub fn exists<'a, T: JsonRef<'a>>(&self, value: T) -> Result<bool> {
// TODO: only checking existence can be more efficient
self.query::<T>(value).map(|v| !v.is_empty())
}

/// Checks whether the JSON path returns any item for the specified JSON value,
/// with variables.
pub fn exists_with_vars<'a, T: Json>(
&self,
value: T::Borrowed<'a>,
vars: T::Borrowed<'a>,
) -> Result<bool> {
pub fn exists_with_vars<'a, T: JsonRef<'a>>(&self, value: T, vars: T) -> Result<bool> {
// TODO: only checking existence can be more efficient
self.query_with_vars::<T>(value, vars)
.map(|v| !v.is_empty())
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
//! let json = json!({"a": 1});
//! let path = JsonPath::new("$.a").unwrap();
//!
//! let nodes = path.query::<Value>(&json).unwrap();
//! let nodes = path.query(&json).unwrap();
//! assert_eq!(nodes.len(), 1);
//! assert_eq!(nodes[0].to_string(), "1");
//! ```
Expand Down
28 changes: 28 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use std::io::Write;

fn main() {
loop {
print!("json: ");
std::io::stdout().flush().unwrap();
let mut json = String::new();
std::io::stdin().read_line(&mut json).unwrap();

print!("path: ");
std::io::stdout().flush().unwrap();
let mut path = String::new();
std::io::stdin().read_line(&mut path).unwrap();

let json: serde_json::Value = serde_json::from_str(&json).unwrap();
let path = sql_json_path::JsonPath::new(&path).unwrap();
match path.query(&json) {
Ok(values) => {
for value in values {
println!("{}", value);
}
}
Err(err) => {
println!("{}", err);
}
}
}
}
4 changes: 2 additions & 2 deletions tests/postgres.rs
Original file line number Diff line number Diff line change
Expand Up @@ -416,13 +416,13 @@ fn query_regex() {
fn jsonb_path_exists(json: &str, path: &str) -> Result<bool, EvalError> {
let json = serde_json::Value::from_str(json).unwrap();
let path = JsonPath::from_str(path).unwrap();
let list = path.query::<serde_json::Value>(&json)?;
let list = path.query(&json)?;
Ok(!list.is_empty())
}

fn jsonb_path_query(json: &str, path: &str) -> Result<Vec<String>, EvalError> {
let json = serde_json::Value::from_str(json).unwrap();
let path = JsonPath::from_str(path).unwrap();
let list = path.query::<serde_json::Value>(&json)?;
let list = path.query(&json)?;
Ok(list.into_iter().map(|v| v.to_string()).collect())
}

0 comments on commit d0af9ce

Please sign in to comment.