nyxa-speedups 0.0.1__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.
@@ -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 = "base64"
7
+ version = "0.23.1"
8
+ source = "registry+https://github.com/rust-lang/crates.io-index"
9
+ checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5"
10
+
11
+ [[package]]
12
+ name = "block-buffer"
13
+ version = "0.12.1"
14
+ source = "registry+https://github.com/rust-lang/crates.io-index"
15
+ checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa"
16
+ dependencies = [
17
+ "hybrid-array",
18
+ ]
19
+
20
+ [[package]]
21
+ name = "cfg-if"
22
+ version = "1.0.5"
23
+ source = "registry+https://github.com/rust-lang/crates.io-index"
24
+ checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600"
25
+
26
+ [[package]]
27
+ name = "cmov"
28
+ version = "0.5.4"
29
+ source = "registry+https://github.com/rust-lang/crates.io-index"
30
+ checksum = "0c9ea0ac24bc397ab3c98583a3c9ba74fa56b09a4449bbe172b9b1ddb016027a"
31
+
32
+ [[package]]
33
+ name = "const-oid"
34
+ version = "0.10.2"
35
+ source = "registry+https://github.com/rust-lang/crates.io-index"
36
+ checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c"
37
+
38
+ [[package]]
39
+ name = "cpufeatures"
40
+ version = "0.3.1"
41
+ source = "registry+https://github.com/rust-lang/crates.io-index"
42
+ checksum = "5ca28b0ae3115b884660db4118d803791fd6756b6e88f39c0f3f7859060d7566"
43
+ dependencies = [
44
+ "libc",
45
+ ]
46
+
47
+ [[package]]
48
+ name = "crypto-common"
49
+ version = "0.2.2"
50
+ source = "registry+https://github.com/rust-lang/crates.io-index"
51
+ checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453"
52
+ dependencies = [
53
+ "hybrid-array",
54
+ ]
55
+
56
+ [[package]]
57
+ name = "ctutils"
58
+ version = "0.4.3"
59
+ source = "registry+https://github.com/rust-lang/crates.io-index"
60
+ checksum = "03bb0e1cc970d482d121d9a1744999169b69a07470b3d644a7894e53fcaf4574"
61
+ dependencies = [
62
+ "cmov",
63
+ ]
64
+
65
+ [[package]]
66
+ name = "digest"
67
+ version = "0.11.3"
68
+ source = "registry+https://github.com/rust-lang/crates.io-index"
69
+ checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2"
70
+ dependencies = [
71
+ "block-buffer",
72
+ "const-oid",
73
+ "crypto-common",
74
+ "ctutils",
75
+ ]
76
+
77
+ [[package]]
78
+ name = "equivalent"
79
+ version = "1.0.2"
80
+ source = "registry+https://github.com/rust-lang/crates.io-index"
81
+ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
82
+
83
+ [[package]]
84
+ name = "foldhash"
85
+ version = "0.2.0"
86
+ source = "registry+https://github.com/rust-lang/crates.io-index"
87
+ checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
88
+
89
+ [[package]]
90
+ name = "hashbrown"
91
+ version = "0.17.1"
92
+ source = "registry+https://github.com/rust-lang/crates.io-index"
93
+ checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
94
+
95
+ [[package]]
96
+ name = "heck"
97
+ version = "0.5.0"
98
+ source = "registry+https://github.com/rust-lang/crates.io-index"
99
+ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
100
+
101
+ [[package]]
102
+ name = "hmac"
103
+ version = "0.13.0"
104
+ source = "registry+https://github.com/rust-lang/crates.io-index"
105
+ checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f"
106
+ dependencies = [
107
+ "digest",
108
+ ]
109
+
110
+ [[package]]
111
+ name = "hybrid-array"
112
+ version = "0.4.15"
113
+ source = "registry+https://github.com/rust-lang/crates.io-index"
114
+ checksum = "27f864f10dfb56725ce5ce5472bc52252c8f93a4ab86327122cebf62c5f59a17"
115
+ dependencies = [
116
+ "typenum",
117
+ ]
118
+
119
+ [[package]]
120
+ name = "indexmap"
121
+ version = "2.14.2"
122
+ source = "registry+https://github.com/rust-lang/crates.io-index"
123
+ checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855"
124
+ dependencies = [
125
+ "equivalent",
126
+ "hashbrown",
127
+ ]
128
+
129
+ [[package]]
130
+ name = "itoa"
131
+ version = "1.0.18"
132
+ source = "registry+https://github.com/rust-lang/crates.io-index"
133
+ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
134
+
135
+ [[package]]
136
+ name = "libc"
137
+ version = "0.2.190"
138
+ source = "registry+https://github.com/rust-lang/crates.io-index"
139
+ checksum = "ce5d3ddc6d3fa000eb1536d85e147bfe31aacaba692ed6a876f95cb7c855be78"
140
+
141
+ [[package]]
142
+ name = "memchr"
143
+ version = "2.8.3"
144
+ source = "registry+https://github.com/rust-lang/crates.io-index"
145
+ checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
146
+
147
+ [[package]]
148
+ name = "nyxa-speedups"
149
+ version = "0.0.1"
150
+ dependencies = [
151
+ "base64",
152
+ "hmac",
153
+ "memchr",
154
+ "pyo3",
155
+ "serde_json",
156
+ "sha2",
157
+ ]
158
+
159
+ [[package]]
160
+ name = "once_cell"
161
+ version = "1.21.4"
162
+ source = "registry+https://github.com/rust-lang/crates.io-index"
163
+ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
164
+
165
+ [[package]]
166
+ name = "portable-atomic"
167
+ version = "1.15.0"
168
+ source = "registry+https://github.com/rust-lang/crates.io-index"
169
+ checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85"
170
+
171
+ [[package]]
172
+ name = "proc-macro2"
173
+ version = "1.0.107"
174
+ source = "registry+https://github.com/rust-lang/crates.io-index"
175
+ checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
176
+ dependencies = [
177
+ "unicode-ident",
178
+ ]
179
+
180
+ [[package]]
181
+ name = "pyo3"
182
+ version = "0.29.3"
183
+ source = "registry+https://github.com/rust-lang/crates.io-index"
184
+ checksum = "700d18fa267b73b9b521fd7e13580e2f446916f176cacee1ab63fcc8191f1655"
185
+ dependencies = [
186
+ "libc",
187
+ "once_cell",
188
+ "portable-atomic",
189
+ "pyo3-build-config",
190
+ "pyo3-ffi",
191
+ "pyo3-macros",
192
+ ]
193
+
194
+ [[package]]
195
+ name = "pyo3-build-config"
196
+ version = "0.29.3"
197
+ source = "registry+https://github.com/rust-lang/crates.io-index"
198
+ checksum = "7b3fc0c4d08f6bb10e71fe39dfb9e2f59c6eb6854e22ec8092f50c69a4499adb"
199
+ dependencies = [
200
+ "target-lexicon",
201
+ ]
202
+
203
+ [[package]]
204
+ name = "pyo3-ffi"
205
+ version = "0.29.3"
206
+ source = "registry+https://github.com/rust-lang/crates.io-index"
207
+ checksum = "dfc0b8e19df29aad7086cf977bb0c2a2f143e30567eb113e9cf72b62ca698330"
208
+ dependencies = [
209
+ "libc",
210
+ "pyo3-build-config",
211
+ ]
212
+
213
+ [[package]]
214
+ name = "pyo3-macros"
215
+ version = "0.29.3"
216
+ source = "registry+https://github.com/rust-lang/crates.io-index"
217
+ checksum = "6100e8a4b5eba53afaa5ed078364851a0b2499c553a44c31026b929049b49dc6"
218
+ dependencies = [
219
+ "proc-macro2",
220
+ "pyo3-macros-backend",
221
+ "quote",
222
+ "syn 2.0.119",
223
+ ]
224
+
225
+ [[package]]
226
+ name = "pyo3-macros-backend"
227
+ version = "0.29.3"
228
+ source = "registry+https://github.com/rust-lang/crates.io-index"
229
+ checksum = "6143877a16e82b5a727b7127ff4cd86858a24a28d745d72f43e6f227c7b1bdb3"
230
+ dependencies = [
231
+ "heck",
232
+ "proc-macro2",
233
+ "quote",
234
+ "syn 2.0.119",
235
+ ]
236
+
237
+ [[package]]
238
+ name = "quote"
239
+ version = "1.0.47"
240
+ source = "registry+https://github.com/rust-lang/crates.io-index"
241
+ checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
242
+ dependencies = [
243
+ "proc-macro2",
244
+ ]
245
+
246
+ [[package]]
247
+ name = "serde"
248
+ version = "1.0.229"
249
+ source = "registry+https://github.com/rust-lang/crates.io-index"
250
+ checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba"
251
+ dependencies = [
252
+ "serde_core",
253
+ ]
254
+
255
+ [[package]]
256
+ name = "serde_core"
257
+ version = "1.0.229"
258
+ source = "registry+https://github.com/rust-lang/crates.io-index"
259
+ checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48"
260
+ dependencies = [
261
+ "serde_derive",
262
+ ]
263
+
264
+ [[package]]
265
+ name = "serde_derive"
266
+ version = "1.0.229"
267
+ source = "registry+https://github.com/rust-lang/crates.io-index"
268
+ checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
269
+ dependencies = [
270
+ "proc-macro2",
271
+ "quote",
272
+ "syn 3.0.9",
273
+ ]
274
+
275
+ [[package]]
276
+ name = "serde_json"
277
+ version = "1.0.154"
278
+ source = "registry+https://github.com/rust-lang/crates.io-index"
279
+ checksum = "e7e9cc8b1b85264074fbcc02a88680c4096b1e47df8f739dceb03bf482f04bd6"
280
+ dependencies = [
281
+ "foldhash",
282
+ "indexmap",
283
+ "itoa",
284
+ "memchr",
285
+ "serde",
286
+ "serde_core",
287
+ "zmij",
288
+ ]
289
+
290
+ [[package]]
291
+ name = "sha2"
292
+ version = "0.11.0"
293
+ source = "registry+https://github.com/rust-lang/crates.io-index"
294
+ checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4"
295
+ dependencies = [
296
+ "cfg-if",
297
+ "cpufeatures",
298
+ "digest",
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.9"
315
+ source = "registry+https://github.com/rust-lang/crates.io-index"
316
+ checksum = "d78c8dee4c7bf0e14673097256fed6142ce9d3b85a408189d07482442145823b"
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 = "typenum"
331
+ version = "1.20.1"
332
+ source = "registry+https://github.com/rust-lang/crates.io-index"
333
+ checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20"
334
+
335
+ [[package]]
336
+ name = "unicode-ident"
337
+ version = "1.0.26"
338
+ source = "registry+https://github.com/rust-lang/crates.io-index"
339
+ checksum = "d245f478577f809a851594d02313b640fb437e0bb33866753cff937863096954"
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"
@@ -0,0 +1,28 @@
1
+ [package]
2
+ name = "nyxa-speedups"
3
+ version = "0.0.1"
4
+ edition = "2021"
5
+ description = "Optional native accelerators for the Nyxa framework"
6
+ license = "MIT"
7
+ publish = false
8
+ readme = "README.md"
9
+
10
+ [lib]
11
+ name = "nyxa_speedups"
12
+ crate-type = ["cdylib"]
13
+
14
+ [dependencies]
15
+ base64 = "0.23.1"
16
+ hmac = "0.13.0"
17
+ memchr = "2.8.3"
18
+ pyo3 = { version = "0.29", features = ["extension-module", "abi3-py313"] }
19
+ serde_json = { version = "1", features = ["preserve_order"] }
20
+ sha2 = "0.11.0"
21
+
22
+ [profile.release]
23
+ lto = "fat"
24
+ codegen-units = 1
25
+ opt-level = 3
26
+ # macOS 27 dyld rejects cdylibs whose LINKEDIT string pool is only 4-byte
27
+ # aligned after ``strip=debuginfo`` (rust-lang/rust#157750). Keep symbols.
28
+ strip = "none"
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Al-Amin Islam Nerob
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,98 @@
1
+ Metadata-Version: 2.4
2
+ Name: nyxa-speedups
3
+ Version: 0.0.1
4
+ Classifier: Programming Language :: Rust
5
+ Classifier: Programming Language :: Python :: Implementation :: CPython
6
+ License-File: LICENSE
7
+ Summary: Native accelerators for the Nyxa framework (bundled with nyxa by default)
8
+ Author-email: Al-Amin Islam Nerob <alamin@aincoder.com>
9
+ License-Expression: MIT
10
+ Requires-Python: >=3.13
11
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
12
+ Project-URL: Repository, https://github.com/NyxaDev/Nyxa
13
+
14
+ # nyxa-speedups
15
+
16
+ Rust accelerators for the Nyxa framework — drop-in native versions of
17
+ the hot paths (routing, headers, query/cookie parsing, multipart,
18
+ cookie signing, URL building, form validation, pagination JSON).
19
+ Bundled with `nyxa` by default; every helper has a pure-Python
20
+ reference in `nyxa._speedups` with identical results.
21
+
22
+ ## Features
23
+
24
+ - **`Matcher`** — route-tree matcher built by `RouteTree`:
25
+ `Matcher()`, `add_node() -> id`, `add_static(parent, segment,
26
+ child)`, `add_param(parent, name, pattern, child)` (compiled regex
27
+ or `None`), `set_wildcard(parent, child)`, `add_handler(node,
28
+ methods, route)`, `find(method, path) -> (route, params) | None`.
29
+ - **HTTP parsing** — `parse_query(qs)`, `parse_query_multi(qs)`,
30
+ `parse_cookies(header)`, `scan_headers(...)`, `encode_headers(...)`,
31
+ `parse_multipart(body, boundary, max_fields, max_files,
32
+ max_part_size=None)` (bounded).
33
+ - **`HeaderIndex`** — `header_index(raw)` builds a byte-exact index
34
+ over ASGI `[(bytes, bytes)]` pairs: `idx.get(name)`, `idx.items()`;
35
+ plus `flatten_headers(headers)` and `normalize_headers(...)`.
36
+ - **Signed cookies** — `sign_cookie(value, key, timestamp=False)`,
37
+ `verify_cookie(value, key, max_age=None)` — the same format the
38
+ session middleware uses.
39
+ - **URLs** — `url_build(...)` for fast path construction.
40
+ - **Validation** — `validate_plan(plan, data)` evaluates compiled
41
+ `nyxa-forms` rule plans natively; `NATIVE_RULE_IDS` maps rule names
42
+ to the ids the native engine covers.
43
+ - **Pagination JSON** — `paginate_to_json(rows, meta)` encodes
44
+ `{"data": rows, "meta": meta}` when every cell is JSON-safe.
45
+ - **Graceful fallback** — each helper returns `None` for inputs it
46
+ doesn't cover (non-ASCII, quoted cookies, unusual items) and the
47
+ framework transparently falls back to the Python reference —
48
+ results are always identical.
49
+ - **Kill switch** — `NYXA_NO_SPEEDUPS=1` forces the Python
50
+ implementations.
51
+
52
+ ## Install
53
+
54
+ ```bash
55
+ pip install nyxa # nyxa-speedups (maturin wheel) is bundled by default
56
+ # standalone: pip install nyxa-speedups
57
+ ```
58
+
59
+ No configuration — the framework probes the module at import and
60
+ uses it where available.
61
+
62
+ ## Public API
63
+
64
+ Module `nyxa_speedups` (native extension):
65
+
66
+ - **`Matcher`** — the route-tree pyclass (see Features).
67
+ - **`HeaderIndex`** — header-pair index: `get(name) -> str | None`,
68
+ `items() -> [(name, value)]`.
69
+ - **`header_index(raw)`** — build a `HeaderIndex` or `None`.
70
+ - **`parse_query(qs)`** — `dict[str, str]`, last value wins.
71
+ - **`parse_query_multi(qs)`** — repeated keys collapse to lists.
72
+ - **`parse_cookies(header)`** — `Cookie` header → `dict[str, str]`.
73
+ - **`scan_headers(...)`** / **`encode_headers(...)`** — header
74
+ scanning/serialization used by request/response paths.
75
+ - **`parse_multipart(body, boundary, max_fields, max_files,
76
+ max_part_size=None)`** — bounded multipart parse.
77
+ - **`flatten_headers(headers)`** — `str | list` values → wire pairs.
78
+ - **`normalize_headers(...)`** — header map normalization.
79
+ - **`sign_cookie(value, key, timestamp=False)`** → signed string.
80
+ - **`verify_cookie(value, key, max_age=None)`** → payload or `None`.
81
+ - **`url_build(...)`** — fast URL construction.
82
+ - **`validate_plan(plan, data)`** — native rule-plan evaluation or
83
+ `None` to defer to Python.
84
+ - **`paginate_to_json(rows, meta)`** — JSON bytes or `None`.
85
+ - **`NATIVE_RULE_IDS`** — `dict[str, int]` of rules the native
86
+ validator covers.
87
+
88
+ All functions return `None` on uncovered input — callers fall back to
89
+ Python for full semantics.
90
+
91
+ ## Configuration
92
+
93
+ `NYXA_NO_SPEEDUPS=1` disables all acceleration.
94
+
95
+ ## License
96
+
97
+ MIT
98
+
@@ -0,0 +1,84 @@
1
+ # nyxa-speedups
2
+
3
+ Rust accelerators for the Nyxa framework — drop-in native versions of
4
+ the hot paths (routing, headers, query/cookie parsing, multipart,
5
+ cookie signing, URL building, form validation, pagination JSON).
6
+ Bundled with `nyxa` by default; every helper has a pure-Python
7
+ reference in `nyxa._speedups` with identical results.
8
+
9
+ ## Features
10
+
11
+ - **`Matcher`** — route-tree matcher built by `RouteTree`:
12
+ `Matcher()`, `add_node() -> id`, `add_static(parent, segment,
13
+ child)`, `add_param(parent, name, pattern, child)` (compiled regex
14
+ or `None`), `set_wildcard(parent, child)`, `add_handler(node,
15
+ methods, route)`, `find(method, path) -> (route, params) | None`.
16
+ - **HTTP parsing** — `parse_query(qs)`, `parse_query_multi(qs)`,
17
+ `parse_cookies(header)`, `scan_headers(...)`, `encode_headers(...)`,
18
+ `parse_multipart(body, boundary, max_fields, max_files,
19
+ max_part_size=None)` (bounded).
20
+ - **`HeaderIndex`** — `header_index(raw)` builds a byte-exact index
21
+ over ASGI `[(bytes, bytes)]` pairs: `idx.get(name)`, `idx.items()`;
22
+ plus `flatten_headers(headers)` and `normalize_headers(...)`.
23
+ - **Signed cookies** — `sign_cookie(value, key, timestamp=False)`,
24
+ `verify_cookie(value, key, max_age=None)` — the same format the
25
+ session middleware uses.
26
+ - **URLs** — `url_build(...)` for fast path construction.
27
+ - **Validation** — `validate_plan(plan, data)` evaluates compiled
28
+ `nyxa-forms` rule plans natively; `NATIVE_RULE_IDS` maps rule names
29
+ to the ids the native engine covers.
30
+ - **Pagination JSON** — `paginate_to_json(rows, meta)` encodes
31
+ `{"data": rows, "meta": meta}` when every cell is JSON-safe.
32
+ - **Graceful fallback** — each helper returns `None` for inputs it
33
+ doesn't cover (non-ASCII, quoted cookies, unusual items) and the
34
+ framework transparently falls back to the Python reference —
35
+ results are always identical.
36
+ - **Kill switch** — `NYXA_NO_SPEEDUPS=1` forces the Python
37
+ implementations.
38
+
39
+ ## Install
40
+
41
+ ```bash
42
+ pip install nyxa # nyxa-speedups (maturin wheel) is bundled by default
43
+ # standalone: pip install nyxa-speedups
44
+ ```
45
+
46
+ No configuration — the framework probes the module at import and
47
+ uses it where available.
48
+
49
+ ## Public API
50
+
51
+ Module `nyxa_speedups` (native extension):
52
+
53
+ - **`Matcher`** — the route-tree pyclass (see Features).
54
+ - **`HeaderIndex`** — header-pair index: `get(name) -> str | None`,
55
+ `items() -> [(name, value)]`.
56
+ - **`header_index(raw)`** — build a `HeaderIndex` or `None`.
57
+ - **`parse_query(qs)`** — `dict[str, str]`, last value wins.
58
+ - **`parse_query_multi(qs)`** — repeated keys collapse to lists.
59
+ - **`parse_cookies(header)`** — `Cookie` header → `dict[str, str]`.
60
+ - **`scan_headers(...)`** / **`encode_headers(...)`** — header
61
+ scanning/serialization used by request/response paths.
62
+ - **`parse_multipart(body, boundary, max_fields, max_files,
63
+ max_part_size=None)`** — bounded multipart parse.
64
+ - **`flatten_headers(headers)`** — `str | list` values → wire pairs.
65
+ - **`normalize_headers(...)`** — header map normalization.
66
+ - **`sign_cookie(value, key, timestamp=False)`** → signed string.
67
+ - **`verify_cookie(value, key, max_age=None)`** → payload or `None`.
68
+ - **`url_build(...)`** — fast URL construction.
69
+ - **`validate_plan(plan, data)`** — native rule-plan evaluation or
70
+ `None` to defer to Python.
71
+ - **`paginate_to_json(rows, meta)`** — JSON bytes or `None`.
72
+ - **`NATIVE_RULE_IDS`** — `dict[str, int]` of rules the native
73
+ validator covers.
74
+
75
+ All functions return `None` on uncovered input — callers fall back to
76
+ Python for full semantics.
77
+
78
+ ## Configuration
79
+
80
+ `NYXA_NO_SPEEDUPS=1` disables all acceleration.
81
+
82
+ ## License
83
+
84
+ MIT
@@ -0,0 +1,35 @@
1
+ [build-system]
2
+ requires = ["maturin>=1.5,<2.0"]
3
+ build-backend = "maturin"
4
+
5
+ [project]
6
+ name = "nyxa-speedups"
7
+ version = "0.0.1"
8
+ description = "Native accelerators for the Nyxa framework (bundled with nyxa by default)"
9
+ readme = "README.md"
10
+ authors = [{ name = "Al-Amin Islam Nerob", email = "alamin@aincoder.com" }]
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ requires-python = ">=3.13"
14
+ classifiers = [
15
+ "Programming Language :: Rust",
16
+ "Programming Language :: Python :: Implementation :: CPython",
17
+ ]
18
+
19
+ [project.urls]
20
+ Repository = "https://github.com/NyxaDev/Nyxa"
21
+
22
+ [tool.maturin]
23
+ module-name = "nyxa_speedups"
24
+
25
+ # Rebuild in the parent project's env when the Rust sources change
26
+ [tool.uv]
27
+ cache-keys = [
28
+ { file = "pyproject.toml" },
29
+ { file = "Cargo.toml" },
30
+ { file = "src/**/*.rs" },
31
+ ]
32
+
33
+ [tool.pytest.ini_options]
34
+ asyncio_mode = "auto"
35
+ testpaths = ["tests"]