Recommendation: Adopt the faithful, header-derived approach (windows-rs
windows-clang pipeline, PR #4649)
as the metadata source of truth for the Rust projection. The evidence below supports
this decisively for the windows-rs use case.
win32metadata (microsoft/win32metadata)
is a C#/ClangSharp scraper that aims to produce metadata higher-level than the
headers. It synthesizes friendly constructs — loose #define constants promoted to
enums, handle lifetimes/RAII hints, struct-size fields, SetLastError behavior, doc
URLs, OS-version availability, ANSI/Unicode merging, and an editorial sub-namespace
taxonomy — encoded with a large custom-attribute vocabulary. To do this it needs an
enormous body of hand-curated configuration (libMappings.rsp, enums.json,
documentationMappings.rsp, remap/partition files, manual patches).
In-house (windows-clang → RDL → winmd) parses the SDK headers with libclang and
emits only what the source directly expresses: SAL (_In_/_Out_/_opt_,
counted/sized buffers, _z_, _COM_Outptr_), __declspec (uuid, noreturn,
align, dllimport, deprecated), calling conventions, #pragma pack/alignment,
unions, bitfields, scoped enums, IDL attributes, and the symbol→DLL map recovered from
import libs. Everything lands in a single flat Windows.Win32 namespace, partitioned
one file per defining header.
-
Curation is the cost center. win32metadata's value-add is exactly the part that cannot be derived and must be hand-maintained forever — thousands of lines of
.rsp/.jsonconfig that drift against every SDK release. The in-house tool has no type-level curation: its entire config is a list of headers, satellite rules, and import libs (constslices inmain.rs). Adding APIs = listing a header and regenerating; a full SDK generational bump is absorbed with zero scraper changes. -
The "bells and whistles" don't help Rust. The synthesized attributes serve C#/.NET consumers. Rust ergonomics that matter (RAII handles,
Resultwrapping, typed factories) belong in the hand-writtenwindowsprojection layer, not smuggled into metadata as synthetic attributes. The in-house pipeline emits exactly 11 attributes, all consumed by bindgen; win32metadata-only attributes (RAIIFree,AssociatedEnum,AlsoUsableFor,Agile,ConstAttribute, …) are simply gone. -
Faithful = fewer places to be wrong. Where win32metadata's higher-level output looks more ergonomic (
D2D1CreateFactory<T>, enum-typed flags, optional handles), those are hand-patches with no header basis. The in-house signatures that look lower-level are correct, and the ergonomics reappear in the projection layer. Meanwhile faithfulness caught real ABI bugs the higher-level path masked (e.g. MSVC reverse-vtable-order for overloaded virtuals → stack-cookie fail-fast;_COM_Outptr_opt_optionality loss). -
Reviewability & reproducibility. The committed
metadata/win32/*.rdltext corpus makes every scrape change a readablegit diff; builds are byte-for-byte deterministic (validated on Linux). No dependence on an external, separately-versioned project or itsmdmerge/patching toolchain. -
Namespaces were an editorial invention. The SDK is a flat C namespace (only 0.02% of type names collide). win32metadata's sub-namespaces have no source signal to recover; the flat namespace + per-header files is the one faithful, mechanical routing signal, while per-function DLL truth is preserved as data (
#[library("…")]).
The faithful approach deliberately omits things win32metadata provides: loose-constant→enum promotion, RAII/handle-close metadata, struct auto-size fields, Unicode-first merging, doc URLs, and OS availability. These are handled by:
- a short, explicitly-tracked editorial-deviation ledger (~13 automatable rules, e.g. unsigned-constant width, string-alias normalization, SAL-driven pointer const-ness) — the single audited place the scrape "tips the scales," each justified by author intent, not by matching win32metadata for its own sake; and
- the hand-written projection layer for genuine ergonomics.
This is the right boundary: metadata stays honest and self-maintaining; opinion lives in reviewable Rust code.
For windows-rs, the faithful in-house pipeline eliminates a large external curation dependency, produces deterministic reviewable output, self-maintains across SDK bumps, and — because it re-homes ergonomics into the projection layer — loses nothing Rust consumers actually need while gaining ABI correctness. Recommend standardizing on it, keeping the deviation ledger short and the projection layer as the home for higher-level conveniences.