DWG/DXF-Import-Spike: acadrust baut zu wasm32 (Crate dwgimport)

- src-tauri/dwgimport: eigenstaendiges Crate (cdylib+rlib, eigener [workspace]),
  dep acadrust 0.4 (MPL-2.0, pure Rust). parse_dxf_summary(bytes) via
  DxfReader::from_reader + Cursor<Vec<u8>> -> JSON (version/entityCount/
  entityTypeCounts/layerNames). wasm-Fassade parse_dxf_summary_json.
- getrandom wasm_js-Feature noetig (transitiv via ahash) -> als Dep gesetzt.
- Kernbeweis: acadrust kompiliert nach wasm32 (839 KB), DXF-Parse headless
  getestet (5 Entities korrekt). Beweist den DWG/DXF-Import-Weg im Rust/WASM-Kern.
- build:dwgimport-Script, src-tauri/Cargo.toml exclude erweitert.
This commit is contained in:
2026-07-05 03:12:32 +02:00
parent dbf78a9d75
commit 715e950d7c
5 changed files with 901 additions and 2 deletions
+2 -1
View File
@@ -18,7 +18,8 @@
"build:engine": "wasm-pack build src-tauri/render2d --release --target web --out-dir ../../src/engine/pkg --out-name render2d --no-default-features --features web",
"build:engine3d": "wasm-pack build src-tauri/render3d --release --target web --out-dir ../../src/engine/pkg3d --out-name render3d --no-default-features --features web",
"build:geometry": "wasm-pack build src-tauri/geometry --release --target web --out-dir ../../src/engine/pkgGeometry --out-name geometry --no-default-features --features web",
"build:kernel2d": "wasm-pack build src-tauri/kernel2d --release --target web --out-dir ../../src/engine/pkgKernel2d --out-name kernel2d --no-default-features --features web"
"build:kernel2d": "wasm-pack build src-tauri/kernel2d --release --target web --out-dir ../../src/engine/pkgKernel2d --out-name kernel2d --no-default-features --features web",
"build:dwgimport": "wasm-pack build src-tauri/dwgimport --release --target web --out-dir ../../src/engine/pkgDwgImport --out-name dwgimport --no-default-features --features web"
},
"dependencies": {
"@mlightcad/libredwg-web": "^0.7.7",
+1 -1
View File
@@ -8,7 +8,7 @@ members = ["."]
# wird und das TS-Frontend die Joins direkt per WASM aufruft (statt TS-Duplikat).
# kernel2d: analog — eigenstaendiger 2D-Geometrie-Kern (Port von kernel2d.ts),
# per wasm-pack (Feature "web") zu WASM gebaut, ausserhalb des cad-tauri-Workspace.
exclude = ["render2d", "render3d", "geometry", "kernel2d"]
exclude = ["render2d", "render3d", "geometry", "kernel2d", "dwgimport"]
[package]
name = "cad-tauri"
+578
View File
@@ -0,0 +1,578 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "acadrust"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "153498e7c9b058326ff0fae11bc9fd870cf2ea0aa9111875d03625fa9018c218"
dependencies = [
"ahash",
"anyhow",
"bitflags",
"byteorder",
"encoding_rs",
"flate2",
"indexmap",
"itoa",
"nalgebra",
"nom",
"once_cell",
"ryu",
"thiserror",
]
[[package]]
name = "adler2"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
[[package]]
name = "ahash"
version = "0.8.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75"
dependencies = [
"cfg-if",
"getrandom",
"once_cell",
"version_check",
"zerocopy",
]
[[package]]
name = "anyhow"
version = "1.0.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3"
[[package]]
name = "approx"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6"
dependencies = [
"num-traits",
]
[[package]]
name = "autocfg"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
[[package]]
name = "bitflags"
version = "2.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8"
[[package]]
name = "bumpalo"
version = "3.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649"
[[package]]
name = "bytemuck"
version = "1.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec"
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "cfg-if"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "console_error_panic_hook"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc"
dependencies = [
"cfg-if",
"wasm-bindgen",
]
[[package]]
name = "crc32fast"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511"
dependencies = [
"cfg-if",
]
[[package]]
name = "dwgimport"
version = "0.1.0"
dependencies = [
"acadrust",
"console_error_panic_hook",
"getrandom",
"serde",
"serde_json",
"wasm-bindgen",
]
[[package]]
name = "encoding_rs"
version = "0.8.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3"
dependencies = [
"cfg-if",
]
[[package]]
name = "equivalent"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "flate2"
version = "1.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c"
dependencies = [
"crc32fast",
"miniz_oxide",
]
[[package]]
name = "getrandom"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
dependencies = [
"cfg-if",
"js-sys",
"libc",
"r-efi",
"wasip2",
"wasm-bindgen",
]
[[package]]
name = "hashbrown"
version = "0.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
[[package]]
name = "indexmap"
version = "2.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
dependencies = [
"equivalent",
"hashbrown",
]
[[package]]
name = "itoa"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
[[package]]
name = "js-sys"
version = "0.3.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102"
dependencies = [
"cfg-if",
"wasm-bindgen",
]
[[package]]
name = "libc"
version = "0.2.186"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
[[package]]
name = "matrixmultiply"
version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a06de3016e9fae57a36fd14dba131fccf49f74b40b7fbdb472f96e361ec71a08"
dependencies = [
"autocfg",
"rawpointer",
]
[[package]]
name = "memchr"
version = "2.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4"
[[package]]
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "miniz_oxide"
version = "0.8.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
dependencies = [
"adler2",
"simd-adler32",
]
[[package]]
name = "nalgebra"
version = "0.32.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b5c17de023a86f59ed79891b2e5d5a94c705dbe904a5b5c9c952ea6221b03e4"
dependencies = [
"approx",
"matrixmultiply",
"nalgebra-macros",
"num-complex",
"num-rational",
"num-traits",
"simba",
"typenum",
]
[[package]]
name = "nalgebra-macros"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "254a5372af8fc138e36684761d3c0cdb758a4410e938babcff1c860ce14ddbfc"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "nom"
version = "7.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
dependencies = [
"memchr",
"minimal-lexical",
]
[[package]]
name = "num-complex"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495"
dependencies = [
"num-traits",
]
[[package]]
name = "num-integer"
version = "0.1.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
dependencies = [
"num-traits",
]
[[package]]
name = "num-rational"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824"
dependencies = [
"num-integer",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.21.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
[[package]]
name = "paste"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]]
name = "proc-macro2"
version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368"
dependencies = [
"proc-macro2",
]
[[package]]
name = "r-efi"
version = "5.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
[[package]]
name = "rawpointer"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3"
[[package]]
name = "rustversion"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
[[package]]
name = "ryu"
version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f"
[[package]]
name = "safe_arch"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96b02de82ddbe1b636e6170c21be622223aea188ef2e139be0a5b219ec215323"
dependencies = [
"bytemuck",
]
[[package]]
name = "serde"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
"serde_derive",
]
[[package]]
name = "serde_core"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.150"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
dependencies = [
"itoa",
"memchr",
"serde",
"serde_core",
"zmij",
]
[[package]]
name = "simba"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "061507c94fc6ab4ba1c9a0305018408e312e17c041eb63bef8aa726fa33aceae"
dependencies = [
"approx",
"num-complex",
"num-traits",
"paste",
"wide",
]
[[package]]
name = "simd-adler32"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214"
[[package]]
name = "syn"
version = "2.0.118"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "thiserror"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "typenum"
version = "1.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20"
[[package]]
name = "unicode-ident"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "wasip2"
version = "1.0.4+wasi-0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487"
dependencies = [
"wit-bindgen",
]
[[package]]
name = "wasm-bindgen"
version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4"
dependencies = [
"cfg-if",
"once_cell",
"rustversion",
"wasm-bindgen-macro",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e"
dependencies = [
"bumpalo",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24"
dependencies = [
"unicode-ident",
]
[[package]]
name = "wide"
version = "0.7.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ce5da8ecb62bcd8ec8b7ea19f69a51275e91299be594ea5cc6ef7819e16cd03"
dependencies = [
"bytemuck",
"safe_arch",
]
[[package]]
name = "wit-bindgen"
version = "0.57.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e"
[[package]]
name = "zerocopy"
version = "0.8.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce1022995ff5ff5d841ad7d994facc23098cd40152f2c1d11cd607c6f530653f"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.8.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ae7f38b72ec2a254e2b87ef277cf2cd4fb97cbebf944faa6f33354da0867930"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "zmij"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
+36
View File
@@ -0,0 +1,36 @@
# Eigener leerer Workspace-Block: entkoppelt dwgimport vollstaendig vom
# cad-tauri-Workspace (src-tauri/Cargo.toml). Muster: kernel2d/render2d.
[workspace]
[package]
name = "dwgimport"
version = "0.1.0"
edition = "2021"
description = "DXF-Import-Probe: beweist, dass acadrust (MPL-2.0) aus einem Byte-Buffer parst und nach wasm32-unknown-unknown kompiliert."
# cdylib: fuer wasm-pack (Feature \"web\"). rlib: fuer cargo test + Pfad-Dep.
[lib]
crate-type = ["cdylib", "rlib"]
[features]
# Standard: headless, kein WASM-Overhead — per `cargo test` pruefbar.
default = []
# Browser-Bindings: wasm-bindgen-Fassade; nur fuer wasm32-unknown-unknown.
web = ["dep:wasm-bindgen", "dep:serde_json", "dep:console_error_panic_hook"]
[dependencies]
# DXF/DWG-Parser (MPL-2.0), von crates.io.
acadrust = "0.4"
# getrandom wird transitiv via ahash→acadrust gezogen. Fuer wasm32 muss das
# Feature "wasm_js" explizit aktiviert werden (sonst Compile-Fehler).
# Direkte Dep mit Feature-Aktivierung unifiziert das Flag fuer alle Abhaengigen.
getrandom = { version = "0.3", features = ["wasm_js"] }
# Serialisierung: immer vorhanden (fuer den headless parse_dxf_summary-Kern).
serde = { version = "1", features = ["derive"] }
serde_json = { version = "1", optional = true }
# WASM-Bindings — nur im Feature "web" aktiv.
wasm-bindgen = { version = "0.2", optional = true }
console_error_panic_hook = { version = "0.1", optional = true }
+284
View File
@@ -0,0 +1,284 @@
// dwgimport — SPIKE: beweist, dass acadrust (MPL-2.0) aus einem Byte-Buffer
// ein DXF parst und nach wasm32-unknown-unknown kompiliert.
//
// Aufbau:
// - `parse_dxf_summary`: headless, feature-frei testbar.
// - `#[cfg(feature="web")]` wasm-bindgen-Fassade darueber.
//
// API-Stuetzpunkt acadrust:
// `DxfReader::from_reader<R: Read + Seek + 'static>(reader: R)`
// → std::io::Cursor<&[u8]> implementiert Read + Seek → WASM-tauglich.
use std::collections::HashMap;
use std::io::Cursor;
use acadrust::DxfReader;
// serde_json nur bei Feature "web" als optionale Dep, aber serde ist immer da.
// Fuer den headless-Kern bauen wir das JSON mit einem einfachen Format-String,
// damit keine Compile-Time-Dep auf serde_json im Default-Feature noetig ist.
/// Parst ein DXF aus einem Byte-Slice und gibt ein JSON-Summary zurueck.
///
/// Rueckgabe-JSON-Schema:
/// ```json
/// {
/// "version": "AC1015",
/// "entityCount": 5,
/// "entityTypeCounts": { "LINE": 3, "CIRCLE": 2 },
/// "layerNames": ["0", "Wand"]
/// }
/// ```
///
/// Fehler: String mit Fehlerbeschreibung.
pub fn parse_dxf_summary(bytes: &[u8]) -> Result<String, String> {
// Cursor<Vec<u8>> implementiert Read + Seek + 'static — kein std::fs noetig.
// (from_reader verlangt R: 'static; Cursor<&[u8]> wuerde die Lifetime verletzen.)
let cursor = Cursor::new(bytes.to_vec());
let reader = DxfReader::from_reader(cursor)
.map_err(|e| format!("DxfReader::from_reader fehlgeschlagen: {e}"))?;
let doc = reader
.read()
.map_err(|e| format!("DxfReader::read fehlgeschlagen: {e}"))?;
// Versions-String aus dem Enum (Debug-Format, z. B. "AC1015").
let version = format!("{:?}", doc.version);
// Entitaeten zaehlen und nach Typ aufschluesseln.
let mut type_counts: HashMap<&str, usize> = HashMap::new();
for entity in doc.entities() {
let typ = entity.as_entity().entity_type();
*type_counts.entry(typ).or_insert(0) += 1;
}
let entity_count = type_counts.values().sum::<usize>();
// Layer-Namen aus der Layer-Tabelle.
let mut layer_names: Vec<String> = doc
.layers
.iter()
.map(|l| l.name.clone())
.collect();
layer_names.sort();
// JSON-Serialisierung ohne optionale serde_json-Dep im Default-Feature.
// Fuer den headless-Test reicht ein sauberer Format-String.
let type_counts_json = {
let mut pairs: Vec<String> = type_counts
.iter()
.map(|(k, v)| format!(" \"{k}\": {v}"))
.collect();
pairs.sort(); // deterministisch fuer Tests
format!("{{\n{}\n }}", pairs.join(",\n"))
};
let layer_names_json = {
let quoted: Vec<String> = layer_names
.iter()
.map(|n| format!("\"{}\"", n.replace('"', "\\\"")))
.collect();
format!("[{}]", quoted.join(", "))
};
Ok(format!(
"{{\n \"version\": \"{version}\",\n \"entityCount\": {entity_count},\n \"entityTypeCounts\": {type_counts_json},\n \"layerNames\": {layer_names_json}\n}}"
))
}
// ---------------------------------------------------------------------------
// WASM-Fassade (nur bei Feature "web" compiliert)
// ---------------------------------------------------------------------------
#[cfg(feature = "web")]
mod wasm {
use super::parse_dxf_summary;
use wasm_bindgen::prelude::*;
/// Initialisiert den Panic-Hook fuer bessere Fehlermeldungen im Browser.
#[wasm_bindgen(start)]
pub fn init_panic_hook() {
console_error_panic_hook::set_once();
}
/// WASM-Fassade: nimmt einen Byte-Buffer (Uint8Array aus JS) und gibt ein
/// JSON-String zurueck, das das DXF-Summary beschreibt.
///
/// JS-Aufruf:
/// ```js
/// import init, { parse_dxf_summary_json } from './pkgDwgImport/dwgimport.js';
/// await init();
/// const json = parse_dxf_summary_json(new Uint8Array(buffer));
/// ```
#[wasm_bindgen]
pub fn parse_dxf_summary_json(bytes: &[u8]) -> Result<String, JsValue> {
parse_dxf_summary(bytes)
.map_err(|e| JsValue::from_str(&e))
}
}
// ---------------------------------------------------------------------------
// Tests
// ---------------------------------------------------------------------------
#[cfg(test)]
mod tests {
use super::*;
/// Minimales ASCII-DXF mit 3 LINE- und 2 CIRCLE-Entitaeten auf Layer "WAND"
/// und Layer "0". Wird direkt als Byte-Slice eingebettet — kein Datei-IO.
const MINI_DXF: &str = r#" 0
SECTION
2
HEADER
9
$ACADVER
1
AC1015
0
ENDSEC
0
SECTION
2
TABLES
0
TABLE
2
LAYER
70
2
0
LAYER
2
0
70
0
62
7
6
Continuous
0
LAYER
2
WAND
70
0
62
3
6
Continuous
0
ENDTAB
0
ENDSEC
0
SECTION
2
ENTITIES
0
LINE
8
WAND
10
0.0
20
0.0
30
0.0
11
100.0
21
0.0
31
0.0
0
LINE
8
WAND
10
100.0
20
0.0
30
0.0
11
100.0
21
50.0
31
0.0
0
LINE
8
0
10
100.0
20
50.0
30
0.0
11
0.0
21
0.0
31
0.0
0
CIRCLE
8
WAND
10
50.0
20
25.0
30
0.0
40
10.0
0
CIRCLE
8
0
10
20.0
20
10.0
30
0.0
40
5.0
0
ENDSEC
0
EOF
"#;
#[test]
fn test_parse_mini_dxf() {
let result = parse_dxf_summary(MINI_DXF.as_bytes());
assert!(result.is_ok(), "parse_dxf_summary schlug fehl: {:?}", result);
let json = result.unwrap();
println!("DXF-Summary:\n{json}");
// Version muss AC1015 sein.
assert!(json.contains("AC1015"), "Version AC1015 nicht im JSON: {json}");
// Genau 5 Entitaeten: 3 LINE + 2 CIRCLE.
assert!(
json.contains("\"entityCount\": 5"),
"entityCount soll 5 sein: {json}"
);
assert!(
json.contains("\"LINE\": 3"),
"LINE-Zaehler soll 3 sein: {json}"
);
assert!(
json.contains("\"CIRCLE\": 2"),
"CIRCLE-Zaehler soll 2 sein: {json}"
);
// Layer "WAND" und "0" muessen erscheinen.
assert!(json.contains("\"WAND\""), "Layer WAND fehlt: {json}");
assert!(json.contains("\"0\""), "Layer 0 fehlt: {json}");
}
}