diff --git a/src/parser.rs b/src/parser.rs index add5276..6f8d188 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -19,7 +19,7 @@ pub(super) struct JSPathParser; const MAX_VAL: i64 = 9007199254740991; // Maximum safe integer value in JavaScript const MIN_VAL: i64 = -9007199254740991; // Minimum safe integer value in JavaScript -pub(super) type Parsed = Result; +pub type Parsed = Result; /// Parses a string into a [JsonPath]. /// diff --git a/src/parser/errors.rs b/src/parser/errors.rs index 43f4b7c..c7fd563 100644 --- a/src/parser/errors.rs +++ b/src/parser/errors.rs @@ -6,7 +6,7 @@ use std::str::ParseBoolError; use thiserror::Error; /// This error type is used to represent errors that can occur during the parsing of JSONPath expressions. -#[derive(Error, Debug, PartialEq)] +#[derive(Error, Debug, PartialEq, Clone)] pub enum JsonPathError { #[error("Failed to parse rule: {0}")] PestError(#[from] Box>), diff --git a/src/query.rs b/src/query.rs index 498cb1b..887496c 100644 --- a/src/query.rs +++ b/src/query.rs @@ -11,7 +11,8 @@ mod test; mod test_function; use crate::parser::errors::JsonPathError; -use crate::parser::parse_json_path; +use crate::parser::model::JpQuery; +use crate::parser::{parse_json_path, Parsed}; use crate::query::queryable::Queryable; use crate::query::state::{Data, Pointer}; use state::State; @@ -62,7 +63,16 @@ impl<'a, T: Queryable> From> for QueryRef<'a, T> { /// The main function to process a JSONPath query. /// It takes a path and a value, and returns a vector of `QueryResult` thus values + paths. pub fn js_path<'a, T: Queryable>(path: &str, value: &'a T) -> Queried>> { - match parse_json_path(path)?.process(State::root(value)).data { + js_path_process(&parse_json_path(path)?, value) +} + +/// A convenience function to process a JSONPath query +/// and return a vector of values, omitting the path. +pub fn js_path_process<'a, 'b, T: Queryable>( + path: &'b JpQuery, + value: &'a T, +) -> Queried>> { + match path.process(State::root(value)).data { Data::Ref(p) => Ok(vec![p.into()]), Data::Refs(refs) => Ok(refs.into_iter().map(Into::into).collect()), Data::Value(v) => Err(v.into()), @@ -89,9 +99,9 @@ pub fn js_path_path(path: &str, value: &T) -> Queried Queried<()> { + let json1 = json!({ + "a": 1, + "b": 2, + "c": 3 + }); + let json2 = json!({ + "a": 1, + "b": 2, + "c": 3 + }); + + let jq = parse_json_path("$[?@<3]")?; + + let v1 = js_path_process(&jq, &json1)?; + let v2 = js_path_process(&jq, &json2)?; + + assert_eq!(v1, v2); + + Ok(()) + } }