server: much improved xmls pretty printer

This commit is contained in:
Bill Thiede 2025-08-12 17:00:58 -07:00
parent 5c9955a89e
commit 3a41ab1767
4 changed files with 72 additions and 469 deletions

472
Cargo.lock generated
View File

@ -1131,12 +1131,6 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6"
[[package]]
name = "convert_case"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
[[package]] [[package]]
name = "core-foundation" name = "core-foundation"
version = "0.9.4" version = "0.9.4"
@ -1361,23 +1355,6 @@ dependencies = [
"url", "url",
] ]
[[package]]
name = "cssparser"
version = "0.28.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1db8599a9761b371751fbf13e076fa03c6e1a78f8c5288e6ab9467f10a2322c1"
dependencies = [
"cssparser-macros",
"dtoa-short",
"itoa 0.4.8",
"matches",
"phf 0.8.0",
"proc-macro2",
"quote",
"smallvec 1.15.1",
"syn 1.0.109",
]
[[package]] [[package]]
name = "cssparser" name = "cssparser"
version = "0.34.0" version = "0.34.0"
@ -1387,7 +1364,7 @@ dependencies = [
"cssparser-macros", "cssparser-macros",
"dtoa-short", "dtoa-short",
"itoa 1.0.15", "itoa 1.0.15",
"phf 0.11.3", "phf",
"smallvec 1.15.1", "smallvec 1.15.1",
] ]
@ -1400,7 +1377,7 @@ dependencies = [
"cssparser-macros", "cssparser-macros",
"dtoa-short", "dtoa-short",
"itoa 1.0.15", "itoa 1.0.15",
"phf 0.11.3", "phf",
"smallvec 1.15.1", "smallvec 1.15.1",
] ]
@ -1569,10 +1546,8 @@ version = "0.99.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f"
dependencies = [ dependencies = [
"convert_case",
"proc-macro2", "proc-macro2",
"quote", "quote",
"rustc_version 0.4.1",
"syn 2.0.104", "syn 2.0.104",
] ]
@ -3251,7 +3226,7 @@ dependencies = [
"mailparse", "mailparse",
"maplit", "maplit",
"memmap", "memmap",
"quick-xml 0.38.1", "quick-xml",
"regex", "regex",
"reqwest", "reqwest",
"scraper", "scraper",
@ -3265,7 +3240,6 @@ dependencies = [
"tracing", "tracing",
"url", "url",
"urlencoding", "urlencoding",
"xmlem",
"xtracing", "xtracing",
"zip", "zip",
] ]
@ -3554,8 +3528,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7a7213d12e1864c0f002f52c2923d4556935a43dec5e71355c2760e0f6e7a18" checksum = "c7a7213d12e1864c0f002f52c2923d4556935a43dec5e71355c2760e0f6e7a18"
dependencies = [ dependencies = [
"log", "log",
"phf 0.11.3", "phf",
"phf_codegen 0.11.3", "phf_codegen",
"string_cache", "string_cache",
"string_cache_codegen", "string_cache_codegen",
"tendril", "tendril",
@ -3603,12 +3577,6 @@ dependencies = [
"regex-automata 0.1.10", "regex-automata 0.1.10",
] ]
[[package]]
name = "matches"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5"
[[package]] [[package]]
name = "matchit" name = "matchit"
version = "0.7.3" version = "0.7.3"
@ -3881,12 +3849,6 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "nodrop"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
[[package]] [[package]]
name = "nom" name = "nom"
version = "7.1.3" version = "7.1.3"
@ -4340,35 +4302,14 @@ dependencies = [
"sha2 0.10.9", "sha2 0.10.9",
] ]
[[package]]
name = "phf"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12"
dependencies = [
"phf_macros 0.8.0",
"phf_shared 0.8.0",
"proc-macro-hack",
]
[[package]] [[package]]
name = "phf" name = "phf"
version = "0.11.3" version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078"
dependencies = [ dependencies = [
"phf_macros 0.11.3", "phf_macros",
"phf_shared 0.11.3", "phf_shared",
]
[[package]]
name = "phf_codegen"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815"
dependencies = [
"phf_generator 0.8.0",
"phf_shared 0.8.0",
] ]
[[package]] [[package]]
@ -4377,18 +4318,8 @@ version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a"
dependencies = [ dependencies = [
"phf_generator 0.11.3", "phf_generator",
"phf_shared 0.11.3", "phf_shared",
]
[[package]]
name = "phf_generator"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526"
dependencies = [
"phf_shared 0.8.0",
"rand 0.7.3",
] ]
[[package]] [[package]]
@ -4397,53 +4328,30 @@ version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d"
dependencies = [ dependencies = [
"phf_shared 0.11.3", "phf_shared",
"rand 0.8.5", "rand 0.8.5",
] ]
[[package]]
name = "phf_macros"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c"
dependencies = [
"phf_generator 0.8.0",
"phf_shared 0.8.0",
"proc-macro-hack",
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]] [[package]]
name = "phf_macros" name = "phf_macros"
version = "0.11.3" version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216"
dependencies = [ dependencies = [
"phf_generator 0.11.3", "phf_generator",
"phf_shared 0.11.3", "phf_shared",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.104", "syn 2.0.104",
] ]
[[package]]
name = "phf_shared"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7"
dependencies = [
"siphasher 0.3.11",
]
[[package]] [[package]]
name = "phf_shared" name = "phf_shared"
version = "0.11.3" version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5"
dependencies = [ dependencies = [
"siphasher 1.0.1", "siphasher",
] ]
[[package]] [[package]]
@ -4616,12 +4524,6 @@ dependencies = [
"syn 2.0.104", "syn 2.0.104",
] ]
[[package]]
name = "proc-macro-hack"
version = "0.5.20+deprecated"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.96" version = "1.0.96"
@ -4663,48 +4565,6 @@ dependencies = [
"prost", "prost",
] ]
[[package]]
name = "qname"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fac552bc5de28a2d8ebb5d93d157b1eb3d1ca58f88ba2d1e2b931951cb52b29"
dependencies = [
"qname-impl",
"qname-macro",
]
[[package]]
name = "qname-impl"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c28cd0334d1ed0cb075cde40d45b9ee648fe79e69a18c3e2891f79c3ec788304"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "qname-macro"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e673fdaa2dcfd19fac443c4a361cc2635b2304592cdc5352ef76bb8dd38333c"
dependencies = [
"proc-macro2",
"qname-impl",
"quote",
"syn 1.0.109",
]
[[package]]
name = "quick-xml"
version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8533f14c8382aaad0d592c812ac3b826162128b65662331e1127b45c3d18536b"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "quick-xml" name = "quick-xml"
version = "0.38.1" version = "0.38.1"
@ -4802,20 +4662,6 @@ dependencies = [
"scheduled-thread-pool", "scheduled-thread-pool",
] ]
[[package]]
name = "rand"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
dependencies = [
"getrandom 0.1.16",
"libc",
"rand_chacha 0.2.2",
"rand_core 0.5.1",
"rand_hc",
"rand_pcg",
]
[[package]] [[package]]
name = "rand" name = "rand"
version = "0.8.5" version = "0.8.5"
@ -4837,16 +4683,6 @@ dependencies = [
"rand_core 0.9.3", "rand_core 0.9.3",
] ]
[[package]]
name = "rand_chacha"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
dependencies = [
"ppv-lite86",
"rand_core 0.5.1",
]
[[package]] [[package]]
name = "rand_chacha" name = "rand_chacha"
version = "0.3.1" version = "0.3.1"
@ -4867,15 +4703,6 @@ dependencies = [
"rand_core 0.9.3", "rand_core 0.9.3",
] ]
[[package]]
name = "rand_core"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
dependencies = [
"getrandom 0.1.16",
]
[[package]] [[package]]
name = "rand_core" name = "rand_core"
version = "0.6.4" version = "0.6.4"
@ -4904,24 +4731,6 @@ dependencies = [
"rand 0.8.5", "rand 0.8.5",
] ]
[[package]]
name = "rand_hc"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
dependencies = [
"rand_core 0.5.1",
]
[[package]]
name = "rand_pcg"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429"
dependencies = [
"rand_core 0.5.1",
]
[[package]] [[package]]
name = "rayon" name = "rayon"
version = "1.10.0" version = "1.10.0"
@ -5562,24 +5371,6 @@ dependencies = [
"web-sys", "web-sys",
] ]
[[package]]
name = "selectors"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fdea87c686be721aab36607728047801ee21561bfdbd6bf0da7ace2536d5879f"
dependencies = [
"bitflags 1.3.2",
"cssparser 0.28.1",
"derive_more 0.99.20",
"fxhash",
"log",
"phf 0.8.0",
"phf_codegen 0.8.0",
"precomputed-hash",
"servo_arc 0.1.1",
"smallvec 1.15.1",
]
[[package]] [[package]]
name = "selectors" name = "selectors"
version = "0.26.0" version = "0.26.0"
@ -5592,10 +5383,10 @@ dependencies = [
"fxhash", "fxhash",
"log", "log",
"new_debug_unreachable", "new_debug_unreachable",
"phf 0.11.3", "phf",
"phf_codegen 0.11.3", "phf_codegen",
"precomputed-hash", "precomputed-hash",
"servo_arc 0.4.1", "servo_arc",
"smallvec 1.15.1", "smallvec 1.15.1",
] ]
@ -5611,10 +5402,10 @@ dependencies = [
"fxhash", "fxhash",
"log", "log",
"new_debug_unreachable", "new_debug_unreachable",
"phf 0.11.3", "phf",
"phf_codegen 0.11.3", "phf_codegen",
"precomputed-hash", "precomputed-hash",
"servo_arc 0.4.1", "servo_arc",
"smallvec 1.15.1", "smallvec 1.15.1",
] ]
@ -5737,16 +5528,6 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "servo_arc"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d98238b800e0d1576d8b6e3de32827c2d74bee68bb97748dcf5071fb53965432"
dependencies = [
"nodrop",
"stable_deref_trait",
]
[[package]] [[package]]
name = "servo_arc" name = "servo_arc"
version = "0.4.1" version = "0.4.1"
@ -5855,12 +5636,6 @@ version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
[[package]]
name = "siphasher"
version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
[[package]] [[package]]
name = "siphasher" name = "siphasher"
version = "1.0.1" version = "1.0.1"
@ -6169,7 +5944,7 @@ checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f"
dependencies = [ dependencies = [
"new_debug_unreachable", "new_debug_unreachable",
"parking_lot 0.12.4", "parking_lot 0.12.4",
"phf_shared 0.11.3", "phf_shared",
"precomputed-hash", "precomputed-hash",
"serde", "serde",
] ]
@ -6180,8 +5955,8 @@ version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c711928715f1fe0fe509c53b43e993a9a557babc2d0a3567d0a3006f1ac931a0" checksum = "c711928715f1fe0fe509c53b43e993a9a557babc2d0a3567d0a3006f1ac931a0"
dependencies = [ dependencies = [
"phf_generator 0.11.3", "phf_generator",
"phf_shared 0.11.3", "phf_shared",
"proc-macro2", "proc-macro2",
"quote", "quote",
] ]
@ -7218,189 +6993,6 @@ version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
[[package]]
name = "unic-char-property"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221"
dependencies = [
"unic-char-range",
]
[[package]]
name = "unic-char-range"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc"
[[package]]
name = "unic-common"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc"
[[package]]
name = "unic-ucd"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "625b18f7601e1127504a20ae731dc3c7826d0e86d5f7fe3434f8137669240efd"
dependencies = [
"unic-ucd-age",
"unic-ucd-bidi",
"unic-ucd-block",
"unic-ucd-case",
"unic-ucd-category",
"unic-ucd-common",
"unic-ucd-hangul",
"unic-ucd-ident",
"unic-ucd-name",
"unic-ucd-name_aliases",
"unic-ucd-normal",
"unic-ucd-segment",
"unic-ucd-version",
]
[[package]]
name = "unic-ucd-age"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c8cfdfe71af46b871dc6af2c24fcd360e2f3392ee4c5111877f2947f311671c"
dependencies = [
"unic-char-property",
"unic-char-range",
"unic-ucd-version",
]
[[package]]
name = "unic-ucd-bidi"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d1d568b51222484e1f8209ce48caa6b430bf352962b877d592c29ab31fb53d8c"
dependencies = [
"unic-char-property",
"unic-char-range",
"unic-ucd-version",
]
[[package]]
name = "unic-ucd-block"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b2a16f2d7ecd25325a1053ca5a66e7fa1b68911a65c5e97f8d2e1b236b6f1d7"
dependencies = [
"unic-char-property",
"unic-char-range",
"unic-ucd-version",
]
[[package]]
name = "unic-ucd-case"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d98d6246a79bac6cf66beee01422bda7c882e11d837fa4969bfaaba5fdea6d3"
dependencies = [
"unic-char-property",
"unic-char-range",
"unic-ucd-version",
]
[[package]]
name = "unic-ucd-category"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b8d4591f5fcfe1bd4453baaf803c40e1b1e69ff8455c47620440b46efef91c0"
dependencies = [
"matches",
"unic-char-property",
"unic-char-range",
"unic-ucd-version",
]
[[package]]
name = "unic-ucd-common"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9b78b910beafa1aae5c59bf00877c6cece1c5db28a1241ad801e86cecdff4ad"
dependencies = [
"unic-char-property",
"unic-char-range",
"unic-ucd-version",
]
[[package]]
name = "unic-ucd-hangul"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb1dc690e19010e1523edb9713224cba5ef55b54894fe33424439ec9a40c0054"
dependencies = [
"unic-ucd-version",
]
[[package]]
name = "unic-ucd-ident"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e230a37c0381caa9219d67cf063aa3a375ffed5bf541a452db16e744bdab6987"
dependencies = [
"unic-char-property",
"unic-char-range",
"unic-ucd-version",
]
[[package]]
name = "unic-ucd-name"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8fc55a45b2531089dc1773bf60c1f104b38e434b774ffc37b9c29a9b0f492e"
dependencies = [
"unic-char-property",
"unic-ucd-hangul",
"unic-ucd-version",
]
[[package]]
name = "unic-ucd-name_aliases"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b7674212643087699ba247a63dd05f1204c7e4880ec9342e545a7cffcc6a46f"
dependencies = [
"unic-char-property",
"unic-ucd-version",
]
[[package]]
name = "unic-ucd-normal"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86aed873b8202d22b13859dda5fe7c001d271412c31d411fd9b827e030569410"
dependencies = [
"unic-char-property",
"unic-char-range",
"unic-ucd-category",
"unic-ucd-hangul",
"unic-ucd-version",
]
[[package]]
name = "unic-ucd-segment"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2079c122a62205b421f499da10f3ee0f7697f012f55b675e002483c73ea34700"
dependencies = [
"unic-char-property",
"unic-char-range",
"unic-ucd-version",
]
[[package]]
name = "unic-ucd-version"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4"
dependencies = [
"unic-common",
]
[[package]] [[package]]
name = "unicase" name = "unicase"
version = "2.8.1" version = "2.8.1"
@ -7738,8 +7330,8 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57ffde1dc01240bdf9992e3205668b235e59421fd085e8a317ed98da0178d414" checksum = "57ffde1dc01240bdf9992e3205668b235e59421fd085e8a317ed98da0178d414"
dependencies = [ dependencies = [
"phf 0.11.3", "phf",
"phf_codegen 0.11.3", "phf_codegen",
"string_cache", "string_cache",
"string_cache_codegen", "string_cache_codegen",
] ]
@ -8139,22 +7731,6 @@ version = "0.8.27"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fd8403733700263c6eb89f192880191f1b83e332f7a20371ddcf421c4a337c7" checksum = "6fd8403733700263c6eb89f192880191f1b83e332f7a20371ddcf421c4a337c7"
[[package]]
name = "xmlem"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15d7eadd176b9e994da5c27acd46001a82256afa9e49b1b56b37e117e63a0aee"
dependencies = [
"cssparser 0.28.1",
"indexmap 1.9.3",
"once_cell",
"qname",
"quick-xml 0.22.0",
"selectors 0.23.0",
"slotmap",
"unic-ucd",
]
[[package]] [[package]]
name = "xtracing" name = "xtracing"
version = "0.3.2" version = "0.3.2"

View File

@ -54,7 +54,7 @@ urlencoding = "2.1.3"
#xtracing = { path = "../../xtracing" } #xtracing = { path = "../../xtracing" }
xtracing = { version = "0.3.2", registry = "xinu" } xtracing = { version = "0.3.2", registry = "xinu" }
zip = "4.3.0" zip = "4.3.0"
xmlem = "0.1.0"
[build-dependencies] [build-dependencies]
build-info-build = "0.0.41" build-info-build = "0.0.41"

View File

@ -43,4 +43,6 @@ pub enum ServerError {
AskamaError(#[from] askama::Error), AskamaError(#[from] askama::Error),
#[error("xml error: {0}")] #[error("xml error: {0}")]
XmlError(#[from] quick_xml::Error), XmlError(#[from] quick_xml::Error),
#[error("xml encoding error: {0}")]
XmlEncodingError(#[from] quick_xml::encoding::EncodingError),
} }

View File

@ -2,7 +2,7 @@ use std::{
collections::{HashMap, HashSet}, collections::{HashMap, HashSet},
fs::File, fs::File,
io::{Cursor, Read}, io::{Cursor, Read},
str::FromStr,
}; };
use askama::Template; use askama::Template;
@ -14,7 +14,7 @@ use memmap::MmapOptions;
use quick_xml::de::from_str as xml_from_str; use quick_xml::de::from_str as xml_from_str;
use sqlx::{types::Json, PgPool}; use sqlx::{types::Json, PgPool};
use tracing::{error, info, info_span, instrument, warn}; use tracing::{error, info, info_span, instrument, warn};
use xmlem::{display, Document};
use zip::ZipArchive; use zip::ZipArchive;
use crate::{ use crate::{
@ -407,15 +407,12 @@ pub async fn thread(
} else { } else {
// DMARC reports are XML // DMARC reports are XML
// Pretty print XML // Pretty print XML
let doc_result = Document::from_str(&raw_content); match pretty_print_xml_with_trimming(&raw_content) {
if let Ok(doc) = doc_result { Ok(pretty_xml) => pretty_xml,
doc.to_string_pretty_with_config(&display::Config::default_pretty()) Err(e) => {
} else { error!("Failed to pretty print XML: {:?}", e);
error!( raw_content
"Failed to parse XML for pretty printing: {:?}", }
doc_result.unwrap_err()
);
raw_content
} }
}; };
current_html.push_str(&format!( current_html.push_str(&format!(
@ -897,15 +894,12 @@ fn extract_mixed(m: &ParsedMail, part_addr: &mut Vec<String>) -> Result<Body, Se
} else { } else {
// DMARC reports are XML // DMARC reports are XML
// Pretty print XML // Pretty print XML
let doc_result = Document::from_str(&xml); match pretty_print_xml_with_trimming(&xml) {
if let Ok(doc) = doc_result { Ok(pretty_xml) => pretty_xml,
doc.to_string_pretty_with_config(&display::Config::default_pretty()) Err(e) => {
} else { error!("Failed to pretty print XML: {:?}", e);
error!( xml
"Failed to parse XML for pretty printing: {:?}", }
doc_result.unwrap_err()
);
xml
} }
}; };
parts.push(Body::html(format!("\n<pre>{}</pre>", html_escape::encode_text(&pretty_printed_content)))); parts.push(Body::html(format!("\n<pre>{}</pre>", html_escape::encode_text(&pretty_printed_content))));
@ -1864,6 +1858,37 @@ pub fn parse_dmarc_report(xml: &str) -> Result<String, ServerError> {
Ok(html) Ok(html)
} }
fn pretty_print_xml_with_trimming(xml_input: &str) -> Result<String, ServerError> {
use quick_xml::events::{Event, BytesText};
use quick_xml::reader::Reader;
use quick_xml::writer::Writer;
use std::io::Cursor;
let mut reader = Reader::from_str(xml_input);
reader.config_mut().trim_text(true);
let mut writer = Writer::new_with_indent(Cursor::new(Vec::new()), b' ', 4);
let mut buf = Vec::new();
loop {
match reader.read_event_into(&mut buf) {
Ok(Event::Eof) => break,
Ok(Event::Text(e)) => {
let trimmed_text = e.decode()?.trim().to_string();
writer.write_event(Event::Text(BytesText::new(&trimmed_text)))?;
},
Ok(event) => {
writer.write_event(event)?;
},
Err(e) => return Err(ServerError::StringError(format!("XML parsing error: {}", e))),
}
buf.clear();
}
let result = writer.into_inner().into_inner();
Ok(String::from_utf8(result)?)
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;