navrules 0.1.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.
- navrules-0.1.0/PKG-INFO +155 -0
- navrules-0.1.0/README.md +128 -0
- navrules-0.1.0/pyproject.toml +55 -0
- navrules-0.1.0/rust/Cargo.lock +345 -0
- navrules-0.1.0/rust/Cargo.toml +28 -0
- navrules-0.1.0/rust/src/condition.rs +183 -0
- navrules-0.1.0/rust/src/lib.rs +23 -0
- navrules-0.1.0/rust/src/ruleset.rs +179 -0
- navrules-0.1.0/rust/src/value.rs +148 -0
- navrules-0.1.0/src/navrules/__init__.py +45 -0
- navrules-0.1.0/src/navrules/_native/__init__.py +27 -0
- navrules-0.1.0/src/navrules/abstract.py +255 -0
- navrules-0.1.0/src/navrules/availability.py +96 -0
- navrules-0.1.0/src/navrules/conditions.py +184 -0
- navrules-0.1.0/src/navrules/context.py +290 -0
- navrules-0.1.0/src/navrules/environment.py +367 -0
- navrules-0.1.0/src/navrules/loader.py +129 -0
- navrules-0.1.0/src/navrules/operators.py +162 -0
- navrules-0.1.0/src/navrules/policies.py +71 -0
- navrules-0.1.0/src/navrules/py.typed +0 -0
- navrules-0.1.0/src/navrules/registry.py +111 -0
- navrules-0.1.0/src/navrules/ruleset.py +345 -0
- navrules-0.1.0/src/navrules/storages/__init__.py +6 -0
- navrules-0.1.0/src/navrules/storages/abstract.py +39 -0
- navrules-0.1.0/src/navrules/storages/file.py +37 -0
- navrules-0.1.0/src/navrules/storages/memory.py +17 -0
navrules-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: navrules
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Classifier: Development Status :: 4 - Beta
|
|
5
|
+
Classifier: Intended Audience :: Developers
|
|
6
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
7
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
11
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
12
|
+
Classifier: Framework :: AsyncIO
|
|
13
|
+
Classifier: Typing :: Typed
|
|
14
|
+
Requires-Dist: cel-python>=0.1.5 ; extra == 'cel'
|
|
15
|
+
Requires-Dist: pandas>=2.0 ; extra == 'pandas'
|
|
16
|
+
Provides-Extra: cel
|
|
17
|
+
Provides-Extra: pandas
|
|
18
|
+
Summary: Generic, low-latency rule evaluation engine (priority, first-match, all-match policies) with optional Rust backend
|
|
19
|
+
Keywords: rules,rule-engine,policy,first-match,evaluation,asyncio
|
|
20
|
+
Author-email: Jesus Lara <jesuslara@phenobarbital.info>
|
|
21
|
+
License-Expression: MIT
|
|
22
|
+
Requires-Python: >=3.11
|
|
23
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
24
|
+
Project-URL: Homepage, https://github.com/phenobarbital/ai-parrot
|
|
25
|
+
Project-URL: Repository, https://github.com/phenobarbital/ai-parrot
|
|
26
|
+
|
|
27
|
+
# navrules
|
|
28
|
+
|
|
29
|
+
Generic, low-latency **rule evaluation engine** with priority-ordered
|
|
30
|
+
first-match, declarative conditions, and an optional **Rust backend** for the
|
|
31
|
+
CPU-bound hot path.
|
|
32
|
+
|
|
33
|
+
Extracted from a production rewards system; designed to be shared by any
|
|
34
|
+
consumer that evaluates "subject + environment vs. N rules": rewards/badges,
|
|
35
|
+
payrate selection at clock-out, eligibility checks, etc.
|
|
36
|
+
|
|
37
|
+
- **Zero mandatory dependencies** — stdlib only; `pandas` and `cel` are extras.
|
|
38
|
+
- **Two-phase rule contract** — `fits(ctx, env)` (sync, cheap pre-filter) and
|
|
39
|
+
`async evaluate(ctx, env)` (full evaluation, may do I/O).
|
|
40
|
+
- **Policies** — `ALL_MATCH`, `ANY_MATCH`, `FIRST_MATCH` (priority-ordered,
|
|
41
|
+
short-circuiting, typed result payload).
|
|
42
|
+
- **Rust hot path** — declarative rule sets compile once into a native
|
|
43
|
+
matcher (PyO3 + rayon, GIL released); pure-Python fallback is always
|
|
44
|
+
available (`navrules.HAS_RUST` tells you which one is active).
|
|
45
|
+
|
|
46
|
+
## Quick start: payrate selection at clock-out
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
from navrules import ConditionRule, EvalContext, Environment, Policy, RuleSet
|
|
50
|
+
|
|
51
|
+
ruleset: RuleSet[dict] = RuleSet(
|
|
52
|
+
policy=Policy.FIRST_MATCH,
|
|
53
|
+
default={"payrate": 25.0, "code": "BASE"},
|
|
54
|
+
)
|
|
55
|
+
ruleset.add_rule({
|
|
56
|
+
"rule_type": "ConditionRule",
|
|
57
|
+
"name": "ot_weekend",
|
|
58
|
+
"priority": 100,
|
|
59
|
+
"conditions": {"env.is_weekend": True, "ctx.worked_hours": {"gt": 8}},
|
|
60
|
+
"result": {"payrate": 33.75, "code": "OT-WKND"},
|
|
61
|
+
})
|
|
62
|
+
ruleset.add_rule({
|
|
63
|
+
"rule_type": "ConditionRule",
|
|
64
|
+
"name": "night_diff",
|
|
65
|
+
"priority": 90,
|
|
66
|
+
"conditions": {
|
|
67
|
+
"env.day_period": {"in": ["evening", "night"]},
|
|
68
|
+
"ctx.job_code": {"in": ["TECH1", "TECH2"]},
|
|
69
|
+
},
|
|
70
|
+
"result": {"payrate": 29.50, "code": "NIGHT"},
|
|
71
|
+
})
|
|
72
|
+
ruleset.compile() # sorts by priority, compiles to Rust when available
|
|
73
|
+
|
|
74
|
+
# hot path — one call per clock-out, no async, no I/O:
|
|
75
|
+
env = Environment.at(clockout_ts, tz=site_tz)
|
|
76
|
+
ctx = EvalContext.from_user(employee, worked_hours=9.5, job_code="TECH1")
|
|
77
|
+
result = ruleset.evaluate_sync(ctx, env)
|
|
78
|
+
payrate = result.value["payrate"]
|
|
79
|
+
|
|
80
|
+
# end-of-day close, thousands of activities (rayon batch):
|
|
81
|
+
results = ruleset.evaluate_batch(contexts, env)
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Condition DSL
|
|
85
|
+
|
|
86
|
+
JSON-friendly dict, one entry per field (entries AND together):
|
|
87
|
+
|
|
88
|
+
```json
|
|
89
|
+
{
|
|
90
|
+
"env.is_weekend": true,
|
|
91
|
+
"ctx.worked_hours": {"gte": 4, "lt": 12},
|
|
92
|
+
"ctx.job_code": {"in": ["TECH1", "TECH2"]},
|
|
93
|
+
"quarter": "Q4"
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
- Scalar value ⇒ `eq` shorthand. A `{op: operand}` map applies operators;
|
|
98
|
+
multiple operators under one field AND together.
|
|
99
|
+
- `ctx.` prefix reads the evaluation context, `env.` the environment; bare
|
|
100
|
+
keys resolve ctx first, then env.
|
|
101
|
+
- Operators: `eq ne gt gte lt lte in not_in contains startswith endswith
|
|
102
|
+
regex between is_null`.
|
|
103
|
+
- Missing values match only `is_null`; `bool` never coerces to a number;
|
|
104
|
+
`int`/`float` coerce to each other. The Rust backend mirrors these
|
|
105
|
+
semantics bit-for-bit (enforced by the parity suite).
|
|
106
|
+
- Custom operators can be registered on an `OperatorRegistry`; rule sets
|
|
107
|
+
using them transparently fall back to the Python matcher.
|
|
108
|
+
|
|
109
|
+
## Rule families
|
|
110
|
+
|
|
111
|
+
| Family | Use case | Backend |
|
|
112
|
+
|---|---|---|
|
|
113
|
+
| `ConditionRule` | Declarative conditions, CPU-bound (payrates, ambient rules) | Rust or Python |
|
|
114
|
+
| `AbstractRule` subclass | Code rules; `evaluate()` may hit a DB or service | Python (async) |
|
|
115
|
+
| `ComputedRule` | Pull pattern: the rule queries its own candidates | Python (async) |
|
|
116
|
+
|
|
117
|
+
Mixed sets work: `await ruleset.evaluate(ctx, env)` walks rules in priority
|
|
118
|
+
order, awaiting I/O rules in their turn.
|
|
119
|
+
|
|
120
|
+
## Environment
|
|
121
|
+
|
|
122
|
+
`Environment` derives ~35 temporal fields from a single timestamp
|
|
123
|
+
(`is_weekend`, `quarter`, `day_period`, `week_position`, `is_pay_period`,
|
|
124
|
+
business-day counters...). `Environment.at(ts, tz=...)` evaluates at any
|
|
125
|
+
instant and timezone; `extra={...}` carries site-specific ambient values.
|
|
126
|
+
|
|
127
|
+
## Loading rules from storage
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
from navrules.storages import FileStorage
|
|
131
|
+
|
|
132
|
+
async with FileStorage("payrate_rules.json") as storage:
|
|
133
|
+
for spec in await storage.load():
|
|
134
|
+
ruleset.add_rule(spec)
|
|
135
|
+
ruleset.compile()
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
`AbstractStorage` is the extension point for DB-backed definitions.
|
|
139
|
+
|
|
140
|
+
## Development
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
# Python-only (fallback backend):
|
|
144
|
+
uv run --no-project --with pytest --with pytest-asyncio --with-editable . pytest tests
|
|
145
|
+
|
|
146
|
+
# Native backend:
|
|
147
|
+
make build-rust # maturin develop --release
|
|
148
|
+
cargo test # crate unit tests (rust/)
|
|
149
|
+
RUN_BENCH=1 pytest tests/benchmarks -s
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
The wheel is built with maturin (`abi3-py311`: one wheel covers CPython
|
|
153
|
+
3.11+). If the native extension cannot be imported, navrules silently runs
|
|
154
|
+
on the pure-Python matcher — set `NAVRULES_DISABLE_RUST=1` to force it.
|
|
155
|
+
|
navrules-0.1.0/README.md
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# navrules
|
|
2
|
+
|
|
3
|
+
Generic, low-latency **rule evaluation engine** with priority-ordered
|
|
4
|
+
first-match, declarative conditions, and an optional **Rust backend** for the
|
|
5
|
+
CPU-bound hot path.
|
|
6
|
+
|
|
7
|
+
Extracted from a production rewards system; designed to be shared by any
|
|
8
|
+
consumer that evaluates "subject + environment vs. N rules": rewards/badges,
|
|
9
|
+
payrate selection at clock-out, eligibility checks, etc.
|
|
10
|
+
|
|
11
|
+
- **Zero mandatory dependencies** — stdlib only; `pandas` and `cel` are extras.
|
|
12
|
+
- **Two-phase rule contract** — `fits(ctx, env)` (sync, cheap pre-filter) and
|
|
13
|
+
`async evaluate(ctx, env)` (full evaluation, may do I/O).
|
|
14
|
+
- **Policies** — `ALL_MATCH`, `ANY_MATCH`, `FIRST_MATCH` (priority-ordered,
|
|
15
|
+
short-circuiting, typed result payload).
|
|
16
|
+
- **Rust hot path** — declarative rule sets compile once into a native
|
|
17
|
+
matcher (PyO3 + rayon, GIL released); pure-Python fallback is always
|
|
18
|
+
available (`navrules.HAS_RUST` tells you which one is active).
|
|
19
|
+
|
|
20
|
+
## Quick start: payrate selection at clock-out
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
from navrules import ConditionRule, EvalContext, Environment, Policy, RuleSet
|
|
24
|
+
|
|
25
|
+
ruleset: RuleSet[dict] = RuleSet(
|
|
26
|
+
policy=Policy.FIRST_MATCH,
|
|
27
|
+
default={"payrate": 25.0, "code": "BASE"},
|
|
28
|
+
)
|
|
29
|
+
ruleset.add_rule({
|
|
30
|
+
"rule_type": "ConditionRule",
|
|
31
|
+
"name": "ot_weekend",
|
|
32
|
+
"priority": 100,
|
|
33
|
+
"conditions": {"env.is_weekend": True, "ctx.worked_hours": {"gt": 8}},
|
|
34
|
+
"result": {"payrate": 33.75, "code": "OT-WKND"},
|
|
35
|
+
})
|
|
36
|
+
ruleset.add_rule({
|
|
37
|
+
"rule_type": "ConditionRule",
|
|
38
|
+
"name": "night_diff",
|
|
39
|
+
"priority": 90,
|
|
40
|
+
"conditions": {
|
|
41
|
+
"env.day_period": {"in": ["evening", "night"]},
|
|
42
|
+
"ctx.job_code": {"in": ["TECH1", "TECH2"]},
|
|
43
|
+
},
|
|
44
|
+
"result": {"payrate": 29.50, "code": "NIGHT"},
|
|
45
|
+
})
|
|
46
|
+
ruleset.compile() # sorts by priority, compiles to Rust when available
|
|
47
|
+
|
|
48
|
+
# hot path — one call per clock-out, no async, no I/O:
|
|
49
|
+
env = Environment.at(clockout_ts, tz=site_tz)
|
|
50
|
+
ctx = EvalContext.from_user(employee, worked_hours=9.5, job_code="TECH1")
|
|
51
|
+
result = ruleset.evaluate_sync(ctx, env)
|
|
52
|
+
payrate = result.value["payrate"]
|
|
53
|
+
|
|
54
|
+
# end-of-day close, thousands of activities (rayon batch):
|
|
55
|
+
results = ruleset.evaluate_batch(contexts, env)
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Condition DSL
|
|
59
|
+
|
|
60
|
+
JSON-friendly dict, one entry per field (entries AND together):
|
|
61
|
+
|
|
62
|
+
```json
|
|
63
|
+
{
|
|
64
|
+
"env.is_weekend": true,
|
|
65
|
+
"ctx.worked_hours": {"gte": 4, "lt": 12},
|
|
66
|
+
"ctx.job_code": {"in": ["TECH1", "TECH2"]},
|
|
67
|
+
"quarter": "Q4"
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
- Scalar value ⇒ `eq` shorthand. A `{op: operand}` map applies operators;
|
|
72
|
+
multiple operators under one field AND together.
|
|
73
|
+
- `ctx.` prefix reads the evaluation context, `env.` the environment; bare
|
|
74
|
+
keys resolve ctx first, then env.
|
|
75
|
+
- Operators: `eq ne gt gte lt lte in not_in contains startswith endswith
|
|
76
|
+
regex between is_null`.
|
|
77
|
+
- Missing values match only `is_null`; `bool` never coerces to a number;
|
|
78
|
+
`int`/`float` coerce to each other. The Rust backend mirrors these
|
|
79
|
+
semantics bit-for-bit (enforced by the parity suite).
|
|
80
|
+
- Custom operators can be registered on an `OperatorRegistry`; rule sets
|
|
81
|
+
using them transparently fall back to the Python matcher.
|
|
82
|
+
|
|
83
|
+
## Rule families
|
|
84
|
+
|
|
85
|
+
| Family | Use case | Backend |
|
|
86
|
+
|---|---|---|
|
|
87
|
+
| `ConditionRule` | Declarative conditions, CPU-bound (payrates, ambient rules) | Rust or Python |
|
|
88
|
+
| `AbstractRule` subclass | Code rules; `evaluate()` may hit a DB or service | Python (async) |
|
|
89
|
+
| `ComputedRule` | Pull pattern: the rule queries its own candidates | Python (async) |
|
|
90
|
+
|
|
91
|
+
Mixed sets work: `await ruleset.evaluate(ctx, env)` walks rules in priority
|
|
92
|
+
order, awaiting I/O rules in their turn.
|
|
93
|
+
|
|
94
|
+
## Environment
|
|
95
|
+
|
|
96
|
+
`Environment` derives ~35 temporal fields from a single timestamp
|
|
97
|
+
(`is_weekend`, `quarter`, `day_period`, `week_position`, `is_pay_period`,
|
|
98
|
+
business-day counters...). `Environment.at(ts, tz=...)` evaluates at any
|
|
99
|
+
instant and timezone; `extra={...}` carries site-specific ambient values.
|
|
100
|
+
|
|
101
|
+
## Loading rules from storage
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
from navrules.storages import FileStorage
|
|
105
|
+
|
|
106
|
+
async with FileStorage("payrate_rules.json") as storage:
|
|
107
|
+
for spec in await storage.load():
|
|
108
|
+
ruleset.add_rule(spec)
|
|
109
|
+
ruleset.compile()
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
`AbstractStorage` is the extension point for DB-backed definitions.
|
|
113
|
+
|
|
114
|
+
## Development
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
# Python-only (fallback backend):
|
|
118
|
+
uv run --no-project --with pytest --with pytest-asyncio --with-editable . pytest tests
|
|
119
|
+
|
|
120
|
+
# Native backend:
|
|
121
|
+
make build-rust # maturin develop --release
|
|
122
|
+
cargo test # crate unit tests (rust/)
|
|
123
|
+
RUN_BENCH=1 pytest tests/benchmarks -s
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
The wheel is built with maturin (`abi3-py311`: one wheel covers CPython
|
|
127
|
+
3.11+). If the native extension cannot be imported, navrules silently runs
|
|
128
|
+
on the pure-Python matcher — set `NAVRULES_DISABLE_RUST=1` to force it.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["maturin>=1.7,<2.0"]
|
|
3
|
+
build-backend = "maturin"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "navrules"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
requires-python = ">=3.11"
|
|
9
|
+
description = "Generic, low-latency rule evaluation engine (priority, first-match, all-match policies) with optional Rust backend"
|
|
10
|
+
readme = "README.md"
|
|
11
|
+
authors = [
|
|
12
|
+
{name = "Jesus Lara", email = "jesuslara@phenobarbital.info"}
|
|
13
|
+
]
|
|
14
|
+
license = "MIT"
|
|
15
|
+
keywords = ["rules", "rule-engine", "policy", "first-match", "evaluation", "asyncio"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 4 - Beta",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"Operating System :: POSIX :: Linux",
|
|
20
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
21
|
+
"Programming Language :: Python :: 3.11",
|
|
22
|
+
"Programming Language :: Python :: 3.12",
|
|
23
|
+
"Programming Language :: Python :: 3.13",
|
|
24
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
25
|
+
"Framework :: AsyncIO",
|
|
26
|
+
"Typing :: Typed",
|
|
27
|
+
]
|
|
28
|
+
# The core engine is dependency-free by design: consumers (rewards, payrate
|
|
29
|
+
# systems) must be able to install it without dragging frameworks along.
|
|
30
|
+
dependencies = []
|
|
31
|
+
|
|
32
|
+
[project.optional-dependencies]
|
|
33
|
+
pandas = ["pandas>=2.0"]
|
|
34
|
+
cel = ["cel-python>=0.1.5"]
|
|
35
|
+
|
|
36
|
+
[project.urls]
|
|
37
|
+
Homepage = "https://github.com/phenobarbital/ai-parrot"
|
|
38
|
+
Repository = "https://github.com/phenobarbital/ai-parrot"
|
|
39
|
+
|
|
40
|
+
[tool.maturin]
|
|
41
|
+
python-source = "src"
|
|
42
|
+
manifest-path = "rust/Cargo.toml"
|
|
43
|
+
module-name = "navrules._native._navrules"
|
|
44
|
+
features = ["pyo3/extension-module"]
|
|
45
|
+
|
|
46
|
+
[dependency-groups]
|
|
47
|
+
dev = [
|
|
48
|
+
"pytest>=8.0",
|
|
49
|
+
"pytest-asyncio>=0.24",
|
|
50
|
+
"pytest-benchmark>=4.0",
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
[tool.pytest.ini_options]
|
|
54
|
+
testpaths = ["tests"]
|
|
55
|
+
asyncio_mode = "auto"
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
# This file is automatically @generated by Cargo.
|
|
2
|
+
# It is not intended for manual editing.
|
|
3
|
+
version = 4
|
|
4
|
+
|
|
5
|
+
[[package]]
|
|
6
|
+
name = "aho-corasick"
|
|
7
|
+
version = "1.1.4"
|
|
8
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
9
|
+
checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
|
|
10
|
+
dependencies = [
|
|
11
|
+
"memchr",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
[[package]]
|
|
15
|
+
name = "autocfg"
|
|
16
|
+
version = "1.5.1"
|
|
17
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
18
|
+
checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
|
|
19
|
+
|
|
20
|
+
[[package]]
|
|
21
|
+
name = "cfg-if"
|
|
22
|
+
version = "1.0.4"
|
|
23
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
24
|
+
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
|
25
|
+
|
|
26
|
+
[[package]]
|
|
27
|
+
name = "crossbeam-deque"
|
|
28
|
+
version = "0.8.7"
|
|
29
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
30
|
+
checksum = "5181e0de7b61eb03a81e347d6dd8797bae9da5146707b51077e2d71a54ec0ceb"
|
|
31
|
+
dependencies = [
|
|
32
|
+
"crossbeam-epoch",
|
|
33
|
+
"crossbeam-utils",
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
[[package]]
|
|
37
|
+
name = "crossbeam-epoch"
|
|
38
|
+
version = "0.9.20"
|
|
39
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
40
|
+
checksum = "2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f"
|
|
41
|
+
dependencies = [
|
|
42
|
+
"crossbeam-utils",
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
[[package]]
|
|
46
|
+
name = "crossbeam-utils"
|
|
47
|
+
version = "0.8.22"
|
|
48
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
49
|
+
checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17"
|
|
50
|
+
|
|
51
|
+
[[package]]
|
|
52
|
+
name = "either"
|
|
53
|
+
version = "1.17.0"
|
|
54
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
55
|
+
checksum = "9e5e8f6c15a24b9a3ee5efec809ccd006d3b30e8b3bb63c39af737c7f87daa1d"
|
|
56
|
+
|
|
57
|
+
[[package]]
|
|
58
|
+
name = "heck"
|
|
59
|
+
version = "0.5.0"
|
|
60
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
61
|
+
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
|
62
|
+
|
|
63
|
+
[[package]]
|
|
64
|
+
name = "indoc"
|
|
65
|
+
version = "2.0.7"
|
|
66
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
67
|
+
checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706"
|
|
68
|
+
dependencies = [
|
|
69
|
+
"rustversion",
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
[[package]]
|
|
73
|
+
name = "itoa"
|
|
74
|
+
version = "1.0.18"
|
|
75
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
76
|
+
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
|
|
77
|
+
|
|
78
|
+
[[package]]
|
|
79
|
+
name = "libc"
|
|
80
|
+
version = "0.2.189"
|
|
81
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
82
|
+
checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2"
|
|
83
|
+
|
|
84
|
+
[[package]]
|
|
85
|
+
name = "memchr"
|
|
86
|
+
version = "2.8.3"
|
|
87
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
88
|
+
checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
|
|
89
|
+
|
|
90
|
+
[[package]]
|
|
91
|
+
name = "memoffset"
|
|
92
|
+
version = "0.9.1"
|
|
93
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
94
|
+
checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
|
|
95
|
+
dependencies = [
|
|
96
|
+
"autocfg",
|
|
97
|
+
]
|
|
98
|
+
|
|
99
|
+
[[package]]
|
|
100
|
+
name = "navrules_native"
|
|
101
|
+
version = "0.1.0"
|
|
102
|
+
dependencies = [
|
|
103
|
+
"pyo3",
|
|
104
|
+
"rayon",
|
|
105
|
+
"regex",
|
|
106
|
+
"serde",
|
|
107
|
+
"serde_json",
|
|
108
|
+
]
|
|
109
|
+
|
|
110
|
+
[[package]]
|
|
111
|
+
name = "once_cell"
|
|
112
|
+
version = "1.21.4"
|
|
113
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
114
|
+
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
|
115
|
+
|
|
116
|
+
[[package]]
|
|
117
|
+
name = "portable-atomic"
|
|
118
|
+
version = "1.14.0"
|
|
119
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
120
|
+
checksum = "3d20d5497ef88037a52ff98267d066e7f11fcc5e99bbfbd58a42336193aacec3"
|
|
121
|
+
|
|
122
|
+
[[package]]
|
|
123
|
+
name = "proc-macro2"
|
|
124
|
+
version = "1.0.107"
|
|
125
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
126
|
+
checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
|
|
127
|
+
dependencies = [
|
|
128
|
+
"unicode-ident",
|
|
129
|
+
]
|
|
130
|
+
|
|
131
|
+
[[package]]
|
|
132
|
+
name = "pyo3"
|
|
133
|
+
version = "0.24.2"
|
|
134
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
135
|
+
checksum = "e5203598f366b11a02b13aa20cab591229ff0a89fd121a308a5df751d5fc9219"
|
|
136
|
+
dependencies = [
|
|
137
|
+
"cfg-if",
|
|
138
|
+
"indoc",
|
|
139
|
+
"libc",
|
|
140
|
+
"memoffset",
|
|
141
|
+
"once_cell",
|
|
142
|
+
"portable-atomic",
|
|
143
|
+
"pyo3-build-config",
|
|
144
|
+
"pyo3-ffi",
|
|
145
|
+
"pyo3-macros",
|
|
146
|
+
"unindent",
|
|
147
|
+
]
|
|
148
|
+
|
|
149
|
+
[[package]]
|
|
150
|
+
name = "pyo3-build-config"
|
|
151
|
+
version = "0.24.2"
|
|
152
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
153
|
+
checksum = "99636d423fa2ca130fa5acde3059308006d46f98caac629418e53f7ebb1e9999"
|
|
154
|
+
dependencies = [
|
|
155
|
+
"once_cell",
|
|
156
|
+
"target-lexicon",
|
|
157
|
+
]
|
|
158
|
+
|
|
159
|
+
[[package]]
|
|
160
|
+
name = "pyo3-ffi"
|
|
161
|
+
version = "0.24.2"
|
|
162
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
163
|
+
checksum = "78f9cf92ba9c409279bc3305b5409d90db2d2c22392d443a87df3a1adad59e33"
|
|
164
|
+
dependencies = [
|
|
165
|
+
"libc",
|
|
166
|
+
"pyo3-build-config",
|
|
167
|
+
]
|
|
168
|
+
|
|
169
|
+
[[package]]
|
|
170
|
+
name = "pyo3-macros"
|
|
171
|
+
version = "0.24.2"
|
|
172
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
173
|
+
checksum = "0b999cb1a6ce21f9a6b147dcf1be9ffedf02e0043aec74dc390f3007047cecd9"
|
|
174
|
+
dependencies = [
|
|
175
|
+
"proc-macro2",
|
|
176
|
+
"pyo3-macros-backend",
|
|
177
|
+
"quote",
|
|
178
|
+
"syn 2.0.119",
|
|
179
|
+
]
|
|
180
|
+
|
|
181
|
+
[[package]]
|
|
182
|
+
name = "pyo3-macros-backend"
|
|
183
|
+
version = "0.24.2"
|
|
184
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
185
|
+
checksum = "822ece1c7e1012745607d5cf0bcb2874769f0f7cb34c4cde03b9358eb9ef911a"
|
|
186
|
+
dependencies = [
|
|
187
|
+
"heck",
|
|
188
|
+
"proc-macro2",
|
|
189
|
+
"pyo3-build-config",
|
|
190
|
+
"quote",
|
|
191
|
+
"syn 2.0.119",
|
|
192
|
+
]
|
|
193
|
+
|
|
194
|
+
[[package]]
|
|
195
|
+
name = "quote"
|
|
196
|
+
version = "1.0.47"
|
|
197
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
198
|
+
checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
|
|
199
|
+
dependencies = [
|
|
200
|
+
"proc-macro2",
|
|
201
|
+
]
|
|
202
|
+
|
|
203
|
+
[[package]]
|
|
204
|
+
name = "rayon"
|
|
205
|
+
version = "1.12.0"
|
|
206
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
207
|
+
checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d"
|
|
208
|
+
dependencies = [
|
|
209
|
+
"either",
|
|
210
|
+
"rayon-core",
|
|
211
|
+
]
|
|
212
|
+
|
|
213
|
+
[[package]]
|
|
214
|
+
name = "rayon-core"
|
|
215
|
+
version = "1.13.0"
|
|
216
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
217
|
+
checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91"
|
|
218
|
+
dependencies = [
|
|
219
|
+
"crossbeam-deque",
|
|
220
|
+
"crossbeam-utils",
|
|
221
|
+
]
|
|
222
|
+
|
|
223
|
+
[[package]]
|
|
224
|
+
name = "regex"
|
|
225
|
+
version = "1.13.1"
|
|
226
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
227
|
+
checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d"
|
|
228
|
+
dependencies = [
|
|
229
|
+
"aho-corasick",
|
|
230
|
+
"memchr",
|
|
231
|
+
"regex-automata",
|
|
232
|
+
"regex-syntax",
|
|
233
|
+
]
|
|
234
|
+
|
|
235
|
+
[[package]]
|
|
236
|
+
name = "regex-automata"
|
|
237
|
+
version = "0.4.16"
|
|
238
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
239
|
+
checksum = "8fcfdb36bda0c880c5931cdc7a2bcdc8ba4556847b9d912bca70bc94708711ad"
|
|
240
|
+
dependencies = [
|
|
241
|
+
"aho-corasick",
|
|
242
|
+
"memchr",
|
|
243
|
+
"regex-syntax",
|
|
244
|
+
]
|
|
245
|
+
|
|
246
|
+
[[package]]
|
|
247
|
+
name = "regex-syntax"
|
|
248
|
+
version = "0.8.11"
|
|
249
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
250
|
+
checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4"
|
|
251
|
+
|
|
252
|
+
[[package]]
|
|
253
|
+
name = "rustversion"
|
|
254
|
+
version = "1.0.23"
|
|
255
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
256
|
+
checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f"
|
|
257
|
+
|
|
258
|
+
[[package]]
|
|
259
|
+
name = "serde"
|
|
260
|
+
version = "1.0.229"
|
|
261
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
262
|
+
checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba"
|
|
263
|
+
dependencies = [
|
|
264
|
+
"serde_core",
|
|
265
|
+
"serde_derive",
|
|
266
|
+
]
|
|
267
|
+
|
|
268
|
+
[[package]]
|
|
269
|
+
name = "serde_core"
|
|
270
|
+
version = "1.0.229"
|
|
271
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
272
|
+
checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48"
|
|
273
|
+
dependencies = [
|
|
274
|
+
"serde_derive",
|
|
275
|
+
]
|
|
276
|
+
|
|
277
|
+
[[package]]
|
|
278
|
+
name = "serde_derive"
|
|
279
|
+
version = "1.0.229"
|
|
280
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
281
|
+
checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
|
|
282
|
+
dependencies = [
|
|
283
|
+
"proc-macro2",
|
|
284
|
+
"quote",
|
|
285
|
+
"syn 3.0.3",
|
|
286
|
+
]
|
|
287
|
+
|
|
288
|
+
[[package]]
|
|
289
|
+
name = "serde_json"
|
|
290
|
+
version = "1.0.151"
|
|
291
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
292
|
+
checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14"
|
|
293
|
+
dependencies = [
|
|
294
|
+
"itoa",
|
|
295
|
+
"memchr",
|
|
296
|
+
"serde",
|
|
297
|
+
"serde_core",
|
|
298
|
+
"zmij",
|
|
299
|
+
]
|
|
300
|
+
|
|
301
|
+
[[package]]
|
|
302
|
+
name = "syn"
|
|
303
|
+
version = "2.0.119"
|
|
304
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
305
|
+
checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
|
|
306
|
+
dependencies = [
|
|
307
|
+
"proc-macro2",
|
|
308
|
+
"quote",
|
|
309
|
+
"unicode-ident",
|
|
310
|
+
]
|
|
311
|
+
|
|
312
|
+
[[package]]
|
|
313
|
+
name = "syn"
|
|
314
|
+
version = "3.0.3"
|
|
315
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
316
|
+
checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3"
|
|
317
|
+
dependencies = [
|
|
318
|
+
"proc-macro2",
|
|
319
|
+
"quote",
|
|
320
|
+
"unicode-ident",
|
|
321
|
+
]
|
|
322
|
+
|
|
323
|
+
[[package]]
|
|
324
|
+
name = "target-lexicon"
|
|
325
|
+
version = "0.13.5"
|
|
326
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
327
|
+
checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca"
|
|
328
|
+
|
|
329
|
+
[[package]]
|
|
330
|
+
name = "unicode-ident"
|
|
331
|
+
version = "1.0.24"
|
|
332
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
333
|
+
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
|
334
|
+
|
|
335
|
+
[[package]]
|
|
336
|
+
name = "unindent"
|
|
337
|
+
version = "0.2.4"
|
|
338
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
339
|
+
checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
|
|
340
|
+
|
|
341
|
+
[[package]]
|
|
342
|
+
name = "zmij"
|
|
343
|
+
version = "1.0.23"
|
|
344
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
345
|
+
checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"
|