relateby-pattern 0.7.2__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.
- relateby_pattern-0.7.2/Cargo.toml +32 -0
- relateby_pattern-0.7.2/PKG-INFO +14 -0
- relateby_pattern-0.7.2/README.md +104 -0
- relateby_pattern-0.7.2/benches/Cargo.toml +16 -0
- relateby_pattern-0.7.2/benches/benches/README.md +18 -0
- relateby_pattern-0.7.2/benches/benches/pattern_operations.rs +13 -0
- relateby_pattern-0.7.2/benches/src/lib.rs +3 -0
- relateby_pattern-0.7.2/crates/gram-codec/Cargo.toml +67 -0
- relateby_pattern-0.7.2/crates/gram-codec/README.md +387 -0
- relateby_pattern-0.7.2/crates/gram-codec/benches/codec_benchmarks.rs +196 -0
- relateby_pattern-0.7.2/crates/gram-codec/examples/advanced_usage.rs +167 -0
- relateby_pattern-0.7.2/crates/gram-codec/examples/basic_usage.rs +123 -0
- relateby_pattern-0.7.2/crates/gram-codec/examples/interop_check.rs +28 -0
- relateby_pattern-0.7.2/crates/gram-codec/pyproject.toml +39 -0
- relateby_pattern-0.7.2/crates/gram-codec/src/ast.rs +586 -0
- relateby_pattern-0.7.2/crates/gram-codec/src/cst/lowering.rs +176 -0
- relateby_pattern-0.7.2/crates/gram-codec/src/cst/mod.rs +11 -0
- relateby_pattern-0.7.2/crates/gram-codec/src/cst/parser.rs +583 -0
- relateby_pattern-0.7.2/crates/gram-codec/src/cst/syntax_node.rs +74 -0
- relateby_pattern-0.7.2/crates/gram-codec/src/error.rs +299 -0
- relateby_pattern-0.7.2/crates/gram-codec/src/json.rs +353 -0
- relateby_pattern-0.7.2/crates/gram-codec/src/lib.rs +253 -0
- relateby_pattern-0.7.2/crates/gram-codec/src/parser/annotation.rs +173 -0
- relateby_pattern-0.7.2/crates/gram-codec/src/parser/combinators.rs +135 -0
- relateby_pattern-0.7.2/crates/gram-codec/src/parser/error.rs +129 -0
- relateby_pattern-0.7.2/crates/gram-codec/src/parser/mod.rs +253 -0
- relateby_pattern-0.7.2/crates/gram-codec/src/parser/node.rs +76 -0
- relateby_pattern-0.7.2/crates/gram-codec/src/parser/relationship.rs +382 -0
- relateby_pattern-0.7.2/crates/gram-codec/src/parser/subject.rs +229 -0
- relateby_pattern-0.7.2/crates/gram-codec/src/parser/types.rs +214 -0
- relateby_pattern-0.7.2/crates/gram-codec/src/parser/value.rs +738 -0
- relateby_pattern-0.7.2/crates/gram-codec/src/python.rs +389 -0
- relateby_pattern-0.7.2/crates/gram-codec/src/serializer.rs +522 -0
- relateby_pattern-0.7.2/crates/gram-codec/src/standard_graph.rs +20 -0
- relateby_pattern-0.7.2/crates/gram-codec/src/transform.rs +494 -0
- relateby_pattern-0.7.2/crates/gram-codec/src/value.rs +384 -0
- relateby_pattern-0.7.2/crates/gram-codec/src/wasm.rs +197 -0
- relateby_pattern-0.7.2/crates/gram-codec/tests/advanced_features_tests.rs +286 -0
- relateby_pattern-0.7.2/crates/gram-codec/tests/arrow_style_variants_tests.rs +306 -0
- relateby_pattern-0.7.2/crates/gram-codec/tests/arrow_types_tests.rs +185 -0
- relateby_pattern-0.7.2/crates/gram-codec/tests/ast_integration_tests.rs +80 -0
- relateby_pattern-0.7.2/crates/gram-codec/tests/ast_roundtrip_tests.rs +110 -0
- relateby_pattern-0.7.2/crates/gram-codec/tests/corpus/mod.rs +204 -0
- relateby_pattern-0.7.2/crates/gram-codec/tests/corpus/parser.rs +263 -0
- relateby_pattern-0.7.2/crates/gram-codec/tests/corpus/runner.rs +226 -0
- relateby_pattern-0.7.2/crates/gram-codec/tests/corpus/validator.rs +289 -0
- relateby_pattern-0.7.2/crates/gram-codec/tests/corpus_integration.rs +71 -0
- relateby_pattern-0.7.2/crates/gram-codec/tests/cst/comment_tests.rs +138 -0
- relateby_pattern-0.7.2/crates/gram-codec/tests/cst/error_recovery_tests.rs +20 -0
- relateby_pattern-0.7.2/crates/gram-codec/tests/cst/lowering_tests.rs +215 -0
- relateby_pattern-0.7.2/crates/gram-codec/tests/cst/mod.rs +4 -0
- relateby_pattern-0.7.2/crates/gram-codec/tests/cst/parse_tests.rs +206 -0
- relateby_pattern-0.7.2/crates/gram-codec/tests/cst_integration.rs +8 -0
- relateby_pattern-0.7.2/crates/gram-codec/tests/edge_cases_tests.rs +322 -0
- relateby_pattern-0.7.2/crates/gram-codec/tests/interop_gram_hs_tests.rs +150 -0
- relateby_pattern-0.7.2/crates/gram-codec/tests/json_alignment_test.rs +101 -0
- relateby_pattern-0.7.2/crates/gram-codec/tests/map_roundtrip.rs +138 -0
- relateby_pattern-0.7.2/crates/gram-codec/tests/parser_tests.rs +177 -0
- relateby_pattern-0.7.2/crates/gram-codec/tests/relationship_with_edge_identifier_tests.rs +170 -0
- relateby_pattern-0.7.2/crates/gram-codec/tests/round_trip_tests.rs +215 -0
- relateby_pattern-0.7.2/crates/gram-codec/tests/schema_validation.rs +217 -0
- relateby_pattern-0.7.2/crates/gram-codec/tests/serializer_tests.rs +255 -0
- relateby_pattern-0.7.2/crates/gram-codec/tests/value_types_tests.rs +210 -0
- relateby_pattern-0.7.2/crates/pattern-core/API-CHANGES.md +228 -0
- relateby_pattern-0.7.2/crates/pattern-core/API-IMPROVEMENTS-SUMMARY.md +288 -0
- relateby_pattern-0.7.2/crates/pattern-core/CHANGELOG.md +102 -0
- relateby_pattern-0.7.2/crates/pattern-core/Cargo.toml +63 -0
- relateby_pattern-0.7.2/crates/pattern-core/GENERIC-VALUE-FIX.md +231 -0
- relateby_pattern-0.7.2/crates/pattern-core/PYTHON-DEVELOPMENT.md +292 -0
- relateby_pattern-0.7.2/crates/pattern-core/PYTHON-TYPE-CHECKING.md +160 -0
- relateby_pattern-0.7.2/crates/pattern-core/README.md +224 -0
- relateby_pattern-0.7.2/crates/pattern-core/TERMINOLOGY-CLEANUP-SUMMARY.md +223 -0
- relateby_pattern-0.7.2/crates/pattern-core/TERMINOLOGY-CORRECTION.md +191 -0
- relateby_pattern-0.7.2/crates/pattern-core/TRAVERSABLE_NOTES.md +193 -0
- relateby_pattern-0.7.2/crates/pattern-core/benches/fold_benchmarks.rs +288 -0
- relateby_pattern-0.7.2/crates/pattern-core/benches/ord_benchmarks.rs +330 -0
- relateby_pattern-0.7.2/crates/pattern-core/benches/predicate_benchmarks.rs +223 -0
- relateby_pattern-0.7.2/crates/pattern-core/benches/query_benchmarks.rs +278 -0
- relateby_pattern-0.7.2/crates/pattern-core/benches/semigroup_benchmarks.rs +235 -0
- relateby_pattern-0.7.2/crates/pattern-core/examples/comonad_usage.rs +284 -0
- relateby_pattern-0.7.2/crates/pattern-core/examples/paramorphism_usage.rs +175 -0
- relateby_pattern-0.7.2/crates/pattern-core/examples/standard_graph_usage.rs +179 -0
- relateby_pattern-0.7.2/crates/pattern-core/pyproject.toml +39 -0
- relateby_pattern-0.7.2/crates/pattern-core/src/graph/algorithms.rs +713 -0
- relateby_pattern-0.7.2/crates/pattern-core/src/graph/graph_classifier.rs +167 -0
- relateby_pattern-0.7.2/crates/pattern-core/src/graph/graph_query.rs +515 -0
- relateby_pattern-0.7.2/crates/pattern-core/src/graph/graph_view.rs +188 -0
- relateby_pattern-0.7.2/crates/pattern-core/src/graph/mod.rs +26 -0
- relateby_pattern-0.7.2/crates/pattern-core/src/graph/standard.rs +453 -0
- relateby_pattern-0.7.2/crates/pattern-core/src/graph/transform/context.rs +42 -0
- relateby_pattern-0.7.2/crates/pattern-core/src/graph/transform/map_filter_fold.rs +139 -0
- relateby_pattern-0.7.2/crates/pattern-core/src/graph/transform/mod.rs +11 -0
- relateby_pattern-0.7.2/crates/pattern-core/src/graph/transform/para.rs +280 -0
- relateby_pattern-0.7.2/crates/pattern-core/src/graph/transform/types.rs +49 -0
- relateby_pattern-0.7.2/crates/pattern-core/src/graph/transform/unfold_graph.rs +61 -0
- relateby_pattern-0.7.2/crates/pattern-core/src/lib.rs +727 -0
- relateby_pattern-0.7.2/crates/pattern-core/src/pattern/comonad.rs +147 -0
- relateby_pattern-0.7.2/crates/pattern-core/src/pattern/comonad_helpers.rs +227 -0
- relateby_pattern-0.7.2/crates/pattern-core/src/pattern/core.rs +3996 -0
- relateby_pattern-0.7.2/crates/pattern-core/src/pattern/mod.rs +7 -0
- relateby_pattern-0.7.2/crates/pattern-core/src/pattern/unfold.rs +69 -0
- relateby_pattern-0.7.2/crates/pattern-core/src/pattern_graph.rs +566 -0
- relateby_pattern-0.7.2/crates/pattern-core/src/python.rs +14 -0
- relateby_pattern-0.7.2/crates/pattern-core/src/reconcile.rs +355 -0
- relateby_pattern-0.7.2/crates/pattern-core/src/subject.rs +501 -0
- relateby_pattern-0.7.2/crates/pattern-core/src/test_utils/equivalence.rs +207 -0
- relateby_pattern-0.7.2/crates/pattern-core/src/test_utils/generators.rs +146 -0
- relateby_pattern-0.7.2/crates/pattern-core/src/test_utils/helpers.rs +209 -0
- relateby_pattern-0.7.2/crates/pattern-core/src/test_utils/mod.rs +10 -0
- relateby_pattern-0.7.2/crates/pattern-core/src/wasm.rs +3328 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/algorithms.rs +654 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/analysis.rs +131 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/analysis_balanced_tree_bug.rs +44 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/analysis_property.rs +15 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/analysis_trailing_zeros_bug.rs +87 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/comonad_laws.rs +293 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/equivalence/extracted_data.rs +24 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/equivalence/pattern_structure.rs +48 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/equivalence/test_data.rs +50 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/foldable_basic.rs +322 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/foldable_collections.rs +337 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/foldable_custom.rs +346 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/foldable_integration.rs +257 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/foldable_scale.rs +347 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/functor_laws.rs +399 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/graph_classifier.rs +124 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/graph_query.rs +632 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/graph_view.rs +233 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/hash_basic.rs +276 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/hash_consistency.rs +245 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/hash_integration.rs +341 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/helpers_example.rs +21 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/monoid_default.rs +342 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/monoid_identity.rs +356 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/monoid_integration.rs +412 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/ord_basic.rs +329 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/ord_collections.rs +436 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/ord_equivalence.rs +305 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/ord_extrema.rs +322 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/ord_property.rs +311 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/pattern_graph.rs +186 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/predicate_contains.rs +432 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/predicate_matches.rs +423 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/predicate_properties.rs +306 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/property/equality.rs +26 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/property/validation.rs +17 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/python/PHASE6-PROGRESS.md +204 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/python/README.md +201 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/query_all_values.rs +164 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/query_all_values_property.rs +83 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/query_any_value.rs +130 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/query_any_value_property.rs +76 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/query_existing.rs +287 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/query_filter.rs +187 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/query_filter_property.rs +107 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/query_find_first.rs +435 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/semigroup_basic.rs +263 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/semigroup_equivalence.rs +294 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/semigroup_integration.rs +296 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/semigroup_property.rs +284 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/snapshot/README.md +29 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/snapshot/analysis.rs +46 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/snapshot/serialization.rs +14 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/snapshot/validation.rs +52 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/snapshot_analysis.rs +68 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/snapshot_validation.rs +59 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/standard_graph_tests.rs +612 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/transform.rs +507 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/traversable_integration.rs +263 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/traversable_laws.rs +118 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/traversable_option.rs +170 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/traversable_result.rs +316 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/traversable_validate.rs +315 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/unit/validation.rs +112 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/validation.rs +120 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/validation_property.rs +15 -0
- relateby_pattern-0.7.2/crates/pattern-core/tests/verify_short_circuit_bug.rs +112 -0
- relateby_pattern-0.7.2/crates/pattern-core/uv.lock +873 -0
- relateby_pattern-0.7.2/pyproject.toml +88 -0
- relateby_pattern-0.7.2/relateby/__init__.py +3 -0
- relateby_pattern-0.7.2/relateby/_native/__init__.py +1 -0
- relateby_pattern-0.7.2/relateby/gram/__init__.py +302 -0
- relateby_pattern-0.7.2/relateby/gram/__init__.pyi +26 -0
- relateby_pattern-0.7.2/relateby/pattern/__init__.py +69 -0
- relateby_pattern-0.7.2/relateby/pattern/__init__.pyi +229 -0
- relateby_pattern-0.7.2/relateby/pattern/_decode.py +163 -0
- relateby_pattern-0.7.2/relateby/pattern/_graph_transforms.py +475 -0
- relateby_pattern-0.7.2/relateby/pattern/_pattern.py +422 -0
- relateby_pattern-0.7.2/relateby/pattern/_standard_graph.py +319 -0
- relateby_pattern-0.7.2/relateby/pattern/_subject.py +77 -0
- relateby_pattern-0.7.2/relateby/pattern/_value.py +143 -0
- relateby_pattern-0.7.2/relateby/py.typed +1 -0
- relateby_pattern-0.7.2/relateby_build/__init__.py +432 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
[workspace]
|
|
2
|
+
members = [
|
|
3
|
+
"crates/pattern-core",
|
|
4
|
+
"crates/gram-codec",
|
|
5
|
+
"benches",
|
|
6
|
+
]
|
|
7
|
+
exclude = ["external/tree-sitter-gram"]
|
|
8
|
+
resolver = "2"
|
|
9
|
+
|
|
10
|
+
[workspace.package]
|
|
11
|
+
version = "0.7.2"
|
|
12
|
+
edition = "2021"
|
|
13
|
+
rust-version = "1.70.0"
|
|
14
|
+
authors = ["gram-data"]
|
|
15
|
+
license = "BSD-3-Clause"
|
|
16
|
+
description = "Rust port of gram-hs pattern data structure and graph views"
|
|
17
|
+
repository = "https://github.com/relateby/pattern-rs"
|
|
18
|
+
|
|
19
|
+
[workspace.dependencies]
|
|
20
|
+
serde = { version = "1.0", features = ["derive"] }
|
|
21
|
+
serde_json = "1.0"
|
|
22
|
+
thiserror = "2.0"
|
|
23
|
+
proptest = "1.0"
|
|
24
|
+
insta = "1.0"
|
|
25
|
+
criterion = { version = "0.5", default-features = false, features = ["html_reports"] }
|
|
26
|
+
clap = { version = "4", features = ["derive"] }
|
|
27
|
+
strsim = "0.11"
|
|
28
|
+
|
|
29
|
+
# Note: Previously had `[profile.release]` with opt-level="z" and lto=true,
|
|
30
|
+
# but this affected ALL workspace crates (not just WASM). Removed to avoid
|
|
31
|
+
# performance degradation in non-WASM binaries. For WASM size optimization,
|
|
32
|
+
# use wasm-pack which applies appropriate settings: `wasm-pack build --release`
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: relateby-pattern
|
|
3
|
+
Version: 0.7.2
|
|
4
|
+
Summary: Combined Python distribution for relateby.pattern and relateby.gram
|
|
5
|
+
License: Apache-2.0
|
|
6
|
+
Requires-Python: >=3.8,<3.14
|
|
7
|
+
Provides-Extra: dev
|
|
8
|
+
Requires-Dist: maturin>=1.0,<2.0; extra == 'dev'
|
|
9
|
+
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
10
|
+
Requires-Dist: pytest-cov>=4.0; extra == 'dev'
|
|
11
|
+
Requires-Dist: twine>=5.0; extra == 'dev'
|
|
12
|
+
Requires-Dist: pdoc>=14.0; extra == 'dev'
|
|
13
|
+
Provides-Extra: all
|
|
14
|
+
Requires-Dist: relateby-pattern[dev]; extra == 'all'
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Relateby
|
|
2
|
+
|
|
3
|
+
Combined Python distribution for the pattern-rs library. One install provides both subpackages:
|
|
4
|
+
|
|
5
|
+
- **relateby.pattern** — Pattern data structures (from pattern-core)
|
|
6
|
+
- **relateby.gram** — Gram notation parser and serializer (from gram-codec)
|
|
7
|
+
|
|
8
|
+
The published distribution name is **relateby-pattern** while the import namespace remains `relateby.*`.
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
# Combined distribution (pattern + gram)
|
|
14
|
+
pip install relateby-pattern
|
|
15
|
+
|
|
16
|
+
# With optional dependencies (e.g. dev tools)
|
|
17
|
+
pip install relateby-pattern[dev] # maturin, pytest, pytest-cov
|
|
18
|
+
pip install relateby-pattern[all] # all optional extras
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
For a local source checkout, prefer `uv` with a project-local virtual environment:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
cd python/packages/relateby
|
|
25
|
+
uv venv --python 3.13 .venv
|
|
26
|
+
source .venv/bin/activate
|
|
27
|
+
uv pip install '.[dev]'
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
`python/packages/relateby` does not currently support editable installs (`pip install -e .`) because the custom build backend only implements wheel and sdist builds.
|
|
31
|
+
The supported Python range is `>=3.8,<3.14`; `3.13` is the recommended local development target.
|
|
32
|
+
|
|
33
|
+
After installation, run import checks and examples from outside `python/packages/relateby` so the source tree does not shadow the installed package.
|
|
34
|
+
|
|
35
|
+
## Use
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
import relateby.pattern
|
|
39
|
+
import relateby.gram
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
There are no top-level `pattern_core` or `gram_codec` imports; use `relateby.pattern` and `relateby.gram` only.
|
|
43
|
+
|
|
44
|
+
Representative public imports:
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
from relateby.pattern import Pattern, StandardGraph, StringVal, Subject
|
|
48
|
+
from relateby.gram import gram_validate, parse_gram, round_trip
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Example public workflow:
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
alice = Subject.from_id("alice").with_label("Person").with_property("name", StringVal("Alice"))
|
|
55
|
+
graph = StandardGraph.from_patterns([Pattern.point(alice)])
|
|
56
|
+
|
|
57
|
+
assert graph.node_count == 1
|
|
58
|
+
assert len(parse_gram("(alice:Person)")) == 1
|
|
59
|
+
assert gram_validate("(alice:Person)") == []
|
|
60
|
+
assert round_trip("(alice:Person)") == "(alice:Person)"
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## JSON Interchange
|
|
64
|
+
|
|
65
|
+
`Pattern<Subject>` can be serialized to and from a plain JSON-compatible format defined by the [gram interchange schema](https://github.com/gram-data/tree-sitter-gram/blob/main/docs/pattern.schema.json). This is useful when you need to pass patterns across a process or network boundary without re-parsing gram notation on the other side.
|
|
66
|
+
|
|
67
|
+
**Producer** (parse gram → emit raw JSON):
|
|
68
|
+
|
|
69
|
+
```python
|
|
70
|
+
from relateby.gram import parse_raw
|
|
71
|
+
import json
|
|
72
|
+
|
|
73
|
+
raw = parse_raw("(alice:Person)-[:KNOWS]->(bob:Person)")
|
|
74
|
+
payload = json.dumps(raw)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Consumer** (receive raw JSON → reconstruct patterns):
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
from relateby.pattern import pattern_from_dict, validate_payload
|
|
81
|
+
import json
|
|
82
|
+
|
|
83
|
+
raw = json.loads(payload)
|
|
84
|
+
patterns = [pattern_from_dict(item) for item in validate_payload(raw)]
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Round-trip** (native ↔ JSON):
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
from relateby.pattern import pattern_from_dict, pattern_to_dict
|
|
91
|
+
|
|
92
|
+
raw = pattern_to_dict(pattern) # Pattern[Subject] → RawPattern dict
|
|
93
|
+
restored = pattern_from_dict(raw) # RawPattern dict → Pattern[Subject]
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
`RawPattern` and `RawSubject` are `TypedDict` types exported from `relateby.pattern` for use in type annotations.
|
|
97
|
+
|
|
98
|
+
## Building from source
|
|
99
|
+
|
|
100
|
+
From the repository root, build the wheel from the combined package directory (requires maturin and Rust; Python 3.8–3.13 for the extension build):
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
cd python/packages/relateby && uv build --wheel --python 3.13 --out-dir dist
|
|
104
|
+
```
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "pattern-rs-benches"
|
|
3
|
+
version.workspace = true
|
|
4
|
+
edition.workspace = true
|
|
5
|
+
rust-version.workspace = true
|
|
6
|
+
license.workspace = true
|
|
7
|
+
description = "Benchmarks for pattern-rs"
|
|
8
|
+
|
|
9
|
+
[[bench]]
|
|
10
|
+
name = "pattern_operations"
|
|
11
|
+
harness = false
|
|
12
|
+
|
|
13
|
+
[dependencies]
|
|
14
|
+
criterion = { workspace = true }
|
|
15
|
+
pattern_core = { package = "relateby-pattern", path = "../crates/pattern-core" }
|
|
16
|
+
gram_codec = { package = "relateby-gram", path = "../crates/gram-codec" }
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Benchmark Suite
|
|
2
|
+
|
|
3
|
+
This directory contains performance benchmarks using Criterion.
|
|
4
|
+
|
|
5
|
+
## Running Benchmarks
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
cargo bench
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Benchmark Organization
|
|
12
|
+
|
|
13
|
+
- `pattern_operations.rs` - Core pattern operation benchmarks
|
|
14
|
+
|
|
15
|
+
## WASM Compatibility
|
|
16
|
+
|
|
17
|
+
Benchmarks use conditional compilation for WASM targets due to timing limitations.
|
|
18
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//! Benchmarks for pattern operations
|
|
2
|
+
//!
|
|
3
|
+
//! These benchmarks measure performance of pattern operations to track
|
|
4
|
+
//! performance over time and detect regressions.
|
|
5
|
+
|
|
6
|
+
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
|
7
|
+
|
|
8
|
+
fn benchmark_placeholder(c: &mut Criterion) {
|
|
9
|
+
c.bench_function("placeholder", |b| b.iter(|| black_box(42)));
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
criterion_group!(benches, benchmark_placeholder);
|
|
13
|
+
criterion_main!(benches);
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "relateby-gram"
|
|
3
|
+
version.workspace = true
|
|
4
|
+
edition.workspace = true
|
|
5
|
+
rust-version.workspace = true
|
|
6
|
+
authors.workspace = true
|
|
7
|
+
license.workspace = true
|
|
8
|
+
description = "Bidirectional codec between Gram notation and Pattern data structures"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
documentation = "https://docs.rs/relateby-gram"
|
|
11
|
+
repository = "https://github.com/relateby/pattern-rs"
|
|
12
|
+
|
|
13
|
+
[package.metadata.docs.rs]
|
|
14
|
+
all-features = false
|
|
15
|
+
features = []
|
|
16
|
+
|
|
17
|
+
[dependencies]
|
|
18
|
+
# Version must match workspace [workspace.package] version when publishing to crates.io.
|
|
19
|
+
pattern_core = { package = "relateby-pattern", path = "../pattern-core", version = "0.7.2" }
|
|
20
|
+
nom = "7"
|
|
21
|
+
serde = { version = "1.0", features = ["derive"] }
|
|
22
|
+
serde_json = "1.0"
|
|
23
|
+
thiserror.workspace = true
|
|
24
|
+
tree-sitter = { version = "0.25", optional = true }
|
|
25
|
+
tree-sitter-gram = { version = "0.6", optional = true }
|
|
26
|
+
|
|
27
|
+
# WASM support
|
|
28
|
+
wasm-bindgen = { version = "0.2", optional = true }
|
|
29
|
+
js-sys = { version = "0.3", optional = true }
|
|
30
|
+
|
|
31
|
+
# Python support
|
|
32
|
+
pyo3 = { version = "0.23", optional = true, features = ["extension-module"] }
|
|
33
|
+
pythonize = { version = "0.23", optional = true }
|
|
34
|
+
|
|
35
|
+
[dev-dependencies]
|
|
36
|
+
insta.workspace = true
|
|
37
|
+
criterion.workspace = true
|
|
38
|
+
proptest = "1.0"
|
|
39
|
+
|
|
40
|
+
[features]
|
|
41
|
+
default = []
|
|
42
|
+
wasm = ["wasm-bindgen", "js-sys"]
|
|
43
|
+
python = ["pyo3", "pythonize", "pyo3/abi3-py38"]
|
|
44
|
+
cst = ["dep:tree-sitter", "dep:tree-sitter-gram"]
|
|
45
|
+
|
|
46
|
+
[lib]
|
|
47
|
+
name = "gram_codec"
|
|
48
|
+
path = "src/lib.rs"
|
|
49
|
+
crate-type = ["cdylib", "rlib"]
|
|
50
|
+
|
|
51
|
+
[[bench]]
|
|
52
|
+
name = "codec_benchmarks"
|
|
53
|
+
harness = false
|
|
54
|
+
required-features = []
|
|
55
|
+
|
|
56
|
+
[[example]]
|
|
57
|
+
name = "interop_check"
|
|
58
|
+
path = "examples/interop_check.rs"
|
|
59
|
+
|
|
60
|
+
[[example]]
|
|
61
|
+
name = "basic_usage"
|
|
62
|
+
path = "examples/basic_usage.rs"
|
|
63
|
+
|
|
64
|
+
[[example]]
|
|
65
|
+
name = "advanced_usage"
|
|
66
|
+
path = "examples/advanced_usage.rs"
|
|
67
|
+
|
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
# Gram Codec
|
|
2
|
+
|
|
3
|
+
Bidirectional codec between [Gram notation](https://github.com/gram-data/tree-sitter-gram) (human-readable text format) and Pattern data structures.
|
|
4
|
+
|
|
5
|
+
[](https://github.com/relateby/pattern-rs/actions)
|
|
6
|
+
[](https://opensource.org/licenses/Apache-2.0)
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- **Full Grammar Support**: Parses all Gram syntax forms (nodes, relationships, subject patterns, annotations)
|
|
11
|
+
- **Round-Trip Correctness**: Parse → serialize → parse produces structurally equivalent patterns
|
|
12
|
+
- **Error Recovery**: Reports all syntax errors, not just the first
|
|
13
|
+
- **Value Types**: Supports strings, integers, decimals, booleans, arrays, ranges, tagged strings
|
|
14
|
+
- **Unicode Support**: Full Unicode identifier and property value support
|
|
15
|
+
- **Comprehensive Testing**: 139+ tests covering all syntax forms and edge cases
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
Add to your `Cargo.toml`:
|
|
20
|
+
|
|
21
|
+
```toml
|
|
22
|
+
[dependencies]
|
|
23
|
+
gram-codec = { path = "../gram-codec" }
|
|
24
|
+
pattern-core = { path = "../pattern-core" }
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Quick Start
|
|
28
|
+
|
|
29
|
+
### Parsing Gram Notation
|
|
30
|
+
|
|
31
|
+
```rust
|
|
32
|
+
use gram_codec::parse_gram;
|
|
33
|
+
|
|
34
|
+
// Parse a simple node
|
|
35
|
+
let patterns = parse_gram("(hello)")?;
|
|
36
|
+
println!("Identifier: {}", patterns[0].value.identity.0);
|
|
37
|
+
|
|
38
|
+
// Parse a relationship
|
|
39
|
+
let patterns = parse_gram("(alice)-[:KNOWS]->(bob)")?;
|
|
40
|
+
println!("Relationship with {} elements", patterns[0].elements.len());
|
|
41
|
+
|
|
42
|
+
// Parse a subject pattern
|
|
43
|
+
let patterns = parse_gram("[team | (alice), (bob)]")?;
|
|
44
|
+
println!("Team has {} members", patterns[0].elements.len());
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Serializing Patterns
|
|
48
|
+
|
|
49
|
+
```rust
|
|
50
|
+
use gram_codec::{to_gram_pattern, to_gram};
|
|
51
|
+
use pattern_core::{Pattern, Subject, Symbol};
|
|
52
|
+
use std::collections::{HashMap, HashSet};
|
|
53
|
+
|
|
54
|
+
// Create a pattern
|
|
55
|
+
let subject = Subject {
|
|
56
|
+
identity: Symbol("hello".to_string()),
|
|
57
|
+
labels: HashSet::new(),
|
|
58
|
+
properties: HashMap::new(),
|
|
59
|
+
};
|
|
60
|
+
let pattern = Pattern::point(subject);
|
|
61
|
+
|
|
62
|
+
// Serialize a single pattern
|
|
63
|
+
let gram_text = to_gram_pattern(&pattern)?;
|
|
64
|
+
println!("{}", gram_text); // Output: (hello)
|
|
65
|
+
|
|
66
|
+
// Serialize multiple patterns
|
|
67
|
+
let multiple = to_gram(&[pattern.clone(), pattern])?;
|
|
68
|
+
println!("{}", multiple); // Output: (hello)\n(hello)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Round-Trip Correctness
|
|
72
|
+
|
|
73
|
+
```rust
|
|
74
|
+
use gram_codec::{parse_gram, to_gram_pattern};
|
|
75
|
+
|
|
76
|
+
let original = "(alice:Person {name: \"Alice\"})";
|
|
77
|
+
|
|
78
|
+
// Parse
|
|
79
|
+
let parsed = parse_gram(original)?;
|
|
80
|
+
|
|
81
|
+
// Serialize
|
|
82
|
+
let serialized = to_gram_pattern(&parsed[0])?;
|
|
83
|
+
|
|
84
|
+
// Re-parse
|
|
85
|
+
let reparsed = parse_gram(&serialized)?;
|
|
86
|
+
|
|
87
|
+
// Verify structural equivalence
|
|
88
|
+
assert_eq!(parsed[0].value.identity, reparsed[0].value.identity);
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Supported Gram Syntax
|
|
92
|
+
|
|
93
|
+
### Node Patterns (0 elements)
|
|
94
|
+
|
|
95
|
+
```gram
|
|
96
|
+
() // Empty node
|
|
97
|
+
(hello) // Node with identifier
|
|
98
|
+
(a:Person) // Node with label
|
|
99
|
+
(a:Person {name: "Alice"}) // Node with properties
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Relationship Patterns (2 elements)
|
|
103
|
+
|
|
104
|
+
The grammar accepts **multiple visual arrow styles** that normalize to **4 semantic arrow kinds**:
|
|
105
|
+
|
|
106
|
+
#### Right Arrow (`right_arrow`) - Directed left-to-right
|
|
107
|
+
```gram
|
|
108
|
+
(a)-->(b) // Single-stroke (canonical)
|
|
109
|
+
(a)==>(b) // Double-stroke
|
|
110
|
+
(a)~~>(b) // Squiggle
|
|
111
|
+
(a)-[:KNOWS]->(b) // With label
|
|
112
|
+
(a)-[:KNOWS {since: 2020}]->(b) // With properties
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
#### Left Arrow (`left_arrow`) - Directed right-to-left (elements reversed)
|
|
116
|
+
```gram
|
|
117
|
+
(a)<--(b) // Single-stroke (canonical)
|
|
118
|
+
(a)<==(b) // Double-stroke
|
|
119
|
+
(a)<~~(b) // Squiggle
|
|
120
|
+
// Note: (a)<--(b) stores elements as [b, a] (reversed!)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
#### Bidirectional Arrow (`bidirectional_arrow`) - Mutual connection
|
|
124
|
+
```gram
|
|
125
|
+
(a)<-->(b) // Single-stroke (canonical)
|
|
126
|
+
(a)<==>(b) // Double-stroke
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
#### Undirected Arrow (`undirected_arrow`) - No directionality
|
|
130
|
+
```gram
|
|
131
|
+
(a)~~(b) // Squiggle (canonical)
|
|
132
|
+
(a)==(b) // Double-stroke
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Element Ordering:**
|
|
136
|
+
- **Right arrows**: Elements stored as `[left, right]` (as written)
|
|
137
|
+
- **Left arrows**: Elements stored as `[right, left]` (reversed from visual order!)
|
|
138
|
+
- **Bidirectional/Undirected**: Elements stored as `[first, second]` (as written)
|
|
139
|
+
|
|
140
|
+
### Subject Patterns (N elements)
|
|
141
|
+
|
|
142
|
+
```gram
|
|
143
|
+
[team | (alice), (bob)] // Pattern with elements
|
|
144
|
+
[outer | [inner | (leaf)]] // Nested patterns
|
|
145
|
+
[root:Type {p: 1} | e1, e2] // With identifier, label, properties
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Annotated Patterns (1 element)
|
|
149
|
+
|
|
150
|
+
```gram
|
|
151
|
+
@type(node) (a) // Annotation on node
|
|
152
|
+
@depth(2) [x | y, z] // Annotation on subject pattern
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Property Values
|
|
156
|
+
|
|
157
|
+
```gram
|
|
158
|
+
{
|
|
159
|
+
name: "Alice", // String
|
|
160
|
+
age: 30, // Integer
|
|
161
|
+
score: 95.5, // Decimal
|
|
162
|
+
active: true, // Boolean
|
|
163
|
+
tags: ["rust", "wasm"], // Array
|
|
164
|
+
range: 1..10 // Range
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Comments
|
|
169
|
+
|
|
170
|
+
```gram
|
|
171
|
+
// This is a line comment
|
|
172
|
+
(hello)-->(world) // End-of-line comment
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Advanced Usage
|
|
176
|
+
|
|
177
|
+
### Complex Relationships
|
|
178
|
+
|
|
179
|
+
```rust
|
|
180
|
+
let gram_text = "(alice:Person {name: \"Alice\", age: 30})-[:KNOWS {since: 2020}]->(bob:Person {name: \"Bob\"})";
|
|
181
|
+
let patterns = parse_gram_notation(gram_text)?;
|
|
182
|
+
|
|
183
|
+
// Access left node
|
|
184
|
+
println!("Left: {}", patterns[0].elements[0].value.identity.0);
|
|
185
|
+
|
|
186
|
+
// Access edge
|
|
187
|
+
println!("Edge labels: {:?}", patterns[0].value.labels);
|
|
188
|
+
|
|
189
|
+
// Access right node
|
|
190
|
+
println!("Right: {}", patterns[0].elements[1].value.identity.0);
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Nested Patterns
|
|
194
|
+
|
|
195
|
+
```rust
|
|
196
|
+
let gram_text = "[outer:Group | [inner:Team | (alice), (bob)], (charlie)]";
|
|
197
|
+
let patterns = parse_gram_notation(gram_text)?;
|
|
198
|
+
|
|
199
|
+
println!("Outer: {}", patterns[0].value.identity.0);
|
|
200
|
+
println!("Elements: {}", patterns[0].elements.len());
|
|
201
|
+
println!("First element is nested: {}",
|
|
202
|
+
!patterns[0].elements[0].elements.is_empty());
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Path Patterns
|
|
206
|
+
|
|
207
|
+
```rust
|
|
208
|
+
// Chained relationships
|
|
209
|
+
let gram_text = "(a)-->(b)-->(c)-->(d)";
|
|
210
|
+
let patterns = parse_gram_notation(gram_text)?;
|
|
211
|
+
|
|
212
|
+
// Creates nested relationship structure
|
|
213
|
+
println!("Path pattern parsed");
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Unicode Support
|
|
217
|
+
|
|
218
|
+
```rust
|
|
219
|
+
// Unicode identifiers must be quoted
|
|
220
|
+
let gram_text = "(\"世界\" {greeting: \"こんにちは\"})";
|
|
221
|
+
let patterns = parse_gram_notation(gram_text)?;
|
|
222
|
+
|
|
223
|
+
println!("Identifier: {}", patterns[0].value.identity.0);
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Error Handling
|
|
227
|
+
|
|
228
|
+
```rust
|
|
229
|
+
use gram_codec::parse_gram_notation;
|
|
230
|
+
|
|
231
|
+
let invalid_gram = "(unclosed";
|
|
232
|
+
match parse_gram_notation(invalid_gram) {
|
|
233
|
+
Ok(_) => println!("Success"),
|
|
234
|
+
Err(e) => {
|
|
235
|
+
println!("Parse error: {}", e.message);
|
|
236
|
+
println!("Error count: {}", e.error_count());
|
|
237
|
+
// Access location information
|
|
238
|
+
println!("Location: line {}, column {}",
|
|
239
|
+
e.location.line, e.location.column);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
## Examples
|
|
245
|
+
|
|
246
|
+
> 📚 **See [`../../examples/gram-codec-README.md`](../../examples/gram-codec-README.md) for complete examples across all platforms!**
|
|
247
|
+
|
|
248
|
+
Run the included examples:
|
|
249
|
+
|
|
250
|
+
```bash
|
|
251
|
+
# Basic usage (10 examples)
|
|
252
|
+
cargo run --package gram-codec --example basic_usage
|
|
253
|
+
|
|
254
|
+
# Advanced usage (10 examples)
|
|
255
|
+
cargo run --package gram-codec --example advanced_usage
|
|
256
|
+
|
|
257
|
+
# Interactive Python demo
|
|
258
|
+
python examples/gram-codec-python/demo.py
|
|
259
|
+
|
|
260
|
+
# Interactive browser demo
|
|
261
|
+
# (After building: wasm-pack build --target web . -- --features wasm)
|
|
262
|
+
python3 -m http.server 8000
|
|
263
|
+
# Open http://localhost:8000/examples/gram-codec-wasm-web/
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
## Testing
|
|
267
|
+
|
|
268
|
+
Run the comprehensive test suite:
|
|
269
|
+
|
|
270
|
+
```bash
|
|
271
|
+
# All tests (159 tests total)
|
|
272
|
+
cargo test --package gram-codec
|
|
273
|
+
|
|
274
|
+
# Specific test suite
|
|
275
|
+
cargo test --package gram-codec --test parser_tests # 18 tests
|
|
276
|
+
cargo test --package gram-codec --test serializer_tests # 15 tests
|
|
277
|
+
cargo test --package gram-codec --test value_types_tests # 13 tests
|
|
278
|
+
cargo test --package gram-codec --test arrow_types_tests # 14 tests (1 ignored)
|
|
279
|
+
cargo test --package gram-codec --test arrow_style_variants_tests # 19 tests
|
|
280
|
+
cargo test --package gram-codec --test edge_cases_tests # 28 tests
|
|
281
|
+
cargo test --package gram-codec --test advanced_features_tests # 22 tests
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### Test Coverage
|
|
285
|
+
|
|
286
|
+
- **159 tests total** (158 passing + 1 ignored)
|
|
287
|
+
- Unit tests for error handling, parser core, serializer core
|
|
288
|
+
- Comprehensive arrow style variant tests (all 10 visual forms documented)
|
|
289
|
+
- Integration tests for all gram syntax forms
|
|
290
|
+
- Edge case handling (nesting, whitespace, comments, error recovery)
|
|
291
|
+
- Round-trip correctness validation
|
|
292
|
+
|
|
293
|
+
## Grammar Authority
|
|
294
|
+
|
|
295
|
+
This codec uses [`tree-sitter-gram`](https://github.com/gram-data/tree-sitter-gram) as the authoritative grammar specification. The pure Rust implementation is validated for 100% conformance with the tree-sitter-gram test corpus.
|
|
296
|
+
|
|
297
|
+
## Architecture
|
|
298
|
+
|
|
299
|
+
The codec consists of several modules:
|
|
300
|
+
|
|
301
|
+
- **`parser`**: Transforms Gram notation text → Pattern structures using a pure Rust `nom` implementation
|
|
302
|
+
- **`serializer`**: Transforms Pattern structures → Gram notation text
|
|
303
|
+
- **`ast`**: AST (Abstract Syntax Tree) types for cross-language JSON serialization
|
|
304
|
+
- **`value`**: Value enum for property types (String, Integer, Decimal, Boolean, Array, Range)
|
|
305
|
+
- **`error`**: Error types with location information
|
|
306
|
+
|
|
307
|
+
## Multi-Platform Support
|
|
308
|
+
|
|
309
|
+
### WASM (WebAssembly)
|
|
310
|
+
|
|
311
|
+
Build for browser and Node.js environments:
|
|
312
|
+
|
|
313
|
+
```bash
|
|
314
|
+
# Using wasm-pack
|
|
315
|
+
wasm-pack build --target web crates/gram-codec -- --features wasm
|
|
316
|
+
|
|
317
|
+
# JavaScript usage
|
|
318
|
+
import init, { parse_gram, validate_gram, round_trip } from './pkg/gram_codec.js';
|
|
319
|
+
await init();
|
|
320
|
+
const result = parse_gram("(hello)-->(world)");
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
**Examples:**
|
|
324
|
+
- `../../examples/gram-codec-wasm-web/` - Interactive browser demo with UI
|
|
325
|
+
- `../../examples/gram-codec-wasm-node/` - Node.js command-line examples
|
|
326
|
+
|
|
327
|
+
### Python
|
|
328
|
+
|
|
329
|
+
Build and install Python bindings:
|
|
330
|
+
|
|
331
|
+
```bash
|
|
332
|
+
pip install maturin
|
|
333
|
+
cd crates/gram-codec
|
|
334
|
+
maturin develop --features python
|
|
335
|
+
|
|
336
|
+
# Python usage
|
|
337
|
+
from gram_codec import parse_gram, validate_gram, round_trip
|
|
338
|
+
result = parse_gram("(hello)-->(world)")
|
|
339
|
+
print(f"Parsed {result['pattern_count']} patterns")
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
**Examples:**
|
|
343
|
+
- `../../examples/gram-codec-python/demo.py` - Interactive demo with REPL mode
|
|
344
|
+
- `../../examples/gram-codec-python/quickstart.py` - Quick 5-minute introduction
|
|
345
|
+
- `../../examples/gram-codec-python/gram_codec.py` - Template with 10 example functions
|
|
346
|
+
|
|
347
|
+
See `pyproject.toml` for packaging configuration.
|
|
348
|
+
|
|
349
|
+
## Performance
|
|
350
|
+
|
|
351
|
+
The codec includes comprehensive benchmarks:
|
|
352
|
+
|
|
353
|
+
```bash
|
|
354
|
+
# Run all benchmarks
|
|
355
|
+
cargo bench --package gram-codec
|
|
356
|
+
|
|
357
|
+
# Specific benchmarks
|
|
358
|
+
cargo bench --package gram-codec --bench codec_benchmarks -- parse_simple_nodes
|
|
359
|
+
cargo bench --package gram-codec --bench codec_benchmarks -- round_trip
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
Benchmarks cover:
|
|
363
|
+
- Parsing simple nodes (10, 100, 1000 patterns)
|
|
364
|
+
- Parsing relationships and chains
|
|
365
|
+
- Parsing subject patterns with many elements
|
|
366
|
+
- Serialization (single and multiple patterns)
|
|
367
|
+
- Round-trip correctness (parse → serialize → parse)
|
|
368
|
+
- Complex patterns with mixed syntax
|
|
369
|
+
|
|
370
|
+
## License
|
|
371
|
+
|
|
372
|
+
Licensed under the Apache License, Version 2.0. See [LICENSE](../../LICENSE) for details.
|
|
373
|
+
|
|
374
|
+
## Contributing
|
|
375
|
+
|
|
376
|
+
Contributions are welcome! Please ensure:
|
|
377
|
+
|
|
378
|
+
- All tests pass: `cargo test --package gram-codec`
|
|
379
|
+
- Code is formatted: `cargo fmt --all`
|
|
380
|
+
- No clippy warnings: `cargo clippy --package gram-codec -- -D warnings`
|
|
381
|
+
- Examples run successfully
|
|
382
|
+
|
|
383
|
+
## Resources
|
|
384
|
+
|
|
385
|
+
- [Gram Notation Specification](https://github.com/gram-data/tree-sitter-gram)
|
|
386
|
+
- [Pattern Core Library](../pattern-core/)
|
|
387
|
+
- [Project Documentation](../../specs/019-gram-codec/)
|