Skip to content

Commit

Permalink
add to string
Browse files Browse the repository at this point in the history
  • Loading branch information
besok committed Sep 28, 2024
1 parent f8ee8db commit 164a65c
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 16 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,6 @@
- Performance improvements
- Change the contract for the struct of errors
- **`0.7.0`**
- Bug fixes and api changes
- Bug fixes and api changes
- **`0.7.1`**
- add Display to JsonPath
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "jsonpath-rust"
description = "The library provides the basic functionality to find the set of the data according to the filtering query."
version = "0.7.0"
version = "0.7.1"
authors = ["BorisZhguchev <[email protected]>"]
edition = "2021"
license = "MIT"
Expand Down
29 changes: 17 additions & 12 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -378,16 +378,21 @@ impl<'a, Data> JsonPathValue<'a, Data> {

#[cfg(test)]
mod tests {
// #[test]
// fn no_value_len_field_test() {
// let json: Box<Value> =
// Box::new(json!([{"verb": "TEST","a":[1,2,3]},{"verb": "TEST","a":[1,2,3]},{"verb": "TEST"}, {"verb": "RUN"}]));
// let path: Box<JsonPath> = Box::from(
// JsonPath::from_str("$.[?(@.verb == 'TEST')].a.length()")
// .expect("the path is correct"),
// );
//
// let v = json.find_slice(&path);
// assert_eq!(v, vec![NewValue(json!(3))]);
// }
use crate::JsonPath;
use std::str::FromStr;

#[test]
fn to_string_test() {
let path: Box<JsonPath> = Box::from(
JsonPath::from_str(
"$.['a'].a..book[1:3][*][1]['a','b'][?(@)][?(@.verb == 'TEST')].a.length()",
)
.unwrap(),
);

assert_eq!(
path.to_string(),
"$.'a'.'a'..book[1:3:1][*][1]['a','b'][?(@ exists )][?(@.'verb' == \"TEST\")].'a'.length()"
);
}
}
119 changes: 117 additions & 2 deletions src/parser/model.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use super::errors::JsonPathParserError;
use super::parse_json_path;
use serde_json::Value;
use std::fmt::{Display, Formatter};
use std::{convert::TryFrom, str::FromStr};

use super::errors::JsonPathParserError;

/// The basic structures for parsing json paths.
/// The common logic of the structures pursues to correspond the internal parsing structure.
///
Expand Down Expand Up @@ -32,6 +32,26 @@ pub enum JsonPath {
Fn(Function),
}

impl Display for JsonPath {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let str = match self {
JsonPath::Root => "$".to_string(),
JsonPath::Field(e) => format!(".'{}'", e),
JsonPath::Chain(elems) => elems.iter().map(ToString::to_string).collect::<String>(),
JsonPath::Descent(e) => {
format!("..{}", e)
}
JsonPath::DescentW => "..*".to_string(),
JsonPath::Index(e) => e.to_string(),
JsonPath::Current(e) => format!("@{}", e),
JsonPath::Wildcard => "[*]".to_string(),
JsonPath::Empty => "".to_string(),
JsonPath::Fn(e) => format!(".{}", e),
};
write!(f, "{}", str)
}
}

impl TryFrom<&str> for JsonPath {
type Error = JsonPathParserError;

Expand Down Expand Up @@ -63,6 +83,16 @@ pub enum Function {
/// length()
Length,
}

impl Display for Function {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let str = match self {
Function::Length => "length()".to_string(),
};
write!(f, "{}", str)
}
}

#[derive(Debug, Clone)]
pub enum JsonPathIndex {
/// A single element in array
Expand All @@ -77,6 +107,39 @@ pub enum JsonPathIndex {
Filter(FilterExpression),
}

impl Display for JsonPathIndex {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let str = match self {
JsonPathIndex::Single(e) => format!("[{}]", e),
JsonPathIndex::UnionIndex(elems) => {
format!(
"[{}]",
elems
.iter()
.map(ToString::to_string)
.collect::<Vec<_>>()
.join(",")
)
}
JsonPathIndex::UnionKeys(elems) => {
format!(
"[{}]",
elems
.iter()
.map(|el| format!("'{}'", el))
.collect::<Vec<_>>()
.join(",")
)
}
JsonPathIndex::Slice(s, e, st) => {
format!("[{}:{}:{}]", s, e, st)
}
JsonPathIndex::Filter(filter) => format!("[?({})]", filter),
};
write!(f, "{}", str)
}
}

#[derive(Debug, Clone, PartialEq)]
pub enum FilterExpression {
/// a single expression like a > 2
Expand All @@ -89,6 +152,26 @@ pub enum FilterExpression {
Not(Box<FilterExpression>),
}

impl Display for FilterExpression {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let str = match self {
FilterExpression::Atom(left, sign, right) => {
format!("{} {} {}", left, sign, right)
}
FilterExpression::And(left, right) => {
format!("{} && {}", left, right)
}
FilterExpression::Or(left, right) => {
format!("{} || {}", left, right)
}
FilterExpression::Not(expr) => {
format!("!{}", expr)
}
};
write!(f, "{}", str)
}
}

impl FilterExpression {
pub fn exists(op: Operand) -> Self {
FilterExpression::Atom(
Expand All @@ -106,6 +189,16 @@ pub enum Operand {
Dynamic(Box<JsonPath>),
}

impl Display for Operand {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let str = match self {
Operand::Static(e) => e.to_string(),
Operand::Dynamic(e) => e.to_string(),
};
write!(f, "{}", str)
}
}

#[allow(dead_code)]
impl Operand {
pub fn val(v: Value) -> Self {
Expand All @@ -132,6 +225,28 @@ pub enum FilterSign {
Exists,
}

impl Display for FilterSign {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let str = match self {
FilterSign::Equal => "==",
FilterSign::Unequal => "!=",
FilterSign::Less => "<",
FilterSign::Greater => ">",
FilterSign::LeOrEq => "<=",
FilterSign::GrOrEq => ">=",
FilterSign::Regex => "~=",
FilterSign::In => "in",
FilterSign::Nin => "nin",
FilterSign::Size => "size",
FilterSign::NoneOf => "noneOf",
FilterSign::AnyOf => "anyOf",
FilterSign::SubSetOf => "subsetOf",
FilterSign::Exists => "exists",
};
write!(f, "{}", str)
}
}

impl FilterSign {
pub fn new(key: &str) -> Self {
match key {
Expand Down

0 comments on commit 164a65c

Please sign in to comment.