Skip to content

Commit 2c99b9b

Browse files
Compile time path (#101)
* Add initial implementation for JSONPath procedural macro Introduces `jsonpath-rust-impl` crate as a procedural macro for JSONPath parsing and validation. Includes AST definitions, Pest-based grammar, and integration with the main library. Starts refining error handling and debugging within parsing logic. * Swap syn crates, refactor CompOp, continue writing * It compiles * Overly verbose version of ToTokens on AST, will replace with macro ASAP once we know what the spec should be * Created first basic test suite with a script and now debugging * Eliminate whitespace validation via compound-atomic($) and not-atomics(!) in pest * almost all tests cleansed * Add nonempty parsing to `PestIgnoredPunctuated` Introduce `parse_terminated_nonempty` to enforce nonempty parsing for `PestIgnoredPunctuated`. Updated relevant AST nodes to use this stricter parsing function, ensuring better validation and error handling for empty input cases. * Add new compile error tests for invalid JSONPath queries These tests validate that the `json_query!` macro correctly rejects various malformed JSONPath expressions. The added cases cover scenarios like empty segments, unexpected tokens, and improper syntax for selectors. * Refactor imports and remove unused public re-exports * Rustfmt all, add trim() calls on raw strings for identifiers, and literals so that rust str->lit parsing doesn't crash on extraneous spaces. * **Consolidate and refactor compile test organization** Refactor compile tests by consolidating failing cases into a single `compile_but_expect_err.rs` file and updating test structure. Removed redundant individual files to streamline file management while retaining all test case coverage. Also adjusted parsing utilities to better handle edge cases and ensure clarity. * fmt * Refactor function parsing and add support for new keywords. All tests including rfc passing. Work still needed to remove redundant parsing logic from main crate. Updated the function parsing logic to support one-arg and two-arg functions, and check function names within the pest grammar. Adjusted syntax rules and tests to reflect these changes. * Add preliminary documentation for the `compiled-path` feature * fmt
1 parent a550f89 commit 2c99b9b

File tree

18 files changed

+2798
-8
lines changed

18 files changed

+2798
-8
lines changed

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,15 @@ regex = "1"
1717
pest = "2.7.15"
1818
pest_derive = "2.7.15"
1919
thiserror = "2.0.9"
20+
jsonpath-rust-impl = {path = "jsonpath-rust-impl", optional = true}
21+
jsonpath-ast = {path = "jsonpath-ast"}
2022

2123
[dev-dependencies]
2224
serde = { version = "1.0", features = ["derive"] }
2325
criterion = "0.5.1"
2426

27+
[features]
28+
compiled-path = ["jsonpath-ast/compiled-path", "dep:jsonpath-rust-impl"]
2529

2630
[[bench]]
2731
name = "regex"

README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,27 @@ The path is supported with the limited elements namely only the elements with th
251251
}
252252
```
253253

254+
### Compiled Paths
255+
🚧Under Construction: Unstable/Unimplemented🚧
256+
257+
By enabling the `compiled-path` feature, the following syntax becomes available:
258+
```rust
259+
fn macros() {
260+
// Existing
261+
let vec = js_path("$.values[?match(@, $.regex)]", &json)?;
262+
// New
263+
let q_ast: JpQuery = ::jsonpath_rust::json_query!($.values[?match(@, $.regex)]);
264+
}
265+
```
266+
267+
This allows for query strings to be created infallibly at compile time for applications where query strings will be static strings in source code.
268+
269+
#### Limitations Of Compiled Path Queries
270+
- Single quote strings are not allowed, however to replace this, rust's [raw string literals](https://doc.rust-lang.org/rust-by-example/std/str.html) such as `r"# ... #"` can be used.
271+
- The macro does not check whitespace, this means that with respect to whitespace, the domain of strings accepted by the macro is a superset of those accepted by the original RFC.
272+
- Due to [constraints on rust identifiers](https://internals.rust-lang.org/t/supporting-emoji-in-identifiers/16838), emoji in member name shorthands such as `json_query!( $.☺ )` are not allowed
273+
- Unicode characters still work in both string literals and bracket field access, ie: `json_query!( $["☺"] )`
274+
254275
### Python bindings
255276

256277
Python bindings ([jsonpath-rust-bindings](https://github.com/night-crawler/jsonpath-rust-bindings)) are available on

jsonpath-ast/Cargo.toml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
[package]
2+
name = "jsonpath-ast"
3+
version = "0.1.0"
4+
edition = "2024"
5+
6+
[dependencies]
7+
proc-macro2 = { version = "1.0.95", features = ["span-locations"] }
8+
pest = "2.7.15"
9+
pest_derive = "2.7.15"
10+
syn = { version = "2.0.101", features = ["default", "extra-traits"] }
11+
pest-ast = "0.3.5"
12+
from-pest = "0.3.3"
13+
syn_derive = { version = "0.2.0", optional = true }
14+
quote = "1.0.40"
15+
derive-new = "0.7.0"
16+
17+
[features]
18+
compiled-path = ["dep:syn_derive"]

0 commit comments

Comments
 (0)