tac2iwxxm 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.
- tac2iwxxm-0.1.0/.gitignore +188 -0
- tac2iwxxm-0.1.0/PKG-INFO +61 -0
- tac2iwxxm-0.1.0/README.md +49 -0
- tac2iwxxm-0.1.0/pyproject.toml +53 -0
- tac2iwxxm-0.1.0/rust/Cargo.lock +180 -0
- tac2iwxxm-0.1.0/rust/Cargo.toml +18 -0
- tac2iwxxm-0.1.0/rust/src/lib.rs +39 -0
- tac2iwxxm-0.1.0/src/tac2iwxxm/__init__.py +30 -0
- tac2iwxxm-0.1.0/src/tac2iwxxm/bulletin.py +131 -0
- tac2iwxxm-0.1.0/src/tac2iwxxm/codec.py +15 -0
- tac2iwxxm-0.1.0/src/tac2iwxxm/convert.py +250 -0
- tac2iwxxm-0.1.0/src/tac2iwxxm/decode.py +502 -0
- tac2iwxxm-0.1.0/src/tac2iwxxm/models.py +121 -0
- tac2iwxxm-0.1.0/src/tac2iwxxm/native.py +62 -0
- tac2iwxxm-0.1.0/src/tac2iwxxm/products/__init__.py +17 -0
- tac2iwxxm-0.1.0/src/tac2iwxxm/products/metar_speci.py +239 -0
- tac2iwxxm-0.1.0/src/tac2iwxxm/products/sigmet_airmet.py +145 -0
- tac2iwxxm-0.1.0/src/tac2iwxxm/products/taf.py +103 -0
- tac2iwxxm-0.1.0/src/tac2iwxxm/products/vaa_tca.py +155 -0
- tac2iwxxm-0.1.0/src/tac2iwxxm/profiles/__init__.py +8 -0
- tac2iwxxm-0.1.0/src/tac2iwxxm/profiles/annex3.py +143 -0
- tac2iwxxm-0.1.0/src/tac2iwxxm/profiles/annex3_products.py +445 -0
- tac2iwxxm-0.1.0/src/tac2iwxxm/profiles/iwxxm_us.py +255 -0
- tac2iwxxm-0.1.0/tests/fixtures/annex3_golden/manifest.json +24 -0
- tac2iwxxm-0.1.0/tests/fixtures/annex3_golden/metar_basic.golden.xml +62 -0
- tac2iwxxm-0.1.0/tests/fixtures/annex3_golden/metar_basic.tac +1 -0
- tac2iwxxm-0.1.0/tests/fixtures/annex3_golden/metar_nil.golden.xml +34 -0
- tac2iwxxm-0.1.0/tests/fixtures/annex3_golden/metar_nil.tac +1 -0
- tac2iwxxm-0.1.0/tests/fixtures/annex3_golden/speci_basic.golden.xml +62 -0
- tac2iwxxm-0.1.0/tests/fixtures/annex3_golden/speci_basic.tac +1 -0
- tac2iwxxm-0.1.0/tests/fixtures/iwxxm_us_field_annotations.json +29 -0
- tac2iwxxm-0.1.0/tests/fixtures/iwxxm_us_golden/airmet_us_basic.golden.xml +73 -0
- tac2iwxxm-0.1.0/tests/fixtures/iwxxm_us_golden/airmet_us_basic.tac +2 -0
- tac2iwxxm-0.1.0/tests/fixtures/iwxxm_us_golden/manifest.json +43 -0
- tac2iwxxm-0.1.0/tests/fixtures/iwxxm_us_golden/metar_us_ao2_slp.golden.xml +69 -0
- tac2iwxxm-0.1.0/tests/fixtures/iwxxm_us_golden/metar_us_ao2_slp.tac +1 -0
- tac2iwxxm-0.1.0/tests/fixtures/iwxxm_us_golden/metar_us_pk_wnd.golden.xml +80 -0
- tac2iwxxm-0.1.0/tests/fixtures/iwxxm_us_golden/metar_us_pk_wnd.tac +1 -0
- tac2iwxxm-0.1.0/tests/fixtures/iwxxm_us_golden/sigmet_us_basic.golden.xml +77 -0
- tac2iwxxm-0.1.0/tests/fixtures/iwxxm_us_golden/sigmet_us_basic.tac +2 -0
- tac2iwxxm-0.1.0/tests/fixtures/iwxxm_us_golden/speci_us_ao2.golden.xml +68 -0
- tac2iwxxm-0.1.0/tests/fixtures/iwxxm_us_golden/speci_us_ao2.tac +1 -0
- tac2iwxxm-0.1.0/tests/fixtures/iwxxm_us_golden/taf_us_altimeter.golden.xml +61 -0
- tac2iwxxm-0.1.0/tests/fixtures/iwxxm_us_golden/taf_us_altimeter.tac +1 -0
- tac2iwxxm-0.1.0/tests/fixtures/metar_ahl_with_bbb.txt +2 -0
- tac2iwxxm-0.1.0/tests/fixtures/metar_multi_ahl.txt +3 -0
- tac2iwxxm-0.1.0/tests/fixtures/metar_single_ahl.txt +2 -0
- tac2iwxxm-0.1.0/tests/fixtures/metar_speci_field_annotations.json +34 -0
- tac2iwxxm-0.1.0/tests/fixtures/product_matrix/airmet_basic.tac +2 -0
- tac2iwxxm-0.1.0/tests/fixtures/product_matrix/manifest.json +50 -0
- tac2iwxxm-0.1.0/tests/fixtures/product_matrix/metar_basic.tac +1 -0
- tac2iwxxm-0.1.0/tests/fixtures/product_matrix/sigmet_basic.tac +2 -0
- tac2iwxxm-0.1.0/tests/fixtures/product_matrix/speci_basic.tac +1 -0
- tac2iwxxm-0.1.0/tests/fixtures/product_matrix/taf_basic.tac +1 -0
- tac2iwxxm-0.1.0/tests/fixtures/product_matrix/tca_basic.tac +15 -0
- tac2iwxxm-0.1.0/tests/fixtures/product_matrix/vaa_basic.tac +15 -0
- tac2iwxxm-0.1.0/tests/test_convert_issue_offsets.py +48 -0
- tac2iwxxm-0.1.0/tests/test_convert_unit.py +185 -0
- tac2iwxxm-0.1.0/tests/test_coverage_gaps.py +322 -0
- tac2iwxxm-0.1.0/tests/test_decode_summary.py +93 -0
- tac2iwxxm-0.1.0/tests/test_decode_tac.py +118 -0
- tac2iwxxm-0.1.0/tests/test_decode_value_aware.py +185 -0
- tac2iwxxm-0.1.0/tests/test_native_scaffold.py +34 -0
- tac2iwxxm-0.1.0/tests/test_pyo3_hotspots.py +43 -0
- tac2iwxxm-0.1.0/tests/test_tac2iwxxm_codec.py +13 -0
- tac2iwxxm-0.1.0/tests/test_tac2iwxxm_import.py +9 -0
- tac2iwxxm-0.1.0/tests/test_tc_f14_002_validate_extra.py +145 -0
- tac2iwxxm-0.1.0/tests/test_tc_f6_001_002_product_matrix.py +79 -0
- tac2iwxxm-0.1.0/tests/test_tc_f6_003_metar_speci_iwxxm_us.py +143 -0
- tac2iwxxm-0.1.0/tests/test_tc_f6_003_taf_sigmet_airmet_iwxxm_us.py +69 -0
- tac2iwxxm-0.1.0/tests/test_tc_f6_010_011_012_edge.py +58 -0
- tac2iwxxm-0.1.0/tests/test_tc_f6_020_021_metar_speci_annex3.py +161 -0
- tac2iwxxm-0.1.0/tests/test_tc_f6_030_bulletin_split.py +135 -0
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# METAR → IWXXM monorepo — apps/, packages/, vendor/
|
|
3
|
+
# =============================================================================
|
|
4
|
+
|
|
5
|
+
# --- Secrets & local operator env (never commit) ---
|
|
6
|
+
.env
|
|
7
|
+
.env.*
|
|
8
|
+
!.env.example
|
|
9
|
+
prod.env
|
|
10
|
+
.envrc
|
|
11
|
+
|
|
12
|
+
# Per-workspace env overrides (apps/* and packages/*)
|
|
13
|
+
apps/**/.env
|
|
14
|
+
apps/**/.env.*
|
|
15
|
+
!apps/**/.env.example
|
|
16
|
+
packages/**/.env
|
|
17
|
+
packages/**/.env.*
|
|
18
|
+
!packages/**/.env.example
|
|
19
|
+
|
|
20
|
+
# Legacy env paths (pre-migration; remove after cutover)
|
|
21
|
+
backend/.env
|
|
22
|
+
auth/.env
|
|
23
|
+
frontend/.env
|
|
24
|
+
|
|
25
|
+
# --- Python (uv workspace: apps/backend, packages/*) ---
|
|
26
|
+
__pycache__/
|
|
27
|
+
*.py[codz]
|
|
28
|
+
*$py.class
|
|
29
|
+
*.so
|
|
30
|
+
.Python
|
|
31
|
+
build/
|
|
32
|
+
develop-eggs/
|
|
33
|
+
dist/
|
|
34
|
+
downloads/
|
|
35
|
+
eggs/
|
|
36
|
+
.eggs/
|
|
37
|
+
lib/
|
|
38
|
+
lib64/
|
|
39
|
+
parts/
|
|
40
|
+
sdist/
|
|
41
|
+
var/
|
|
42
|
+
wheels/
|
|
43
|
+
share/python-wheels/
|
|
44
|
+
*.egg-info/
|
|
45
|
+
.installed.cfg
|
|
46
|
+
*.egg
|
|
47
|
+
MANIFEST
|
|
48
|
+
*.manifest
|
|
49
|
+
*.spec
|
|
50
|
+
pip-log.txt
|
|
51
|
+
pip-delete-this-directory.txt
|
|
52
|
+
__pypackages__/
|
|
53
|
+
*.sage.py
|
|
54
|
+
.venv/
|
|
55
|
+
venv/
|
|
56
|
+
env/
|
|
57
|
+
ENV/
|
|
58
|
+
env.bak/
|
|
59
|
+
venv.bak/
|
|
60
|
+
.pdm-python
|
|
61
|
+
.pdm-build/
|
|
62
|
+
.pixi
|
|
63
|
+
|
|
64
|
+
# --- Node / pnpm workspace (apps/*, packages/*) ---
|
|
65
|
+
**/node_modules/
|
|
66
|
+
.pnp
|
|
67
|
+
.pnp.js
|
|
68
|
+
.pnpm-store/
|
|
69
|
+
npm-debug.log*
|
|
70
|
+
yarn-debug.log*
|
|
71
|
+
yarn-error.log*
|
|
72
|
+
pnpm-debug.log*
|
|
73
|
+
.eslintcache
|
|
74
|
+
*.tsbuildinfo
|
|
75
|
+
|
|
76
|
+
# --- Build & bundle outputs ---
|
|
77
|
+
**/dist/
|
|
78
|
+
**/dist-ssr/
|
|
79
|
+
**/build/
|
|
80
|
+
**/.vite/
|
|
81
|
+
**/.turbo/
|
|
82
|
+
**/.next/
|
|
83
|
+
**/.nuxt/
|
|
84
|
+
**/.output/
|
|
85
|
+
**/.svelte-kit/
|
|
86
|
+
|
|
87
|
+
# --- Test & coverage ---
|
|
88
|
+
.tox/
|
|
89
|
+
.nox/
|
|
90
|
+
.coverage
|
|
91
|
+
.coverage.*
|
|
92
|
+
.coverage-baseline.json
|
|
93
|
+
.cache
|
|
94
|
+
nosetests.xml
|
|
95
|
+
coverage.xml
|
|
96
|
+
*.cover
|
|
97
|
+
*.py.cover
|
|
98
|
+
htmlcov/
|
|
99
|
+
htmlcov_ann/
|
|
100
|
+
cover/
|
|
101
|
+
.hypothesis/
|
|
102
|
+
.pytest_cache/
|
|
103
|
+
.nyc_output
|
|
104
|
+
**/coverage/
|
|
105
|
+
|
|
106
|
+
# Playwright (apps/e2e and legacy frontend/)
|
|
107
|
+
**/test-results/
|
|
108
|
+
**/playwright-report/
|
|
109
|
+
**/blob-report/
|
|
110
|
+
**/.playwright/
|
|
111
|
+
**/playwright/.cache/
|
|
112
|
+
|
|
113
|
+
# --- Typecheck & lint caches ---
|
|
114
|
+
.mypy_cache/
|
|
115
|
+
.dmypy.json
|
|
116
|
+
dmypy.json
|
|
117
|
+
.pyre/
|
|
118
|
+
.pytype/
|
|
119
|
+
.ruff_cache/
|
|
120
|
+
cython_debug/
|
|
121
|
+
|
|
122
|
+
# --- IDE & OS ---
|
|
123
|
+
.vscode/
|
|
124
|
+
.idea/
|
|
125
|
+
*.swp
|
|
126
|
+
*.swo
|
|
127
|
+
*~
|
|
128
|
+
.DS_Store
|
|
129
|
+
Thumbs.db
|
|
130
|
+
|
|
131
|
+
# --- Docs site builds ---
|
|
132
|
+
docs/_build/
|
|
133
|
+
/site
|
|
134
|
+
|
|
135
|
+
# --- Local tooling binaries / artifacts ---
|
|
136
|
+
.tools/
|
|
137
|
+
.local/
|
|
138
|
+
|
|
139
|
+
# --- Cursor (local indexing prefs only; .cursorignore is tracked) ---
|
|
140
|
+
.cursorindexingignore
|
|
141
|
+
|
|
142
|
+
# --- Misc generated ---
|
|
143
|
+
*.log
|
|
144
|
+
*.db
|
|
145
|
+
*.local
|
|
146
|
+
local_settings.py
|
|
147
|
+
db.sqlite3
|
|
148
|
+
db.sqlite3-journal
|
|
149
|
+
instance/
|
|
150
|
+
.webassets-cache
|
|
151
|
+
.scrapy
|
|
152
|
+
.ipynb_checkpoints
|
|
153
|
+
profile_default/
|
|
154
|
+
ipython_config.py
|
|
155
|
+
celerybeat-schedule
|
|
156
|
+
celerybeat.pid
|
|
157
|
+
.abstra/
|
|
158
|
+
.pypirc
|
|
159
|
+
marimo/_static/
|
|
160
|
+
marimo/_lsp/
|
|
161
|
+
__marimo__/
|
|
162
|
+
|
|
163
|
+
# --- Legacy submodule / pre-migration paths (remove after M7 cutover) ---
|
|
164
|
+
# Vendor snapshots live under vendor/schemas/ once migrated (tracked, not ignored).
|
|
165
|
+
GIFTs/.venv/
|
|
166
|
+
GIFTs/.gifts/
|
|
167
|
+
GIFTs/build/
|
|
168
|
+
GIFTs/dist/
|
|
169
|
+
GIFTs/data/
|
|
170
|
+
GIFTs/.coverage
|
|
171
|
+
GIFTs/.pytest_cache/
|
|
172
|
+
GIFTs/.mypy_cache/
|
|
173
|
+
GIFTs/sfstns.db
|
|
174
|
+
GIFTs/driver.py
|
|
175
|
+
GIFTs/wiki/
|
|
176
|
+
|
|
177
|
+
# --- Rust / maturin (tac2iwxxm / iwxxm-validate PyO3) ---
|
|
178
|
+
packages/tac2iwxxm/rust/target/
|
|
179
|
+
packages/iwxxm-validate/rust/target/
|
|
180
|
+
|
|
181
|
+
# E10-34 — synced runtime schema subset (generated; MANIFEST.json is tracked)
|
|
182
|
+
packages/iwxxm-validate/src/iwxxm_validate/schemas/iwxxm/
|
|
183
|
+
packages/iwxxm-validate/src/iwxxm_validate/schemas/iwxxm-us/
|
|
184
|
+
packages/iwxxm-validate/src/iwxxm_validate/schemas/LAST_SYNC.json
|
|
185
|
+
|
|
186
|
+
# ADR-027 — xsdata pydantic trees are committed (T3.7); ignore only bytecode
|
|
187
|
+
packages/shared/src/metar_shared/iwxxm_xsd/**/__pycache__/
|
|
188
|
+
|
tac2iwxxm-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tac2iwxxm
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: General TAC → IWXXM converter (F6)
|
|
5
|
+
License: MIT
|
|
6
|
+
Requires-Python: >=3.12
|
|
7
|
+
Requires-Dist: msgspec>=0.19
|
|
8
|
+
Provides-Extra: validate
|
|
9
|
+
Requires-Dist: iwxxm-validate>=0.1.0; extra == 'validate'
|
|
10
|
+
Requires-Dist: tac-validate>=0.1.0; extra == 'validate'
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
|
|
13
|
+
# tac2iwxxm
|
|
14
|
+
|
|
15
|
+
General TAC → IWXXM converter package (F6 / F14). MIT licensed.
|
|
16
|
+
|
|
17
|
+
See ADR-013 / ADR-014 / ADR-016 / ADR-017.
|
|
18
|
+
|
|
19
|
+
## Install
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# Convert only (no validators)
|
|
23
|
+
pip install tac2iwxxm
|
|
24
|
+
|
|
25
|
+
# Convert + TAC lint + IWXXM XSD/Schematron (F14)
|
|
26
|
+
pip install 'tac2iwxxm[validate]'
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The `[validate]` extra depends on **`tac-validate`** and **`iwxxm-validate`** (E10-20).
|
|
30
|
+
Convert works without the extra.
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
from tac2iwxxm import convert
|
|
34
|
+
|
|
35
|
+
result = convert(
|
|
36
|
+
"METAR KJFK 231751Z 18012KT 10SM FEW040 15/07 A3005=",
|
|
37
|
+
product="METAR",
|
|
38
|
+
)
|
|
39
|
+
assert result.ok and result.xml
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
With `[validate]` installed:
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
from tac_validate import lint
|
|
46
|
+
from iwxxm_validate import validate_iwxxm
|
|
47
|
+
|
|
48
|
+
assert lint(tac, product="METAR").ok
|
|
49
|
+
assert validate_iwxxm(result.xml, iwxxm_version="2025-2").ok
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Native extension (PyO3)
|
|
53
|
+
|
|
54
|
+
Optional Rust hotspots live under `rust/` and import as `tac2iwxxm._rust`
|
|
55
|
+
(ADR-017). Pure Python remains the default `uv sync` path.
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# requires rustc + maturin
|
|
59
|
+
make build-tac2iwxxm-native
|
|
60
|
+
make test-tac2iwxxm-native
|
|
61
|
+
```
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# tac2iwxxm
|
|
2
|
+
|
|
3
|
+
General TAC → IWXXM converter package (F6 / F14). MIT licensed.
|
|
4
|
+
|
|
5
|
+
See ADR-013 / ADR-014 / ADR-016 / ADR-017.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# Convert only (no validators)
|
|
11
|
+
pip install tac2iwxxm
|
|
12
|
+
|
|
13
|
+
# Convert + TAC lint + IWXXM XSD/Schematron (F14)
|
|
14
|
+
pip install 'tac2iwxxm[validate]'
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The `[validate]` extra depends on **`tac-validate`** and **`iwxxm-validate`** (E10-20).
|
|
18
|
+
Convert works without the extra.
|
|
19
|
+
|
|
20
|
+
```python
|
|
21
|
+
from tac2iwxxm import convert
|
|
22
|
+
|
|
23
|
+
result = convert(
|
|
24
|
+
"METAR KJFK 231751Z 18012KT 10SM FEW040 15/07 A3005=",
|
|
25
|
+
product="METAR",
|
|
26
|
+
)
|
|
27
|
+
assert result.ok and result.xml
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
With `[validate]` installed:
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
from tac_validate import lint
|
|
34
|
+
from iwxxm_validate import validate_iwxxm
|
|
35
|
+
|
|
36
|
+
assert lint(tac, product="METAR").ok
|
|
37
|
+
assert validate_iwxxm(result.xml, iwxxm_version="2025-2").ok
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Native extension (PyO3)
|
|
41
|
+
|
|
42
|
+
Optional Rust hotspots live under `rust/` and import as `tac2iwxxm._rust`
|
|
43
|
+
(ADR-017). Pure Python remains the default `uv sync` path.
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# requires rustc + maturin
|
|
47
|
+
make build-tac2iwxxm-native
|
|
48
|
+
make test-tac2iwxxm-native
|
|
49
|
+
```
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "tac2iwxxm"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "General TAC → IWXXM converter (F6)"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = { text = "MIT" }
|
|
7
|
+
requires-python = ">=3.12"
|
|
8
|
+
dependencies = [
|
|
9
|
+
"msgspec>=0.19",
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
[project.optional-dependencies]
|
|
13
|
+
# F14 / E10-20: optional TAC lint + IWXXM XSD/Schematron validators.
|
|
14
|
+
validate = [
|
|
15
|
+
"tac-validate>=0.1.0",
|
|
16
|
+
"iwxxm-validate>=0.1.0",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
[build-system]
|
|
20
|
+
requires = ["hatchling>=1.25"]
|
|
21
|
+
build-backend = "hatchling.build"
|
|
22
|
+
|
|
23
|
+
[tool.hatch.build.targets.wheel]
|
|
24
|
+
packages = ["src/tac2iwxxm"]
|
|
25
|
+
|
|
26
|
+
# Maturin builds the optional PyO3 cdylib (ADR-017 / T4.3). Pure-Python hatch wheel
|
|
27
|
+
# remains the default ``uv sync`` path; CI rust job runs ``maturin develop``.
|
|
28
|
+
[tool.maturin]
|
|
29
|
+
manifest-path = "rust/Cargo.toml"
|
|
30
|
+
python-source = "src"
|
|
31
|
+
module-name = "tac2iwxxm._rust"
|
|
32
|
+
|
|
33
|
+
[tool.pytest.ini_options]
|
|
34
|
+
testpaths = ["tests"]
|
|
35
|
+
pythonpath = ["src"]
|
|
36
|
+
markers = [
|
|
37
|
+
"slow: longer local/CI smokes (clean-venv wheel installs)",
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
[tool.coverage.run]
|
|
41
|
+
branch = true
|
|
42
|
+
source = ["src/tac2iwxxm"]
|
|
43
|
+
|
|
44
|
+
[tool.coverage.report]
|
|
45
|
+
fail_under = 95
|
|
46
|
+
show_missing = true
|
|
47
|
+
|
|
48
|
+
[tool.ruff]
|
|
49
|
+
line-length = 120
|
|
50
|
+
|
|
51
|
+
[tool.ruff.lint]
|
|
52
|
+
select = ["E", "W", "F", "I"]
|
|
53
|
+
ignore = ["E501"]
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# This file is automatically @generated by Cargo.
|
|
2
|
+
# It is not intended for manual editing.
|
|
3
|
+
version = 3
|
|
4
|
+
|
|
5
|
+
[[package]]
|
|
6
|
+
name = "autocfg"
|
|
7
|
+
version = "1.5.1"
|
|
8
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
9
|
+
checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
|
|
10
|
+
|
|
11
|
+
[[package]]
|
|
12
|
+
name = "cfg-if"
|
|
13
|
+
version = "1.0.4"
|
|
14
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
15
|
+
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
|
16
|
+
|
|
17
|
+
[[package]]
|
|
18
|
+
name = "heck"
|
|
19
|
+
version = "0.5.0"
|
|
20
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
21
|
+
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
|
22
|
+
|
|
23
|
+
[[package]]
|
|
24
|
+
name = "indoc"
|
|
25
|
+
version = "2.0.7"
|
|
26
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
27
|
+
checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706"
|
|
28
|
+
dependencies = [
|
|
29
|
+
"rustversion",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[[package]]
|
|
33
|
+
name = "libc"
|
|
34
|
+
version = "0.2.186"
|
|
35
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
36
|
+
checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
|
|
37
|
+
|
|
38
|
+
[[package]]
|
|
39
|
+
name = "memoffset"
|
|
40
|
+
version = "0.9.1"
|
|
41
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
42
|
+
checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
|
|
43
|
+
dependencies = [
|
|
44
|
+
"autocfg",
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
[[package]]
|
|
48
|
+
name = "once_cell"
|
|
49
|
+
version = "1.21.4"
|
|
50
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
51
|
+
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
|
52
|
+
|
|
53
|
+
[[package]]
|
|
54
|
+
name = "portable-atomic"
|
|
55
|
+
version = "1.13.1"
|
|
56
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
57
|
+
checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"
|
|
58
|
+
|
|
59
|
+
[[package]]
|
|
60
|
+
name = "proc-macro2"
|
|
61
|
+
version = "1.0.106"
|
|
62
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
63
|
+
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
|
|
64
|
+
dependencies = [
|
|
65
|
+
"unicode-ident",
|
|
66
|
+
]
|
|
67
|
+
|
|
68
|
+
[[package]]
|
|
69
|
+
name = "pyo3"
|
|
70
|
+
version = "0.23.5"
|
|
71
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
72
|
+
checksum = "7778bffd85cf38175ac1f545509665d0b9b92a198ca7941f131f85f7a4f9a872"
|
|
73
|
+
dependencies = [
|
|
74
|
+
"cfg-if",
|
|
75
|
+
"indoc",
|
|
76
|
+
"libc",
|
|
77
|
+
"memoffset",
|
|
78
|
+
"once_cell",
|
|
79
|
+
"portable-atomic",
|
|
80
|
+
"pyo3-build-config",
|
|
81
|
+
"pyo3-ffi",
|
|
82
|
+
"pyo3-macros",
|
|
83
|
+
"unindent",
|
|
84
|
+
]
|
|
85
|
+
|
|
86
|
+
[[package]]
|
|
87
|
+
name = "pyo3-build-config"
|
|
88
|
+
version = "0.23.5"
|
|
89
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
90
|
+
checksum = "94f6cbe86ef3bf18998d9df6e0f3fc1050a8c5efa409bf712e661a4366e010fb"
|
|
91
|
+
dependencies = [
|
|
92
|
+
"once_cell",
|
|
93
|
+
"target-lexicon",
|
|
94
|
+
]
|
|
95
|
+
|
|
96
|
+
[[package]]
|
|
97
|
+
name = "pyo3-ffi"
|
|
98
|
+
version = "0.23.5"
|
|
99
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
100
|
+
checksum = "e9f1b4c431c0bb1c8fb0a338709859eed0d030ff6daa34368d3b152a63dfdd8d"
|
|
101
|
+
dependencies = [
|
|
102
|
+
"libc",
|
|
103
|
+
"pyo3-build-config",
|
|
104
|
+
]
|
|
105
|
+
|
|
106
|
+
[[package]]
|
|
107
|
+
name = "pyo3-macros"
|
|
108
|
+
version = "0.23.5"
|
|
109
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
110
|
+
checksum = "fbc2201328f63c4710f68abdf653c89d8dbc2858b88c5d88b0ff38a75288a9da"
|
|
111
|
+
dependencies = [
|
|
112
|
+
"proc-macro2",
|
|
113
|
+
"pyo3-macros-backend",
|
|
114
|
+
"quote",
|
|
115
|
+
"syn",
|
|
116
|
+
]
|
|
117
|
+
|
|
118
|
+
[[package]]
|
|
119
|
+
name = "pyo3-macros-backend"
|
|
120
|
+
version = "0.23.5"
|
|
121
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
122
|
+
checksum = "fca6726ad0f3da9c9de093d6f116a93c1a38e417ed73bf138472cf4064f72028"
|
|
123
|
+
dependencies = [
|
|
124
|
+
"heck",
|
|
125
|
+
"proc-macro2",
|
|
126
|
+
"pyo3-build-config",
|
|
127
|
+
"quote",
|
|
128
|
+
"syn",
|
|
129
|
+
]
|
|
130
|
+
|
|
131
|
+
[[package]]
|
|
132
|
+
name = "quote"
|
|
133
|
+
version = "1.0.46"
|
|
134
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
135
|
+
checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368"
|
|
136
|
+
dependencies = [
|
|
137
|
+
"proc-macro2",
|
|
138
|
+
]
|
|
139
|
+
|
|
140
|
+
[[package]]
|
|
141
|
+
name = "rustversion"
|
|
142
|
+
version = "1.0.23"
|
|
143
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
144
|
+
checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f"
|
|
145
|
+
|
|
146
|
+
[[package]]
|
|
147
|
+
name = "syn"
|
|
148
|
+
version = "2.0.118"
|
|
149
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
150
|
+
checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422"
|
|
151
|
+
dependencies = [
|
|
152
|
+
"proc-macro2",
|
|
153
|
+
"quote",
|
|
154
|
+
"unicode-ident",
|
|
155
|
+
]
|
|
156
|
+
|
|
157
|
+
[[package]]
|
|
158
|
+
name = "tac2iwxxm_rust"
|
|
159
|
+
version = "0.1.0"
|
|
160
|
+
dependencies = [
|
|
161
|
+
"pyo3",
|
|
162
|
+
]
|
|
163
|
+
|
|
164
|
+
[[package]]
|
|
165
|
+
name = "target-lexicon"
|
|
166
|
+
version = "0.12.16"
|
|
167
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
168
|
+
checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
|
|
169
|
+
|
|
170
|
+
[[package]]
|
|
171
|
+
name = "unicode-ident"
|
|
172
|
+
version = "1.0.24"
|
|
173
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
174
|
+
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
|
175
|
+
|
|
176
|
+
[[package]]
|
|
177
|
+
name = "unindent"
|
|
178
|
+
version = "0.2.4"
|
|
179
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
180
|
+
checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "tac2iwxxm_rust"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
edition = "2021"
|
|
5
|
+
description = "PyO3 native hotspots for tac2iwxxm (ADR-017)"
|
|
6
|
+
license = "MIT"
|
|
7
|
+
rust-version = "1.74"
|
|
8
|
+
|
|
9
|
+
[lib]
|
|
10
|
+
name = "_rust"
|
|
11
|
+
crate-type = ["cdylib"]
|
|
12
|
+
|
|
13
|
+
[dependencies]
|
|
14
|
+
pyo3 = { version = "0.23", features = ["extension-module"] }
|
|
15
|
+
|
|
16
|
+
[package.metadata.maturin]
|
|
17
|
+
python-source = "../src"
|
|
18
|
+
module-name = "tac2iwxxm._rust"
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
//! PyO3 native extension for `tac2iwxxm` (ADR-017).
|
|
2
|
+
//!
|
|
3
|
+
//! T4.3 scaffold + T4.5 `scan_metar_tokens` hotspot (TAC lexer).
|
|
4
|
+
|
|
5
|
+
use pyo3::prelude::*;
|
|
6
|
+
|
|
7
|
+
/// Extension package version (mirrors Cargo.toml).
|
|
8
|
+
#[pyfunction]
|
|
9
|
+
fn extension_version() -> &'static str {
|
|
10
|
+
env!("CARGO_PKG_VERSION")
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/// Health check used by CI / import smoke tests.
|
|
14
|
+
#[pyfunction]
|
|
15
|
+
fn ping() -> &'static str {
|
|
16
|
+
"pong"
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/// Split METAR/SPECI TAC into whitespace tokens (hotspot scaffold for T4.5+).
|
|
20
|
+
///
|
|
21
|
+
/// Strips a trailing ``=`` terminator when present. Does not yet implement a full
|
|
22
|
+
/// remark-aware lexer — that lands with further PyO3 work.
|
|
23
|
+
#[pyfunction]
|
|
24
|
+
fn scan_metar_tokens(tac: &str) -> Vec<String> {
|
|
25
|
+
let trimmed = tac.trim().trim_end_matches('=').trim();
|
|
26
|
+
trimmed
|
|
27
|
+
.split_whitespace()
|
|
28
|
+
.map(|part| part.to_string())
|
|
29
|
+
.collect()
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
#[pymodule]
|
|
33
|
+
fn _rust(m: &Bound<'_, PyModule>) -> PyResult<()> {
|
|
34
|
+
m.add("__version__", env!("CARGO_PKG_VERSION"))?;
|
|
35
|
+
m.add_function(wrap_pyfunction!(extension_version, m)?)?;
|
|
36
|
+
m.add_function(wrap_pyfunction!(ping, m)?)?;
|
|
37
|
+
m.add_function(wrap_pyfunction!(scan_metar_tokens, m)?)?;
|
|
38
|
+
Ok(())
|
|
39
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""General TAC → IWXXM converter (F6)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from tac2iwxxm.bulletin import BulletinSplitError, split_bulletin
|
|
6
|
+
from tac2iwxxm.convert import ConvertError, convert
|
|
7
|
+
from tac2iwxxm.decode import DecodeResidual, DecodeResult, DecodeSegment, decode_tac
|
|
8
|
+
from tac2iwxxm.models import BulletinMeta, BulletinSplit, ConvertIssue, ConvertResult
|
|
9
|
+
from tac2iwxxm.native import rust_available, rust_module, scan_metar_tokens
|
|
10
|
+
|
|
11
|
+
__version__ = "0.1.0"
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
"BulletinMeta",
|
|
15
|
+
"BulletinSplit",
|
|
16
|
+
"BulletinSplitError",
|
|
17
|
+
"ConvertError",
|
|
18
|
+
"ConvertIssue",
|
|
19
|
+
"ConvertResult",
|
|
20
|
+
"DecodeResidual",
|
|
21
|
+
"DecodeResult",
|
|
22
|
+
"DecodeSegment",
|
|
23
|
+
"__version__",
|
|
24
|
+
"convert",
|
|
25
|
+
"decode_tac",
|
|
26
|
+
"rust_available",
|
|
27
|
+
"rust_module",
|
|
28
|
+
"scan_metar_tokens",
|
|
29
|
+
"split_bulletin",
|
|
30
|
+
]
|