csonpath 0.17.0__tar.gz → 0.19.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {csonpath-0.17.0 → csonpath-0.19.0}/Makefile +46 -6
- {csonpath-0.17.0/csonpath.egg-info → csonpath-0.19.0}/PKG-INFO +78 -24
- {csonpath-0.17.0 → csonpath-0.19.0}/README.md +77 -23
- {csonpath-0.17.0 → csonpath-0.19.0/csonpath.egg-info}/PKG-INFO +78 -24
- {csonpath-0.17.0 → csonpath-0.19.0}/csonpath.egg-info/SOURCES.txt +3 -0
- {csonpath-0.17.0 → csonpath-0.19.0}/csonpath.h +339 -158
- {csonpath-0.17.0 → csonpath-0.19.0}/csonpath_do.h +59 -11
- {csonpath-0.17.0 → csonpath-0.19.0}/csonpath_json-c.h +12 -0
- {csonpath-0.17.0 → csonpath-0.19.0}/csonpath_python.c +104 -24
- csonpath-0.19.0/csonpath_undef.h +44 -0
- csonpath-0.19.0/csonpath_yyjson.h +19 -0
- csonpath-0.17.0/csonpath_yyjson.h → csonpath-0.19.0/csonpath_yyjson_const.h +20 -4
- csonpath-0.19.0/csonpath_yyjson_mut.h +223 -0
- {csonpath-0.17.0 → csonpath-0.19.0}/pyproject.toml +2 -2
- {csonpath-0.17.0 → csonpath-0.19.0}/LICENSE +0 -0
- {csonpath-0.17.0 → csonpath-0.19.0}/MANIFEST.in +0 -0
- {csonpath-0.17.0 → csonpath-0.19.0}/configure +0 -0
- {csonpath-0.17.0 → csonpath-0.19.0}/csonpath.egg-info/dependency_links.txt +0 -0
- {csonpath-0.17.0 → csonpath-0.19.0}/csonpath.egg-info/requires.txt +0 -0
- {csonpath-0.17.0 → csonpath-0.19.0}/csonpath.egg-info/top_level.txt +0 -0
- {csonpath-0.17.0 → csonpath-0.19.0}/csonpath_my_fuzzing.h +0 -0
- {csonpath-0.17.0 → csonpath-0.19.0}/setup.cfg +0 -0
- {csonpath-0.17.0 → csonpath-0.19.0}/setup.py +0 -0
- {csonpath-0.17.0 → csonpath-0.19.0}/tiny-regex-c/.git +0 -0
- {csonpath-0.17.0 → csonpath-0.19.0}/tiny-regex-c/.github/workflows/c-cpp.yml +0 -0
- {csonpath-0.17.0 → csonpath-0.19.0}/tiny-regex-c/.gitignore +0 -0
- {csonpath-0.17.0 → csonpath-0.19.0}/tiny-regex-c/LICENSE +0 -0
- {csonpath-0.17.0 → csonpath-0.19.0}/tiny-regex-c/Makefile +0 -0
- {csonpath-0.17.0 → csonpath-0.19.0}/tiny-regex-c/README.md +0 -0
- {csonpath-0.17.0 → csonpath-0.19.0}/tiny-regex-c/clib.json +0 -0
- {csonpath-0.17.0 → csonpath-0.19.0}/tiny-regex-c/formal_verification.md +0 -0
- {csonpath-0.17.0 → csonpath-0.19.0}/tiny-regex-c/re.c +0 -0
- {csonpath-0.17.0 → csonpath-0.19.0}/tiny-regex-c/re.h +0 -0
- {csonpath-0.17.0 → csonpath-0.19.0}/tiny-regex-c/scripts/exrex.py +0 -0
- {csonpath-0.17.0 → csonpath-0.19.0}/tiny-regex-c/scripts/regex_test.py +0 -0
- {csonpath-0.17.0 → csonpath-0.19.0}/tiny-regex-c/scripts/regex_test_neg.py +0 -0
- {csonpath-0.17.0 → csonpath-0.19.0}/tiny-regex-c/tests/test1.c +0 -0
- {csonpath-0.17.0 → csonpath-0.19.0}/tiny-regex-c/tests/test2.c +0 -0
- {csonpath-0.17.0 → csonpath-0.19.0}/tiny-regex-c/tests/test3.c +0 -0
- {csonpath-0.17.0 → csonpath-0.19.0}/tiny-regex-c/tests/test_compile.c +0 -0
- {csonpath-0.17.0 → csonpath-0.19.0}/tiny-regex-c/tests/test_print.c +0 -0
- {csonpath-0.17.0 → csonpath-0.19.0}/tiny-regex-c/tests/test_rand.c +0 -0
- {csonpath-0.17.0 → csonpath-0.19.0}/tiny-regex-c/tests/test_rand_neg.c +0 -0
- {csonpath-0.17.0 → csonpath-0.19.0}/tiny-regex-c/tests/test_thread.c +0 -0
|
@@ -5,7 +5,7 @@ YYJSON_LDFLAGS=$(shell pkg-config --libs yyjson)
|
|
|
5
5
|
|
|
6
6
|
include config.mk
|
|
7
7
|
|
|
8
|
-
all: test-json-c-get-a test-json-update test-json-filter test-json-subpath test-json-c-array-root test-json-filter-and-missing-key test-json-get-array-big-index test-json-union test-json-audit-bugs test-json-crash-vectors test-json-my-fuzz
|
|
8
|
+
all: test-json-c-get-a test-json-update test-json-filter test-json-subpath test-json-c-array-root test-json-filter-and-missing-key test-json-get-array-big-index test-json-union test-json-audit-bugs test-json-crash-vectors test-json-my-fuzz test-json-regex-overflow
|
|
9
9
|
|
|
10
10
|
YYJSON_TESTS=test-yyjson
|
|
11
11
|
|
|
@@ -15,7 +15,7 @@ bench:
|
|
|
15
15
|
bench-clean:
|
|
16
16
|
make -C bench clean
|
|
17
17
|
|
|
18
|
-
.PHONY: all clean tests pip-dev pip-dev bench bench-clean tests-cli
|
|
18
|
+
.PHONY: all clean tests pip-dev pip-dev bench bench-clean tests-cli tests-rust cov
|
|
19
19
|
|
|
20
20
|
CFLAGS+= -Wall -Wextra -Wno-unused-function -Wno-unused-parameter -O0 -g
|
|
21
21
|
|
|
@@ -52,10 +52,19 @@ test-json-crash-vectors: tests/json-c/crash-vectors.c csonpath_json-c.h csonpath
|
|
|
52
52
|
test-json-my-fuzz: tests/json-c/my_fuzz.c csonpath_json-c.h csonpath_my_fuzzing.h csonpath.h csonpath_do.h
|
|
53
53
|
$(CC) tests/json-c/my_fuzz.c $(EXTRA_FILES) $(JSON_C_CFLAGS) $(CFLAGS) -Wno-format -I./ -o test-json-my-fuzz $(JSON_C_LDFLAGS) $(LDFLAGS)
|
|
54
54
|
|
|
55
|
-
test-
|
|
55
|
+
test-json-regex-overflow: tests/json-c/regex-overflow.c csonpath_json-c.h csonpath.h csonpath_do.h
|
|
56
|
+
$(CC) tests/json-c/regex-overflow.c $(EXTRA_FILES) $(JSON_C_CFLAGS) $(CFLAGS) -Wno-format -I./ -o test-json-regex-overflow $(JSON_C_LDFLAGS) $(LDFLAGS)
|
|
57
|
+
|
|
58
|
+
test-yyjson: tests/yyjson/test-yyjson.c csonpath_yyjson_const.h csonpath.h csonpath_do.h
|
|
56
59
|
$(CC) tests/yyjson/test-yyjson.c $(EXTRA_FILES) $(YYJSON_CFLAGS) $(CFLAGS) -Wno-format -I./ -o test-yyjson $(YYJSON_LDFLAGS) $(LDFLAGS)
|
|
57
60
|
|
|
58
|
-
|
|
61
|
+
test-yyjson-mixed: tests/yyjson/test-yyjson-mixed.c csonpath_yyjson.h csonpath_yyjson_const.h csonpath_yyjson_mut.h csonpath.h csonpath_do.h
|
|
62
|
+
$(CC) tests/yyjson/test-yyjson-mixed.c $(EXTRA_FILES) $(YYJSON_CFLAGS) $(CFLAGS) -Wno-format -I./ -o test-yyjson-mixed $(YYJSON_LDFLAGS) $(LDFLAGS)
|
|
63
|
+
|
|
64
|
+
test-multi-backend-prefix: tests/multi-backend-prefix.c csonpath_json-c.h csonpath_yyjson.h csonpath_yyjson_const.h csonpath_yyjson_mut.h csonpath.h csonpath_do.h
|
|
65
|
+
$(CC) tests/multi-backend-prefix.c $(EXTRA_FILES) $(JSON_C_CFLAGS) $(YYJSON_CFLAGS) $(CFLAGS) -Wno-format -I./ -o test-multi-backend-prefix $(JSON_C_LDFLAGS) $(YYJSON_LDFLAGS) $(LDFLAGS)
|
|
66
|
+
|
|
67
|
+
tests-c: test-json-c-get-a test-json-update test-json-filter test-json-subpath test-json-c-array-root test-json-filter-and-missing-key test-json-get-array-big-index test-json-union test-json-audit-bugs test-json-crash-vectors test-yyjson test-yyjson-mixed test-json-my-fuzz test-multi-backend-prefix test-json-regex-overflow
|
|
59
68
|
./test-json-c-get-a
|
|
60
69
|
./test-json-update
|
|
61
70
|
./test-json-filter
|
|
@@ -67,7 +76,10 @@ tests-c: test-json-c-get-a test-json-update test-json-filter test-json-subpath t
|
|
|
67
76
|
./test-json-audit-bugs
|
|
68
77
|
./test-json-crash-vectors
|
|
69
78
|
./test-yyjson
|
|
79
|
+
./test-yyjson-mixed
|
|
70
80
|
./test-json-my-fuzz
|
|
81
|
+
./test-multi-backend-prefix
|
|
82
|
+
./test-json-regex-overflow
|
|
71
83
|
|
|
72
84
|
csonpath: cli/csonpath_cli.c csonpath_json-c.h csonpath.h csonpath_do.h
|
|
73
85
|
$(CC) cli/csonpath_cli.c $(EXTRA_FILES) $(JSON_C_CFLAGS) $(CFLAGS) -I./ -o csonpath $(JSON_C_LDFLAGS) $(LDFLAGS)
|
|
@@ -81,8 +93,36 @@ pip-dev:
|
|
|
81
93
|
tests-py: pip-dev
|
|
82
94
|
python -m pytest
|
|
83
95
|
|
|
84
|
-
tests:
|
|
96
|
+
tests-rust:
|
|
97
|
+
cargo test --manifest-path rust/Cargo.toml
|
|
98
|
+
|
|
99
|
+
cov:
|
|
100
|
+
$(MAKE) clean
|
|
101
|
+
rm -rf coverage-c coverage-c.html coverage-py coverage-rust build
|
|
102
|
+
find . -name '*.gcov' -delete
|
|
103
|
+
$(MAKE) CFLAGS='--coverage -O0 -g' LDFLAGS='--coverage' tests-c
|
|
104
|
+
$(MAKE) CFLAGS='--coverage -O0 -g' LDFLAGS='--coverage' csonpath
|
|
105
|
+
bash tests/cli/run.sh ./csonpath
|
|
106
|
+
CFLAGS='--coverage -O0' LDFLAGS='--coverage' python setup.py build_ext --inplace --force
|
|
107
|
+
python -m coverage run -m pytest
|
|
108
|
+
python -m coverage html -d coverage-py
|
|
109
|
+
python -m gcovr -r . \
|
|
110
|
+
--gcov-object-directory "$$(ls -d build/temp.* 2>/dev/null | head -1)" \
|
|
111
|
+
--filter 'csonpath\.h' --filter 'csonpath_do\.h' --filter 'csonpath_python\.c' \
|
|
112
|
+
--html-details coverage-c.html
|
|
113
|
+
PATH="$$HOME/.cargo/bin:$$PATH" \
|
|
114
|
+
LLVM_COV="$$(find $$HOME/.rustup/toolchains -name llvm-cov -print -quit)" \
|
|
115
|
+
LLVM_PROFDATA="$$(find $$HOME/.rustup/toolchains -name llvm-profdata -print -quit)" \
|
|
116
|
+
cargo llvm-cov --manifest-path rust/Cargo.toml --html --output-dir coverage-rust
|
|
117
|
+
@echo "Coverage reports:"
|
|
118
|
+
@echo " coverage-c.html"
|
|
119
|
+
@echo " coverage-py/index.html"
|
|
120
|
+
@echo " coverage-rust/html/index.html"
|
|
121
|
+
|
|
122
|
+
tests: tests-py tests-c tests-cli tests-rust
|
|
85
123
|
|
|
86
124
|
clean:
|
|
87
|
-
rm -rvf test-json-c-get-a test-json-update test-json-filter test-json-subpath test-json-c-array-root test-json-filter-and-missing-key test-json-get-array-big-index test-json-union test-json-audit-bugs test-json-crash-vectors test-yyjson test-json-my-fuzz csonpath
|
|
125
|
+
rm -rvf test-json-c-get-a test-json-update test-json-filter test-json-subpath test-json-c-array-root test-json-filter-and-missing-key test-json-get-array-big-index test-json-union test-json-audit-bugs test-json-crash-vectors test-yyjson test-yyjson-mixed test-json-my-fuzz test-multi-backend-prefix test-json-regex-overflow csonpath
|
|
126
|
+
find . -name '*.gcda' -delete
|
|
127
|
+
find . -name '*.gcno' -delete
|
|
88
128
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: csonpath
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.19.0
|
|
4
4
|
Description-Content-Type: text/markdown
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Provides-Extra: dev
|
|
@@ -13,9 +13,9 @@ Dynamic: license-file
|
|
|
13
13
|
|
|
14
14
|
[](https://docs.outscale.com/en/userguide/Open-Source-Projects.html)
|
|
15
15
|
|
|
16
|
-
**csonpath** is a partial [JSONPath](https://goessner.net/articles/JsonPath/) implementation in C
|
|
16
|
+
**csonpath** is a partial [JSONPath](https://goessner.net/articles/JsonPath/) implementation in C. It is **backend-agnostic**: the same core engine can query, update, and remove data from any value representation that supports array, object, and scalar semantics—not just JSON.
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
Out of the box it ships with C backends for [json-c](https://github.com/json-c/json-c) and [yyjson](https://github.com/ibireme/yyjson), plus language bindings for **Python** and **Rust**.
|
|
19
19
|
|
|
20
20
|
---
|
|
21
21
|
|
|
@@ -30,6 +30,7 @@ Unlike many JSONPath libraries, csonpath is **backend-agnostic**: it can work wi
|
|
|
30
30
|
| Array index | `$.array[0]` | Access by zero-based index |
|
|
31
31
|
| Wildcard `[*]` | `$.array[*].field` | Iterate all array elements |
|
|
32
32
|
| Recursive descent `..` | `$..name` | Search recursively for a key |
|
|
33
|
+
| Recursive descent wildcard `..*` | `$..*` | Return all descendants |
|
|
33
34
|
| Union `,` (inside brackets) | `$['a','b']`, `$.array[0,1]`, `$.items[?n==1, ?n==2]` | Match all listed selectors at once |
|
|
34
35
|
| OR fallback `\|` | `$.a \| $.b` | Try the left path first; fall back to the right one if it does not match. Only the first successful path is used. |
|
|
35
36
|
| Filters | `$.items[?price > 10]` | Filter array elements |
|
|
@@ -37,6 +38,7 @@ Unlike many JSONPath libraries, csonpath is **backend-agnostic**: it can work wi
|
|
|
37
38
|
| Multiple filters (`&`) | `$.items[?a=1 & b=2]` | Combine conditions |
|
|
38
39
|
| Subpath expressions | `$.obj[$.key]` | Use JSON values as dynamic path keys |
|
|
39
40
|
| `@` current object | `$.items[?@.price > 10]` | Reference the current element in filters |
|
|
41
|
+
| Type selectors | `$..["@odata.id"]@string()`, `$.*@integer()` | Filter matches by JSON type (`string`, `integer`, `null`) |
|
|
40
42
|
|
|
41
43
|
### Operations
|
|
42
44
|
- **Find First** — retrieve the first match.
|
|
@@ -63,6 +65,7 @@ Unlike many JSONPath libraries, csonpath is **backend-agnostic**: it can work wi
|
|
|
63
65
|
- [C API Reference](#-c-api-reference)
|
|
64
66
|
- [Python API Reference](#-python-api-reference)
|
|
65
67
|
- [CLI](#%EF%B8%8F-cli)
|
|
68
|
+
- [Using Multiple Backends](#-using-multiple-backends)
|
|
66
69
|
- [Custom Backends](#-custom-backends)
|
|
67
70
|
- [Running Tests](#-running-tests)
|
|
68
71
|
- [Directory Structure](#-directory-structure)
|
|
@@ -73,12 +76,12 @@ Unlike many JSONPath libraries, csonpath is **backend-agnostic**: it can work wi
|
|
|
73
76
|
|
|
74
77
|
## 📦 Installation
|
|
75
78
|
|
|
76
|
-
|
|
77
|
-
- C compiler (`gcc` or `clang`)
|
|
78
|
-
- [json-c](https://github.com/json-c/json-c) library (for C usage)
|
|
79
|
-
- Python 3.x (for Python bindings)
|
|
79
|
+
csonpath is a C library at its core. Pick the instructions for the language you want to use it from.
|
|
80
80
|
|
|
81
81
|
### C (json-c)
|
|
82
|
+
|
|
83
|
+
**Prerequisites:** C compiler (`gcc`, `clang`, or `tcc`), [json-c](https://github.com/json-c/json-c).
|
|
84
|
+
|
|
82
85
|
Just include the header in your project. There is no separate install step required:
|
|
83
86
|
```c
|
|
84
87
|
#include "csonpath_json-c.h"
|
|
@@ -88,21 +91,23 @@ Make sure to link against `json-c` when compiling:
|
|
|
88
91
|
gcc myapp.c -o myapp $(pkg-config --cflags --libs json-c)
|
|
89
92
|
```
|
|
90
93
|
|
|
91
|
-
### C (
|
|
92
|
-
The Rust backend is located in `rust/`. It builds both a safe Rust API and the C glue required by the csonpath core.
|
|
94
|
+
### C (yyjson)
|
|
93
95
|
|
|
94
|
-
|
|
95
|
-
cd rust
|
|
96
|
-
cargo build
|
|
97
|
-
cargo test
|
|
98
|
-
```
|
|
96
|
+
**Prerequisites:** C compiler (`gcc`, `clang`, or `tcc`), [yyjson](https://github.com/ibireme/yyjson).
|
|
99
97
|
|
|
100
|
-
To use it from C, include the backend header and link against the produced static library:
|
|
101
98
|
```c
|
|
102
|
-
#include "
|
|
99
|
+
#include "csonpath_yyjson.h"
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Link against `yyjson` when compiling:
|
|
103
|
+
```sh
|
|
104
|
+
gcc myapp.c -o myapp $(pkg-config --cflags --libs yyjson)
|
|
103
105
|
```
|
|
104
106
|
|
|
105
107
|
### Python
|
|
108
|
+
|
|
109
|
+
**Prerequisites:** Python 3.x.
|
|
110
|
+
|
|
106
111
|
Install from PyPI:
|
|
107
112
|
```sh
|
|
108
113
|
pip install csonpath
|
|
@@ -115,6 +120,23 @@ pip install .
|
|
|
115
120
|
make pip-dev
|
|
116
121
|
```
|
|
117
122
|
|
|
123
|
+
### Rust
|
|
124
|
+
|
|
125
|
+
**Prerequisites:** Rust toolchain.
|
|
126
|
+
|
|
127
|
+
The Rust crate is located in `rust/`. Build and test it with:
|
|
128
|
+
```sh
|
|
129
|
+
cd rust
|
|
130
|
+
cargo build
|
|
131
|
+
cargo test
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
To depend on it from another Rust project:
|
|
135
|
+
```toml
|
|
136
|
+
[dependencies]
|
|
137
|
+
csonpath = { path = "rust" }
|
|
138
|
+
```
|
|
139
|
+
|
|
118
140
|
---
|
|
119
141
|
|
|
120
142
|
## 🛠️ Usage
|
|
@@ -195,6 +217,8 @@ p.update_or_create_callback(dst, my_sync_fn, userdata)
|
|
|
195
217
|
|
|
196
218
|
## 📘 C API Reference
|
|
197
219
|
|
|
220
|
+
The reference below uses the **json-c** backend as an example (`struct json_object *`). All backends expose the same functions with their own value type.
|
|
221
|
+
|
|
198
222
|
```c
|
|
199
223
|
struct csonpath *csonpath_new(const char *path);
|
|
200
224
|
```
|
|
@@ -337,17 +361,47 @@ echo '{"a": 1, "b": 2}' | ./csonpath -d '$.b'
|
|
|
337
361
|
|
|
338
362
|
---
|
|
339
363
|
|
|
364
|
+
## 🧩 Using Multiple Backends
|
|
365
|
+
|
|
366
|
+
You can include more than one csonpath backend in the same translation unit, provided you prefix all but one of them to avoid symbol collisions. Define `CSONPATH_USE_PREFIX` before a backend header to prefix its API with the backend name.
|
|
367
|
+
|
|
368
|
+
For example, to use both json-c and the immutable yyjson backend in the same file:
|
|
369
|
+
|
|
370
|
+
```c
|
|
371
|
+
#define CSONPATH_USE_PREFIX
|
|
372
|
+
#include "csonpath_json-c.h"
|
|
373
|
+
|
|
374
|
+
#undef CSONPATH_USE_PREFIX
|
|
375
|
+
#include "csonpath_yyjson_const.h"
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
To use both yyjson backends (immutable and mutable) together, include the aggregator header:
|
|
379
|
+
|
|
380
|
+
```c
|
|
381
|
+
#include "csonpath_yyjson.h"
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
When using the mutable yyjson backend, assign the document pointer to `backend_ctx` before mutable operations:
|
|
385
|
+
|
|
386
|
+
```c
|
|
387
|
+
struct csonpath *mp = yyjson_mut_csonpath_new("$.a");
|
|
388
|
+
mp->backend_ctx = mdoc;
|
|
389
|
+
yyjson_mut_csonpath_update_or_create(mp, mroot, new_val);
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
---
|
|
393
|
+
|
|
340
394
|
## 🔌 Custom Backends
|
|
341
395
|
|
|
342
|
-
csonpath is designed to be backend-agnostic.
|
|
396
|
+
csonpath is designed to be backend-agnostic. The C core manipulates opaque value pointers through a small set of macros, so it can work with any data structure that supports array, object, and scalar semantics.
|
|
343
397
|
|
|
344
|
-
To create a custom backend, define the required macros and types in a header file (similar to `csonpath_json-c.h` or `
|
|
398
|
+
A backend is an adapter that implements those macros for a concrete value representation. To create a custom backend, define the required macros and types in a header file (similar to `csonpath_json-c.h` or `csonpath_yyjson.h`), then include your backend header before `csonpath.h`.
|
|
345
399
|
|
|
346
|
-
|
|
347
|
-
- `csonpath_json-c.h` — json-c
|
|
348
|
-
- `csonpath_yyjson.h` — yyjson
|
|
349
|
-
- `csonpath_python.c` — Python
|
|
350
|
-
- `rust/csonpath_rust_backend.h` — Rust
|
|
400
|
+
Existing backend adapters:
|
|
401
|
+
- `csonpath_json-c.h` — json-c values
|
|
402
|
+
- `csonpath_yyjson.h` — yyjson values
|
|
403
|
+
- `csonpath_python.c` — Python C API values (used by the Python bindings)
|
|
404
|
+
- `rust/csonpath_rust_backend.h` — Rust `serde_json::Value` (used by the Rust crate)
|
|
351
405
|
|
|
352
406
|
---
|
|
353
407
|
|
|
@@ -384,7 +438,7 @@ make tests
|
|
|
384
438
|
| `csonpath_json-c.h` | json-c backend |
|
|
385
439
|
| `csonpath_yyjson.h` | yyjson backend |
|
|
386
440
|
| `csonpath_python.c` | Python C extension backend |
|
|
387
|
-
| `rust/` | Rust
|
|
441
|
+
| `rust/` | Rust crate and its C backend adapter |
|
|
388
442
|
| `csonpath_my_fuzzing.h` | Fuzzer helpers (C) |
|
|
389
443
|
| `tests/` | C and Python test suites |
|
|
390
444
|
| `bench/` | Performance benchmarks |
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
[](https://docs.outscale.com/en/userguide/Open-Source-Projects.html)
|
|
6
6
|
|
|
7
|
-
**csonpath** is a partial [JSONPath](https://goessner.net/articles/JsonPath/) implementation in C
|
|
7
|
+
**csonpath** is a partial [JSONPath](https://goessner.net/articles/JsonPath/) implementation in C. It is **backend-agnostic**: the same core engine can query, update, and remove data from any value representation that supports array, object, and scalar semantics—not just JSON.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Out of the box it ships with C backends for [json-c](https://github.com/json-c/json-c) and [yyjson](https://github.com/ibireme/yyjson), plus language bindings for **Python** and **Rust**.
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
@@ -21,6 +21,7 @@ Unlike many JSONPath libraries, csonpath is **backend-agnostic**: it can work wi
|
|
|
21
21
|
| Array index | `$.array[0]` | Access by zero-based index |
|
|
22
22
|
| Wildcard `[*]` | `$.array[*].field` | Iterate all array elements |
|
|
23
23
|
| Recursive descent `..` | `$..name` | Search recursively for a key |
|
|
24
|
+
| Recursive descent wildcard `..*` | `$..*` | Return all descendants |
|
|
24
25
|
| Union `,` (inside brackets) | `$['a','b']`, `$.array[0,1]`, `$.items[?n==1, ?n==2]` | Match all listed selectors at once |
|
|
25
26
|
| OR fallback `\|` | `$.a \| $.b` | Try the left path first; fall back to the right one if it does not match. Only the first successful path is used. |
|
|
26
27
|
| Filters | `$.items[?price > 10]` | Filter array elements |
|
|
@@ -28,6 +29,7 @@ Unlike many JSONPath libraries, csonpath is **backend-agnostic**: it can work wi
|
|
|
28
29
|
| Multiple filters (`&`) | `$.items[?a=1 & b=2]` | Combine conditions |
|
|
29
30
|
| Subpath expressions | `$.obj[$.key]` | Use JSON values as dynamic path keys |
|
|
30
31
|
| `@` current object | `$.items[?@.price > 10]` | Reference the current element in filters |
|
|
32
|
+
| Type selectors | `$..["@odata.id"]@string()`, `$.*@integer()` | Filter matches by JSON type (`string`, `integer`, `null`) |
|
|
31
33
|
|
|
32
34
|
### Operations
|
|
33
35
|
- **Find First** — retrieve the first match.
|
|
@@ -54,6 +56,7 @@ Unlike many JSONPath libraries, csonpath is **backend-agnostic**: it can work wi
|
|
|
54
56
|
- [C API Reference](#-c-api-reference)
|
|
55
57
|
- [Python API Reference](#-python-api-reference)
|
|
56
58
|
- [CLI](#%EF%B8%8F-cli)
|
|
59
|
+
- [Using Multiple Backends](#-using-multiple-backends)
|
|
57
60
|
- [Custom Backends](#-custom-backends)
|
|
58
61
|
- [Running Tests](#-running-tests)
|
|
59
62
|
- [Directory Structure](#-directory-structure)
|
|
@@ -64,12 +67,12 @@ Unlike many JSONPath libraries, csonpath is **backend-agnostic**: it can work wi
|
|
|
64
67
|
|
|
65
68
|
## 📦 Installation
|
|
66
69
|
|
|
67
|
-
|
|
68
|
-
- C compiler (`gcc` or `clang`)
|
|
69
|
-
- [json-c](https://github.com/json-c/json-c) library (for C usage)
|
|
70
|
-
- Python 3.x (for Python bindings)
|
|
70
|
+
csonpath is a C library at its core. Pick the instructions for the language you want to use it from.
|
|
71
71
|
|
|
72
72
|
### C (json-c)
|
|
73
|
+
|
|
74
|
+
**Prerequisites:** C compiler (`gcc`, `clang`, or `tcc`), [json-c](https://github.com/json-c/json-c).
|
|
75
|
+
|
|
73
76
|
Just include the header in your project. There is no separate install step required:
|
|
74
77
|
```c
|
|
75
78
|
#include "csonpath_json-c.h"
|
|
@@ -79,21 +82,23 @@ Make sure to link against `json-c` when compiling:
|
|
|
79
82
|
gcc myapp.c -o myapp $(pkg-config --cflags --libs json-c)
|
|
80
83
|
```
|
|
81
84
|
|
|
82
|
-
### C (
|
|
83
|
-
The Rust backend is located in `rust/`. It builds both a safe Rust API and the C glue required by the csonpath core.
|
|
85
|
+
### C (yyjson)
|
|
84
86
|
|
|
85
|
-
|
|
86
|
-
cd rust
|
|
87
|
-
cargo build
|
|
88
|
-
cargo test
|
|
89
|
-
```
|
|
87
|
+
**Prerequisites:** C compiler (`gcc`, `clang`, or `tcc`), [yyjson](https://github.com/ibireme/yyjson).
|
|
90
88
|
|
|
91
|
-
To use it from C, include the backend header and link against the produced static library:
|
|
92
89
|
```c
|
|
93
|
-
#include "
|
|
90
|
+
#include "csonpath_yyjson.h"
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Link against `yyjson` when compiling:
|
|
94
|
+
```sh
|
|
95
|
+
gcc myapp.c -o myapp $(pkg-config --cflags --libs yyjson)
|
|
94
96
|
```
|
|
95
97
|
|
|
96
98
|
### Python
|
|
99
|
+
|
|
100
|
+
**Prerequisites:** Python 3.x.
|
|
101
|
+
|
|
97
102
|
Install from PyPI:
|
|
98
103
|
```sh
|
|
99
104
|
pip install csonpath
|
|
@@ -106,6 +111,23 @@ pip install .
|
|
|
106
111
|
make pip-dev
|
|
107
112
|
```
|
|
108
113
|
|
|
114
|
+
### Rust
|
|
115
|
+
|
|
116
|
+
**Prerequisites:** Rust toolchain.
|
|
117
|
+
|
|
118
|
+
The Rust crate is located in `rust/`. Build and test it with:
|
|
119
|
+
```sh
|
|
120
|
+
cd rust
|
|
121
|
+
cargo build
|
|
122
|
+
cargo test
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
To depend on it from another Rust project:
|
|
126
|
+
```toml
|
|
127
|
+
[dependencies]
|
|
128
|
+
csonpath = { path = "rust" }
|
|
129
|
+
```
|
|
130
|
+
|
|
109
131
|
---
|
|
110
132
|
|
|
111
133
|
## 🛠️ Usage
|
|
@@ -186,6 +208,8 @@ p.update_or_create_callback(dst, my_sync_fn, userdata)
|
|
|
186
208
|
|
|
187
209
|
## 📘 C API Reference
|
|
188
210
|
|
|
211
|
+
The reference below uses the **json-c** backend as an example (`struct json_object *`). All backends expose the same functions with their own value type.
|
|
212
|
+
|
|
189
213
|
```c
|
|
190
214
|
struct csonpath *csonpath_new(const char *path);
|
|
191
215
|
```
|
|
@@ -328,17 +352,47 @@ echo '{"a": 1, "b": 2}' | ./csonpath -d '$.b'
|
|
|
328
352
|
|
|
329
353
|
---
|
|
330
354
|
|
|
355
|
+
## 🧩 Using Multiple Backends
|
|
356
|
+
|
|
357
|
+
You can include more than one csonpath backend in the same translation unit, provided you prefix all but one of them to avoid symbol collisions. Define `CSONPATH_USE_PREFIX` before a backend header to prefix its API with the backend name.
|
|
358
|
+
|
|
359
|
+
For example, to use both json-c and the immutable yyjson backend in the same file:
|
|
360
|
+
|
|
361
|
+
```c
|
|
362
|
+
#define CSONPATH_USE_PREFIX
|
|
363
|
+
#include "csonpath_json-c.h"
|
|
364
|
+
|
|
365
|
+
#undef CSONPATH_USE_PREFIX
|
|
366
|
+
#include "csonpath_yyjson_const.h"
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
To use both yyjson backends (immutable and mutable) together, include the aggregator header:
|
|
370
|
+
|
|
371
|
+
```c
|
|
372
|
+
#include "csonpath_yyjson.h"
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
When using the mutable yyjson backend, assign the document pointer to `backend_ctx` before mutable operations:
|
|
376
|
+
|
|
377
|
+
```c
|
|
378
|
+
struct csonpath *mp = yyjson_mut_csonpath_new("$.a");
|
|
379
|
+
mp->backend_ctx = mdoc;
|
|
380
|
+
yyjson_mut_csonpath_update_or_create(mp, mroot, new_val);
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
---
|
|
384
|
+
|
|
331
385
|
## 🔌 Custom Backends
|
|
332
386
|
|
|
333
|
-
csonpath is designed to be backend-agnostic.
|
|
387
|
+
csonpath is designed to be backend-agnostic. The C core manipulates opaque value pointers through a small set of macros, so it can work with any data structure that supports array, object, and scalar semantics.
|
|
334
388
|
|
|
335
|
-
To create a custom backend, define the required macros and types in a header file (similar to `csonpath_json-c.h` or `
|
|
389
|
+
A backend is an adapter that implements those macros for a concrete value representation. To create a custom backend, define the required macros and types in a header file (similar to `csonpath_json-c.h` or `csonpath_yyjson.h`), then include your backend header before `csonpath.h`.
|
|
336
390
|
|
|
337
|
-
|
|
338
|
-
- `csonpath_json-c.h` — json-c
|
|
339
|
-
- `csonpath_yyjson.h` — yyjson
|
|
340
|
-
- `csonpath_python.c` — Python
|
|
341
|
-
- `rust/csonpath_rust_backend.h` — Rust
|
|
391
|
+
Existing backend adapters:
|
|
392
|
+
- `csonpath_json-c.h` — json-c values
|
|
393
|
+
- `csonpath_yyjson.h` — yyjson values
|
|
394
|
+
- `csonpath_python.c` — Python C API values (used by the Python bindings)
|
|
395
|
+
- `rust/csonpath_rust_backend.h` — Rust `serde_json::Value` (used by the Rust crate)
|
|
342
396
|
|
|
343
397
|
---
|
|
344
398
|
|
|
@@ -375,7 +429,7 @@ make tests
|
|
|
375
429
|
| `csonpath_json-c.h` | json-c backend |
|
|
376
430
|
| `csonpath_yyjson.h` | yyjson backend |
|
|
377
431
|
| `csonpath_python.c` | Python C extension backend |
|
|
378
|
-
| `rust/` | Rust
|
|
432
|
+
| `rust/` | Rust crate and its C backend adapter |
|
|
379
433
|
| `csonpath_my_fuzzing.h` | Fuzzer helpers (C) |
|
|
380
434
|
| `tests/` | C and Python test suites |
|
|
381
435
|
| `bench/` | Performance benchmarks |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: csonpath
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.19.0
|
|
4
4
|
Description-Content-Type: text/markdown
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Provides-Extra: dev
|
|
@@ -13,9 +13,9 @@ Dynamic: license-file
|
|
|
13
13
|
|
|
14
14
|
[](https://docs.outscale.com/en/userguide/Open-Source-Projects.html)
|
|
15
15
|
|
|
16
|
-
**csonpath** is a partial [JSONPath](https://goessner.net/articles/JsonPath/) implementation in C
|
|
16
|
+
**csonpath** is a partial [JSONPath](https://goessner.net/articles/JsonPath/) implementation in C. It is **backend-agnostic**: the same core engine can query, update, and remove data from any value representation that supports array, object, and scalar semantics—not just JSON.
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
Out of the box it ships with C backends for [json-c](https://github.com/json-c/json-c) and [yyjson](https://github.com/ibireme/yyjson), plus language bindings for **Python** and **Rust**.
|
|
19
19
|
|
|
20
20
|
---
|
|
21
21
|
|
|
@@ -30,6 +30,7 @@ Unlike many JSONPath libraries, csonpath is **backend-agnostic**: it can work wi
|
|
|
30
30
|
| Array index | `$.array[0]` | Access by zero-based index |
|
|
31
31
|
| Wildcard `[*]` | `$.array[*].field` | Iterate all array elements |
|
|
32
32
|
| Recursive descent `..` | `$..name` | Search recursively for a key |
|
|
33
|
+
| Recursive descent wildcard `..*` | `$..*` | Return all descendants |
|
|
33
34
|
| Union `,` (inside brackets) | `$['a','b']`, `$.array[0,1]`, `$.items[?n==1, ?n==2]` | Match all listed selectors at once |
|
|
34
35
|
| OR fallback `\|` | `$.a \| $.b` | Try the left path first; fall back to the right one if it does not match. Only the first successful path is used. |
|
|
35
36
|
| Filters | `$.items[?price > 10]` | Filter array elements |
|
|
@@ -37,6 +38,7 @@ Unlike many JSONPath libraries, csonpath is **backend-agnostic**: it can work wi
|
|
|
37
38
|
| Multiple filters (`&`) | `$.items[?a=1 & b=2]` | Combine conditions |
|
|
38
39
|
| Subpath expressions | `$.obj[$.key]` | Use JSON values as dynamic path keys |
|
|
39
40
|
| `@` current object | `$.items[?@.price > 10]` | Reference the current element in filters |
|
|
41
|
+
| Type selectors | `$..["@odata.id"]@string()`, `$.*@integer()` | Filter matches by JSON type (`string`, `integer`, `null`) |
|
|
40
42
|
|
|
41
43
|
### Operations
|
|
42
44
|
- **Find First** — retrieve the first match.
|
|
@@ -63,6 +65,7 @@ Unlike many JSONPath libraries, csonpath is **backend-agnostic**: it can work wi
|
|
|
63
65
|
- [C API Reference](#-c-api-reference)
|
|
64
66
|
- [Python API Reference](#-python-api-reference)
|
|
65
67
|
- [CLI](#%EF%B8%8F-cli)
|
|
68
|
+
- [Using Multiple Backends](#-using-multiple-backends)
|
|
66
69
|
- [Custom Backends](#-custom-backends)
|
|
67
70
|
- [Running Tests](#-running-tests)
|
|
68
71
|
- [Directory Structure](#-directory-structure)
|
|
@@ -73,12 +76,12 @@ Unlike many JSONPath libraries, csonpath is **backend-agnostic**: it can work wi
|
|
|
73
76
|
|
|
74
77
|
## 📦 Installation
|
|
75
78
|
|
|
76
|
-
|
|
77
|
-
- C compiler (`gcc` or `clang`)
|
|
78
|
-
- [json-c](https://github.com/json-c/json-c) library (for C usage)
|
|
79
|
-
- Python 3.x (for Python bindings)
|
|
79
|
+
csonpath is a C library at its core. Pick the instructions for the language you want to use it from.
|
|
80
80
|
|
|
81
81
|
### C (json-c)
|
|
82
|
+
|
|
83
|
+
**Prerequisites:** C compiler (`gcc`, `clang`, or `tcc`), [json-c](https://github.com/json-c/json-c).
|
|
84
|
+
|
|
82
85
|
Just include the header in your project. There is no separate install step required:
|
|
83
86
|
```c
|
|
84
87
|
#include "csonpath_json-c.h"
|
|
@@ -88,21 +91,23 @@ Make sure to link against `json-c` when compiling:
|
|
|
88
91
|
gcc myapp.c -o myapp $(pkg-config --cflags --libs json-c)
|
|
89
92
|
```
|
|
90
93
|
|
|
91
|
-
### C (
|
|
92
|
-
The Rust backend is located in `rust/`. It builds both a safe Rust API and the C glue required by the csonpath core.
|
|
94
|
+
### C (yyjson)
|
|
93
95
|
|
|
94
|
-
|
|
95
|
-
cd rust
|
|
96
|
-
cargo build
|
|
97
|
-
cargo test
|
|
98
|
-
```
|
|
96
|
+
**Prerequisites:** C compiler (`gcc`, `clang`, or `tcc`), [yyjson](https://github.com/ibireme/yyjson).
|
|
99
97
|
|
|
100
|
-
To use it from C, include the backend header and link against the produced static library:
|
|
101
98
|
```c
|
|
102
|
-
#include "
|
|
99
|
+
#include "csonpath_yyjson.h"
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Link against `yyjson` when compiling:
|
|
103
|
+
```sh
|
|
104
|
+
gcc myapp.c -o myapp $(pkg-config --cflags --libs yyjson)
|
|
103
105
|
```
|
|
104
106
|
|
|
105
107
|
### Python
|
|
108
|
+
|
|
109
|
+
**Prerequisites:** Python 3.x.
|
|
110
|
+
|
|
106
111
|
Install from PyPI:
|
|
107
112
|
```sh
|
|
108
113
|
pip install csonpath
|
|
@@ -115,6 +120,23 @@ pip install .
|
|
|
115
120
|
make pip-dev
|
|
116
121
|
```
|
|
117
122
|
|
|
123
|
+
### Rust
|
|
124
|
+
|
|
125
|
+
**Prerequisites:** Rust toolchain.
|
|
126
|
+
|
|
127
|
+
The Rust crate is located in `rust/`. Build and test it with:
|
|
128
|
+
```sh
|
|
129
|
+
cd rust
|
|
130
|
+
cargo build
|
|
131
|
+
cargo test
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
To depend on it from another Rust project:
|
|
135
|
+
```toml
|
|
136
|
+
[dependencies]
|
|
137
|
+
csonpath = { path = "rust" }
|
|
138
|
+
```
|
|
139
|
+
|
|
118
140
|
---
|
|
119
141
|
|
|
120
142
|
## 🛠️ Usage
|
|
@@ -195,6 +217,8 @@ p.update_or_create_callback(dst, my_sync_fn, userdata)
|
|
|
195
217
|
|
|
196
218
|
## 📘 C API Reference
|
|
197
219
|
|
|
220
|
+
The reference below uses the **json-c** backend as an example (`struct json_object *`). All backends expose the same functions with their own value type.
|
|
221
|
+
|
|
198
222
|
```c
|
|
199
223
|
struct csonpath *csonpath_new(const char *path);
|
|
200
224
|
```
|
|
@@ -337,17 +361,47 @@ echo '{"a": 1, "b": 2}' | ./csonpath -d '$.b'
|
|
|
337
361
|
|
|
338
362
|
---
|
|
339
363
|
|
|
364
|
+
## 🧩 Using Multiple Backends
|
|
365
|
+
|
|
366
|
+
You can include more than one csonpath backend in the same translation unit, provided you prefix all but one of them to avoid symbol collisions. Define `CSONPATH_USE_PREFIX` before a backend header to prefix its API with the backend name.
|
|
367
|
+
|
|
368
|
+
For example, to use both json-c and the immutable yyjson backend in the same file:
|
|
369
|
+
|
|
370
|
+
```c
|
|
371
|
+
#define CSONPATH_USE_PREFIX
|
|
372
|
+
#include "csonpath_json-c.h"
|
|
373
|
+
|
|
374
|
+
#undef CSONPATH_USE_PREFIX
|
|
375
|
+
#include "csonpath_yyjson_const.h"
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
To use both yyjson backends (immutable and mutable) together, include the aggregator header:
|
|
379
|
+
|
|
380
|
+
```c
|
|
381
|
+
#include "csonpath_yyjson.h"
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
When using the mutable yyjson backend, assign the document pointer to `backend_ctx` before mutable operations:
|
|
385
|
+
|
|
386
|
+
```c
|
|
387
|
+
struct csonpath *mp = yyjson_mut_csonpath_new("$.a");
|
|
388
|
+
mp->backend_ctx = mdoc;
|
|
389
|
+
yyjson_mut_csonpath_update_or_create(mp, mroot, new_val);
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
---
|
|
393
|
+
|
|
340
394
|
## 🔌 Custom Backends
|
|
341
395
|
|
|
342
|
-
csonpath is designed to be backend-agnostic.
|
|
396
|
+
csonpath is designed to be backend-agnostic. The C core manipulates opaque value pointers through a small set of macros, so it can work with any data structure that supports array, object, and scalar semantics.
|
|
343
397
|
|
|
344
|
-
To create a custom backend, define the required macros and types in a header file (similar to `csonpath_json-c.h` or `
|
|
398
|
+
A backend is an adapter that implements those macros for a concrete value representation. To create a custom backend, define the required macros and types in a header file (similar to `csonpath_json-c.h` or `csonpath_yyjson.h`), then include your backend header before `csonpath.h`.
|
|
345
399
|
|
|
346
|
-
|
|
347
|
-
- `csonpath_json-c.h` — json-c
|
|
348
|
-
- `csonpath_yyjson.h` — yyjson
|
|
349
|
-
- `csonpath_python.c` — Python
|
|
350
|
-
- `rust/csonpath_rust_backend.h` — Rust
|
|
400
|
+
Existing backend adapters:
|
|
401
|
+
- `csonpath_json-c.h` — json-c values
|
|
402
|
+
- `csonpath_yyjson.h` — yyjson values
|
|
403
|
+
- `csonpath_python.c` — Python C API values (used by the Python bindings)
|
|
404
|
+
- `rust/csonpath_rust_backend.h` — Rust `serde_json::Value` (used by the Rust crate)
|
|
351
405
|
|
|
352
406
|
---
|
|
353
407
|
|
|
@@ -384,7 +438,7 @@ make tests
|
|
|
384
438
|
| `csonpath_json-c.h` | json-c backend |
|
|
385
439
|
| `csonpath_yyjson.h` | yyjson backend |
|
|
386
440
|
| `csonpath_python.c` | Python C extension backend |
|
|
387
|
-
| `rust/` | Rust
|
|
441
|
+
| `rust/` | Rust crate and its C backend adapter |
|
|
388
442
|
| `csonpath_my_fuzzing.h` | Fuzzer helpers (C) |
|
|
389
443
|
| `tests/` | C and Python test suites |
|
|
390
444
|
| `bench/` | Performance benchmarks |
|