summaryrefslogtreecommitdiffstats
path: root/vendor/windows-bindgen
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:36 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:36 +0000
commite02c5b5930c2c9ba3e5423fe12e2ef0155017297 (patch)
treefd60ebbbb5299e16e5fca8c773ddb74f764760db /vendor/windows-bindgen
parentAdding debian version 1.73.0+dfsg1-1. (diff)
downloadrustc-e02c5b5930c2c9ba3e5423fe12e2ef0155017297.tar.xz
rustc-e02c5b5930c2c9ba3e5423fe12e2ef0155017297.zip
Merging upstream version 1.74.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/windows-bindgen')
-rw-r--r--vendor/windows-bindgen/.cargo-checksum.json2
-rw-r--r--vendor/windows-bindgen/Cargo.toml31
-rw-r--r--vendor/windows-bindgen/default/Windows.Wdk.winmdbin0 -> 879544 bytes
-rw-r--r--vendor/windows-bindgen/default/Windows.Win32.winmdbin0 -> 23189424 bytes
-rw-r--r--vendor/windows-bindgen/default/Windows.winmdbin0 -> 7244288 bytes
-rw-r--r--vendor/windows-bindgen/default/readme.md23
-rw-r--r--vendor/windows-bindgen/readme.md10
-rw-r--r--vendor/windows-bindgen/rustfmt.toml1
-rw-r--r--vendor/windows-bindgen/src/args.rs45
-rw-r--r--vendor/windows-bindgen/src/classes.rs215
-rw-r--r--vendor/windows-bindgen/src/com_methods.rs238
-rw-r--r--vendor/windows-bindgen/src/delegates.rs181
-rw-r--r--vendor/windows-bindgen/src/error.rs55
-rw-r--r--vendor/windows-bindgen/src/extensions/mod.rs57
-rw-r--r--vendor/windows-bindgen/src/extensions/mod/Foundation/IInspectable.rs13
-rw-r--r--vendor/windows-bindgen/src/extensions/mod/Foundation/PropertyValue.rs71
-rw-r--r--vendor/windows-bindgen/src/extensions/mod/Win32/Foundation/NTSTATUS.rs32
-rw-r--r--vendor/windows-bindgen/src/functions.rs285
-rw-r--r--vendor/windows-bindgen/src/interfaces.rs224
-rw-r--r--vendor/windows-bindgen/src/lib.rs413
-rw-r--r--vendor/windows-bindgen/src/metadata/mod.rs926
-rw-r--r--vendor/windows-bindgen/src/method_names.rs30
-rw-r--r--vendor/windows-bindgen/src/rdl/fmt.rs454
-rw-r--r--vendor/windows-bindgen/src/rdl/from_reader.rs435
-rw-r--r--vendor/windows-bindgen/src/rdl/mod.rs338
-rw-r--r--vendor/windows-bindgen/src/rdl/to_winmd.rs335
-rw-r--r--vendor/windows-bindgen/src/rust/cfg.rs169
-rw-r--r--vendor/windows-bindgen/src/rust/classes.rs160
-rw-r--r--vendor/windows-bindgen/src/rust/com_methods.rs207
-rw-r--r--vendor/windows-bindgen/src/rust/constants.rs (renamed from vendor/windows-bindgen/src/constants.rs)85
-rw-r--r--vendor/windows-bindgen/src/rust/delegates.rs156
-rw-r--r--vendor/windows-bindgen/src/rust/enums.rs (renamed from vendor/windows-bindgen/src/enums.rs)101
-rw-r--r--vendor/windows-bindgen/src/rust/extensions/impl/Foundation/Collections/Iterable.rs (renamed from vendor/windows-bindgen/src/extensions/impl/Foundation/Collections/Iterable.rs)50
-rw-r--r--vendor/windows-bindgen/src/rust/extensions/impl/Foundation/Collections/MapView.rs (renamed from vendor/windows-bindgen/src/extensions/impl/Foundation/Collections/MapView.rs)104
-rw-r--r--vendor/windows-bindgen/src/rust/extensions/impl/Foundation/Collections/VectorView.rs (renamed from vendor/windows-bindgen/src/extensions/impl/Foundation/Collections/VectorView.rs)70
-rw-r--r--vendor/windows-bindgen/src/rust/extensions/mod.rs31
-rw-r--r--vendor/windows-bindgen/src/rust/extensions/mod/Foundation/Numerics/Matrix3x2.rs (renamed from vendor/windows-bindgen/src/extensions/mod/Foundation/Numerics/Matrix3x2.rs)0
-rw-r--r--vendor/windows-bindgen/src/rust/extensions/mod/Foundation/Numerics/Matrix4x4.rs (renamed from vendor/windows-bindgen/src/extensions/mod/Foundation/Numerics/Matrix4x4.rs)0
-rw-r--r--vendor/windows-bindgen/src/rust/extensions/mod/Foundation/Numerics/Vector2.rs (renamed from vendor/windows-bindgen/src/extensions/mod/Foundation/Numerics/Vector2.rs)0
-rw-r--r--vendor/windows-bindgen/src/rust/extensions/mod/Foundation/Numerics/Vector3.rs (renamed from vendor/windows-bindgen/src/extensions/mod/Foundation/Numerics/Vector3.rs)0
-rw-r--r--vendor/windows-bindgen/src/rust/extensions/mod/Foundation/Numerics/Vector4.rs (renamed from vendor/windows-bindgen/src/extensions/mod/Foundation/Numerics/Vector4.rs)0
-rw-r--r--vendor/windows-bindgen/src/rust/extensions/mod/Foundation/TimeSpan.rs (renamed from vendor/windows-bindgen/src/extensions/mod/Foundation/TimeSpan.rs)0
-rw-r--r--vendor/windows-bindgen/src/rust/extensions/mod/Win32/Foundation/BOOL.rs (renamed from vendor/windows-bindgen/src/extensions/mod/Win32/Foundation/BOOL.rs)10
-rw-r--r--vendor/windows-bindgen/src/rust/extensions/mod/Win32/Foundation/BOOLEAN.rs (renamed from vendor/windows-bindgen/src/extensions/mod/Win32/Foundation/BOOLEAN.rs)4
-rw-r--r--vendor/windows-bindgen/src/rust/extensions/mod/Win32/Foundation/NTSTATUS.rs32
-rw-r--r--vendor/windows-bindgen/src/rust/extensions/mod/Win32/Foundation/VARIANT_BOOL.rs (renamed from vendor/windows-bindgen/src/extensions/mod/Win32/Foundation/VARIANT_BOOL.rs)4
-rw-r--r--vendor/windows-bindgen/src/rust/extensions/mod/Win32/Foundation/WIN32_ERROR.rs (renamed from vendor/windows-bindgen/src/extensions/mod/Win32/Foundation/WIN32_ERROR.rs)16
-rw-r--r--vendor/windows-bindgen/src/rust/extensions/mod/Win32/Networking/WinSock/IN6_ADDR.rs (renamed from vendor/windows-bindgen/src/extensions/mod/Win32/Networking/WinSock/IN6_ADDR.rs)0
-rw-r--r--vendor/windows-bindgen/src/rust/extensions/mod/Win32/Networking/WinSock/IN_ADDR.rs (renamed from vendor/windows-bindgen/src/extensions/mod/Win32/Networking/WinSock/IN_ADDR.rs)0
-rw-r--r--vendor/windows-bindgen/src/rust/extensions/mod/Win32/Networking/WinSock/SOCKADDR_IN.rs (renamed from vendor/windows-bindgen/src/extensions/mod/Win32/Networking/WinSock/SOCKADDR_IN.rs)0
-rw-r--r--vendor/windows-bindgen/src/rust/extensions/mod/Win32/Networking/WinSock/SOCKADDR_IN6.rs (renamed from vendor/windows-bindgen/src/extensions/mod/Win32/Networking/WinSock/SOCKADDR_IN6.rs)0
-rw-r--r--vendor/windows-bindgen/src/rust/extensions/mod/Win32/Networking/WinSock/SOCKADDR_INET.rs (renamed from vendor/windows-bindgen/src/extensions/mod/Win32/Networking/WinSock/SOCKADDR_INET.rs)0
-rw-r--r--vendor/windows-bindgen/src/rust/extensions/mod/Win32/UI/WindowsAndMessaging/WindowLong.rs (renamed from vendor/windows-bindgen/src/extensions/mod/Win32/UI/WindowsAndMessaging/WindowLong.rs)0
-rw-r--r--vendor/windows-bindgen/src/rust/functions.rs275
-rw-r--r--vendor/windows-bindgen/src/rust/handles.rs (renamed from vendor/windows-bindgen/src/handles.rs)51
-rw-r--r--vendor/windows-bindgen/src/rust/implements.rs (renamed from vendor/windows-bindgen/src/implements.rs)109
-rw-r--r--vendor/windows-bindgen/src/rust/interfaces.rs149
-rw-r--r--vendor/windows-bindgen/src/rust/iterators.rs (renamed from vendor/windows-bindgen/src/iterators.rs)73
-rw-r--r--vendor/windows-bindgen/src/rust/method_names.rs30
-rw-r--r--vendor/windows-bindgen/src/rust/mod.rs280
-rw-r--r--vendor/windows-bindgen/src/rust/standalone.rs217
-rw-r--r--vendor/windows-bindgen/src/rust/structs.rs288
-rw-r--r--vendor/windows-bindgen/src/rust/try_format.rs49
-rw-r--r--vendor/windows-bindgen/src/rust/winrt_methods.rs242
-rw-r--r--vendor/windows-bindgen/src/rust/writer.rs (renamed from vendor/windows-bindgen/src/gen.rs)555
-rw-r--r--vendor/windows-bindgen/src/standalone.rs266
-rw-r--r--vendor/windows-bindgen/src/structs.rs316
-rw-r--r--vendor/windows-bindgen/src/tokens/mod.rs443
-rw-r--r--vendor/windows-bindgen/src/tokens/runtime.rs274
-rw-r--r--vendor/windows-bindgen/src/tokens/to_tokens.rs149
-rw-r--r--vendor/windows-bindgen/src/tokens/token_stream.rs164
-rw-r--r--vendor/windows-bindgen/src/tree.rs36
-rw-r--r--vendor/windows-bindgen/src/try_format.rs31
-rw-r--r--vendor/windows-bindgen/src/winmd/from_reader.rs141
-rw-r--r--vendor/windows-bindgen/src/winmd/mod.rs7
-rw-r--r--vendor/windows-bindgen/src/winmd/verify.rs31
-rw-r--r--vendor/windows-bindgen/src/winmd/writer/blobs.rs48
-rw-r--r--vendor/windows-bindgen/src/winmd/writer/codes.rs71
-rw-r--r--vendor/windows-bindgen/src/winmd/writer/file.rs134
-rw-r--r--vendor/windows-bindgen/src/winmd/writer/mod.rs329
-rw-r--r--vendor/windows-bindgen/src/winmd/writer/strings.rs35
-rw-r--r--vendor/windows-bindgen/src/winmd/writer/tables.rs361
-rw-r--r--vendor/windows-bindgen/src/winmd/writer/traits.rs66
-rw-r--r--vendor/windows-bindgen/src/winmd/writer/type.rs80
-rw-r--r--vendor/windows-bindgen/src/winrt_methods.rs258
85 files changed, 8024 insertions, 3147 deletions
diff --git a/vendor/windows-bindgen/.cargo-checksum.json b/vendor/windows-bindgen/.cargo-checksum.json
index 1515d8f7b..8482360f7 100644
--- a/vendor/windows-bindgen/.cargo-checksum.json
+++ b/vendor/windows-bindgen/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"d3fb5d2a2914f8722455a23bc7480ece5294fac9f6569bc10d2cd2f4e7199d9b","license-apache-2.0":"c16f8dcf1a368b83be78d826ea23de4079fe1b4469a0ab9ee20563f37ff3d44b","license-mit":"c2cfccb812fe482101a8f04597dfc5a9991a6b2748266c47ac91b6a5aae15383","readme.md":"d7baa101eb75cfcd7780483b912e89cac34b3a09bac6bd211b65227862195e66","rustfmt.toml":"8f201bf4d9ff69411e98031ad1b168f58ce02d91fd33bc80406115c2506355d4","src/classes.rs":"544c1a44311c4ea01746bdd6728dbd86b1052aa49369230394eb61b69a199c81","src/com_methods.rs":"62e40fa4fe127c8f51b955132030bb0c2eb154f0e0477bdee00cac96e1a5e81e","src/constants.rs":"baefaface9c8a62a2c511c6d23298d18995c5f66b6b9d33d8e02ec9304d74a63","src/delegates.rs":"48e5130d112cc44678af6546a3f1a4c280dea4ac669d4bfc34200201663d08a9","src/enums.rs":"c9139821ae052d522dd54d3f246eb4f59b264d1e155b1addec1128abd78840c4","src/extensions/impl/Foundation/Collections/Iterable.rs":"873c3d33ee6446beda43126ca2a0f58405078b48fd1b3beb18bb43ef7fd4d9d1","src/extensions/impl/Foundation/Collections/MapView.rs":"262ec7c72ec75cdea4f905efec24a4a9c58411d1804673e4e6219509a0ca27df","src/extensions/impl/Foundation/Collections/VectorView.rs":"ea4a71a8fd7e3b4400d1d63ee0f2a3ca0a7521377285c6921430554529c920fe","src/extensions/mod.rs":"d50589d2c41328809650538a2bcba45557aba0247e70033c91845de153ab8766","src/extensions/mod/Foundation/IInspectable.rs":"28053647ee2c91287321b165949411aa659d2f5a396184759f066c707750f538","src/extensions/mod/Foundation/Numerics/Matrix3x2.rs":"43c2bd8389b7de6bff266e91fafd03c27da56632d47a0d47ed17cf429b8538cc","src/extensions/mod/Foundation/Numerics/Matrix4x4.rs":"da469abb2a40632935f37074b1e9c726d8742fbb3d1c2804674fd287ad3c2979","src/extensions/mod/Foundation/Numerics/Vector2.rs":"d20b8b59fa2193cb81c8d9ccd7e15c5f7827e7392a35bb9d10af42ab4ccd75ac","src/extensions/mod/Foundation/Numerics/Vector3.rs":"df851b7f059e3f31bf0eb76f0515312a68465b2489a8b68f03bdcddf4b47e693","src/extensions/mod/Foundation/Numerics/Vector4.rs":"f309f3e1e0c34b9db3137f113a3519ac1708aaa1aacb899b4b59f0228497e1a4","src/extensions/mod/Foundation/PropertyValue.rs":"c451b9388b3a9023f991e91a0ba48a403b7507fda529532a0042c910b4b04055","src/extensions/mod/Foundation/TimeSpan.rs":"b6de4e26e155771d8ad9e3117e8b33d18f7a4dfc1c2b46ae59b0bad52710ce11","src/extensions/mod/Win32/Foundation/BOOL.rs":"44171d9050b2c8ac3b34677073573f209aafd29e8c6a06bffe9b4619f1317e9b","src/extensions/mod/Win32/Foundation/BOOLEAN.rs":"b203f08c6e7bffbf3b9d41f48f7bd6422c5c38ea7284bd66f1e25377e1e721fe","src/extensions/mod/Win32/Foundation/NTSTATUS.rs":"aba61020a2736b57164290b2a9d605f38185a7a7e02d39449437746064b22513","src/extensions/mod/Win32/Foundation/VARIANT_BOOL.rs":"f517c0d3cc8b3cbd218d84c32ad81f8d6b4f1c3b59f688de7a63afda59d46ce8","src/extensions/mod/Win32/Foundation/WIN32_ERROR.rs":"71b8aed03fdc69a6efb8ed5ec584863a6113ceb1e2968d0b4f605701029ac7c5","src/extensions/mod/Win32/Networking/WinSock/IN6_ADDR.rs":"77bfd4761e35c07092389e746553352fae9c265c8362402389c75cfbe0051b4b","src/extensions/mod/Win32/Networking/WinSock/IN_ADDR.rs":"a69b030fb1082d7f6d610ac95c60ec86b6f67cc10181cb2152408003cf1dc95c","src/extensions/mod/Win32/Networking/WinSock/SOCKADDR_IN.rs":"126e342356b0e1244d4c9489c421281215ff7a857b1b234a50c042ac27caf1a7","src/extensions/mod/Win32/Networking/WinSock/SOCKADDR_IN6.rs":"3479563d2ba7cbb94987605a736b1a62f7a0286dc141a11b48969910a9082462","src/extensions/mod/Win32/Networking/WinSock/SOCKADDR_INET.rs":"ebda0e371f36f0fa782ec0c37ad47c19540a20a58e7810570968357f6f54fef9","src/extensions/mod/Win32/UI/WindowsAndMessaging/WindowLong.rs":"fe5e01b7126c9fe7e7d4ee82a4b3f266b0306e1de20a33476b1ba8f3a782533c","src/functions.rs":"3cfeac90f2f1d0e9df85710e3fa4d90a3107d6454b6f911dff45d81894aa436d","src/gen.rs":"7ef87eaa513662aa8e6e0825ec946b2f03820edcdb22263672974218d2f159b5","src/handles.rs":"054c4491d2c3e58c4987ab00e81003119b4978b81f548fe77c31e7a0063eb015","src/implements.rs":"4098f447a4a830fe1644196fc60b22ff23c12f6269950278651cad98bc5ab509","src/interfaces.rs":"b4c57ae2f7c871c47f4f3728e0fc5fef2e4e5e637c52a2d1a8eb8533b8e27909","src/iterators.rs":"c057d9f021a30e5bcb8daa0a7282e453174c7c6b5e04fafc444e59fbc30d7b22","src/lib.rs":"dd48701aab64a6823703458b134458f93fa349f8919b11d8c54c607177821d9e","src/method_names.rs":"d367fd2c75abc7977b1b17e49e4867e1a602bd56bb8a4188de8fbaa203305917","src/standalone.rs":"6aca1fa4bd47d61343b3873153115d64eb82c5471a280833c0f875c62d8aa051","src/structs.rs":"922e1745fa2919145dd92e7fd15f9237d8584180144ac8138ab17ebdaeeafc09","src/try_format.rs":"ffe15866050fdc9424749c572001953064347d499a06b15d6df783b38011289d","src/winrt_methods.rs":"3cee31e1628a246d67d8265a967ff2c42ff3c436218993817b7c6a331afc9e7f"},"package":"b6935fb09b84ee57929ae92518b475f5dfdfbeb87c5334756acc28ee8e202b60"} \ No newline at end of file
+{"files":{"Cargo.toml":"c8383392d2840c539aa65c64b9a922f0ad10b794d86cd67087e1b4d9029df38a","default/Windows.Wdk.winmd":"8230fd41b87e56f4c1d66415f6be24a40e78f91e0d7a7345082cba07847e0a1a","default/Windows.Win32.winmd":"ac817d1e4e13d6dfd581c9301fc2019d39d346ea53e7935c2e17d24d88a58fbe","default/Windows.winmd":"046c4c01f0b42b514953002a3b736824ea45d74decf5c684c0a15d36ab1c46f6","default/readme.md":"f332e6a2dffbecc176feafc39e7324741a3f26a2a5dc67cd354bfcbb577f632f","license-apache-2.0":"c16f8dcf1a368b83be78d826ea23de4079fe1b4469a0ab9ee20563f37ff3d44b","license-mit":"c2cfccb812fe482101a8f04597dfc5a9991a6b2748266c47ac91b6a5aae15383","readme.md":"5f91803108fe0a6bfe9471d9905d73cfd0e7f37434c1cc32b1e25eaf74732920","src/args.rs":"c54a43f0997224fcfd1d55b0116e7b16c8e70207a1a375a8460bab5d6197f8b4","src/error.rs":"bd92b0d4590fc05b8fb1f235d8f6b23dd2f8fa1797f7638c58434443c629c31f","src/lib.rs":"aac3bc96eeb28d1fa4fa21720e4d96b94f3d0ae26a98a83fdb8250482af3f2f3","src/metadata/mod.rs":"86bb0a3904aca36703c7dbd0ddfa2f76032fd89b71f3292a82bfafdd91d180a8","src/rdl/fmt.rs":"c0f09ca666dd3656b07bbb3bf8166477bb6fed83874e4538f9c8ab338be39347","src/rdl/from_reader.rs":"0408f2bc1d651f84979dd1c6900c17ae380218a05a923c512b5a88fea6225215","src/rdl/mod.rs":"e554edd847d50862844c230f9934348d31f6206d38c137f95b345d015626760a","src/rdl/to_winmd.rs":"c12a372c1ea0efa463fedcba2840d7be0ce7040d3caef5a3fccd3edaaccb14e7","src/rust/cfg.rs":"6f03cdeaa1cfbdae18473d4ba09d4668df2d53de6bb8fae5a3acf45626e05c11","src/rust/classes.rs":"2e768ac612ce4b810f8fb673fb9b8a06d56e8375bc0e9f0710275d4e007e16a8","src/rust/com_methods.rs":"a42b8ee02301711457977569a516840d4387cf662ef57c5de7878052219cbbda","src/rust/constants.rs":"ba6bc0919879a353afb89d053c3e0b34cfc108a06090815171b3031168740b6c","src/rust/delegates.rs":"23c4e1c2ea6afd211b9a1ca9198e2973c1cc7e1a9c7cd957d8123067a89642fe","src/rust/enums.rs":"5c6dc3b1c1da0743b02c740e073d01bc0c30564dc25193bf3f1b9412ddda8a2e","src/rust/extensions/impl/Foundation/Collections/Iterable.rs":"aef6622e7dd2523c8a4e1b4d97e9c0cf31090df6e57e23999cfadecc67cb98e4","src/rust/extensions/impl/Foundation/Collections/MapView.rs":"07ba269a7269dc17c0c44d61bf3c90b25ce1168aa734d017f9ad1a4b49465d1c","src/rust/extensions/impl/Foundation/Collections/VectorView.rs":"f456f25b5ad4a7f5565904df6b0831a2a7b4648662cf4ef83fb0e6a7640d5956","src/rust/extensions/mod.rs":"5c7e066b0e6f4f66c218d9b507452aec078bb17f692c93082e53980aa3ea166e","src/rust/extensions/mod/Foundation/Numerics/Matrix3x2.rs":"43c2bd8389b7de6bff266e91fafd03c27da56632d47a0d47ed17cf429b8538cc","src/rust/extensions/mod/Foundation/Numerics/Matrix4x4.rs":"da469abb2a40632935f37074b1e9c726d8742fbb3d1c2804674fd287ad3c2979","src/rust/extensions/mod/Foundation/Numerics/Vector2.rs":"d20b8b59fa2193cb81c8d9ccd7e15c5f7827e7392a35bb9d10af42ab4ccd75ac","src/rust/extensions/mod/Foundation/Numerics/Vector3.rs":"df851b7f059e3f31bf0eb76f0515312a68465b2489a8b68f03bdcddf4b47e693","src/rust/extensions/mod/Foundation/Numerics/Vector4.rs":"f309f3e1e0c34b9db3137f113a3519ac1708aaa1aacb899b4b59f0228497e1a4","src/rust/extensions/mod/Foundation/TimeSpan.rs":"b6de4e26e155771d8ad9e3117e8b33d18f7a4dfc1c2b46ae59b0bad52710ce11","src/rust/extensions/mod/Win32/Foundation/BOOL.rs":"c0aa2937f2d7900347984c99f003705bbd0491c59a7128845bd7bb042a1fadcd","src/rust/extensions/mod/Win32/Foundation/BOOLEAN.rs":"bdf26478e267b6b3ed37ef1e2145830a1f5edfeac12e8743d34e2a52d1bd3c88","src/rust/extensions/mod/Win32/Foundation/NTSTATUS.rs":"ecb817e1454b5ec6c317a50b1cdb54f37cb47e84cee95467d3ee82b4692c9df2","src/rust/extensions/mod/Win32/Foundation/VARIANT_BOOL.rs":"8f5ac697ca6689a1e26bc0134b2738f0ad13c005a6df3552b8020358b2cbc3bf","src/rust/extensions/mod/Win32/Foundation/WIN32_ERROR.rs":"1080d1237593d13b5b2943530462190beb8f9cd572c6458bf9f41b9db4881f88","src/rust/extensions/mod/Win32/Networking/WinSock/IN6_ADDR.rs":"77bfd4761e35c07092389e746553352fae9c265c8362402389c75cfbe0051b4b","src/rust/extensions/mod/Win32/Networking/WinSock/IN_ADDR.rs":"a69b030fb1082d7f6d610ac95c60ec86b6f67cc10181cb2152408003cf1dc95c","src/rust/extensions/mod/Win32/Networking/WinSock/SOCKADDR_IN.rs":"126e342356b0e1244d4c9489c421281215ff7a857b1b234a50c042ac27caf1a7","src/rust/extensions/mod/Win32/Networking/WinSock/SOCKADDR_IN6.rs":"3479563d2ba7cbb94987605a736b1a62f7a0286dc141a11b48969910a9082462","src/rust/extensions/mod/Win32/Networking/WinSock/SOCKADDR_INET.rs":"ebda0e371f36f0fa782ec0c37ad47c19540a20a58e7810570968357f6f54fef9","src/rust/extensions/mod/Win32/UI/WindowsAndMessaging/WindowLong.rs":"fe5e01b7126c9fe7e7d4ee82a4b3f266b0306e1de20a33476b1ba8f3a782533c","src/rust/functions.rs":"e93c63a8a139b7dd9388341e02e55d4d408ec09d7b8792de68bf2586f11bbff3","src/rust/handles.rs":"6692053c69d3f920290b31d849294f52fa939047166053ef3be051770d4b8f03","src/rust/implements.rs":"6612ac69ecb3ffc96a71d2346d9d72aae090592455c4a59e9d18f74ea15cf232","src/rust/interfaces.rs":"34f8e48d4f50a82ac406fee94631923745b34bddde58de9e1922c5b309d87ee2","src/rust/iterators.rs":"3aa84490bbbf9ba2c9eeb824280697ea8e19614a7a4da0b1543ff65b28422505","src/rust/method_names.rs":"f5c5542117d010303e639fea19dda5b8599ad332d79677e0695c68491710036e","src/rust/mod.rs":"f52d52112b00e92705deaf31e64992b1b442f533015a96ea04ce5fb79ead791e","src/rust/standalone.rs":"43c54f1dc3194e700c8b70edca4171acb8b017d14cc3feb03674068da4daa94d","src/rust/structs.rs":"42a38280a4782aa952df4876f300c3d1beea0f60e242d196a9f07e043b41fceb","src/rust/try_format.rs":"a0119eb452fdd1df843b238a0744992743e19163bc9ad62c9fbb04da3dcb3ec0","src/rust/winrt_methods.rs":"44854c2374df66fc09e1e1bce8854113cf38b8f061168c14d9c3cd02dae3d836","src/rust/writer.rs":"f721a1df3d5f71ea151634eb613098f457fa3fe53f1c82d91a553631212ab363","src/tokens/mod.rs":"2f00c61c7f08be37ba5e53c4b96c4db4bbe86730d513b25c28b22aeb57117a53","src/tokens/runtime.rs":"cbbd8834d770511f8c4346e8db9ef11f58ab1ee31f133cae887afcdff6598ad5","src/tokens/to_tokens.rs":"6090765d9778ab2dd5a16060b00ad761c060da80e99c6744fe7908bb064b9386","src/tokens/token_stream.rs":"8a9978b7bfa23300cca2dccde92554abec7c339f17e39cb41118f8698248c374","src/tree.rs":"f05d1e5bed999ba54aaf624825b4f61fce1468881cb17a838f7fab13d6717822","src/winmd/from_reader.rs":"d38996a3857c4c9da1a758ab77ea5ddbf3b5f37c87380cdac0008ba5624f5792","src/winmd/mod.rs":"5f88e31ba385fa8a90cd4cfecb96cf067d8912d9caaab801ec477acf7cc746f1","src/winmd/verify.rs":"883107c18fc8fc07b74e34f28f5ae7d8e0b6486d4da1a927fcdb6a69e866b676","src/winmd/writer/blobs.rs":"fbf45e284dbe59b2d252c6ce35ce0b135f9d515290949d42056f515ffc126e8c","src/winmd/writer/codes.rs":"bb93f065274395b78cb9f1cd1b094e3686a4d5ca7afa623044cd7f1cb7602e71","src/winmd/writer/file.rs":"58c4284e6f023cfffa0d7f3185eb1f31120ad853d5f0d75b6917207fd04cbbdc","src/winmd/writer/mod.rs":"50ba1f5761837373de94f6958acb594f28fc0b2a277e93f24a09e84bc4e77270","src/winmd/writer/strings.rs":"2c440d01a4fab8eb316b844d56add39c39a6c1335f2cc75f47cbef205f678d99","src/winmd/writer/tables.rs":"893785d07352a8d04489aee5a23908a89276c18301dc2a73631afc00dc4aa78b","src/winmd/writer/traits.rs":"679319d78ee2ac30cdd0c197f137674ed8bd855611d88d429ac7fece453a5803","src/winmd/writer/type.rs":"7f5c59f3711454f7044d00dfa3ede17717c1db4d5bbfee432c07e902ddd71428"},"package":"bc1f16b778125675feee0d15d6dd9f6af0e3ac52b3233d63a10aa39230c1cd75"} \ No newline at end of file
diff --git a/vendor/windows-bindgen/Cargo.toml b/vendor/windows-bindgen/Cargo.toml
index 285ac36ad..0997de862 100644
--- a/vendor/windows-bindgen/Cargo.toml
+++ b/vendor/windows-bindgen/Cargo.toml
@@ -10,11 +10,11 @@
# See Cargo.toml.orig for the original contents.
[package]
-edition = "2018"
+edition = "2021"
name = "windows-bindgen"
-version = "0.49.0"
+version = "0.51.1"
authors = ["Microsoft"]
-description = "Code gen support for the windows and windows-sys crates"
+description = "Windows metadata compiler"
readme = "readme.md"
license = "MIT OR Apache-2.0"
repository = "https://github.com/microsoft/windows-rs"
@@ -23,10 +23,23 @@ repository = "https://github.com/microsoft/windows-rs"
default-target = "x86_64-pc-windows-msvc"
targets = []
-[dependencies.metadata]
-version = "0.49.0"
-package = "windows-metadata"
+[dependencies.proc-macro2]
+version = "1.0"
+features = ["span-locations"]
-[dependencies.tokens]
-version = "0.48.0"
-package = "windows-tokens"
+[dependencies.rayon]
+version = "1.7"
+
+[dependencies.syn]
+version = "2.0"
+features = [
+ "full",
+ "extra-traits",
+]
+
+[dependencies.windows-metadata]
+version = "0.51.1"
+
+[features]
+default = ["metadata"]
+metadata = []
diff --git a/vendor/windows-bindgen/default/Windows.Wdk.winmd b/vendor/windows-bindgen/default/Windows.Wdk.winmd
new file mode 100644
index 000000000..2f2e374f7
--- /dev/null
+++ b/vendor/windows-bindgen/default/Windows.Wdk.winmd
Binary files differ
diff --git a/vendor/windows-bindgen/default/Windows.Win32.winmd b/vendor/windows-bindgen/default/Windows.Win32.winmd
new file mode 100644
index 000000000..43087ac76
--- /dev/null
+++ b/vendor/windows-bindgen/default/Windows.Win32.winmd
Binary files differ
diff --git a/vendor/windows-bindgen/default/Windows.winmd b/vendor/windows-bindgen/default/Windows.winmd
new file mode 100644
index 000000000..374a584ec
--- /dev/null
+++ b/vendor/windows-bindgen/default/Windows.winmd
Binary files differ
diff --git a/vendor/windows-bindgen/default/readme.md b/vendor/windows-bindgen/default/readme.md
new file mode 100644
index 000000000..af56b0ec2
--- /dev/null
+++ b/vendor/windows-bindgen/default/readme.md
@@ -0,0 +1,23 @@
+These `.winmd` files provide the default metadata for the Windows API. This is used to
+generate the `windows` and `windows-sys` crates. To view the metadata, use a tool
+like [ILSpy](https://github.com/icsharpcode/ILSpy).
+
+## Windows.Win32.winmd
+- Source: https://www.nuget.org/packages/Microsoft.Windows.SDK.Win32Metadata/
+- Version: 53.0.14
+
+## Windows.Wdk.winmd
+- Source: https://www.nuget.org/packages/Microsoft.Windows.WDK.Win32Metadata/
+- Version: 0.7.3
+
+## Windows.winmd
+- Source: https://www.nuget.org/packages/Microsoft.Windows.SDK.Contracts
+- Version: 10.0.22621.755
+
+The `Windows.winmd` file was created by merging the .winmd files from the last nuget package as follows:
+
+```
+mdmerge -o out -i . -n 1
+```
+
+As with everything else in this repo, the `.winmd` files in this folder are licensed via MIT or Apache-2.0.
diff --git a/vendor/windows-bindgen/readme.md b/vendor/windows-bindgen/readme.md
index 3a54efce8..d1c29da2e 100644
--- a/vendor/windows-bindgen/readme.md
+++ b/vendor/windows-bindgen/readme.md
@@ -1,16 +1,16 @@
## Rust for Windows
-The [windows](https://crates.io/crates/windows) and [windows-sys](https://crates.io/crates/windows-sys) crates let you call any Windows API past, present, and future using code generated on the fly directly from the [metadata describing the API](https://github.com/microsoft/windows-rs/tree/master/crates/libs/metadata/default) and right into your Rust package where you can call them as if they were just another Rust module. The Rust language projection follows in the tradition established by [C++/WinRT](https://github.com/microsoft/cppwinrt) of building language projections for Windows using standard languages and compilers, providing a natural and idiomatic way for Rust developers to call Windows APIs.
+The [windows](https://crates.io/crates/windows) and [windows-sys](https://crates.io/crates/windows-sys) crates let you call any Windows API past, present, and future using code generated on the fly directly from the [metadata describing the API](https://github.com/microsoft/windows-rs/tree/master/crates/libs/bindgen/default) and right into your Rust package where you can call them as if they were just another Rust module. The Rust language projection follows in the tradition established by [C++/WinRT](https://github.com/microsoft/cppwinrt) of building language projections for Windows using standard languages and compilers, providing a natural and idiomatic way for Rust developers to call Windows APIs.
* [Getting started](https://kennykerr.ca/rust-getting-started/)
-* [Samples](https://github.com/microsoft/windows-rs/tree/0.48.0/crates/samples)
+* [Samples](https://github.com/microsoft/windows-rs/tree/0.51.1/crates/samples)
* [Releases](https://github.com/microsoft/windows-rs/releases)
Start by adding the following to your Cargo.toml file:
```toml
[dependencies.windows]
-version = "0.48"
+version = "0.51"
features = [
"Data_Xml_Dom",
"Win32_Foundation",
@@ -38,9 +38,9 @@ fn main() -> Result<()> {
unsafe {
let event = CreateEventW(None, true, false, None)?;
- SetEvent(event).ok()?;
+ SetEvent(event)?;
WaitForSingleObject(event, 0);
- CloseHandle(event).ok()?;
+ CloseHandle(event)?;
MessageBoxA(None, s!("Ansi"), s!("Caption"), MB_OK);
MessageBoxW(None, w!("Wide"), w!("Caption"), MB_OK);
diff --git a/vendor/windows-bindgen/rustfmt.toml b/vendor/windows-bindgen/rustfmt.toml
deleted file mode 100644
index 43d4840c7..000000000
--- a/vendor/windows-bindgen/rustfmt.toml
+++ /dev/null
@@ -1 +0,0 @@
-newline_style = "Unix"
diff --git a/vendor/windows-bindgen/src/args.rs b/vendor/windows-bindgen/src/args.rs
new file mode 100644
index 000000000..74b2c6ed7
--- /dev/null
+++ b/vendor/windows-bindgen/src/args.rs
@@ -0,0 +1,45 @@
+use crate::Result;
+
+pub fn expand<I, S>(args: I) -> Result<Vec<String>>
+where
+ I: IntoIterator<Item = S>,
+ S: AsRef<str>,
+{
+ let mut result = vec![];
+ from_iter(&mut result, args)?;
+ Ok(result)
+}
+
+fn from_string(result: &mut Vec<String>, value: &str) -> Result<()> {
+ let value = if let Some((value, _)) = value.split_once('#') { value } else { value };
+
+ from_iter(result, value.split_whitespace().map(|arg| arg.to_string()))?;
+ Ok(())
+}
+
+fn from_iter<I, S>(result: &mut Vec<String>, args: I) -> Result<()>
+where
+ I: IntoIterator<Item = S>,
+ S: AsRef<str>,
+{
+ let mut expand = false;
+
+ for arg in args.into_iter().map(|arg| arg.as_ref().to_string()) {
+ if arg.starts_with('-') {
+ expand = false;
+ }
+ if expand {
+ for args in crate::read_file_lines(&arg)? {
+ if !args.starts_with("//") {
+ from_string(result, &args)?;
+ }
+ }
+ } else if arg == "--etc" {
+ expand = true;
+ } else {
+ result.push(arg);
+ }
+ }
+
+ Ok(())
+}
diff --git a/vendor/windows-bindgen/src/classes.rs b/vendor/windows-bindgen/src/classes.rs
deleted file mode 100644
index 3cdf50006..000000000
--- a/vendor/windows-bindgen/src/classes.rs
+++ /dev/null
@@ -1,215 +0,0 @@
-use super::*;
-
-pub fn gen(gen: &Gen, def: TypeDef) -> TokenStream {
- if gen.sys {
- if gen.reader.type_def_has_default_interface(def) {
- let name = to_ident(gen.reader.type_def_name(def));
- quote! {
- pub type #name = *mut ::core::ffi::c_void;
- }
- } else {
- quote! {}
- }
- } else {
- gen_class(gen, def)
- }
-}
-
-fn gen_class(gen: &Gen, def: TypeDef) -> TokenStream {
- if gen.reader.type_def_extends(def) == TypeName::Attribute {
- return TokenStream::new();
- }
-
- let name = to_ident(gen.reader.type_def_name(def));
- let interfaces = gen
- .reader
- .type_interfaces(&Type::TypeDef((def, Vec::new())));
- let mut methods = quote! {};
- let mut method_names = MethodNames::new();
-
- let cfg = gen.reader.type_def_cfg(def, &[]);
- let doc = gen.cfg_doc(&cfg);
- let features = gen.cfg_features(&cfg);
-
- for interface in &interfaces {
- if let Type::TypeDef((def, generics)) = &interface.ty {
- let mut virtual_names = MethodNames::new();
-
- for method in gen.reader.type_def_methods(*def) {
- methods.combine(&winrt_methods::gen(
- gen,
- *def,
- generics,
- interface.kind,
- method,
- &mut method_names,
- &mut virtual_names,
- ));
- }
- }
- }
-
- let factories = interfaces.iter().filter_map(|interface| match interface.kind {
- InterfaceKind::Static => {
- if let Type::TypeDef((def, generics)) = &interface.ty {
- if gen.reader.type_def_methods(*def).next().is_some() {
- let interface_type = gen.type_name(&interface.ty);
- let features = gen.cfg_features(&gen.reader.type_def_cfg(*def, generics));
-
- let hidden = if gen.doc {
- quote! { #[doc(hidden)] }
- } else {
- quote! {}
- };
-
- return Some(quote! {
- #hidden
- #features
- pub fn #interface_type<R, F: FnOnce(&#interface_type) -> ::windows::core::Result<R>>(
- callback: F,
- ) -> ::windows::core::Result<R> {
- static SHARED: ::windows::imp::FactoryCache<#name, #interface_type> =
- ::windows::imp::FactoryCache::new();
- SHARED.call(callback)
- }
- });
- }
- }
- None
- }
- _ => None,
- });
-
- if gen.reader.type_def_has_default_interface(def) {
- let new = if gen.reader.type_def_has_default_constructor(def) {
- quote! {
- pub fn new() -> ::windows::core::Result<Self> {
- Self::IActivationFactory(|f| f.ActivateInstance::<Self>())
- }
- fn IActivationFactory<R, F: FnOnce(&::windows::imp::IGenericFactory) -> ::windows::core::Result<R>>(
- callback: F,
- ) -> ::windows::core::Result<R> {
- static SHARED: ::windows::imp::FactoryCache<#name, ::windows::imp::IGenericFactory> =
- ::windows::imp::FactoryCache::new();
- SHARED.call(callback)
- }
- }
- } else {
- quote! {}
- };
-
- let mut tokens = quote! {
- #doc
- #features
- #[repr(transparent)]
- pub struct #name(::windows::core::IUnknown);
- #features
- impl #name {
- #new
- #methods
- #(#factories)*
- }
- };
-
- tokens.combine(&gen.interface_core_traits(
- def,
- &[],
- &name,
- &TokenStream::new(),
- &TokenStream::new(),
- &features,
- ));
- tokens.combine(&gen.interface_winrt_trait(
- def,
- &[],
- &name,
- &TokenStream::new(),
- &TokenStream::new(),
- &features,
- ));
- tokens.combine(&gen.interface_trait(def, &[], &name, &TokenStream::new(), &features, true));
- tokens.combine(&gen.runtime_name_trait(def, &[], &name, &TokenStream::new(), &features));
- tokens.combine(&gen.async_get(
- def,
- &[],
- &name,
- &TokenStream::new(),
- &TokenStream::new(),
- &features,
- ));
- tokens.combine(&iterators::gen(
- gen,
- def,
- &[],
- &name,
- &TokenStream::new(),
- &TokenStream::new(),
- &cfg,
- ));
- tokens.combine(&gen_conversions(gen, def, &name, &interfaces, &cfg));
- tokens.combine(&gen.agile(def, &name, &TokenStream::new(), &features));
- tokens
- } else {
- let mut tokens = quote! {
- #doc
- #features
- pub struct #name;
- #features
- impl #name {
- #methods
- #(#factories)*
- }
- };
-
- tokens.combine(&gen.runtime_name_trait(def, &[], &name, &TokenStream::new(), &features));
- tokens
- }
-}
-
-fn gen_conversions(
- gen: &Gen,
- def: TypeDef,
- name: &TokenStream,
- interfaces: &[Interface],
- cfg: &Cfg,
-) -> TokenStream {
- let features = gen.cfg_features(cfg);
- let mut tokens = quote! {
- #features
- ::windows::imp::interface_hierarchy!(#name, ::windows::core::IUnknown, ::windows::core::IInspectable);
- };
-
- for interface in interfaces {
- if gen.reader.type_is_exclusive(&interface.ty) {
- continue;
- }
-
- if interface.kind != InterfaceKind::Default
- && interface.kind != InterfaceKind::None
- && interface.kind != InterfaceKind::Base
- {
- continue;
- }
-
- let into = gen.type_name(&interface.ty);
- // TODO: simplify - maybe provide + operator?
- let features = gen.cfg_features(&cfg.union(&gen.reader.type_cfg(&interface.ty)));
-
- tokens.combine(&quote! {
- #features
- impl ::windows::core::CanTryInto<#into> for #name {}
- });
- }
-
- for def in gen.reader.type_def_bases(def) {
- let into = gen.type_def_name(def, &[]);
- let features = gen.cfg_features(&cfg.union(&gen.reader.type_def_cfg(def, &[])));
-
- tokens.combine(&quote! {
- #features
- impl ::windows::core::CanTryInto<#into> for #name {}
- });
- }
-
- tokens
-}
diff --git a/vendor/windows-bindgen/src/com_methods.rs b/vendor/windows-bindgen/src/com_methods.rs
deleted file mode 100644
index cb59b9d64..000000000
--- a/vendor/windows-bindgen/src/com_methods.rs
+++ /dev/null
@@ -1,238 +0,0 @@
-use super::*;
-
-pub fn gen(
- gen: &Gen,
- def: TypeDef,
- kind: InterfaceKind,
- method: MethodDef,
- method_names: &mut MethodNames,
- virtual_names: &mut MethodNames,
- base_count: usize,
-) -> TokenStream {
- let signature = gen.reader.method_def_signature(method, &[]);
- let name = method_names.add(gen, method);
- let vname = virtual_names.add(gen, method);
- let generics = gen.constraint_generics(&signature.params);
- let where_clause = gen.where_clause(&signature.params);
- let mut cfg = gen.reader.signature_cfg(&signature);
- cfg.add_feature(gen.reader.type_def_namespace(def));
- let doc = gen.cfg_method_doc(&cfg);
- let features = gen.cfg_features(&cfg);
-
- if kind == InterfaceKind::None {
- return quote! {};
- }
-
- let mut bases = quote! {};
-
- for _ in 0..base_count {
- bases.combine(&quote! { .base__ });
- }
-
- let kind = gen.reader.signature_kind(&signature);
- match kind {
- SignatureKind::Query(_) => {
- let args = gen.win32_args(&signature.params, kind);
- let params = gen.win32_params(&signature.params, kind);
- let generics = expand_generics(generics, quote!(T));
- let where_clause =
- expand_where_clause(where_clause, quote!(T: ::windows::core::ComInterface));
-
- quote! {
- #doc
- #features
- pub unsafe fn #name<#generics>(&self, #params) -> ::windows::core::Result<T> #where_clause {
- let mut result__ = ::std::ptr::null_mut();
- (::windows::core::Interface::vtable(self)#bases.#vname)(::windows::core::Interface::as_raw(self), #args).from_abi(result__)
- }
- }
- }
- SignatureKind::QueryOptional(_) => {
- let args = gen.win32_args(&signature.params, kind);
- let params = gen.win32_params(&signature.params, kind);
- let generics = expand_generics(generics, quote!(T));
- let where_clause =
- expand_where_clause(where_clause, quote!(T: ::windows::core::ComInterface));
-
- quote! {
- #doc
- #features
- pub unsafe fn #name<#generics>(&self, #params result__: *mut ::core::option::Option<T>) -> ::windows::core::Result<()> #where_clause {
- (::windows::core::Interface::vtable(self)#bases.#vname)(::windows::core::Interface::as_raw(self), #args).ok()
- }
- }
- }
- SignatureKind::ResultValue => {
- let args = gen.win32_args(&signature.params, kind);
- let params = gen.win32_params(&signature.params, kind);
- let return_type = signature.params[signature.params.len() - 1].ty.deref();
- let return_type = gen.type_name(&return_type);
-
- quote! {
- #doc
- #features
- pub unsafe fn #name<#generics>(&self, #params) -> ::windows::core::Result<#return_type> #where_clause {
- let mut result__ = ::windows::core::zeroed::<#return_type>();
- (::windows::core::Interface::vtable(self)#bases.#vname)(::windows::core::Interface::as_raw(self), #args).from_abi(result__)
- }
- }
- }
- SignatureKind::ResultVoid => {
- let args = gen.win32_args(&signature.params, kind);
- let params = gen.win32_params(&signature.params, kind);
-
- quote! {
- #doc
- #features
- pub unsafe fn #name<#generics>(&self, #params) -> ::windows::core::Result<()> #where_clause {
- (::windows::core::Interface::vtable(self)#bases.#vname)(::windows::core::Interface::as_raw(self), #args).ok()
- }
- }
- }
- SignatureKind::ReturnValue => {
- let args = gen.win32_args(&signature.params, kind);
- let params = gen.win32_params(&signature.params, kind);
- let return_type = signature.params[signature.params.len() - 1].ty.deref();
- let is_nullable = gen.reader.type_is_nullable(&return_type);
- let return_type = gen.type_name(&return_type);
-
- if is_nullable {
- quote! {
- #doc
- #features
- pub unsafe fn #name<#generics>(&self, #params) -> ::windows::core::Result<#return_type> #where_clause {
- let mut result__ = ::windows::core::zeroed::<#return_type>();
- (::windows::core::Interface::vtable(self)#bases.#vname)(::windows::core::Interface::as_raw(self), #args);
- ::windows::core::from_abi(result__)
- }
- }
- } else {
- quote! {
- #doc
- #features
- pub unsafe fn #name<#generics>(&self, #params) -> #return_type #where_clause {
- let mut result__ = ::windows::core::zeroed::<#return_type>();
- (::windows::core::Interface::vtable(self)#bases.#vname)(::windows::core::Interface::as_raw(self), #args);
- ::std::mem::transmute(result__)
- }
- }
- }
- }
- SignatureKind::ReturnStruct => {
- let args = gen.win32_args(&signature.params, kind);
- let params = gen.win32_params(&signature.params, kind);
- let return_type = gen.type_name(&signature.return_type.unwrap());
-
- quote! {
- #doc
- #features
- pub unsafe fn #name<#generics>(&self, #params) -> #return_type #where_clause {
- let mut result__: #return_type = ::core::mem::zeroed();
- (::windows::core::Interface::vtable(self)#bases.#vname)(::windows::core::Interface::as_raw(self), &mut result__, #args);
- result__
- }
- }
- }
- SignatureKind::PreserveSig => {
- let args = gen.win32_args(&signature.params, kind);
- let params = gen.win32_params(&signature.params, kind);
- let return_type = gen.return_sig(&signature);
-
- quote! {
- #doc
- #features
- pub unsafe fn #name<#generics>(&self, #params) #return_type #where_clause {
- (::windows::core::Interface::vtable(self)#bases.#vname)(::windows::core::Interface::as_raw(self), #args)
- }
- }
- }
- SignatureKind::ReturnVoid => {
- let args = gen.win32_args(&signature.params, kind);
- let params = gen.win32_params(&signature.params, kind);
-
- quote! {
- #doc
- #features
- pub unsafe fn #name<#generics>(&self, #params) #where_clause {
- (::windows::core::Interface::vtable(self)#bases.#vname)(::windows::core::Interface::as_raw(self), #args)
- }
- }
- }
- }
-}
-
-pub fn gen_upcall(gen: &Gen, sig: &Signature, inner: TokenStream) -> TokenStream {
- match gen.reader.signature_kind(sig) {
- SignatureKind::ResultValue => {
- let invoke_args = sig.params[..sig.params.len() - 1]
- .iter()
- .map(|param| gen_win32_invoke_arg(gen, param));
-
- let result = gen.param_name(sig.params[sig.params.len() - 1].def);
-
- quote! {
- match #inner(#(#invoke_args,)*) {
- ::core::result::Result::Ok(ok__) => {
- // use `core::ptr::write` since the result could be uninitialized
- ::core::ptr::write(#result, ::core::mem::transmute(ok__));
- ::windows::core::HRESULT(0)
- }
- ::core::result::Result::Err(err) => err.into()
- }
- }
- }
- SignatureKind::Query(_) | SignatureKind::QueryOptional(_) | SignatureKind::ResultVoid => {
- let invoke_args = sig
- .params
- .iter()
- .map(|param| gen_win32_invoke_arg(gen, param));
-
- quote! {
- #inner(#(#invoke_args,)*).into()
- }
- }
- SignatureKind::ReturnStruct => {
- let invoke_args = sig
- .params
- .iter()
- .map(|param| gen_win32_invoke_arg(gen, param));
-
- quote! {
- *result__ = #inner(#(#invoke_args,)*)
- }
- }
- _ => {
- let invoke_args = sig
- .params
- .iter()
- .map(|param| gen_win32_invoke_arg(gen, param));
-
- quote! {
- #inner(#(#invoke_args,)*)
- }
- }
- }
-}
-
-fn gen_win32_invoke_arg(gen: &Gen, param: &SignatureParam) -> TokenStream {
- let name = gen.param_name(param.def);
-
- if gen
- .reader
- .param_flags(param.def)
- .contains(ParamAttributes::INPUT)
- && gen.reader.type_is_nullable(&param.ty)
- {
- quote! { ::windows::core::from_raw_borrowed(&#name) }
- } else if (!param.ty.is_pointer() && gen.reader.type_is_nullable(&param.ty))
- || (gen
- .reader
- .param_flags(param.def)
- .contains(ParamAttributes::INPUT)
- && !gen.reader.type_is_primitive(&param.ty))
- {
- quote! { ::core::mem::transmute(&#name) }
- } else {
- quote! { ::core::mem::transmute_copy(&#name) }
- }
-}
diff --git a/vendor/windows-bindgen/src/delegates.rs b/vendor/windows-bindgen/src/delegates.rs
deleted file mode 100644
index a68719c81..000000000
--- a/vendor/windows-bindgen/src/delegates.rs
+++ /dev/null
@@ -1,181 +0,0 @@
-use super::*;
-
-pub fn gen(gen: &Gen, def: TypeDef) -> TokenStream {
- if gen
- .reader
- .type_def_flags(def)
- .contains(TypeAttributes::WINRT)
- {
- gen_delegate(gen, def)
- } else {
- gen_callback(gen, def)
- }
-}
-
-fn gen_callback(gen: &Gen, def: TypeDef) -> TokenStream {
- let name = to_ident(gen.reader.type_def_name(def));
-
- let method = gen.reader.type_def_invoke_method(def);
- let signature = gen.reader.method_def_signature(method, &[]);
- let return_type = gen.return_sig(&signature);
- let cfg = gen.reader.type_def_cfg(def, &[]);
- let doc = gen.cfg_doc(&cfg);
- let features = gen.cfg_features(&cfg);
-
- let params = signature.params.iter().map(|p| {
- let name = gen.param_name(p.def);
- let tokens = gen.type_default_name(&p.ty);
- quote! { #name: #tokens }
- });
-
- quote! {
- #doc
- #features
- pub type #name = ::core::option::Option<unsafe extern "system" fn(#(#params),*) #return_type>;
- }
-}
-
-fn gen_delegate(gen: &Gen, def: TypeDef) -> TokenStream {
- if gen.sys {
- let name = to_ident(gen.reader.type_def_name(def));
- quote! {
- pub type #name = *mut ::core::ffi::c_void;
- }
- } else {
- gen_win_delegate(gen, def)
- }
-}
-
-fn gen_win_delegate(gen: &Gen, def: TypeDef) -> TokenStream {
- let name = to_ident(gen.reader.type_def_name(def));
- let vtbl = name.join("_Vtbl");
- let boxed = name.join("Box");
-
- let generics: &Vec<Type> = &gen.reader.type_def_generics(def).collect();
- let phantoms = gen.generic_phantoms(generics);
- let named_phantoms = gen.generic_named_phantoms(generics);
- let constraints = gen.generic_constraints(generics);
- let generic_names = gen.generic_names(generics);
-
- let ident = gen.type_def_name(def, generics);
-
- let method = gen.reader.type_def_invoke_method(def);
- let signature = gen.reader.method_def_signature(method, generics);
- let fn_constraint = gen_fn_constraint(gen, def, &signature);
-
- let cfg = gen.reader.type_def_cfg(def, generics);
- let doc = gen.cfg_doc(&cfg);
- let features = gen.cfg_features(&cfg);
-
- let vtbl_signature = gen.vtbl_signature(def, generics, &signature);
- let invoke = winrt_methods::gen(
- gen,
- def,
- generics,
- InterfaceKind::Default,
- method,
- &mut MethodNames::new(),
- &mut MethodNames::new(),
- );
- let invoke_upcall = winrt_methods::gen_upcall(gen, &signature, quote! { ((*this).invoke) });
-
- let mut tokens = quote! {
- #doc
- #features
- #[repr(transparent)]
- pub struct #ident(pub ::windows::core::IUnknown, #phantoms) where #constraints;
- #features
- impl<#constraints> #ident {
- pub fn new<#fn_constraint>(invoke: F) -> Self {
- let com = #boxed::<#generic_names F> {
- vtable: &#boxed::<#generic_names F>::VTABLE,
- count: ::windows::imp::RefCount::new(1),
- invoke,
- };
- unsafe {
- ::core::mem::transmute(::std::boxed::Box::new(com))
- }
- }
- #invoke
- }
- #features
- #[repr(C)]
- struct #boxed<#generic_names #fn_constraint> where #constraints {
- vtable: *const #vtbl<#generic_names>,
- invoke: F,
- count: ::windows::imp::RefCount,
- }
- #features
- impl<#constraints #fn_constraint> #boxed<#generic_names F> {
- const VTABLE: #vtbl<#generic_names> = #vtbl::<#generic_names>{
- base__: ::windows::core::IUnknown_Vtbl{QueryInterface: Self::QueryInterface, AddRef: Self::AddRef, Release: Self::Release},
- Invoke: Self::Invoke,
- #(#named_phantoms)*
- };
- unsafe extern "system" fn QueryInterface(this: *mut ::core::ffi::c_void, iid: &::windows::core::GUID, interface: *mut *const ::core::ffi::c_void) -> ::windows::core::HRESULT {
- let this = this as *mut *mut ::core::ffi::c_void as *mut Self;
-
- *interface = if iid == &<#ident as ::windows::core::ComInterface>::IID ||
- iid == &<::windows::core::IUnknown as ::windows::core::ComInterface>::IID ||
- iid == &<::windows::imp::IAgileObject as ::windows::core::ComInterface>::IID {
- &mut (*this).vtable as *mut _ as _
- } else {
- ::core::ptr::null_mut()
- };
-
- // TODO: implement IMarshal
-
- if (*interface).is_null() {
- ::windows::core::HRESULT(-2147467262) // E_NOINTERFACE
- } else {
- (*this).count.add_ref();
- ::windows::core::HRESULT(0)
- }
- }
- unsafe extern "system" fn AddRef(this: *mut ::core::ffi::c_void) -> u32 {
- let this = this as *mut *mut ::core::ffi::c_void as *mut Self;
- (*this).count.add_ref()
- }
- unsafe extern "system" fn Release(this: *mut ::core::ffi::c_void) -> u32 {
- let this = this as *mut *mut ::core::ffi::c_void as *mut Self;
- let remaining = (*this).count.release();
-
- if remaining == 0 {
- let _ = ::std::boxed::Box::from_raw(this);
- }
-
- remaining
- }
- unsafe extern "system" fn Invoke #vtbl_signature {
- let this = this as *mut *mut ::core::ffi::c_void as *mut Self;
- #invoke_upcall
- }
- }
- };
-
- tokens.combine(&gen.interface_core_traits(
- def,
- generics,
- &ident,
- &constraints,
- &phantoms,
- &features,
- ));
- tokens.combine(&gen.interface_trait(def, generics, &ident, &constraints, &features, true));
- tokens.combine(&gen.interface_winrt_trait(
- def,
- generics,
- &ident,
- &constraints,
- &phantoms,
- &features,
- ));
- tokens.combine(&gen.interface_vtbl(def, generics, &ident, &constraints, &features));
- tokens
-}
-
-fn gen_fn_constraint(gen: &Gen, def: TypeDef, signature: &Signature) -> TokenStream {
- let signature = gen.impl_signature(def, signature);
-
- quote! { F: FnMut #signature + ::core::marker::Send + 'static }
-}
diff --git a/vendor/windows-bindgen/src/error.rs b/vendor/windows-bindgen/src/error.rs
new file mode 100644
index 000000000..6d783d084
--- /dev/null
+++ b/vendor/windows-bindgen/src/error.rs
@@ -0,0 +1,55 @@
+pub type Result<T> = std::result::Result<T, Error>;
+
+#[derive(Default, Debug)]
+pub struct Error {
+ message: String,
+ path: String,
+ span: Option<(usize, usize)>,
+}
+
+impl std::error::Error for Error {}
+
+impl From<Error> for std::io::Error {
+ fn from(error: Error) -> Self {
+ std::io::Error::new(std::io::ErrorKind::Other, error.message.as_str())
+ }
+}
+
+impl From<syn::Error> for Error {
+ fn from(error: syn::Error) -> Self {
+ let start = error.span().start();
+ Self { message: error.to_string(), span: Some((start.line, start.column)), ..Self::default() }
+ }
+}
+
+impl std::fmt::Display for Error {
+ fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ writeln!(fmt, "error: {}", self.message)?;
+ if !self.path.is_empty() {
+ if let Some((line, column)) = self.span {
+ writeln!(fmt, " --> {}:{line}:{column}", self.path)?;
+ } else {
+ writeln!(fmt, " --> {}", self.path)?;
+ }
+ }
+ Ok(())
+ }
+}
+
+impl Error {
+ pub(crate) fn new(message: &str) -> Self {
+ Self { message: message.to_string(), ..Self::default() }
+ }
+
+ pub(crate) fn with_path(self, path: &str) -> Self {
+ Self { path: path.to_string(), ..self }
+ }
+
+ // pub(crate) fn with_span(self, span: proc_macro2::Span) -> Self {
+ // let start = span.start();
+ // Self {
+ // span: Some((start.line, start.column)),
+ // ..self
+ // }
+ // }
+}
diff --git a/vendor/windows-bindgen/src/extensions/mod.rs b/vendor/windows-bindgen/src/extensions/mod.rs
deleted file mode 100644
index 9b0b6942e..000000000
--- a/vendor/windows-bindgen/src/extensions/mod.rs
+++ /dev/null
@@ -1,57 +0,0 @@
-use super::*;
-
-pub fn gen_mod(gen: &Gen, namespace: &str) -> TokenStream {
- if namespace == "Windows.Win32.UI.WindowsAndMessaging" {
- return include_str!("mod/Win32/UI/WindowsAndMessaging/WindowLong.rs").into();
- }
-
- if gen.sys {
- return "".into();
- }
-
- match namespace {
- "Windows.Foundation.Numerics" => concat!(
- include_str!("mod/Foundation/Numerics/Matrix3x2.rs"),
- include_str!("mod/Foundation/Numerics/Matrix4x4.rs"),
- include_str!("mod/Foundation/Numerics/Vector2.rs"),
- include_str!("mod/Foundation/Numerics/Vector3.rs"),
- include_str!("mod/Foundation/Numerics/Vector4.rs"),
- ),
- "Windows.Foundation" => concat!(
- include_str!("mod/Foundation/IInspectable.rs"),
- include_str!("mod/Foundation/PropertyValue.rs"),
- include_str!("mod/Foundation/TimeSpan.rs"),
- ),
- "Windows.Win32.Foundation" => concat!(
- include_str!("mod/Win32/Foundation/BOOL.rs"),
- include_str!("mod/Win32/Foundation/BOOLEAN.rs"),
- include_str!("mod/Win32/Foundation/NTSTATUS.rs"),
- include_str!("mod/Win32/Foundation/VARIANT_BOOL.rs"),
- include_str!("mod/Win32/Foundation/WIN32_ERROR.rs"),
- ),
- "Windows.Win32.Networking.WinSock" => concat!(
- include_str!("mod/Win32/Networking/WinSock/IN_ADDR.rs"),
- include_str!("mod/Win32/Networking/WinSock/IN6_ADDR.rs"),
- include_str!("mod/Win32/Networking/WinSock/SOCKADDR_IN.rs"),
- include_str!("mod/Win32/Networking/WinSock/SOCKADDR_IN6.rs"),
- include_str!("mod/Win32/Networking/WinSock/SOCKADDR_INET.rs"),
- ),
- "Windows.Win32.UI.WindowsAndMessaging" => {
- include_str!("mod/Win32/UI/WindowsAndMessaging/WindowLong.rs")
- }
- _ => "",
- }
- .into()
-}
-
-pub fn gen_impl(namespace: &str) -> TokenStream {
- match namespace {
- "Windows.Foundation.Collections" => concat!(
- include_str!("impl/Foundation/Collections/Iterable.rs"),
- include_str!("impl/Foundation/Collections/MapView.rs"),
- include_str!("impl/Foundation/Collections/VectorView.rs"),
- ),
- _ => "",
- }
- .into()
-}
diff --git a/vendor/windows-bindgen/src/extensions/mod/Foundation/IInspectable.rs b/vendor/windows-bindgen/src/extensions/mod/Foundation/IInspectable.rs
deleted file mode 100644
index c8ddabdbb..000000000
--- a/vendor/windows-bindgen/src/extensions/mod/Foundation/IInspectable.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-impl std::fmt::Debug for windows::core::IInspectable {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- // Attempts to retrieve the string representation of the object via the
- // IStringable interface. If that fails, it will use the canonical type
- // name to give some idea of what the object represents.
- let name =
- <windows::core::IInspectable as windows::core::ComInterface>::cast::<IStringable>(self)
- .and_then(|s| s.ToString())
- .or_else(|_| self.GetRuntimeClassName())
- .unwrap_or_default();
- write!(f, "\"{}\"", name)
- }
-}
diff --git a/vendor/windows-bindgen/src/extensions/mod/Foundation/PropertyValue.rs b/vendor/windows-bindgen/src/extensions/mod/Foundation/PropertyValue.rs
deleted file mode 100644
index d9a1f113e..000000000
--- a/vendor/windows-bindgen/src/extensions/mod/Foundation/PropertyValue.rs
+++ /dev/null
@@ -1,71 +0,0 @@
-macro_rules! primitive_boxed_type {
- ($(($t:ty, $m:ident)),+) => {
- $(impl std::convert::TryFrom<$t> for windows::core::IInspectable {
- type Error = windows::core::Error;
- fn try_from(value: $t) -> windows::core::Result<Self> {
- PropertyValue::$m(value)
- }
- }
- impl std::convert::TryFrom<windows::core::IInspectable> for $t {
- type Error = windows::core::Error;
- fn try_from(value: windows::core::IInspectable) -> windows::core::Result<Self> {
- <windows::core::IInspectable as windows::core::ComInterface>::cast::<IReference<$t>>(&value)?.Value()
- }
- }
- impl std::convert::TryFrom<&windows::core::IInspectable> for $t {
- type Error = windows::core::Error;
- fn try_from(value: &windows::core::IInspectable) -> windows::core::Result<Self> {
- <windows::core::IInspectable as windows::core::ComInterface>::cast::<IReference<$t>>(value)?.Value()
- }
- })*
- };
-}
-primitive_boxed_type! {
- (bool, CreateBoolean),
- (u8, CreateUInt8),
- (i16, CreateInt16),
- (u16, CreateUInt16),
- (i32, CreateInt32),
- (u32, CreateUInt32),
- (i64, CreateInt64),
- (u64, CreateUInt64),
- (f32, CreateSingle),
- (f64, CreateDouble)
-}
-impl std::convert::TryFrom<&str> for windows::core::IInspectable {
- type Error = windows::core::Error;
- fn try_from(value: &str) -> windows::core::Result<Self> {
- let value: windows::core::HSTRING = value.into();
- PropertyValue::CreateString(&value)
- }
-}
-impl std::convert::TryFrom<windows::core::HSTRING> for windows::core::IInspectable {
- type Error = windows::core::Error;
- fn try_from(value: windows::core::HSTRING) -> windows::core::Result<Self> {
- PropertyValue::CreateString(&value)
- }
-}
-impl std::convert::TryFrom<&windows::core::HSTRING> for windows::core::IInspectable {
- type Error = windows::core::Error;
- fn try_from(value: &windows::core::HSTRING) -> windows::core::Result<Self> {
- PropertyValue::CreateString(value)
- }
-}
-impl std::convert::TryFrom<windows::core::IInspectable> for windows::core::HSTRING {
- type Error = windows::core::Error;
- fn try_from(value: windows::core::IInspectable) -> windows::core::Result<Self> {
- <windows::core::IInspectable as windows::core::ComInterface>::cast::<
- IReference<windows::core::HSTRING>,
- >(&value)?
- .Value()
- }
-}
-impl std::convert::TryFrom<&windows::core::IInspectable> for windows::core::HSTRING {
- type Error = windows::core::Error;
- fn try_from(value: &windows::core::IInspectable) -> windows::core::Result<Self> {
- <windows::core::IInspectable as windows::core::ComInterface>::cast::<
- IReference<windows::core::HSTRING>,
- >(value)?
- .Value()
- }
-}
diff --git a/vendor/windows-bindgen/src/extensions/mod/Win32/Foundation/NTSTATUS.rs b/vendor/windows-bindgen/src/extensions/mod/Win32/Foundation/NTSTATUS.rs
deleted file mode 100644
index 66d77db19..000000000
--- a/vendor/windows-bindgen/src/extensions/mod/Win32/Foundation/NTSTATUS.rs
+++ /dev/null
@@ -1,32 +0,0 @@
-impl NTSTATUS {
- #[inline]
- pub const fn is_ok(self) -> bool {
- self.0 >= 0
- }
- #[inline]
- pub const fn is_err(self) -> bool {
- !self.is_ok()
- }
- #[inline]
- pub const fn to_hresult(self) -> ::windows::core::HRESULT {
- ::windows::core::HRESULT(self.0 | 0x1000_0000)
- }
- #[inline]
- pub const fn ok(self) -> ::windows::core::Result<()> {
- if self.is_ok() {
- Ok(())
- } else {
- Err(::windows::core::Error { code: self.to_hresult(), info: None })
- }
- }
-}
-impl ::core::convert::From<NTSTATUS> for ::windows::core::HRESULT {
- fn from(value: NTSTATUS) -> Self {
- value.to_hresult()
- }
-}
-impl ::core::convert::From<NTSTATUS> for ::windows::core::Error {
- fn from(value: NTSTATUS) -> Self {
- Self { code: value.to_hresult(), info: None }
- }
-}
diff --git a/vendor/windows-bindgen/src/functions.rs b/vendor/windows-bindgen/src/functions.rs
deleted file mode 100644
index f5ec866bb..000000000
--- a/vendor/windows-bindgen/src/functions.rs
+++ /dev/null
@@ -1,285 +0,0 @@
-use super::*;
-
-pub fn gen(gen: &Gen, def: MethodDef) -> TokenStream {
- if gen.sys {
- gen_sys_function(gen, def)
- } else {
- gen_win_function(gen, def)
- }
-}
-
-fn gen_sys_function(gen: &Gen, def: MethodDef) -> TokenStream {
- let signature = gen.reader.method_def_signature(def, &[]);
- let cfg = gen.reader.signature_cfg(&signature);
- let mut tokens = gen.cfg_features(&cfg);
- tokens.combine(&gen_link(gen, &signature, &cfg));
- tokens
-}
-
-fn gen_win_function(gen: &Gen, def: MethodDef) -> TokenStream {
- let name = to_ident(gen.reader.method_def_name(def));
- let signature = gen.reader.method_def_signature(def, &[]);
- let generics = gen.constraint_generics(&signature.params);
- let where_clause = gen.where_clause(&signature.params);
- let abi_return_type = gen.return_sig(&signature);
- let cfg = gen.reader.signature_cfg(&signature);
- let doc = gen.cfg_doc(&cfg);
- let features = gen.cfg_features(&cfg);
- let link = gen_link(gen, &signature, &cfg);
-
- let kind = gen.reader.signature_kind(&signature);
- match kind {
- SignatureKind::Query(_) => {
- let args = gen.win32_args(&signature.params, kind);
- let params = gen.win32_params(&signature.params, kind);
- let generics = expand_generics(generics, quote!(T));
- let where_clause =
- expand_where_clause(where_clause, quote!(T: ::windows::core::ComInterface));
-
- quote! {
- #doc
- #features
- #[inline]
- pub unsafe fn #name<#generics>(#params) -> ::windows::core::Result<T> #where_clause {
- #link
- let mut result__ = ::std::ptr::null_mut();
- #name(#args).from_abi(result__)
- }
- }
- }
- SignatureKind::QueryOptional(_) => {
- let args = gen.win32_args(&signature.params, kind);
- let params = gen.win32_params(&signature.params, kind);
- let generics = expand_generics(generics, quote!(T));
- let where_clause =
- expand_where_clause(where_clause, quote!(T: ::windows::core::ComInterface));
-
- quote! {
- #doc
- #features
- #[inline]
- pub unsafe fn #name<#generics>(#params result__: *mut ::core::option::Option<T>) -> ::windows::core::Result<()> #where_clause {
- #link
- #name(#args).ok()
- }
- }
- }
- SignatureKind::ResultValue => {
- let args = gen.win32_args(&signature.params, kind);
- let params = gen.win32_params(&signature.params, kind);
- let return_type = signature.params[signature.params.len() - 1].ty.deref();
- let return_type = gen.type_name(&return_type);
-
- quote! {
- #doc
- #features
- #[inline]
- pub unsafe fn #name<#generics>(#params) -> ::windows::core::Result<#return_type> #where_clause {
- #link
- let mut result__ = ::windows::core::zeroed::<#return_type>();
- #name(#args).from_abi(result__)
- }
- }
- }
- SignatureKind::ResultVoid => {
- let args = gen.win32_args(&signature.params, kind);
- let params = gen.win32_params(&signature.params, kind);
-
- quote! {
- #doc
- #features
- #[inline]
- pub unsafe fn #name<#generics>(#params) -> ::windows::core::Result<()> #where_clause {
- #link
- #name(#args).ok()
- }
- }
- }
- SignatureKind::ReturnValue => {
- let args = gen.win32_args(&signature.params, kind);
- let params = gen.win32_params(&signature.params, kind);
- let return_type = signature.params[signature.params.len() - 1].ty.deref();
- let is_nullable = gen.reader.type_is_nullable(&return_type);
- let return_type = gen.type_name(&return_type);
-
- if is_nullable {
- quote! {
- #doc
- #features
- #[inline]
- pub unsafe fn #name<#generics>(#params) -> ::windows::core::Result<#return_type> #where_clause {
- #link
- let mut result__ = ::windows::core::zeroed::<#return_type>();
- #name(#args);
- ::windows::core::from_abi(result__.assume_init())
- }
- }
- } else {
- quote! {
- #doc
- #features
- #[inline]
- pub unsafe fn #name<#generics>(#params) -> #return_type #where_clause {
- #link
- let mut result__ = ::windows::core::zeroed::<#return_type>();
- #name(#args);
- ::std::mem::transmute(result__)
- }
- }
- }
- }
- SignatureKind::ReturnStruct | SignatureKind::PreserveSig => {
- if handle_last_error(gen, def, &signature) {
- let args = gen.win32_args(&signature.params, kind);
- let params = gen.win32_params(&signature.params, kind);
- let return_type = gen.type_name(&signature.return_type.unwrap());
-
- quote! {
- #doc
- #features
- #[inline]
- pub unsafe fn #name<#generics>(#params) -> ::windows::core::Result<#return_type> #where_clause {
- #link
- let result__ = #name(#args);
- ::windows::imp::then(!result__.is_invalid(), ||result__).ok_or_else(::windows::core::Error::from_win32)
- }
- }
- } else {
- let args = gen.win32_args(&signature.params, kind);
- let params = gen.win32_params(&signature.params, kind);
-
- quote! {
- #doc
- #features
- #[inline]
- pub unsafe fn #name<#generics>(#params) #abi_return_type #where_clause {
- #link
- #name(#args)
- }
- }
- }
- }
- SignatureKind::ReturnVoid => {
- let args = gen.win32_args(&signature.params, kind);
- let params = gen.win32_params(&signature.params, kind);
- let does_not_return = does_not_return(gen, def);
-
- quote! {
- #doc
- #features
- #[inline]
- pub unsafe fn #name<#generics>(#params) #does_not_return #where_clause {
- #link
- #name(#args)
- }
- }
- }
- }
-}
-
-fn gen_link(gen: &Gen, signature: &Signature, cfg: &Cfg) -> TokenStream {
- let name = gen.reader.method_def_name(signature.def);
- let ident = to_ident(name);
- let library = gen.reader.method_def_module_name(signature.def);
- let abi = gen.reader.method_def_extern_abi(signature.def);
-
- let symbol = if let Some(impl_map) = gen.reader.method_def_impl_map(signature.def) {
- gen.reader.impl_map_import_name(impl_map)
- } else {
- name
- };
-
- let link_name = if symbol != name {
- quote! { #[link_name = #symbol] }
- } else {
- quote! {}
- };
-
- let params = signature.params.iter().map(|p| {
- let name = gen.param_name(p.def);
- let tokens = if p.kind == SignatureParamKind::ValueType {
- gen.type_default_name(&p.ty)
- } else {
- gen.type_abi_name(&p.ty)
- };
- quote! { #name: #tokens }
- });
-
- let return_type = gen.return_sig(signature);
-
- if gen.std || !gen.namespace.starts_with("Windows.") {
- let library = library.trim_end_matches(".dll");
-
- quote! {
- #[link(name = #library)]
- extern #abi {
- #link_name
- pub fn #ident(#(#params),*) #return_type;
- }
- }
- } else if let Some(library) = gen.reader.method_def_static_lib(signature.def) {
- quote! {
- #[link(name = #library, kind = "static")]
- extern #abi {
- #link_name
- pub fn #ident(#(#params),*) #return_type;
- }
- }
- } else {
- let symbol = if symbol != name {
- format!(" \"{symbol}\"")
- } else {
- String::new()
- };
-
- let doc = if gen.sys {
- gen.cfg_doc(cfg).0
- } else {
- String::new()
- };
-
- let mut tokens = String::new();
- for param in params {
- tokens.push_str(&format!("{}, ", param.as_str()));
- }
- let tokens = tokens.trim_end_matches(", ");
- format!(
- r#"::windows_targets::link!("{library}" "{abi}"{symbol}{doc} fn {name}({tokens}){return_type});"#
- )
- .into()
- }
-}
-
-fn does_not_return(gen: &Gen, def: MethodDef) -> TokenStream {
- if gen.reader.method_def_does_not_return(def) {
- quote! { -> ! }
- } else {
- quote! {}
- }
-}
-
-fn handle_last_error(gen: &Gen, def: MethodDef, signature: &Signature) -> bool {
- if let Some(map) = gen.reader.method_def_impl_map(def) {
- if gen
- .reader
- .impl_map_flags(map)
- .contains(PInvokeAttributes::LAST_ERROR)
- {
- if let Some(Type::TypeDef((return_type, _))) = &signature.return_type {
- if gen.reader.type_def_is_handle(*return_type) {
- if gen
- .reader
- .type_def_underlying_type(*return_type)
- .is_pointer()
- {
- return true;
- }
- if !gen.reader.type_def_invalid_values(*return_type).is_empty() {
- return true;
- }
- }
- }
- }
- }
- false
-}
diff --git a/vendor/windows-bindgen/src/interfaces.rs b/vendor/windows-bindgen/src/interfaces.rs
deleted file mode 100644
index 1643e7798..000000000
--- a/vendor/windows-bindgen/src/interfaces.rs
+++ /dev/null
@@ -1,224 +0,0 @@
-use super::*;
-
-pub fn gen(gen: &Gen, def: TypeDef) -> TokenStream {
- if gen.sys {
- gen_sys_interface(gen, def)
- } else {
- gen_win_interface(gen, def)
- }
-}
-
-fn gen_sys_interface(gen: &Gen, def: TypeDef) -> TokenStream {
- let name = gen.reader.type_def_name(def);
- let ident = to_ident(name);
-
- if gen.reader.type_def_is_exclusive(def) {
- quote! {}
- } else {
- quote! {
- pub type #ident = *mut ::core::ffi::c_void;
- }
- }
-}
-
-fn gen_win_interface(gen: &Gen, def: TypeDef) -> TokenStream {
- let generics: &Vec<Type> = &gen.reader.type_def_generics(def).collect();
- let ident = gen.type_def_name(def, generics);
- let is_exclusive = gen.reader.type_def_is_exclusive(def);
- let phantoms = gen.generic_phantoms(generics);
- let constraints = gen.generic_constraints(generics);
- let cfg = gen.reader.type_def_cfg(def, &[]);
- let doc = gen.cfg_doc(&cfg);
- let features = gen.cfg_features(&cfg);
- let interfaces = gen
- .reader
- .type_interfaces(&Type::TypeDef((def, generics.to_vec())));
- let vtables = gen.reader.type_def_vtables(def);
- let has_unknown_base = matches!(vtables.first(), Some(Type::IUnknown));
-
- let mut tokens = if is_exclusive {
- quote! { #[doc(hidden)] }
- } else {
- quote! { #doc }
- };
-
- if has_unknown_base {
- tokens.combine(&quote! {
- #features
- #[repr(transparent)]
- pub struct #ident(::windows::core::IUnknown, #phantoms) where #constraints;
- });
- } else {
- tokens.combine(&quote! {
- #features
- #[repr(transparent)]
- pub struct #ident(::std::ptr::NonNull<::std::ffi::c_void>);
- });
- }
-
- if !is_exclusive {
- let mut methods = quote! {};
- // We need to distinguish between public and virtual methods because some WinRT type hierarchies inherit colliding (overloaded)
- // methods that must be distinguishable.
- let method_names = &mut MethodNames::new();
- let virtual_names = &mut MethodNames::new();
-
- if gen
- .reader
- .type_def_flags(def)
- .contains(TypeAttributes::WINRT)
- {
- for method in gen.reader.type_def_methods(def) {
- methods.combine(&winrt_methods::gen(
- gen,
- def,
- generics,
- InterfaceKind::Default,
- method,
- method_names,
- virtual_names,
- ));
- }
- for interface in &interfaces {
- if let Type::TypeDef((def, generics)) = &interface.ty {
- for method in gen.reader.type_def_methods(*def) {
- methods.combine(&winrt_methods::gen(
- gen,
- *def,
- generics,
- InterfaceKind::None,
- method,
- method_names,
- virtual_names,
- ));
- }
- }
- }
- } else {
- let mut bases = vtables.len();
- for ty in &vtables {
- match ty {
- Type::IUnknown | Type::IInspectable => {}
- Type::TypeDef((def, _)) => {
- let kind = if gen.reader.type_def_type_name(*def) == TypeName::IDispatch {
- InterfaceKind::None
- } else {
- InterfaceKind::Default
- };
- for method in gen.reader.type_def_methods(*def) {
- methods.combine(&com_methods::gen(
- gen,
- *def,
- kind,
- method,
- method_names,
- virtual_names,
- bases,
- ));
- }
- }
- _ => unimplemented!(),
- }
-
- bases -= 1;
- }
- for method in gen.reader.type_def_methods(def) {
- methods.combine(&com_methods::gen(
- gen,
- def,
- InterfaceKind::Default,
- method,
- method_names,
- virtual_names,
- 0,
- ));
- }
- }
-
- tokens.combine(&quote! {
- #features
- impl<#constraints> #ident {
- #methods
- }
- });
-
- if !vtables.is_empty() && generics.is_empty() {
- let mut hierarchy = format!("::windows::imp::interface_hierarchy!({ident}");
- let mut hierarchy_cfg = cfg.clone();
-
- for ty in &vtables {
- let into = gen.type_name(ty);
-
- write!(&mut hierarchy, ", {into}").unwrap();
- hierarchy_cfg = hierarchy_cfg.union(&gen.reader.type_cfg(ty));
- }
-
- hierarchy.push_str(");");
- tokens.combine(&gen.cfg_features(&hierarchy_cfg));
- tokens.push_str(&hierarchy);
- } else {
- for ty in &vtables {
- let into = gen.type_name(ty);
- let cfg = gen.cfg_features(&cfg.union(&gen.reader.type_cfg(ty)));
- tokens.combine(&quote! {
- #cfg
- impl<#constraints> windows::core::CanInto<#into> for #ident {}
- });
- }
- }
-
- if gen
- .reader
- .type_def_flags(def)
- .contains(TypeAttributes::WINRT)
- {
- for interface in &interfaces {
- let into = gen.type_name(&interface.ty);
- let cfg = gen.cfg_features(&cfg.union(&gen.reader.type_cfg(&interface.ty)));
- tokens.combine(&quote! {
- #cfg
- impl<#constraints> windows::core::CanTryInto<#into> for #ident {}
- });
- }
- }
-
- tokens.combine(&gen.interface_core_traits(
- def,
- generics,
- &ident,
- &constraints,
- &phantoms,
- &features,
- ));
- tokens.combine(&gen.interface_winrt_trait(
- def,
- generics,
- &ident,
- &constraints,
- &phantoms,
- &features,
- ));
- tokens.combine(&gen.async_get(def, generics, &ident, &constraints, &phantoms, &features));
- tokens.combine(&iterators::gen(
- gen,
- def,
- generics,
- &ident,
- &constraints,
- &phantoms,
- &cfg,
- ));
- tokens.combine(&gen.agile(def, &ident, &constraints, &features));
- }
-
- tokens.combine(&gen.interface_trait(
- def,
- generics,
- &ident,
- &constraints,
- &features,
- has_unknown_base,
- ));
- tokens.combine(&gen.interface_vtbl(def, generics, &ident, &constraints, &features));
- tokens
-}
diff --git a/vendor/windows-bindgen/src/lib.rs b/vendor/windows-bindgen/src/lib.rs
index 0957a4f64..c9eec0e95 100644
--- a/vendor/windows-bindgen/src/lib.rs
+++ b/vendor/windows-bindgen/src/lib.rs
@@ -1,225 +1,268 @@
-/*!
-Learn more about Rust for Windows here: <https://github.com/microsoft/windows-rs>
-*/
-
-mod classes;
-mod com_methods;
-mod constants;
-mod delegates;
-mod enums;
-mod extensions;
-mod functions;
-mod gen;
-mod handles;
-mod implements;
-mod interfaces;
-mod iterators;
-mod method_names;
-mod standalone;
-mod structs;
-mod try_format;
-mod winrt_methods;
-
-use metadata::reader::*;
-use method_names::*;
-pub use standalone::*;
-use std::collections::*;
-use std::fmt::Write;
-use tokens::*;
-use try_format::*;
-
-#[doc(hidden)]
-pub use gen::*;
-
-#[doc(hidden)]
-pub fn namespace(gen: &Gen, tree: &Tree) -> String {
- let mut tokens = TokenStream::new();
-
- if tree.namespace == "Windows" || !tree.namespace.starts_with("Windows.") {
- tokens.combine(&allow());
- }
-
- for (name, tree) in &tree.nested {
- let name = to_ident(name);
- let namespace = tree.namespace[tree.namespace.find('.').unwrap() + 1..].replace('.', "_");
- if !gen.component {
- tokens.combine(&quote! { #[cfg(feature = #namespace)] });
- }
- tokens.combine(&quote! { pub mod #name; });
- }
+mod args;
+mod error;
+mod metadata;
+mod rdl;
+mod rust;
+mod tokens;
+mod tree;
+mod winmd;
- let mut functions = BTreeMap::<&str, TokenStream>::new();
- let mut types = BTreeMap::<TypeKind, BTreeMap<&str, TokenStream>>::new();
+pub use error::{Error, Result};
+use tree::Tree;
- for method in gen.reader.namespace_functions(tree.namespace) {
- let name = gen.reader.method_def_name(method);
- functions
- .entry(name)
- .or_default()
- .combine(&functions::gen(gen, method));
- }
+enum ArgKind {
+ None,
+ Input,
+ Output,
+ Filter,
+ Config,
+}
- for field in gen.reader.namespace_constants(tree.namespace) {
- let name = gen.reader.field_name(field);
- types
- .entry(TypeKind::Class)
- .or_default()
- .entry(name)
- .or_default()
- .combine(&constants::gen(gen, field));
- }
+pub fn bindgen<I, S>(args: I) -> Result<String>
+where
+ I: IntoIterator<Item = S>,
+ S: AsRef<str>,
+{
+ let time = std::time::Instant::now();
+ let args = args::expand(args)?;
- for def in gen
- .reader
- .namespace_types(tree.namespace, &Default::default())
- {
- let type_name = gen.reader.type_def_type_name(def);
- if REMAP_TYPES.iter().any(|(x, _)| x == &type_name) {
- continue;
- }
- if CORE_TYPES.iter().any(|(x, _)| x == &type_name) {
- continue;
+ let mut kind = ArgKind::None;
+ let mut output = None;
+ let mut input = Vec::<&str>::new();
+ let mut include = Vec::<&str>::new();
+ let mut exclude = Vec::<&str>::new();
+ let mut config = std::collections::BTreeMap::<&str, &str>::new();
+ let mut format = false;
+
+ for arg in &args {
+ if arg.starts_with('-') {
+ kind = ArgKind::None;
}
- let name = type_name.name;
- let kind = gen.reader.type_def_kind(def);
+
match kind {
- TypeKind::Class => {
- if gen
- .reader
- .type_def_flags(def)
- .contains(TypeAttributes::WINRT)
- {
- types
- .entry(kind)
- .or_default()
- .insert(name, classes::gen(gen, def));
+ ArgKind::None => match arg.as_str() {
+ "-i" | "--in" => kind = ArgKind::Input,
+ "-o" | "--out" => kind = ArgKind::Output,
+ "-f" | "--filter" => kind = ArgKind::Filter,
+ "--config" => kind = ArgKind::Config,
+ "--format" => format = true,
+ _ => return Err(Error::new(&format!("invalid option `{arg}`"))),
+ },
+ ArgKind::Output => {
+ if output.is_none() {
+ output = Some(arg.as_str());
+ } else {
+ return Err(Error::new("too many outputs"));
}
}
- TypeKind::Interface => types
- .entry(kind)
- .or_default()
- .entry(name)
- .or_default()
- .combine(&interfaces::gen(gen, def)),
- TypeKind::Enum => types
- .entry(kind)
- .or_default()
- .entry(name)
- .or_default()
- .combine(&enums::gen(gen, def)),
- TypeKind::Struct => {
- if gen.reader.type_def_fields(def).next().is_none() {
- if let Some(guid) = gen.reader.type_def_guid(def) {
- let ident = to_ident(name);
- let value = gen.guid(&guid);
- let guid = gen.type_name(&Type::GUID);
- let cfg = gen.reader.type_def_cfg(def, &[]);
- let doc = gen.cfg_doc(&cfg);
- let constant = quote! {
- #doc
- pub const #ident: #guid = #value;
- };
- types
- .entry(TypeKind::Class)
- .or_default()
- .entry(name)
- .or_default()
- .combine(&constant);
- continue;
- }
+ ArgKind::Input => input.push(arg.as_str()),
+ ArgKind::Filter => {
+ if let Some(rest) = arg.strip_prefix('!') {
+ exclude.push(rest);
+ } else {
+ include.push(arg.as_str());
+ }
+ }
+ ArgKind::Config => {
+ if let Some((key, value)) = arg.split_once('=') {
+ config.insert(key, value);
+ } else {
+ config.insert(arg, "");
}
- types
- .entry(kind)
- .or_default()
- .entry(name)
- .or_default()
- .combine(&structs::gen(gen, def));
}
- TypeKind::Delegate => types
- .entry(kind)
- .or_default()
- .entry(name)
- .or_default()
- .combine(&delegates::gen(gen, def)),
}
}
- for function in functions.values() {
- tokens.combine(function);
+ if format {
+ if output.is_some() || !include.is_empty() || !exclude.is_empty() {
+ return Err(Error::new("`--format` cannot be combined with `--out` or `--filter`"));
+ }
+
+ let input = filter_input(&input, &["rdl"])?;
+
+ if input.is_empty() {
+ return Err(Error::new("no .rdl inputs"));
+ }
+
+ for path in &input {
+ read_file_text(path).and_then(|source| rdl::File::parse_str(&source)).and_then(|file| write_to_file(path, file.fmt())).map_err(|err| err.with_path(path))?;
+ }
+
+ return Ok(String::new());
}
- for ty in types.values().flat_map(|v| v.values()) {
- tokens.combine(ty);
+ let Some(output) = output else {
+ return Err(Error::new("no output"));
+ };
+
+ // This isn't strictly necessary but avoids a common newbie pitfall where all metadata
+ // would be generated when building a component for a specific API.
+ if include.is_empty() {
+ return Err(Error::new("at least one `--filter` must be specified"));
+ }
+
+ let output = canonicalize(output)?;
+
+ let input = read_input(&input)?;
+ let reader = metadata::Reader::new(&input);
+ let filter = metadata::Filter::new(&include, &exclude);
+
+ winmd::verify(&reader, &filter)?;
+
+ match extension(&output) {
+ "rdl" => rdl::from_reader(&reader, &filter, config, &output)?,
+ "winmd" => winmd::from_reader(&reader, &filter, config, &output)?,
+ "rs" => rust::from_reader(&reader, &filter, config, &output)?,
+ _ => return Err(Error::new("output extension must be one of winmd/rdl/rs")),
}
- tokens.combine(&extensions::gen_mod(gen, tree.namespace));
- try_format(tokens.into_string())
+ let elapsed = time.elapsed().as_secs_f32();
+
+ if elapsed > 0.1 {
+ Ok(format!(" Finished writing `{}` in {:.2}s", output, time.elapsed().as_secs_f32()))
+ } else {
+ Ok(format!(" Finished writing `{}`", output,))
+ }
}
-#[doc(hidden)]
-pub fn namespace_impl(gen: &Gen, tree: &Tree) -> String {
- let mut types = BTreeMap::<&str, TokenStream>::new();
-
- for def in gen
- .reader
- .namespace_types(tree.namespace, &Default::default())
- {
- let type_name = gen.reader.type_def_type_name(def);
- if CORE_TYPES.iter().any(|(x, _)| x == &type_name) {
- continue;
+fn filter_input(input: &[&str], extensions: &[&str]) -> Result<Vec<String>> {
+ fn try_push(path: &str, extensions: &[&str], results: &mut Vec<String>) -> Result<()> {
+ // First canonicalize input so that the extension check below will match the case of the path.
+ let path = canonicalize(path)?;
+
+ if extensions.contains(&extension(&path)) {
+ results.push(path);
}
- if gen.reader.type_def_kind(def) != TypeKind::Interface {
- continue;
+
+ Ok(())
+ }
+
+ let mut results = vec![];
+
+ for input in input {
+ let path = std::path::Path::new(input);
+
+ if !path.exists() {
+ return Err(Error::new("failed to read input").with_path(input));
}
- let tokens = implements::gen(gen, def);
- if !tokens.is_empty() {
- types.insert(type_name.name, tokens);
+ if path.is_dir() {
+ for entry in path.read_dir().map_err(|_| Error::new("failed to read directory").with_path(input))?.flatten() {
+ let path = entry.path();
+
+ if path.is_file() {
+ try_push(&path.to_string_lossy(), extensions, &mut results)?;
+ }
+ }
+ } else {
+ try_push(&path.to_string_lossy(), extensions, &mut results)?;
}
}
+ Ok(results)
+}
- let types = types.values();
+fn read_input(input: &[&str]) -> Result<Vec<metadata::File>> {
+ let input = filter_input(input, &["winmd", "rdl"])?;
+ let mut results = vec![];
- let mut tokens = quote! {
- #(#types)*
- };
+ if cfg!(feature = "metadata") {
+ results.push(metadata::File::new(std::include_bytes!("../default/Windows.winmd").to_vec()).unwrap());
+ results.push(metadata::File::new(std::include_bytes!("../default/Windows.Win32.winmd").to_vec()).unwrap());
+ results.push(metadata::File::new(std::include_bytes!("../default/Windows.Wdk.winmd").to_vec()).unwrap());
+ } else if input.is_empty() {
+ return Err(Error::new("no inputs"));
+ }
+
+ for input in &input {
+ let file = if extension(input) == "winmd" { read_winmd_file(input)? } else { read_rdl_file(input)? };
+
+ results.push(file);
+ }
- tokens.combine(&extensions::gen_impl(tree.namespace));
- try_format(tokens.into_string())
+ Ok(results)
}
-/// Generates bindings for a specific component namespace.
-pub fn component(namespace: &str, files: &[File]) -> String {
- let reader = &Reader::new(files);
- let tree = reader.tree(namespace, &Default::default());
- let mut gen = Gen::new(reader);
- gen.namespace = tree.namespace;
- gen.component = true;
- let mut bindings = crate::namespace(&gen, &tree);
- bindings.push_str(&namespace_impl(&gen, &tree));
- try_format(bindings)
+fn read_file_text(path: &str) -> Result<String> {
+ std::fs::read_to_string(path).map_err(|_| Error::new("failed to read text file"))
}
-fn allow() -> TokenStream {
- quote! {
- #![allow(non_snake_case, non_upper_case_globals, non_camel_case_types, dead_code, clippy::all)]
+fn read_file_bytes(path: &str) -> Result<Vec<u8>> {
+ std::fs::read(path).map_err(|_| Error::new("failed to read binary file"))
+}
+
+fn read_file_lines(path: &str) -> Result<Vec<String>> {
+ use std::io::BufRead;
+ fn error(path: &str) -> Error {
+ Error::new("failed to read lines").with_path(path)
}
+ let file = std::io::BufReader::new(std::fs::File::open(path).map_err(|_| error(path))?);
+ let mut lines = vec![];
+ for line in file.lines() {
+ lines.push(line.map_err(|_| error(path))?);
+ }
+ Ok(lines)
}
-/// Expand a possibly empty generics list with a new generic
-fn expand_generics(generics: TokenStream, new: TokenStream) -> TokenStream {
- if generics.is_empty() {
- quote!(#new)
- } else {
- quote!(#generics, #new)
+fn read_rdl_file(path: &str) -> Result<metadata::File> {
+ read_file_text(path)
+ .and_then(|source| rdl::File::parse_str(&source))
+ .and_then(|file| file.into_winmd())
+ .map(|bytes| {
+ // TODO: Write bytes to file if you need to debug the intermediate .winmd file like so:
+ _ = write_to_file("temp.winmd", &bytes);
+
+ // Unwrapping here is fine since `rdl_to_winmd` should have produced a valid winmd
+ metadata::File::new(bytes).unwrap()
+ })
+ .map_err(|err| err.with_path(path))
+}
+
+fn read_winmd_file(path: &str) -> Result<metadata::File> {
+ read_file_bytes(path).and_then(|bytes| metadata::File::new(bytes).ok_or_else(|| Error::new("failed to read .winmd format").with_path(path)))
+}
+
+fn write_to_file<C: AsRef<[u8]>>(path: &str, contents: C) -> Result<()> {
+ if let Some(parent) = std::path::Path::new(path).parent() {
+ std::fs::create_dir_all(parent).map_err(|_| Error::new("failed to create directory").with_path(path))?;
+ }
+
+ std::fs::write(path, contents).map_err(|_| Error::new("failed to write file").with_path(path))
+}
+
+fn canonicalize(value: &str) -> Result<String> {
+ let temp = !std::path::Path::new(value).exists();
+
+ // `std::fs::canonicalize` only works if the file exists so we temporarily create it here.
+ if temp {
+ write_to_file(value, "")?;
+ }
+
+ let path = std::fs::canonicalize(value).map_err(|_| Error::new("failed to find path").with_path(value))?;
+
+ if temp {
+ std::fs::remove_file(value).map_err(|_| Error::new("failed to remove temporary file").with_path(value))?;
+ }
+
+ let path = path.to_string_lossy().trim_start_matches(r"\\?\").to_string();
+
+ match path.rsplit_once('.') {
+ Some((file, extension)) => Ok(format!("{file}.{}", extension.to_lowercase())),
+ _ => Ok(path),
}
}
-/// Expand a possibly emppty where clause with a new generic constraint
-fn expand_where_clause(where_clause: TokenStream, generic: TokenStream) -> TokenStream {
- if where_clause.is_empty() {
- quote!(where #generic)
+fn extension(path: &str) -> &str {
+ path.rsplit_once('.').map_or("", |(_, extension)| extension)
+}
+
+fn directory(path: &str) -> &str {
+ path.rsplit_once(&['/', '\\']).map_or("", |(directory, _)| directory)
+}
+
+fn trim_tick(name: &str) -> &str {
+ if name.as_bytes().iter().rev().nth(1) == Some(&b'`') {
+ &name[..name.len() - 2]
} else {
- quote!(#where_clause #generic)
+ name
}
}
diff --git a/vendor/windows-bindgen/src/metadata/mod.rs b/vendor/windows-bindgen/src/metadata/mod.rs
new file mode 100644
index 000000000..027a282ac
--- /dev/null
+++ b/vendor/windows-bindgen/src/metadata/mod.rs
@@ -0,0 +1,926 @@
+use std::collections::*;
+pub use windows_metadata::*;
+
+#[derive(Clone)]
+pub struct Interface {
+ pub ty: Type,
+ pub kind: InterfaceKind,
+}
+
+#[derive(Copy, Clone, PartialEq, Eq)]
+pub enum InterfaceKind {
+ None,
+ Default,
+ Overridable,
+ Static,
+ Base,
+}
+
+#[derive(Copy, Clone, PartialEq, Eq)]
+pub struct QueryPosition {
+ pub object: usize,
+ pub guid: usize,
+}
+
+#[derive(Copy, Clone, PartialEq, Eq)]
+pub enum SignatureKind {
+ Query(QueryPosition),
+ QueryOptional(QueryPosition),
+ ResultValue,
+ ResultVoid,
+ ReturnStruct,
+ ReturnValue,
+ ReturnVoid,
+ PreserveSig,
+}
+
+#[derive(Copy, Clone, Eq, PartialEq)]
+pub enum SignatureParamKind {
+ ArrayFixed(usize),
+ ArrayRelativeLen(usize),
+ ArrayRelativeByteLen(usize),
+ ArrayRelativePtr(usize),
+ TryInto,
+ IntoParam,
+ OptionalPointer,
+ ValueType,
+ Blittable,
+ Other,
+}
+
+impl SignatureParamKind {
+ fn is_array(&self) -> bool {
+ matches!(self, Self::ArrayFixed(_) | Self::ArrayRelativeLen(_) | Self::ArrayRelativeByteLen(_) | Self::ArrayRelativePtr(_))
+ }
+}
+
+pub struct Signature {
+ pub def: MethodDef,
+ pub params: Vec<SignatureParam>,
+ pub return_type: Type,
+ pub call_flags: MethodCallAttributes,
+}
+
+pub struct SignatureParam {
+ pub def: Param,
+ pub ty: Type,
+ pub kind: SignatureParamKind,
+}
+
+#[derive(PartialEq, Eq, Debug)]
+pub enum AsyncKind {
+ None,
+ Action,
+ ActionWithProgress,
+ Operation,
+ OperationWithProgress,
+}
+
+pub fn type_def_invoke_method(reader: &Reader, row: TypeDef) -> MethodDef {
+ reader.type_def_methods(row).find(|method| reader.method_def_name(*method) == "Invoke").expect("`Invoke` method not found")
+}
+
+pub fn type_def_generics(reader: &Reader, def: TypeDef) -> Vec<Type> {
+ reader.type_def_generics(def).map(Type::GenericParam).collect()
+}
+
+// TODO: namespace should not be required - it's a hack to accomodate Win32 metadata
+// TODO: this is very Rust-specific and Win32-metadata specific with all of its translation. Replace with literal signature parser that just returns slice of types.
+pub fn method_def_signature(reader: &Reader, namespace: &str, row: MethodDef, generics: &[Type]) -> Signature {
+ let mut blob = reader.row_blob(row, 4);
+ let call_flags = MethodCallAttributes(blob.read_usize() as u8);
+ let _param_count = blob.read_usize();
+ let mut return_type = reader.type_from_blob(&mut blob, None, generics);
+
+ let mut params: Vec<SignatureParam> = reader
+ .method_def_params(row)
+ .filter_map(|param| {
+ let param_is_const = reader.has_attribute(param, "ConstAttribute");
+ if reader.param_sequence(param) == 0 {
+ if param_is_const {
+ return_type = return_type.clone().to_const_type();
+ }
+ None
+ } else {
+ let is_output = reader.param_flags(param).contains(ParamAttributes::Out);
+ let mut ty = reader.type_from_blob(&mut blob, None, generics);
+
+ if let Some(name) = param_or_enum(reader, param) {
+ let def = reader.get_type_def(TypeName::new(namespace, &name)).next().expect("Enum not found");
+ ty = Type::PrimitiveOrEnum(Box::new(ty), Box::new(Type::TypeDef(def, Vec::new())));
+ }
+
+ if param_is_const || !is_output {
+ ty = ty.to_const_type();
+ }
+ if !is_output {
+ ty = ty.to_const_ptr();
+ }
+ let kind = param_kind(reader, param);
+ Some(SignatureParam { def: param, ty, kind })
+ }
+ })
+ .collect();
+
+ for position in 0..params.len() {
+ // Point len params back to the corresponding ptr params.
+ match params[position].kind {
+ SignatureParamKind::ArrayRelativeLen(relative) | SignatureParamKind::ArrayRelativeByteLen(relative) => {
+ // The len params must be input only.
+ if !reader.param_flags(params[relative].def).contains(ParamAttributes::Out) && position != relative && !params[relative].ty.is_pointer() {
+ params[relative].kind = SignatureParamKind::ArrayRelativePtr(position);
+ } else {
+ params[position].kind = SignatureParamKind::Other;
+ }
+ }
+ SignatureParamKind::ArrayFixed(_) => {
+ if reader.has_attribute(params[position].def, "FreeWithAttribute") {
+ params[position].kind = SignatureParamKind::Other;
+ }
+ }
+ _ => {}
+ }
+ }
+
+ let mut sets = BTreeMap::<usize, Vec<usize>>::new();
+
+ // Finds sets of ptr params pointing at the same len param.
+ for (position, param) in params.iter().enumerate() {
+ match param.kind {
+ SignatureParamKind::ArrayRelativeLen(relative) | SignatureParamKind::ArrayRelativeByteLen(relative) => {
+ sets.entry(relative).or_default().push(position);
+ }
+ _ => {}
+ }
+ }
+
+ // Remove all sets.
+ for (len, ptrs) in sets {
+ if ptrs.len() > 1 {
+ params[len].kind = SignatureParamKind::Other;
+ for ptr in ptrs {
+ params[ptr].kind = SignatureParamKind::Other;
+ }
+ }
+ }
+
+ // Remove any byte arrays that aren't byte-sized types.
+ for position in 0..params.len() {
+ if let SignatureParamKind::ArrayRelativeByteLen(relative) = params[position].kind {
+ if !params[position].ty.is_byte_size() {
+ params[position].kind = SignatureParamKind::Other;
+ params[relative].kind = SignatureParamKind::Other;
+ }
+ }
+ }
+
+ for param in &mut params {
+ if param.kind == SignatureParamKind::Other {
+ if signature_param_is_convertible(reader, param) {
+ if type_is_non_exclusive_winrt_interface(reader, &param.ty) {
+ param.kind = SignatureParamKind::TryInto;
+ } else {
+ param.kind = SignatureParamKind::IntoParam;
+ }
+ } else {
+ let flags = reader.param_flags(param.def);
+ if param.ty.is_pointer() && (flags.contains(ParamAttributes::Optional) || reader.has_attribute(param.def, "ReservedAttribute")) {
+ param.kind = SignatureParamKind::OptionalPointer;
+ } else if type_is_primitive(reader, &param.ty) && (!param.ty.is_pointer() || type_is_blittable(reader, &param.ty.deref())) {
+ param.kind = SignatureParamKind::ValueType;
+ } else if type_is_blittable(reader, &param.ty) {
+ param.kind = SignatureParamKind::Blittable;
+ }
+ }
+ }
+ }
+
+ Signature { def: row, params, return_type, call_flags }
+}
+
+fn param_kind(reader: &Reader, row: Param) -> SignatureParamKind {
+ for attribute in reader.attributes(row) {
+ match reader.attribute_name(attribute) {
+ "NativeArrayInfoAttribute" => {
+ for (_, value) in reader.attribute_args(attribute) {
+ match value {
+ Value::I16(value) => return SignatureParamKind::ArrayRelativeLen(value as usize),
+ Value::I32(value) => return SignatureParamKind::ArrayFixed(value as usize),
+ _ => {}
+ }
+ }
+ }
+ "MemorySizeAttribute" => {
+ for (_, value) in reader.attribute_args(attribute) {
+ if let Value::I16(value) = value {
+ return SignatureParamKind::ArrayRelativeByteLen(value as usize);
+ }
+ }
+ }
+ _ => {}
+ }
+ }
+ SignatureParamKind::Other
+}
+
+// TODO: this is a terribly broken Win32 metadata attribute - need to get rid of it.
+fn param_or_enum(reader: &Reader, row: Param) -> Option<String> {
+ reader.find_attribute(row, "AssociatedEnumAttribute").and_then(|attribute| {
+ for (_, arg) in reader.attribute_args(attribute) {
+ if let Value::String(name) = arg {
+ return Some(name);
+ }
+ }
+ None
+ })
+}
+
+pub fn signature_param_is_borrowed(reader: &Reader, param: &SignatureParam) -> bool {
+ type_is_borrowed(reader, &param.ty)
+}
+
+pub fn signature_param_is_convertible(reader: &Reader, param: &SignatureParam) -> bool {
+ !reader.param_flags(param.def).contains(ParamAttributes::Out) && !param.ty.is_winrt_array() && !param.ty.is_pointer() && !param.kind.is_array() && (type_is_borrowed(reader, &param.ty) || type_is_non_exclusive_winrt_interface(reader, &param.ty) || type_is_trivially_convertible(reader, &param.ty))
+}
+
+fn signature_param_is_retval(reader: &Reader, param: &SignatureParam) -> bool {
+ // The Win32 metadata uses `RetValAttribute` to call out retval methods but it is employed
+ // very sparingly, so this heuristic is used to apply the transformation more uniformly.
+ if reader.has_attribute(param.def, "RetValAttribute") {
+ return true;
+ }
+ if !param.ty.is_pointer() {
+ return false;
+ }
+ if param.ty.is_void() {
+ return false;
+ }
+ let flags = reader.param_flags(param.def);
+ if flags.contains(ParamAttributes::In) || !flags.contains(ParamAttributes::Out) || flags.contains(ParamAttributes::Optional) || param.kind.is_array() {
+ return false;
+ }
+ if param_kind(reader, param.def).is_array() {
+ return false;
+ }
+ // If it's bigger than 128 bits, best to pass as a reference.
+ if reader.type_size(&param.ty.deref()) > 16 {
+ return false;
+ }
+ // Win32 callbacks are defined as `Option<T>` so we don't include them here to avoid
+ // producing the `Result<Option<T>>` anti-pattern.
+ !type_is_callback(reader, &param.ty.deref())
+}
+
+pub fn signature_kind(reader: &Reader, signature: &Signature) -> SignatureKind {
+ if reader.has_attribute(signature.def, "CanReturnMultipleSuccessValuesAttribute") {
+ return SignatureKind::PreserveSig;
+ }
+ match &signature.return_type {
+ Type::Void if signature_is_retval(reader, signature) => SignatureKind::ReturnValue,
+ Type::Void => SignatureKind::ReturnVoid,
+ Type::HRESULT => {
+ if signature.params.len() >= 2 {
+ if let Some(guid) = signature_param_is_query_guid(reader, &signature.params) {
+ if let Some(object) = signature_param_is_query_object(reader, &signature.params) {
+ if reader.param_flags(signature.params[object].def).contains(ParamAttributes::Optional) {
+ return SignatureKind::QueryOptional(QueryPosition { object, guid });
+ } else {
+ return SignatureKind::Query(QueryPosition { object, guid });
+ }
+ }
+ }
+ }
+ if signature_is_retval(reader, signature) {
+ SignatureKind::ResultValue
+ } else {
+ SignatureKind::ResultVoid
+ }
+ }
+ Type::TypeDef(def, _) if reader.type_def_type_name(*def) == TypeName::NTSTATUS => SignatureKind::ResultVoid,
+ Type::TypeDef(def, _) if reader.type_def_type_name(*def) == TypeName::WIN32_ERROR => SignatureKind::ResultVoid,
+ Type::TypeDef(def, _) if reader.type_def_type_name(*def) == TypeName::BOOL && method_def_last_error(reader, signature.def) => SignatureKind::ResultVoid,
+ _ if type_is_struct(reader, &signature.return_type) => SignatureKind::ReturnStruct,
+ _ => SignatureKind::PreserveSig,
+ }
+}
+
+fn signature_is_retval(reader: &Reader, signature: &Signature) -> bool {
+ signature.params.last().map_or(false, |param| signature_param_is_retval(reader, param))
+ && signature.params[..signature.params.len() - 1].iter().all(|param| {
+ let flags = reader.param_flags(param.def);
+ !flags.contains(ParamAttributes::Out)
+ })
+}
+
+fn signature_param_is_query_guid(reader: &Reader, params: &[SignatureParam]) -> Option<usize> {
+ params.iter().rposition(|param| param.ty == Type::ConstPtr(Box::new(Type::GUID), 1) && !reader.param_flags(param.def).contains(ParamAttributes::Out))
+}
+
+fn signature_param_is_query_object(reader: &Reader, params: &[SignatureParam]) -> Option<usize> {
+ params.iter().rposition(|param| param.ty == Type::MutPtr(Box::new(Type::Void), 2) && reader.has_attribute(param.def, "ComOutPtrAttribute"))
+}
+
+fn method_def_last_error(reader: &Reader, row: MethodDef) -> bool {
+ if let Some(map) = reader.method_def_impl_map(row) {
+ reader.impl_map_flags(map).contains(PInvokeAttributes::SupportsLastError)
+ } else {
+ false
+ }
+}
+
+fn type_is_borrowed(reader: &Reader, ty: &Type) -> bool {
+ match ty {
+ Type::TypeDef(row, _) => !type_def_is_blittable(reader, *row),
+ Type::BSTR | Type::PCSTR | Type::PCWSTR | Type::IInspectable | Type::IUnknown | Type::GenericParam(_) => true,
+ _ => false,
+ }
+}
+
+pub fn type_is_non_exclusive_winrt_interface(reader: &Reader, ty: &Type) -> bool {
+ match ty {
+ Type::TypeDef(row, _) => {
+ let flags = reader.type_def_flags(*row);
+ if !flags.contains(TypeAttributes::WindowsRuntime) {
+ false
+ } else {
+ match reader.type_def_kind(*row) {
+ TypeKind::Interface => !type_def_is_exclusive(reader, *row),
+ TypeKind::Class => reader.has_attribute(*row, "ComposableAttribute"),
+ _ => false,
+ }
+ }
+ }
+ _ => false,
+ }
+}
+
+fn type_is_trivially_convertible(reader: &Reader, ty: &Type) -> bool {
+ match ty {
+ Type::TypeDef(row, _) => match reader.type_def_kind(*row) {
+ TypeKind::Struct => type_def_is_handle(reader, *row),
+ _ => false,
+ },
+ Type::PCSTR | Type::PCWSTR => true,
+ _ => false,
+ }
+}
+
+fn type_is_callback(reader: &Reader, ty: &Type) -> bool {
+ match ty {
+ Type::TypeDef(row, _) => type_def_is_callback(reader, *row),
+ _ => false,
+ }
+}
+
+fn type_def_is_callback(reader: &Reader, row: TypeDef) -> bool {
+ !reader.type_def_flags(row).contains(TypeAttributes::WindowsRuntime) && reader.type_def_kind(row) == TypeKind::Delegate
+}
+
+pub fn type_has_callback(reader: &Reader, ty: &Type) -> bool {
+ match ty {
+ Type::TypeDef(row, _) => type_def_has_callback(reader, *row),
+ Type::Win32Array(ty, _) => type_has_callback(reader, ty),
+ _ => false,
+ }
+}
+pub fn type_def_has_callback(reader: &Reader, row: TypeDef) -> bool {
+ if type_def_is_callback(reader, row) {
+ return true;
+ }
+ if reader.type_def_kind(row) != TypeKind::Struct {
+ return false;
+ }
+ fn check(reader: &Reader, row: TypeDef) -> bool {
+ if reader.type_def_fields(row).any(|field| type_has_callback(reader, &reader.field_type(field, Some(row)))) {
+ return true;
+ }
+ false
+ }
+ let type_name = reader.type_def_type_name(row);
+ if type_name.namespace.is_empty() {
+ check(reader, row)
+ } else {
+ for row in reader.get_type_def(type_name) {
+ if check(reader, row) {
+ return true;
+ }
+ }
+ false
+ }
+}
+
+pub fn type_interfaces(reader: &Reader, ty: &Type) -> Vec<Interface> {
+ // TODO: collect into btree map and then return collected vec
+ // This will both sort the results and should make finding dupes faster
+ fn walk(reader: &Reader, result: &mut Vec<Interface>, parent: &Type, is_base: bool) {
+ if let Type::TypeDef(row, generics) = parent {
+ for imp in reader.type_def_interface_impls(*row) {
+ let mut child = Interface {
+ ty: reader.interface_impl_type(imp, generics),
+ kind: if reader.has_attribute(imp, "DefaultAttribute") { InterfaceKind::Default } else { InterfaceKind::None },
+ };
+
+ child.kind = if !is_base && child.kind == InterfaceKind::Default {
+ InterfaceKind::Default
+ } else if child.kind == InterfaceKind::Overridable {
+ continue;
+ } else if is_base {
+ InterfaceKind::Base
+ } else {
+ InterfaceKind::None
+ };
+ let mut found = false;
+ for existing in result.iter_mut() {
+ if existing.ty == child.ty {
+ found = true;
+ if child.kind == InterfaceKind::Default {
+ existing.kind = child.kind
+ }
+ }
+ }
+ if !found {
+ walk(reader, result, &child.ty, is_base);
+ result.push(child);
+ }
+ }
+ }
+ }
+ let mut result = Vec::new();
+ walk(reader, &mut result, ty, false);
+ if let Type::TypeDef(row, _) = ty {
+ if reader.type_def_kind(*row) == TypeKind::Class {
+ for base in type_def_bases(reader, *row) {
+ walk(reader, &mut result, &Type::TypeDef(base, Vec::new()), true);
+ }
+ for attribute in reader.attributes(*row) {
+ match reader.attribute_name(attribute) {
+ "StaticAttribute" | "ActivatableAttribute" => {
+ for (_, arg) in reader.attribute_args(attribute) {
+ if let Value::TypeName(type_name) = arg {
+ let def = reader.get_type_def(TypeName::parse(&type_name)).next().expect("Type not found");
+ result.push(Interface { ty: Type::TypeDef(def, Vec::new()), kind: InterfaceKind::Static });
+ break;
+ }
+ }
+ }
+ _ => {}
+ }
+ }
+ }
+ }
+ result.sort_by(|a, b| type_name(reader, &a.ty).cmp(type_name(reader, &b.ty)));
+ result
+}
+
+fn type_name<'a>(reader: &Reader<'a>, ty: &Type) -> &'a str {
+ match ty {
+ Type::TypeDef(row, _) => reader.type_def_name(*row),
+ _ => "",
+ }
+}
+
+pub fn type_def_async_kind(reader: &Reader, row: TypeDef) -> AsyncKind {
+ match reader.type_def_type_name(row) {
+ TypeName::IAsyncAction => AsyncKind::Action,
+ TypeName::IAsyncActionWithProgress => AsyncKind::ActionWithProgress,
+ TypeName::IAsyncOperation => AsyncKind::Operation,
+ TypeName::IAsyncOperationWithProgress => AsyncKind::OperationWithProgress,
+ _ => AsyncKind::None,
+ }
+}
+
+pub fn field_is_blittable(reader: &Reader, row: Field, enclosing: TypeDef) -> bool {
+ type_is_blittable(reader, &reader.field_type(row, Some(enclosing)))
+}
+
+pub fn field_is_copyable(reader: &Reader, row: Field, enclosing: TypeDef) -> bool {
+ type_is_copyable(reader, &reader.field_type(row, Some(enclosing)))
+}
+
+pub fn field_guid(reader: &Reader, row: Field) -> Option<GUID> {
+ reader.find_attribute(row, "GuidAttribute").map(|attribute| GUID::from_args(&reader.attribute_args(attribute)))
+}
+
+pub fn field_is_ansi(reader: &Reader, row: Field) -> bool {
+ reader.find_attribute(row, "NativeEncodingAttribute").is_some_and(|attribute| matches!(reader.attribute_args(attribute).get(0), Some((_, Value::String(encoding))) if encoding == "ansi"))
+}
+
+pub fn type_is_blittable(reader: &Reader, ty: &Type) -> bool {
+ match ty {
+ Type::TypeDef(row, _) => type_def_is_blittable(reader, *row),
+ Type::String | Type::BSTR | Type::IInspectable | Type::IUnknown | Type::GenericParam(_) => false,
+ Type::Win32Array(kind, _) => type_is_blittable(reader, kind),
+ Type::WinrtArray(kind) => type_is_blittable(reader, kind),
+ _ => true,
+ }
+}
+
+fn type_is_copyable(reader: &Reader, ty: &Type) -> bool {
+ match ty {
+ Type::TypeDef(row, _) => type_def_is_copyable(reader, *row),
+ Type::String | Type::BSTR | Type::IInspectable | Type::IUnknown | Type::GenericParam(_) => false,
+ Type::Win32Array(kind, _) => type_is_copyable(reader, kind),
+ Type::WinrtArray(kind) => type_is_copyable(reader, kind),
+ _ => true,
+ }
+}
+
+pub fn type_def_is_blittable(reader: &Reader, row: TypeDef) -> bool {
+ match reader.type_def_kind(row) {
+ TypeKind::Struct => {
+ if reader.type_def_flags(row).contains(TypeAttributes::WindowsRuntime) {
+ reader.type_def_fields(row).all(|field| field_is_blittable(reader, field, row))
+ } else {
+ true
+ }
+ }
+ TypeKind::Enum => true,
+ TypeKind::Delegate => !reader.type_def_flags(row).contains(TypeAttributes::WindowsRuntime),
+ _ => false,
+ }
+}
+
+pub fn type_def_is_copyable(reader: &Reader, row: TypeDef) -> bool {
+ match reader.type_def_kind(row) {
+ TypeKind::Struct => reader.type_def_fields(row).all(|field| field_is_copyable(reader, field, row)),
+ TypeKind::Enum => true,
+ TypeKind::Delegate => !reader.type_def_flags(row).contains(TypeAttributes::WindowsRuntime),
+ _ => false,
+ }
+}
+
+pub fn method_def_special_name(reader: &Reader, row: MethodDef) -> String {
+ let name = reader.method_def_name(row);
+ if reader.method_def_flags(row).contains(MethodAttributes::SpecialName) {
+ if name.starts_with("get") {
+ name[4..].to_string()
+ } else if name.starts_with("put") {
+ format!("Set{}", &name[4..])
+ } else if name.starts_with("add") {
+ name[4..].to_string()
+ } else if name.starts_with("remove") {
+ format!("Remove{}", &name[7..])
+ } else {
+ name.to_string()
+ }
+ } else {
+ if let Some(attribute) = reader.find_attribute(row, "OverloadAttribute") {
+ for (_, arg) in reader.attribute_args(attribute) {
+ if let Value::String(name) = arg {
+ return name;
+ }
+ }
+ }
+ name.to_string()
+ }
+}
+
+pub fn method_def_static_lib(reader: &Reader, row: MethodDef) -> Option<String> {
+ reader.find_attribute(row, "StaticLibraryAttribute").and_then(|attribute| {
+ let args = reader.attribute_args(attribute);
+ if let Value::String(value) = &args[0].1 {
+ return Some(value.clone());
+ }
+ None
+ })
+}
+
+pub fn method_def_extern_abi(reader: &Reader, def: MethodDef) -> &'static str {
+ let impl_map = reader.method_def_impl_map(def).expect("ImplMap not found");
+ let flags = reader.impl_map_flags(impl_map);
+
+ if flags.contains(PInvokeAttributes::CallConvPlatformapi) {
+ "system"
+ } else if flags.contains(PInvokeAttributes::CallConvCdecl) {
+ "cdecl"
+ } else {
+ unimplemented!()
+ }
+}
+
+pub fn type_def_has_default_constructor(reader: &Reader, row: TypeDef) -> bool {
+ for attribute in reader.attributes(row) {
+ if reader.attribute_name(attribute) == "ActivatableAttribute" {
+ if reader.attribute_args(attribute).iter().any(|arg| matches!(arg.1, Value::TypeName(_))) {
+ continue;
+ } else {
+ return true;
+ }
+ }
+ }
+ false
+}
+
+pub fn type_def_has_default_interface(reader: &Reader, row: TypeDef) -> bool {
+ reader.type_def_interface_impls(row).any(|imp| reader.has_attribute(imp, "DefaultAttribute"))
+}
+
+pub fn type_def_is_exclusive(reader: &Reader, row: TypeDef) -> bool {
+ reader.has_attribute(row, "ExclusiveToAttribute")
+}
+
+pub fn type_is_exclusive(reader: &Reader, ty: &Type) -> bool {
+ match ty {
+ Type::TypeDef(row, _) => type_def_is_exclusive(reader, *row),
+ _ => false,
+ }
+}
+
+pub fn type_is_struct(reader: &Reader, ty: &Type) -> bool {
+ // This check is used to detect virtual functions that return C-style PODs that affect how the stack is packed for x86.
+ // It could be defined as a struct with more than one field but that check is complicated as it would have to detect
+ // nested structs. Fortunately, this is rare enough that this check is sufficient.
+ match ty {
+ Type::TypeDef(row, _) => reader.type_def_kind(*row) == TypeKind::Struct && !type_def_is_handle(reader, *row),
+ Type::GUID => true,
+ _ => false,
+ }
+}
+
+fn type_def_is_primitive(reader: &Reader, row: TypeDef) -> bool {
+ match reader.type_def_kind(row) {
+ TypeKind::Enum => true,
+ TypeKind::Struct => type_def_is_handle(reader, row),
+ TypeKind::Delegate => !reader.type_def_flags(row).contains(TypeAttributes::WindowsRuntime),
+ _ => false,
+ }
+}
+
+pub fn type_is_primitive(reader: &Reader, ty: &Type) -> bool {
+ match ty {
+ Type::TypeDef(row, _) => type_def_is_primitive(reader, *row),
+ Type::Bool | Type::Char | Type::I8 | Type::U8 | Type::I16 | Type::U16 | Type::I32 | Type::U32 | Type::I64 | Type::U64 | Type::F32 | Type::F64 | Type::ISize | Type::USize | Type::HRESULT | Type::ConstPtr(_, _) | Type::MutPtr(_, _) => true,
+ _ => false,
+ }
+}
+
+fn type_has_explicit_layout(reader: &Reader, ty: &Type) -> bool {
+ match ty {
+ Type::TypeDef(row, _) => type_def_has_explicit_layout(reader, *row),
+ Type::Win32Array(ty, _) => type_has_explicit_layout(reader, ty),
+ _ => false,
+ }
+}
+
+pub fn type_def_has_explicit_layout(reader: &Reader, row: TypeDef) -> bool {
+ if reader.type_def_kind(row) != TypeKind::Struct {
+ return false;
+ }
+ fn check(reader: &Reader, row: TypeDef) -> bool {
+ if reader.type_def_flags(row).contains(TypeAttributes::ExplicitLayout) {
+ return true;
+ }
+ if reader.type_def_fields(row).any(|field| type_has_explicit_layout(reader, &reader.field_type(field, Some(row)))) {
+ return true;
+ }
+ false
+ }
+ let type_name = reader.type_def_type_name(row);
+ if type_name.namespace.is_empty() {
+ check(reader, row)
+ } else {
+ for row in reader.get_type_def(type_name) {
+ if check(reader, row) {
+ return true;
+ }
+ }
+ false
+ }
+}
+
+fn type_has_packing(reader: &Reader, ty: &Type) -> bool {
+ match ty {
+ Type::TypeDef(row, _) => type_def_has_packing(reader, *row),
+ Type::Win32Array(ty, _) => type_has_packing(reader, ty),
+ _ => false,
+ }
+}
+
+pub fn type_def_has_packing(reader: &Reader, row: TypeDef) -> bool {
+ if reader.type_def_kind(row) != TypeKind::Struct {
+ return false;
+ }
+ fn check(reader: &Reader, row: TypeDef) -> bool {
+ if reader.type_def_class_layout(row).is_some() {
+ return true;
+ }
+ if reader.type_def_fields(row).any(|field| type_has_packing(reader, &reader.field_type(field, Some(row)))) {
+ return true;
+ }
+ false
+ }
+ let type_name = reader.type_def_type_name(row);
+ if type_name.namespace.is_empty() {
+ check(reader, row)
+ } else {
+ for row in reader.get_type_def(type_name) {
+ if check(reader, row) {
+ return true;
+ }
+ }
+ false
+ }
+}
+
+pub fn type_def_default_interface(reader: &Reader, row: TypeDef) -> Option<Type> {
+ reader.type_def_interface_impls(row).find_map(move |row| if reader.has_attribute(row, "DefaultAttribute") { Some(reader.interface_impl_type(row, &[])) } else { None })
+}
+
+fn type_signature(reader: &Reader, ty: &Type) -> String {
+ match ty {
+ Type::Bool => "b1".to_string(),
+ Type::Char => "c2".to_string(),
+ Type::I8 => "i1".to_string(),
+ Type::U8 => "u1".to_string(),
+ Type::I16 => "i2".to_string(),
+ Type::U16 => "u2".to_string(),
+ Type::I32 => "i4".to_string(),
+ Type::U32 => "u4".to_string(),
+ Type::I64 => "i8".to_string(),
+ Type::U64 => "u8".to_string(),
+ Type::F32 => "f4".to_string(),
+ Type::F64 => "f8".to_string(),
+ Type::ISize => "is".to_string(),
+ Type::USize => "us".to_string(),
+ Type::String => "string".to_string(),
+ Type::IInspectable => "cinterface(IInspectable)".to_string(),
+ Type::GUID => "g16".to_string(),
+ Type::HRESULT => "struct(Windows.Foundation.HResult;i4)".to_string(),
+ Type::TypeDef(row, generics) => type_def_signature(reader, *row, generics),
+ rest => unimplemented!("{rest:?}"),
+ }
+}
+
+pub fn type_def_signature(reader: &Reader, row: TypeDef, generics: &[Type]) -> String {
+ match reader.type_def_kind(row) {
+ TypeKind::Interface => type_def_interface_signature(reader, row, generics),
+ TypeKind::Class => {
+ if let Some(Type::TypeDef(default, generics)) = type_def_default_interface(reader, row) {
+ format!("rc({};{})", reader.type_def_type_name(row), type_def_interface_signature(reader, default, &generics))
+ } else {
+ unimplemented!();
+ }
+ }
+ TypeKind::Enum => format!("enum({};{})", reader.type_def_type_name(row), type_signature(reader, &reader.type_def_underlying_type(row))),
+ TypeKind::Struct => {
+ let mut result = format!("struct({}", reader.type_def_type_name(row));
+ for field in reader.type_def_fields(row) {
+ result.push(';');
+ result.push_str(&type_signature(reader, &reader.field_type(field, Some(row))));
+ }
+ result.push(')');
+ result
+ }
+ TypeKind::Delegate => {
+ if generics.is_empty() {
+ format!("delegate({})", type_def_interface_signature(reader, row, generics))
+ } else {
+ type_def_interface_signature(reader, row, generics)
+ }
+ }
+ }
+}
+
+fn type_def_interface_signature(reader: &Reader, row: TypeDef, generics: &[Type]) -> String {
+ let guid = type_def_guid(reader, row).unwrap();
+ if generics.is_empty() {
+ format!("{{{guid:#?}}}")
+ } else {
+ let mut result = format!("pinterface({{{guid:#?}}}");
+ for generic in generics {
+ result.push(';');
+ result.push_str(&type_signature(reader, generic));
+ }
+ result.push(')');
+ result
+ }
+}
+
+pub fn type_def_is_handle(reader: &Reader, row: TypeDef) -> bool {
+ reader.has_attribute(row, "NativeTypedefAttribute")
+}
+
+pub fn type_has_replacement(reader: &Reader, ty: &Type) -> bool {
+ match ty {
+ Type::HRESULT | Type::PCSTR | Type::PCWSTR => true,
+ Type::TypeDef(row, _) => type_def_is_handle(reader, *row) || reader.type_def_kind(*row) == TypeKind::Enum,
+ _ => false,
+ }
+}
+
+pub fn type_def_guid(reader: &Reader, row: TypeDef) -> Option<GUID> {
+ reader.find_attribute(row, "GuidAttribute").map(|attribute| GUID::from_args(&reader.attribute_args(attribute)))
+}
+
+pub fn type_def_bases(reader: &Reader, mut row: TypeDef) -> Vec<TypeDef> {
+ let mut bases = Vec::new();
+ loop {
+ match reader.type_def_extends(row) {
+ Some(base) if base != TypeName::Object => {
+ row = reader.get_type_def(base).next().expect("Type not found");
+ bases.push(row);
+ }
+ _ => break,
+ }
+ }
+ bases
+}
+
+pub fn type_def_is_agile(reader: &Reader, row: TypeDef) -> bool {
+ for attribute in reader.attributes(row) {
+ match reader.attribute_name(attribute) {
+ "AgileAttribute" => return true,
+ "MarshalingBehaviorAttribute" => {
+ if let Some((_, Value::EnumDef(_, value))) = reader.attribute_args(attribute).get(0) {
+ if let Value::I32(2) = **value {
+ return true;
+ }
+ }
+ }
+ _ => {}
+ }
+ }
+ matches!(reader.type_def_type_name(row), TypeName::IAsyncAction | TypeName::IAsyncActionWithProgress | TypeName::IAsyncOperation | TypeName::IAsyncOperationWithProgress)
+}
+
+pub fn type_def_invalid_values(reader: &Reader, row: TypeDef) -> Vec<i64> {
+ let mut values = Vec::new();
+ for attribute in reader.attributes(row) {
+ if reader.attribute_name(attribute) == "InvalidHandleValueAttribute" {
+ if let Some((_, Value::I64(value))) = reader.attribute_args(attribute).get(0) {
+ values.push(*value);
+ }
+ }
+ }
+ values
+}
+
+pub fn type_def_usable_for(reader: &Reader, row: TypeDef) -> Option<TypeDef> {
+ if let Some(attribute) = reader.find_attribute(row, "AlsoUsableForAttribute") {
+ if let Some((_, Value::String(name))) = reader.attribute_args(attribute).get(0) {
+ return reader.get_type_def(TypeName::new(reader.type_def_namespace(row), name.as_str())).next();
+ }
+ }
+ None
+}
+
+fn type_def_is_nullable(reader: &Reader, row: TypeDef) -> bool {
+ match reader.type_def_kind(row) {
+ TypeKind::Interface | TypeKind::Class => true,
+ // Win32 callbacks are defined as `Option<T>` so we don't include them here to avoid them
+ // from being doubly wrapped in `Option`.
+ TypeKind::Delegate => reader.type_def_flags(row).contains(TypeAttributes::WindowsRuntime),
+ _ => false,
+ }
+}
+
+pub fn type_is_nullable(reader: &Reader, ty: &Type) -> bool {
+ match ty {
+ Type::TypeDef(row, _) => type_def_is_nullable(reader, *row),
+ Type::IInspectable | Type::IUnknown => true,
+ _ => false,
+ }
+}
+
+pub fn type_def_vtables(reader: &Reader, row: TypeDef) -> Vec<Type> {
+ let mut result = Vec::new();
+ if reader.type_def_flags(row).contains(TypeAttributes::WindowsRuntime) {
+ result.push(Type::IUnknown);
+ if reader.type_def_kind(row) != TypeKind::Delegate {
+ result.push(Type::IInspectable);
+ }
+ } else {
+ let mut next = row;
+ while let Some(base) = type_def_interfaces(reader, next, &[]).next() {
+ match base {
+ Type::TypeDef(row, _) => {
+ next = row;
+ result.insert(0, base);
+ }
+ Type::IInspectable => {
+ result.insert(0, Type::IUnknown);
+ result.insert(1, Type::IInspectable);
+ break;
+ }
+ Type::IUnknown => {
+ result.insert(0, Type::IUnknown);
+ break;
+ }
+ rest => unimplemented!("{rest:?}"),
+ }
+ }
+ }
+ result
+}
+
+pub fn type_def_interfaces<'a>(reader: &'a Reader<'a>, row: TypeDef, generics: &'a [Type]) -> impl Iterator<Item = Type> + 'a {
+ reader.type_def_interface_impls(row).map(move |row| reader.interface_impl_type(row, generics))
+}
+
+pub fn type_underlying_type(reader: &Reader, ty: &Type) -> Type {
+ match ty {
+ Type::TypeDef(row, _) => reader.type_def_underlying_type(*row),
+ Type::HRESULT => Type::I32,
+ _ => ty.clone(),
+ }
+}
diff --git a/vendor/windows-bindgen/src/method_names.rs b/vendor/windows-bindgen/src/method_names.rs
deleted file mode 100644
index 9f5dad1c6..000000000
--- a/vendor/windows-bindgen/src/method_names.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-use super::*;
-
-pub struct MethodNames(BTreeMap<String, u32>);
-
-impl MethodNames {
- pub fn new() -> Self {
- Self(BTreeMap::new())
- }
-
- pub fn add(&mut self, gen: &Gen, method: MethodDef) -> TokenStream {
- let name = gen.reader.method_def_special_name(method);
- let overload = self.0.entry(name.to_string()).or_insert(0);
- *overload += 1;
- if *overload > 1 {
- format!("{name}{overload}").into()
- } else {
- to_ident(&name)
- }
- }
-
- pub fn add_vtable_types(&mut self, gen: &Gen, def: TypeDef) {
- for def in gen.reader.type_def_vtables(def) {
- if let Type::TypeDef((def, _)) = def {
- for method in gen.reader.type_def_methods(def) {
- self.add(gen, method);
- }
- }
- }
- }
-}
diff --git a/vendor/windows-bindgen/src/rdl/fmt.rs b/vendor/windows-bindgen/src/rdl/fmt.rs
new file mode 100644
index 000000000..8b2df36aa
--- /dev/null
+++ b/vendor/windows-bindgen/src/rdl/fmt.rs
@@ -0,0 +1,454 @@
+use super::*;
+
+// TODO: should we use rustfmt in the short term (with pre/post)
+
+#[derive(Default)]
+pub struct Writer {
+ out: String,
+ indent: usize,
+ newline: bool,
+}
+
+impl Writer {
+ pub fn new(file: &rdl::File) -> Self {
+ let mut writer = Self::default();
+ writer.rdl_file(file);
+ writer
+ }
+
+ pub fn into_string(mut self) -> String {
+ self.out.push('\n');
+ self.out
+ }
+
+ fn word(&mut self, value: &str) {
+ if self.newline {
+ self.newline = false;
+ self.out.push('\n');
+ for _ in 0..self.indent {
+ self.out.push_str(" ");
+ }
+ }
+
+ self.out.push_str(value);
+ }
+
+ fn newline(&mut self) {
+ self.newline = true;
+ }
+
+ fn rdl_file(&mut self, file: &rdl::File) {
+ if file.winrt {
+ self.word("#![winrt]\n");
+ } else {
+ self.word("#![win32]\n");
+ }
+
+ self.newline();
+
+ for reference in &file.references {
+ self.item_use(reference);
+ }
+
+ for module in &file.modules {
+ self.rdl_module(module);
+ }
+ }
+
+ fn rdl_module(&mut self, module: &rdl::Module) {
+ self.word("mod ");
+ self.word(module.name());
+ self.word(" {");
+ self.newline();
+ self.indent += 1;
+
+ for member in &module.members {
+ self.rdl_module_member(member);
+ self.newline();
+ }
+
+ self.indent -= 1;
+ self.newline();
+ self.word("}");
+ self.newline();
+ }
+
+ fn rdl_module_member(&mut self, member: &rdl::ModuleMember) {
+ match member {
+ rdl::ModuleMember::Module(member) => self.rdl_module(member),
+ rdl::ModuleMember::Interface(member) => self.rdl_interface(member),
+ rdl::ModuleMember::Struct(member) => self.rdl_struct(member),
+ rdl::ModuleMember::Enum(member) => self.rdl_enum(member),
+ rdl::ModuleMember::Class(member) => self.rdl_class(member),
+ rdl::ModuleMember::Constant(member) => self.rdl_constant(member),
+ rdl::ModuleMember::Function(member) => self.rdl_function(member),
+ }
+ }
+
+ fn rdl_class(&mut self, member: &rdl::Class) {
+ self.attrs(&member.attributes);
+ self.word("class ");
+ self.word(&member.name);
+
+ if !member.extends.is_empty() || member.base.is_some() {
+ self.word(" : ");
+
+ if let Some(path) = &member.base {
+ self.word("class ");
+ self.type_path(path);
+
+ if !member.extends.is_empty() {
+ self.word(", ");
+ }
+ }
+
+ let mut first = true;
+ for path in &member.extends {
+ if first {
+ first = false;
+ } else {
+ self.word(", ");
+ }
+ self.type_path(path);
+ }
+ }
+
+ self.word(";");
+ self.newline();
+ }
+
+ fn rdl_interface(&mut self, member: &rdl::Interface) {
+ self.attrs(&member.attributes);
+ self.word("interface ");
+ self.word(&member.name);
+
+ if !member.generics.is_empty() {
+ self.word("<");
+
+ let mut first = true;
+ for generic in &member.generics {
+ if first {
+ first = false;
+ } else {
+ self.word(", ");
+ }
+ self.word(generic);
+ }
+
+ self.word(">");
+ }
+
+ if !member.extends.is_empty() {
+ self.word(" : ");
+
+ let mut first = true;
+ for path in &member.extends {
+ if first {
+ first = false;
+ } else {
+ self.word(", ");
+ }
+ self.type_path(path);
+ }
+ }
+
+ self.word(" {");
+ self.newline();
+ self.indent += 1;
+
+ for method in &member.methods {
+ self.trait_item_fn(method);
+ self.word(";");
+ self.newline();
+ }
+
+ self.indent -= 1;
+ self.newline();
+ self.word("}");
+ }
+
+ fn rdl_constant(&mut self, member: &rdl::Constant) {
+ self.item_const(&member.item);
+ }
+
+ fn rdl_function(&mut self, member: &rdl::Function) {
+ self.trait_item_fn(&member.item);
+ self.word(";");
+ self.newline();
+ }
+
+ fn item_const(&mut self, item: &syn::ItemConst) {
+ self.word("const ");
+ self.ident(&item.ident);
+ self.word(": ");
+ self.ty(&item.ty);
+ self.word(" = ");
+ self.expr(&item.expr);
+ self.word(";");
+ self.newline();
+ }
+
+ fn attrs(&mut self, attrs: &[syn::Attribute]) {
+ for attr in attrs {
+ self.attr(attr);
+ }
+ }
+
+ fn attr(&mut self, attr: &syn::Attribute) {
+ self.word("#[");
+ self.meta(&attr.meta);
+ self.word("]");
+ self.newline();
+ }
+
+ fn meta(&mut self, meta: &syn::Meta) {
+ match meta {
+ syn::Meta::Path(path) => self.path(path),
+ syn::Meta::List(list) => self.meta_list(list),
+ syn::Meta::NameValue(meta) => self.meta_name_value(meta),
+ }
+ }
+
+ fn meta_list(&mut self, meta_list: &syn::MetaList) {
+ self.path(&meta_list.path);
+ self.word("(");
+ self.word(&meta_list.tokens.to_string());
+ self.word(")");
+ }
+
+ fn meta_name_value(&mut self, meta: &syn::MetaNameValue) {
+ self.path(&meta.path);
+ self.word(" = ");
+ self.expr(&meta.value);
+ }
+
+ fn rdl_struct(&mut self, member: &rdl::Struct) {
+ self.attrs(&member.attributes);
+
+ self.word("struct ");
+ self.word(&member.name);
+ self.word(" {");
+ self.newline();
+ self.indent += 1;
+
+ for field in &member.fields {
+ self.word(&field.name);
+ self.word(": ");
+ self.ty(&field.ty);
+ self.word(",");
+ self.newline();
+ }
+
+ self.indent -= 1;
+ self.newline();
+ self.word("}");
+ }
+
+ fn rdl_enum(&mut self, member: &rdl::Enum) {
+ self.attrs(&member.item.attrs);
+
+ self.word("enum ");
+ self.ident(&member.item.ident);
+ self.word(" {");
+ self.newline();
+ self.indent += 1;
+
+ for variant in &member.item.variants {
+ self.ident(&variant.ident);
+ if let Some((_, expr)) = &variant.discriminant {
+ self.word(" = ");
+ self.expr(expr);
+ }
+ self.word(",");
+ self.newline();
+ }
+
+ self.indent -= 1;
+ self.newline();
+ self.word("}");
+ }
+
+ fn trait_item_fn(&mut self, method: &syn::TraitItemFn) {
+ self.attrs(&method.attrs);
+ self.signature(&method.sig);
+ }
+
+ fn signature(&mut self, signature: &syn::Signature) {
+ self.word("fn ");
+ self.ident(&signature.ident);
+ self.word("(");
+
+ let mut first = true;
+ for input in &signature.inputs {
+ if first {
+ first = false;
+ } else {
+ self.word(", ");
+ }
+ self.fn_arg(input);
+ }
+
+ self.word(")");
+
+ if let syn::ReturnType::Type(_, ty) = &signature.output {
+ self.word(" -> ");
+ self.ty(ty);
+ }
+ }
+
+ fn fn_arg(&mut self, fn_arg: &syn::FnArg) {
+ if let syn::FnArg::Typed(pat_type) = fn_arg {
+ self.pat_type(pat_type);
+ }
+ }
+
+ fn pat_type(&mut self, pat_type: &syn::PatType) {
+ self.pat(&pat_type.pat);
+ self.word(": ");
+ self.ty(&pat_type.ty);
+ }
+
+ fn pat(&mut self, pat: &syn::Pat) {
+ match pat {
+ syn::Pat::Ident(pat_ident) => self.pat_ident(pat_ident),
+ rest => unimplemented!("{rest:?}"),
+ }
+ }
+
+ fn pat_ident(&mut self, pat_ident: &syn::PatIdent) {
+ self.ident(&pat_ident.ident);
+ }
+
+ fn ty(&mut self, ty: &syn::Type) {
+ match ty {
+ syn::Type::Path(ty) => self.type_path(ty),
+ syn::Type::Ptr(ptr) => self.type_ptr(ptr),
+ syn::Type::Array(array) => self.type_array(array),
+ rest => unimplemented!("{rest:?}"),
+ }
+ }
+
+ fn type_array(&mut self, array: &syn::TypeArray) {
+ self.word("[");
+ self.ty(&array.elem);
+ self.word("; ");
+ self.expr(&array.len);
+ self.word("]");
+ }
+
+ fn expr(&mut self, expr: &syn::Expr) {
+ match expr {
+ syn::Expr::Lit(lit) => self.expr_lit(lit),
+ syn::Expr::Unary(unary) => self.expr_unary(unary),
+ rest => unimplemented!("{rest:?}"),
+ }
+ }
+
+ fn expr_unary(&mut self, unary: &syn::ExprUnary) {
+ self.word("-");
+ self.expr(&unary.expr);
+ }
+
+ fn expr_lit(&mut self, expr: &syn::ExprLit) {
+ self.lit(&expr.lit);
+ }
+
+ fn lit(&mut self, lit: &syn::Lit) {
+ match lit {
+ syn::Lit::Int(lit) => self.lit_int(lit),
+ syn::Lit::Str(lit) => self.lit_str(lit),
+ _ => _ = dbg!(lit),
+ }
+ }
+
+ fn lit_str(&mut self, lit: &syn::LitStr) {
+ self.word("\"");
+ self.word(&lit.value());
+ self.word("\"");
+ }
+
+ fn lit_int(&mut self, lit: &syn::LitInt) {
+ self.word(&lit.token().to_string());
+ }
+
+ fn type_ptr(&mut self, ptr: &syn::TypePtr) {
+ if ptr.mutability.is_some() {
+ self.word("*mut ");
+ } else {
+ self.word("*const ");
+ }
+ self.ty(&ptr.elem);
+ }
+
+ fn type_path(&mut self, ty: &syn::TypePath) {
+ self.path(&ty.path);
+ }
+
+ fn path(&mut self, path: &syn::Path) {
+ let mut first = true;
+ for segment in &path.segments {
+ if first {
+ first = false;
+ } else {
+ self.word("::");
+ }
+ self.path_segment(segment);
+ }
+ }
+
+ pub fn path_segment(&mut self, segment: &syn::PathSegment) {
+ self.ident(&segment.ident);
+
+ if let syn::PathArguments::AngleBracketed(args) = &segment.arguments {
+ self.word("<");
+
+ let mut first = true;
+ for arg in &args.args {
+ if first {
+ first = false;
+ } else {
+ self.word(", ");
+ }
+ self.generic_argument(arg);
+ }
+
+ self.word(">");
+ }
+ }
+
+ fn generic_argument(&mut self, arg: &syn::GenericArgument) {
+ match arg {
+ syn::GenericArgument::Type(ty) => self.ty(ty),
+ rest => unimplemented!("{rest:?}"),
+ }
+ }
+
+ fn item_use(&mut self, item: &syn::ItemUse) {
+ self.word("use ");
+ self.use_tree(&item.tree);
+ self.word(";");
+ self.newline();
+ }
+
+ fn use_tree(&mut self, use_tree: &syn::UseTree) {
+ match use_tree {
+ syn::UseTree::Path(use_path) => self.use_path(use_path),
+ syn::UseTree::Name(use_name) => self.use_name(use_name),
+ _ => {}
+ }
+ }
+
+ fn use_path(&mut self, use_path: &syn::UsePath) {
+ self.ident(&use_path.ident);
+ self.word("::");
+ self.use_tree(&use_path.tree);
+ }
+
+ fn use_name(&mut self, use_name: &syn::UseName) {
+ self.ident(&use_name.ident);
+ }
+
+ pub fn ident(&mut self, ident: &syn::Ident) {
+ self.word(&ident.to_string());
+ }
+}
diff --git a/vendor/windows-bindgen/src/rdl/from_reader.rs b/vendor/windows-bindgen/src/rdl/from_reader.rs
new file mode 100644
index 000000000..136430a9a
--- /dev/null
+++ b/vendor/windows-bindgen/src/rdl/from_reader.rs
@@ -0,0 +1,435 @@
+use super::*;
+use crate::tokens::{quote, to_ident, TokenStream};
+use crate::{rdl, Error, Result, Tree};
+use metadata::RowReader;
+
+pub fn from_reader(reader: &metadata::Reader, filter: &metadata::Filter, mut config: std::collections::BTreeMap<&str, &str>, output: &str) -> Result<()> {
+ let dialect = match config.remove("type") {
+ Some("winrt") => Dialect::WinRT,
+ Some("win32") => Dialect::Win32,
+ _ => return Err(Error::new("configuration value `type` must be `win32` or `winrt`")),
+ };
+
+ let mut writer = Writer::new(reader, filter, output, dialect);
+
+ // TODO: be sure to use the same "split" key for winmd splitting.
+ // May also want to support split=N similar to the way MIDLRT supports winmd splitting
+ // at different nesting levels.
+ writer.split = config.remove("split").is_some();
+
+ if let Some((key, _)) = config.first_key_value() {
+ return Err(Error::new(&format!("invalid configuration value `{key}`")));
+ }
+
+ if writer.split {
+ gen_split(&writer)
+ } else {
+ gen_file(&writer)
+ }
+}
+
+fn gen_split(writer: &Writer) -> Result<()> {
+ let tree = Tree::new(writer.reader, writer.filter);
+ let directory = crate::directory(writer.output);
+
+ // TODO: parallelize
+ for tree in tree.flatten() {
+ let tokens = writer.tree(tree);
+
+ if !tokens.is_empty() {
+ let output = format!("{directory}/{}.rdl", tree.namespace);
+ writer.write_to_file(&output, tokens)?;
+ }
+ }
+
+ Ok(())
+}
+
+fn gen_file(writer: &Writer) -> Result<()> {
+ let tree = Tree::new(writer.reader, writer.filter);
+ let tokens = writer.tree(&tree);
+ writer.write_to_file(writer.output, tokens)
+}
+
+#[derive(Debug, Copy, Clone, PartialEq)]
+enum Dialect {
+ Win32,
+ WinRT,
+}
+
+struct Writer<'a> {
+ reader: &'a metadata::Reader<'a>,
+ filter: &'a metadata::Filter<'a>,
+ namespace: &'a str,
+ dialect: Dialect,
+ split: bool,
+ output: &'a str,
+}
+
+impl<'a> Writer<'a> {
+ fn new(reader: &'a metadata::Reader, filter: &'a metadata::Filter, output: &'a str, dialect: Dialect) -> Self {
+ Self { reader, filter, namespace: "", output, dialect, split: false }
+ }
+
+ fn with_namespace(&self, namespace: &'a str) -> Self {
+ Self { reader: self.reader, filter: self.filter, namespace, dialect: self.dialect, output: self.output, split: self.split }
+ }
+
+ fn write_to_file(&self, output: &str, tokens: TokenStream) -> Result<()> {
+ let dialect = match self.dialect {
+ Dialect::Win32 => quote! { #![win32] },
+ Dialect::WinRT => quote! { #![winrt] },
+ };
+
+ let tokens = quote! {
+ #dialect
+ #tokens
+ };
+
+ let file = rdl::File::parse_str(&tokens.into_string())?;
+ crate::write_to_file(output, file.fmt())
+ //crate::write_to_file(output, tokens.into_string())
+ }
+
+ fn tree(&self, tree: &'a Tree) -> TokenStream {
+ let items = self.items(tree);
+
+ if self.split {
+ let mut tokens = items;
+
+ if !tokens.is_empty() {
+ for name in tree.namespace.rsplit('.').map(to_ident) {
+ tokens = quote! {
+ mod #name {
+ #tokens
+ }
+ };
+ }
+ }
+
+ tokens
+ } else {
+ let name = to_ident(tree.namespace.rsplit_once('.').map_or(tree.namespace, |(_, name)| name));
+
+ let modules = tree.nested.values().map(|tree| self.with_namespace(tree.namespace).tree(tree));
+
+ if tree.namespace.is_empty() {
+ quote! {
+ #(#modules)*
+ #items
+ }
+ } else {
+ quote! {
+ mod #name {
+ #(#modules)*
+ #items
+ }
+ }
+ }
+ }
+ }
+
+ fn items(&self, tree: &'a Tree) -> TokenStream {
+ let mut functions = vec![];
+ let mut constants = vec![];
+ let mut types = vec![];
+
+ if !tree.namespace.is_empty() {
+ for item in self.reader.namespace_items(tree.namespace, self.filter).filter(|item| match item {
+ metadata::Item::Type(def) => {
+ let winrt = self.reader.type_def_flags(*def).contains(metadata::TypeAttributes::WindowsRuntime);
+ match self.dialect {
+ Dialect::Win32 => !winrt,
+ Dialect::WinRT => winrt,
+ }
+ }
+ metadata::Item::Fn(_, _) | metadata::Item::Const(_) => self.dialect == Dialect::Win32,
+ }) {
+ match item {
+ metadata::Item::Type(def) => types.push(self.type_def(def)),
+ metadata::Item::Const(field) => constants.push(self.constant(field)),
+ metadata::Item::Fn(method, namespace) => functions.push(self.function(method, &namespace)),
+ }
+ }
+ }
+
+ quote! {
+ #(#functions)*
+ #(#constants)*
+ #(#types)*
+ }
+ }
+
+ fn function(&self, def: metadata::MethodDef, _namespace: &str) -> TokenStream {
+ let name = to_ident(self.reader.method_def_name(def));
+ quote! { fn #name(); }
+ }
+
+ fn constant(&self, def: metadata::Field) -> TokenStream {
+ let name = to_ident(self.reader.field_name(def));
+ quote! { const #name: i32 = 0; }
+ }
+
+ fn type_def(&self, def: metadata::TypeDef) -> TokenStream {
+ if let Some(extends) = self.reader.type_def_extends(def) {
+ if extends.namespace == "System" {
+ if extends.name == "Enum" {
+ self.enum_def(def)
+ } else if extends.name == "ValueType" {
+ self.struct_def(def)
+ } else if extends.name == "MulticastDelegate" {
+ self.delegate_def(def)
+ } else {
+ self.class_def(def)
+ }
+ } else {
+ self.class_def(def)
+ }
+ } else {
+ self.interface_def(def)
+ }
+ }
+
+ fn enum_def(&self, def: metadata::TypeDef) -> TokenStream {
+ let name = to_ident(self.reader.type_def_name(def));
+
+ quote! {
+ struct #name {
+
+ }
+ }
+ }
+
+ fn struct_def(&self, def: metadata::TypeDef) -> TokenStream {
+ let name = to_ident(self.reader.type_def_name(def));
+
+ let fields = self.reader.type_def_fields(def).map(|field| {
+ let name = to_ident(self.reader.field_name(field));
+ let ty = self.ty(&self.reader.field_type(field, Some(def)));
+ quote! {
+ #name: #ty
+ }
+ });
+
+ quote! {
+ struct #name {
+ #(#fields),*
+ }
+ }
+ }
+
+ fn delegate_def(&self, def: metadata::TypeDef) -> TokenStream {
+ let name = to_ident(self.reader.type_def_name(def));
+
+ quote! {
+ struct #name {
+
+ }
+ }
+ }
+
+ fn class_def(&self, def: metadata::TypeDef) -> TokenStream {
+ let name = to_ident(self.reader.type_def_name(def));
+ let implements = self.implements(def, &[]);
+
+ quote! {
+ class #name #implements;
+ }
+ }
+
+ fn interface_def(&self, def: metadata::TypeDef) -> TokenStream {
+ let name = to_ident(self.reader.type_def_name(def));
+ let generics = &metadata::type_def_generics(self.reader, def);
+ let implements = self.implements(def, generics);
+
+ let methods = self.reader.type_def_methods(def).map(|method| {
+ let name = to_ident(self.reader.method_def_name(method));
+
+ // TODO: use reader.method_def_signature instead
+ let signature = metadata::method_def_signature(self.reader, self.reader.type_def_namespace(def), method, generics);
+
+ let return_type = self.return_type(&signature.return_type);
+
+ let params = signature.params.iter().map(|param| {
+ let name = to_ident(self.reader.param_name(param.def));
+ let ty = self.ty(&param.ty);
+ quote! { #name: #ty }
+ });
+
+ quote! {
+ fn #name(#(#params),*) #return_type;
+ }
+ });
+
+ let generics = self.generics(generics);
+
+ quote! {
+ interface #name #generics #implements {
+ #(#methods)*
+ }
+ }
+ }
+
+ fn generics(&self, generics: &[metadata::Type]) -> TokenStream {
+ if generics.is_empty() {
+ quote! {}
+ } else {
+ let generics = generics.iter().map(|generic| self.ty(generic));
+
+ quote! { <#(#generics),*>}
+ }
+ }
+
+ fn implements(&self, def: metadata::TypeDef, generics: &[metadata::Type]) -> TokenStream {
+ let mut types = Vec::<TokenStream>::new();
+
+ // TODO: if a winrt composable class then start with base
+ // TODO: then list default interface first
+ // Then everything else
+
+ for imp in self.reader.type_def_interface_impls(def) {
+ let ty = self.reader.interface_impl_type(imp, generics);
+ if self.reader.has_attribute(imp, "DefaultAttribute") {
+ types.insert(0, self.ty(&ty));
+ } else {
+ types.push(self.ty(&ty));
+ }
+ }
+
+ if let Some(type_name) = self.reader.type_def_extends(def) {
+ if type_name != metadata::TypeName::Object {
+ let namespace = self.namespace(type_name.namespace);
+ let name = to_ident(type_name.name);
+ // TODO: ideally the "class" contextual keyword wouldn't be needed here
+ // but currently there's no way to tell the base class apart from a required interface.
+ types.insert(0, quote! { class #namespace #name });
+ }
+ }
+
+ if types.is_empty() {
+ quote! {}
+ } else {
+ quote! { : #(#types),* }
+ }
+ }
+
+ fn return_type(&self, ty: &metadata::Type) -> TokenStream {
+ match ty {
+ metadata::Type::Void => quote! {},
+ _ => {
+ let ty = self.ty(ty);
+ quote! { -> #ty }
+ }
+ }
+ }
+
+ fn ty(&self, ty: &metadata::Type) -> TokenStream {
+ match ty {
+ metadata::Type::Void => quote! { ::core::ffi::c_void },
+ metadata::Type::Bool => quote! { bool },
+ metadata::Type::Char => quote! { u16 },
+ metadata::Type::I8 => quote! { i8 },
+ metadata::Type::U8 => quote! { u8 },
+ metadata::Type::I16 => quote! { i16 },
+ metadata::Type::U16 => quote! { u16 },
+ metadata::Type::I32 => quote! { i32 },
+ metadata::Type::U32 => quote! { u32 },
+ metadata::Type::I64 => quote! { i64 },
+ metadata::Type::U64 => quote! { u64 },
+ metadata::Type::F32 => quote! { f32 },
+ metadata::Type::F64 => quote! { f64 },
+ metadata::Type::ISize => quote! { isize },
+ metadata::Type::USize => quote! { usize },
+
+ // TODO: dialect-specific keywords for "well-known types" that don't map to metadata in all cases.
+ metadata::Type::String => quote! { HSTRING },
+ metadata::Type::HRESULT => quote! { HRESULT },
+ metadata::Type::GUID => quote! { GUID },
+ metadata::Type::IInspectable => quote! { IInspectable },
+ metadata::Type::IUnknown => quote! { IUnknown },
+
+ metadata::Type::TypeDef(def, generics) => {
+ let namespace = self.namespace(self.reader.type_def_namespace(*def));
+ let name = to_ident(self.reader.type_def_name(*def));
+ if generics.is_empty() {
+ quote! { #namespace #name }
+ } else {
+ let generics = generics.iter().map(|ty| self.ty(ty));
+ quote! { #namespace #name<#(#generics,)*> }
+ }
+ }
+
+ metadata::Type::TypeRef(code) => {
+ let type_name = self.reader.type_def_or_ref(*code);
+ let namespace = self.namespace(type_name.namespace);
+ let name = to_ident(type_name.name);
+ quote! { #namespace #name }
+ }
+
+ metadata::Type::GenericParam(generic) => self.reader.generic_param_name(*generic).into(),
+ metadata::Type::WinrtArray(ty) => self.ty(ty),
+ metadata::Type::WinrtArrayRef(ty) => self.ty(ty),
+ metadata::Type::ConstRef(ty) => self.ty(ty),
+ metadata::Type::MutPtr(ty, _pointers) => self.ty(ty),
+ metadata::Type::ConstPtr(ty, _pointers) => self.ty(ty),
+ metadata::Type::Win32Array(ty, _len) => self.ty(ty),
+ // TODO: these types should just be regular metadata type defs
+ metadata::Type::PSTR => quote! { PSTR },
+ metadata::Type::PWSTR => quote! { PWSTR },
+ metadata::Type::PCSTR => quote! { PCSTR },
+ metadata::Type::PCWSTR => quote! { PCWSTR },
+ metadata::Type::BSTR => quote! { BSTR },
+ metadata::Type::PrimitiveOrEnum(_, ty) => self.ty(ty),
+ rest => unimplemented!("{rest:?}"),
+ }
+ }
+
+ fn namespace(&self, namespace: &str) -> TokenStream {
+ // TODO: handle nested structs?
+ if namespace.is_empty() || self.namespace == namespace {
+ quote! {}
+ } else {
+ // TODO: problem with making relative paths here is that we don't have the context to disambiguate
+
+ // let mut relative = self.namespace.split('.').peekable();
+ // let mut namespace = namespace.split('.').peekable();
+ // let mut related = false;
+
+ // while relative.peek() == namespace.peek() {
+ // related = true;
+
+ // if relative.next().is_none() {
+ // break;
+ // }
+
+ // namespace.next();
+ // }
+
+ // let mut tokens = TokenStream::new();
+
+ // if related {
+ // for _ in 0..relative.count() {
+ // tokens.push_str("super::");
+ // }
+ // }
+
+ // for namespace in namespace {
+ // tokens.push_str(namespace);
+ // tokens.push_str("::");
+ // }
+
+ // tokens
+
+ // TODO: so instead we just gen it out in full
+
+ let mut tokens = TokenStream::new();
+
+ for namespace in namespace.split('.') {
+ tokens.push_str(namespace);
+ tokens.push_str("::");
+ }
+
+ tokens
+ }
+ }
+}
diff --git a/vendor/windows-bindgen/src/rdl/mod.rs b/vendor/windows-bindgen/src/rdl/mod.rs
new file mode 100644
index 000000000..6cabb168b
--- /dev/null
+++ b/vendor/windows-bindgen/src/rdl/mod.rs
@@ -0,0 +1,338 @@
+use super::*;
+mod fmt;
+mod from_reader;
+mod to_winmd;
+use crate::Result;
+pub use from_reader::from_reader;
+use syn::spanned::Spanned;
+
+// TODO: may want to finally get rid of `syn` as it also doesn't support preserving code comments
+
+impl File {
+ pub fn parse_str(input: &str) -> Result<Self> {
+ Ok(syn::parse_str::<Self>(input)?)
+ }
+
+ // Note: this isn't called automatically by `parse_str` to avoid canonicalizing when we're merely formatting IDL.
+ pub fn canonicalize(&mut self) -> Result<()> {
+ // TODO maybe we rewrite the `File` here to resolve any `super` references and use declarations so that
+ // subsequently the rdl-to-winmd conversion can just assume everything's fully qualified?
+ // * super can't refer to something outside of the IDL file
+ // * use declarations are only used for unqualified names that aren't defined in the IDL file
+ // * use declarations don't support globs and must name all externally defined types
+ // This way we can quickly kick out common invalid IDL files before we lost file/span context info
+
+ Ok(())
+ }
+
+ pub fn fmt(&self) -> String {
+ fmt::Writer::new(self).into_string()
+ }
+
+ pub fn into_winmd(mut self) -> Result<Vec<u8>> {
+ self.canonicalize()?;
+ to_winmd::rdl_to_winmd(&self)
+ }
+}
+
+// The value of the IDL-specific memory representation is that it allows for constructs that are not modeled in the abstract Module
+// tree such as the use declarations and if we get rid of it we'd always "format" IDL by stripping out any of that into a single
+// canonical form which would not be very friendly to developers.
+#[derive(Debug)]
+pub struct File {
+ pub winrt: bool,
+ pub references: Vec<syn::ItemUse>,
+ pub modules: Vec<Module>,
+}
+
+// TODO: need to change these to unpack the syn types and store strings we can reference for efficiency along with spans since the syn
+// is made for value semantics.
+
+#[derive(Clone, Debug)]
+pub struct Module {
+ pub namespace: String,
+ pub members: Vec<ModuleMember>,
+}
+
+#[derive(Clone, Debug)]
+pub enum ModuleMember {
+ Module(Module),
+ Interface(Interface),
+ Struct(Struct),
+ Enum(Enum),
+ Class(Class),
+ Function(Function),
+ Constant(Constant),
+}
+
+impl ModuleMember {
+ pub fn name(&self) -> &str {
+ match self {
+ Self::Module(module) => crate::extension(&module.namespace),
+ Self::Interface(member) => &member.name,
+ Self::Struct(member) => &member.name,
+ Self::Enum(member) => &member.name,
+ Self::Class(member) => &member.name,
+ Self::Function(member) => &member.name,
+ Self::Constant(member) => &member.name,
+ }
+ }
+}
+
+#[derive(Clone, Debug)]
+pub struct Enum {
+ pub winrt: bool,
+ pub name: String,
+ pub item: syn::ItemEnum,
+}
+
+#[derive(Clone, Debug)]
+pub struct Constant {
+ pub name: String,
+ pub item: syn::ItemConst,
+}
+
+#[derive(Clone, Debug)]
+pub struct Struct {
+ pub winrt: bool,
+ pub name: String,
+ pub attributes: Vec<syn::Attribute>,
+ pub span: proc_macro2::Span,
+ pub fields: Vec<Field>,
+}
+
+#[derive(Clone, Debug)]
+pub struct Field {
+ pub name: String,
+ pub attributes: Vec<syn::Attribute>,
+ pub span: proc_macro2::Span,
+ pub ty: syn::Type,
+}
+
+#[derive(Clone, Debug)]
+pub struct Class {
+ pub name: String,
+ pub attributes: Vec<syn::Attribute>,
+ pub base: Option<syn::TypePath>,
+ pub extends: Vec<syn::TypePath>,
+}
+
+#[derive(Clone, Debug)]
+pub struct Function {
+ pub name: String,
+ pub item: syn::TraitItemFn,
+}
+
+#[derive(Clone, Debug)]
+pub struct Interface {
+ pub winrt: bool,
+ pub name: String,
+ pub generics: Vec<String>,
+ pub attributes: Vec<syn::Attribute>,
+ pub extends: Vec<syn::TypePath>,
+ pub methods: Vec<syn::TraitItemFn>,
+}
+
+syn::custom_keyword!(interface);
+syn::custom_keyword!(class);
+
+fn winrt(input: syn::parse::ParseStream) -> syn::Result<bool> {
+ let attributes = input.call(syn::Attribute::parse_inner)?;
+ if attributes.len() == 1 {
+ if let syn::Meta::Path(path) = &attributes[0].meta {
+ if path.is_ident("winrt") {
+ return Ok(true);
+ }
+
+ if path.is_ident("win32") {
+ return Ok(false);
+ }
+ }
+ }
+
+ Err(syn::Error::new(input.span(), "A single `#![win32]` or `#![winrt]` attribute required"))
+}
+
+impl syn::parse::Parse for File {
+ fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
+ let mut references = vec![];
+ let mut modules = vec![];
+ let winrt = winrt(input)?;
+
+ while !input.is_empty() {
+ let lookahead = input.lookahead1();
+ if lookahead.peek(syn::Token![mod]) {
+ modules.push(Module::parse("", winrt, input)?);
+ } else if lookahead.peek(syn::Token![use]) {
+ references.push(input.parse()?);
+ } else {
+ return Err(lookahead.error());
+ }
+ }
+ Ok(Self { winrt, references, modules })
+ }
+}
+
+impl Module {
+ fn name(&self) -> &str {
+ self.namespace.rsplit_once('.').map_or(&self.namespace, |(_, name)| name)
+ }
+
+ fn parse(namespace: &str, winrt: bool, input: syn::parse::ParseStream) -> syn::Result<Self> {
+ input.parse::<syn::Token![mod]>()?;
+ let name = input.parse::<syn::Ident>()?.to_string();
+
+ let namespace = if namespace.is_empty() { name.to_string() } else { format!("{namespace}.{name}") };
+
+ let content;
+ syn::braced!(content in input);
+ let mut members = vec![];
+ while !content.is_empty() {
+ members.push(ModuleMember::parse(&namespace, winrt, &content)?);
+ }
+ Ok(Self { namespace, members })
+ }
+}
+
+impl ModuleMember {
+ fn parse(namespace: &str, winrt: bool, input: syn::parse::ParseStream) -> syn::Result<Self> {
+ let attributes: Vec<syn::Attribute> = input.call(syn::Attribute::parse_outer)?;
+ let lookahead = input.lookahead1();
+ if lookahead.peek(syn::Token![mod]) {
+ if let Some(attribute) = attributes.first() {
+ return Err(syn::Error::new(attribute.span(), "`use` attributes not supported"));
+ }
+ Ok(ModuleMember::Module(Module::parse(namespace, winrt, input)?))
+ } else if lookahead.peek(interface) {
+ Ok(ModuleMember::Interface(Interface::parse(namespace, winrt, attributes, input)?))
+ } else if lookahead.peek(syn::Token![struct]) {
+ Ok(ModuleMember::Struct(Struct::parse(namespace, winrt, attributes, input)?))
+ } else if lookahead.peek(syn::Token![enum]) {
+ Ok(ModuleMember::Enum(Enum::parse(namespace, winrt, attributes, input)?))
+ } else if lookahead.peek(class) {
+ Ok(ModuleMember::Class(Class::parse(attributes, input)?))
+ } else if lookahead.peek(syn::Token![fn]) {
+ Ok(ModuleMember::Function(Function::parse(namespace, attributes, input)?))
+ } else if lookahead.peek(syn::Token![const]) {
+ Ok(ModuleMember::Constant(Constant::parse(namespace, attributes, input)?))
+ } else {
+ Err(lookahead.error())
+ }
+ }
+}
+
+impl Class {
+ fn parse(attributes: Vec<syn::Attribute>, input: syn::parse::ParseStream) -> syn::Result<Self> {
+ input.parse::<class>()?;
+ let name = input.parse::<syn::Ident>()?.to_string();
+ let mut extends = Vec::new();
+ let mut base = None;
+
+ if input.peek(syn::Token![:]) {
+ input.parse::<syn::Token![:]>()?;
+ while !input.peek(syn::Token![;]) {
+ if input.peek(class) {
+ input.parse::<class>()?;
+ base = Some(input.parse()?);
+ } else {
+ extends.push(input.parse()?);
+ }
+ _ = input.parse::<syn::Token![,]>();
+ }
+ }
+
+ input.parse::<syn::Token![;]>()?;
+ Ok(Self { attributes, name, base, extends })
+ }
+}
+
+impl Interface {
+ fn parse(_namespace: &str, winrt: bool, attributes: Vec<syn::Attribute>, input: syn::parse::ParseStream) -> syn::Result<Self> {
+ input.parse::<interface>()?;
+ let name = input.parse::<syn::Ident>()?.to_string();
+
+ let mut generics = Vec::new();
+
+ if input.peek(syn::Token![<]) {
+ input.parse::<syn::Token![<]>()?;
+ while input.peek(syn::Ident) {
+ generics.push(input.parse::<syn::Ident>()?.to_string());
+ _ = input.parse::<syn::Token![,]>();
+ }
+
+ input.parse::<syn::Token![>]>()?;
+ }
+
+ let mut extends = Vec::new();
+
+ if input.peek(syn::Token![:]) {
+ input.parse::<syn::Token![:]>()?;
+ while !input.peek(syn::token::Brace) {
+ extends.push(input.parse()?);
+ _ = input.parse::<syn::Token![,]>();
+ }
+ }
+
+ let content;
+ syn::braced!(content in input);
+ let mut methods = vec![];
+ while !content.is_empty() {
+ methods.push(content.parse()?);
+ }
+ Ok(Self { winrt, attributes, generics, extends, name, methods })
+ }
+}
+
+impl Struct {
+ fn parse(_namespace: &str, winrt: bool, attributes: Vec<syn::Attribute>, input: syn::parse::ParseStream) -> syn::Result<Self> {
+ // TODO: need to validate that the struct is valid according to the constraints of the winmd type system.
+ // Same for the other types. That way we can spit out errors quickly for things like unnamed fields.
+ let span = input.span();
+ let item: syn::ItemStruct = input.parse()?;
+ let name = item.ident.to_string();
+ let mut fields = vec![];
+
+ let syn::Fields::Named(named) = item.fields else {
+ return Err(syn::Error::new(item.span(), "unnamed fields not supported"));
+ };
+
+ for field in named.named {
+ fields.push(Field {
+ span: field.span(),
+ attributes: field.attrs,
+ // Simply unwrapping since we already know that it is a named field.
+ name: field.ident.unwrap().to_string(),
+ ty: field.ty,
+ });
+ }
+
+ Ok(Self { winrt, name, attributes, span, fields })
+ }
+}
+
+impl Enum {
+ fn parse(_namespace: &str, winrt: bool, attributes: Vec<syn::Attribute>, input: syn::parse::ParseStream) -> syn::Result<Self> {
+ let mut item: syn::ItemEnum = input.parse()?;
+ item.attrs = attributes;
+ let name = item.ident.to_string();
+ Ok(Self { winrt, name, item })
+ }
+}
+
+impl Constant {
+ fn parse(_namespace: &str, attributes: Vec<syn::Attribute>, input: syn::parse::ParseStream) -> syn::Result<Self> {
+ let mut item: syn::ItemConst = input.parse()?;
+ item.attrs = attributes;
+ let name = item.ident.to_string();
+ Ok(Self { name, item })
+ }
+}
+
+impl Function {
+ fn parse(_namespace: &str, attributes: Vec<syn::Attribute>, input: syn::parse::ParseStream) -> syn::Result<Self> {
+ let mut item: syn::TraitItemFn = input.parse()?;
+ item.attrs = attributes;
+ let name = item.sig.ident.to_string();
+ Ok(Self { name, item })
+ }
+}
diff --git a/vendor/windows-bindgen/src/rdl/to_winmd.rs b/vendor/windows-bindgen/src/rdl/to_winmd.rs
new file mode 100644
index 000000000..d1dc65b12
--- /dev/null
+++ b/vendor/windows-bindgen/src/rdl/to_winmd.rs
@@ -0,0 +1,335 @@
+use super::*;
+use crate::winmd::{self, writer};
+use crate::{rdl, Result};
+
+// TODO: store span in winmd so that errors resolving type references can be traced back to file/line/column
+use std::collections::HashMap;
+//use syn::spanned::Spanned;
+
+// TODO: this creates a temporary in-memory winmd used to treat the IDL content uniformly as metadata.
+// The winmd_to_winmd does the harder job of validating and producing canonical winmd for public consumption.
+
+pub fn rdl_to_winmd(file: &rdl::File) -> Result<Vec<u8>> {
+ // Local-to-qualified type names found in use declaration - e.g. "IStringable" -> "Windows.Foundation.IStringable"
+ // This is just a convenience for the developer to shorten common references like this but would not support globs or renames.
+ // Note that none of these are verified to be real until much later when the winmd is validated since we don't
+ // know what other metadata may be combined
+ let mut _use_map = HashMap::<String, String>::new();
+
+ // TODO: read file and populate use_map
+
+ // Types are collected here in two passes - this allows us to figure out whether a local name points to a relative type
+ // or a type from a use declaration...?
+ let mut collector = HashMap::<String, HashMap<&str, rdl::ModuleMember>>::new();
+
+ file.modules.iter().for_each(|module| collect_module(&mut collector, module));
+
+ // TODO: collect type names into hashmap (phase 1) and just drop clones of the IDL members into the collector
+
+ // TODO: Can we just walk the collector at this point and populate the winmd writer and thus need the read-phase?
+ // this second walking of the collector is basically the "define" phase
+
+ let mut writer = winmd::Writer::new("temp.winmd");
+
+ collector.iter().for_each(|(namespace, members)| members.iter().for_each(|(name, member)| write_member(&mut writer, namespace, name, member)));
+
+ Ok(writer.into_stream())
+}
+
+fn collect_module<'a>(collector: &mut HashMap<String, HashMap<&'a str, rdl::ModuleMember>>, module: &'a rdl::Module) {
+ module.members.iter().for_each(|member| collect_member(collector, module, member));
+}
+
+fn collect_member<'a>(collector: &mut HashMap<String, HashMap<&'a str, rdl::ModuleMember>>, module: &'a rdl::Module, member: &'a rdl::ModuleMember) {
+ match member {
+ rdl::ModuleMember::Module(module) => collect_module(collector, module),
+ rdl::ModuleMember::Constant(_) | rdl::ModuleMember::Function(_) => {
+ collector.entry(module.namespace.to_string()).or_default().entry("Apis").or_insert(member.clone());
+ }
+ _ => {
+ collector.entry(module.namespace.to_string()).or_default().entry(member.name()).or_insert(member.clone());
+ }
+ }
+}
+
+fn write_member(writer: &mut winmd::Writer, namespace: &str, name: &str, member: &rdl::ModuleMember) {
+ match member {
+ rdl::ModuleMember::Interface(member) => write_interface(writer, namespace, name, member),
+ rdl::ModuleMember::Struct(member) => write_struct(writer, namespace, name, member),
+ rdl::ModuleMember::Enum(member) => write_enum(writer, namespace, name, member),
+ rdl::ModuleMember::Class(member) => write_class(writer, namespace, name, member),
+ rest => unimplemented!("{rest:?}"),
+ }
+}
+
+fn write_interface(writer: &mut winmd::Writer, namespace: &str, name: &str, member: &rdl::Interface) {
+ let mut flags = metadata::TypeAttributes::Public | metadata::TypeAttributes::Interface | metadata::TypeAttributes::Abstract;
+
+ if member.winrt {
+ flags |= metadata::TypeAttributes::WindowsRuntime
+ }
+
+ writer.tables.TypeDef.push(winmd::TypeDef {
+ Extends: 0,
+ FieldList: writer.tables.Field.len() as u32,
+ MethodList: writer.tables.MethodDef.len() as u32,
+ Flags: flags.0,
+ TypeName: writer.strings.insert(name),
+ TypeNamespace: writer.strings.insert(namespace),
+ });
+
+ for (number, generic) in member.generics.iter().enumerate() {
+ writer.tables.GenericParam.push(writer::GenericParam {
+ Number: number as u16,
+ Flags: 0,
+ Owner: writer::TypeOrMethodDef::TypeDef(writer.tables.TypeDef.len() as u32 - 1).encode(),
+ Name: writer.strings.insert(generic),
+ });
+ }
+
+ for type_path in &member.extends {
+ let ty = syn_type_path(namespace, &member.generics, type_path);
+
+ let reference = match &ty {
+ winmd::Type::TypeRef(type_name) if type_name.generics.is_empty() => writer.insert_type_ref(&type_name.namespace, &type_name.name),
+ winmd::Type::TypeRef(_) => writer.insert_type_spec(ty),
+ rest => unimplemented!("{rest:?}"),
+ };
+
+ writer.tables.InterfaceImpl.push(writer::InterfaceImpl { Class: writer.tables.TypeDef.len() as u32 - 1, Interface: reference });
+ }
+
+ for method in &member.methods {
+ let signature = syn_signature(namespace, &member.generics, &method.sig);
+
+ let params: Vec<winmd::Type> = signature.params.iter().map(|param| param.ty.clone()).collect();
+
+ let signature_blob = writer.insert_method_sig(metadata::MethodCallAttributes(0), &signature.return_type, &params);
+
+ let flags = metadata::MethodAttributes::Abstract | metadata::MethodAttributes::HideBySig | metadata::MethodAttributes::HideBySig | metadata::MethodAttributes::NewSlot | metadata::MethodAttributes::Public | metadata::MethodAttributes::Virtual;
+
+ writer.tables.MethodDef.push(winmd::MethodDef {
+ RVA: 0,
+ ImplFlags: 0,
+ Flags: flags.0,
+ Name: writer.strings.insert(&method.sig.ident.to_string()),
+ Signature: signature_blob,
+ ParamList: writer.tables.Param.len() as u32,
+ });
+
+ for (sequence, param) in signature.params.iter().enumerate() {
+ writer.tables.Param.push(winmd::Param { Flags: 0, Sequence: (sequence + 1) as u16, Name: writer.strings.insert(&param.name) });
+ }
+ }
+}
+
+fn write_struct(writer: &mut winmd::Writer, namespace: &str, name: &str, member: &rdl::Struct) {
+ let mut flags = metadata::TypeAttributes::Public | metadata::TypeAttributes::Sealed | metadata::TypeAttributes::SequentialLayout;
+
+ if member.winrt {
+ flags |= metadata::TypeAttributes::WindowsRuntime
+ }
+
+ let extends = writer.insert_type_ref("System", "ValueType");
+
+ writer.tables.TypeDef.push(winmd::TypeDef {
+ Extends: extends,
+ FieldList: writer.tables.Field.len() as u32,
+ MethodList: writer.tables.MethodDef.len() as u32,
+ Flags: flags.0,
+ TypeName: writer.strings.insert(name),
+ TypeNamespace: writer.strings.insert(namespace),
+ });
+
+ for field in &member.fields {
+ let flags = metadata::FieldAttributes::Public;
+ let ty = syn_type(namespace, &[], &field.ty);
+ let signature = writer.insert_field_sig(&ty);
+
+ writer.tables.Field.push(winmd::Field { Flags: flags.0, Name: writer.strings.insert(&field.name), Signature: signature });
+ }
+}
+
+fn write_enum(_writer: &mut winmd::Writer, _namespace: &str, _name: &str, _member: &rdl::Enum) {}
+
+fn write_class(writer: &mut winmd::Writer, namespace: &str, name: &str, member: &rdl::Class) {
+ let flags = metadata::TypeAttributes::Public | metadata::TypeAttributes::Sealed | metadata::TypeAttributes::WindowsRuntime;
+
+ let extends = if let Some(base) = &member.base {
+ match syn_type_path(namespace, &[], base) {
+ winmd::Type::TypeRef(base) => writer.insert_type_ref(&base.namespace, &base.name),
+ rest => unimplemented!("{rest:?}"),
+ }
+ } else {
+ writer.insert_type_ref("System", "Object")
+ };
+
+ writer.tables.TypeDef.push(winmd::TypeDef {
+ Extends: extends,
+ // Even though ECMA-335 says these can be "null", bugs in ILDASM necessitate this to avoid "misreading" the list terminators.
+ FieldList: writer.tables.Field.len() as u32,
+ MethodList: writer.tables.MethodDef.len() as u32,
+ Flags: flags.0,
+ TypeName: writer.strings.insert(name),
+ TypeNamespace: writer.strings.insert(namespace),
+ });
+
+ for (index, extends) in member.extends.iter().enumerate() {
+ let ty = syn_type_path(namespace, &[], extends);
+
+ let reference = match &ty {
+ winmd::Type::TypeRef(type_name) if type_name.generics.is_empty() => writer.insert_type_ref(&type_name.namespace, &type_name.name),
+ winmd::Type::TypeRef(_) => writer.insert_type_spec(ty),
+ winmd::Type::IUnknown => writer.insert_type_ref("Windows.Win32.System.Com", "IUnknown"),
+ winmd::Type::IInspectable => writer.insert_type_ref("Windows.Win32.System.WinRT", "IInspectable"),
+ rest => unimplemented!("{rest:?}"),
+ };
+
+ writer.tables.InterfaceImpl.push(writer::InterfaceImpl { Class: writer.tables.TypeDef.len() as u32 - 1, Interface: reference });
+
+ if index == 0 {
+ // TODO: add the DefaultAttribute to the first interface
+ }
+ }
+}
+
+fn syn_signature(namespace: &str, generics: &[String], sig: &syn::Signature) -> winmd::Signature {
+ let params = sig
+ .inputs
+ .iter()
+ .map(|param| match param {
+ syn::FnArg::Typed(pat_type) => {
+ let name = match &*pat_type.pat {
+ syn::Pat::Ident(pat_ident) => pat_ident.ident.to_string(),
+ rest => unimplemented!("{rest:?}"),
+ };
+ let ty = syn_type(namespace, generics, &pat_type.ty);
+ winmd::SignatureParam { name, ty }
+ }
+ rest => unimplemented!("{rest:?}"),
+ })
+ .collect();
+
+ let return_type = if let syn::ReturnType::Type(_, ty) = &sig.output { syn_type(namespace, generics, ty) } else { winmd::Type::Void };
+
+ winmd::Signature { params, return_type, call_flags: 0 }
+}
+
+fn syn_type(namespace: &str, generics: &[String], ty: &syn::Type) -> winmd::Type {
+ match ty {
+ syn::Type::Path(ty) => syn_type_path(namespace, generics, ty),
+ syn::Type::Ptr(ptr) => syn_type_ptr(namespace, ptr),
+ syn::Type::Array(array) => syn_type_array(namespace, array),
+ rest => unimplemented!("{rest:?}"),
+ }
+}
+
+fn syn_type_array(namespace: &str, array: &syn::TypeArray) -> winmd::Type {
+ let ty = syn_type(namespace, &[], &array.elem);
+
+ if let syn::Expr::Lit(lit) = &array.len {
+ if let syn::Lit::Int(lit) = &lit.lit {
+ if let Ok(len) = lit.base10_parse() {
+ return ty.into_array(len);
+ }
+ }
+ }
+
+ unimplemented!()
+}
+
+fn syn_type_ptr(namespace: &str, ptr: &syn::TypePtr) -> winmd::Type {
+ let ty = syn_type(namespace, &[], &ptr.elem);
+ if ptr.mutability.is_some() {
+ ty.into_mut_ptr()
+ } else {
+ ty.into_const_ptr()
+ }
+}
+
+fn syn_type_path(namespace: &str, generics: &[String], ty: &syn::TypePath) -> winmd::Type {
+ if ty.qself.is_none() {
+ return syn_path(namespace, generics, &ty.path);
+ }
+
+ unimplemented!()
+}
+
+fn syn_path(namespace: &str, generics: &[String], path: &syn::Path) -> winmd::Type {
+ if let Some(segment) = path.segments.first() {
+ if path.segments.len() == 1 && segment.arguments.is_empty() {
+ let name = segment.ident.to_string();
+
+ if let Some(number) = generics.iter().position(|generic| generic == &name) {
+ return winmd::Type::GenericParam(number as u16);
+ }
+
+ match name.as_str() {
+ "void" => return winmd::Type::Void,
+ "bool" => return winmd::Type::Bool,
+ "char" => return winmd::Type::Char,
+ "i8" => return winmd::Type::I8,
+ "u8" => return winmd::Type::U8,
+ "i16" => return winmd::Type::I16,
+ "u16" => return winmd::Type::U16,
+ "i32" => return winmd::Type::I32,
+ "u32" => return winmd::Type::U32,
+ "i64" => return winmd::Type::I64,
+ "u64" => return winmd::Type::U64,
+ "f32" => return winmd::Type::F32,
+ "f64" => return winmd::Type::F64,
+ "isize" => return winmd::Type::ISize,
+ "usize" => return winmd::Type::USize,
+ "HSTRING" => return winmd::Type::String,
+ "GUID" => return winmd::Type::GUID,
+ "IUnknown" => return winmd::Type::IUnknown,
+ "IInspectable" => return winmd::Type::IInspectable,
+ "HRESULT" => return winmd::Type::HRESULT,
+ "PSTR" => return winmd::Type::PSTR,
+ "PWSTR" => return winmd::Type::PWSTR,
+ "PCSTR" => return winmd::Type::PCSTR,
+ "PCWSTR" => return winmd::Type::PCWSTR,
+ "BSTR" => return winmd::Type::BSTR,
+ _ => {}
+ };
+ }
+ }
+
+ // TODO: Here we assume that paths are absolute since there's no way to disambiguate between nested and absolute paths
+ // The canonicalize function (should maybe) preprocesses the IDL to make this work
+
+ let mut builder = vec![];
+
+ for segment in &path.segments {
+ let segment = segment.ident.to_string();
+
+ if segment == "super" {
+ if builder.is_empty() {
+ for segment in namespace.split('.') {
+ builder.push(segment.to_string());
+ }
+ }
+ builder.pop();
+ } else {
+ builder.push(segment);
+ }
+ }
+
+ // Unwrapping is fine as there should always be at least one segment.
+ let (name, type_namespace) = builder.split_last().unwrap();
+ let type_namespace = if type_namespace.is_empty() { namespace.to_string() } else { type_namespace.join(".") };
+ let mut type_generics = vec![];
+
+ if let Some(segment) = path.segments.last() {
+ if let syn::PathArguments::AngleBracketed(args) = &segment.arguments {
+ for arg in &args.args {
+ match arg {
+ syn::GenericArgument::Type(ty) => type_generics.push(syn_type(namespace, generics, ty)),
+ rest => unimplemented!("{rest:?}"),
+ }
+ }
+ }
+ }
+
+ winmd::Type::TypeRef(winmd::TypeName { namespace: type_namespace, name: name.to_string(), generics: type_generics })
+}
diff --git a/vendor/windows-bindgen/src/rust/cfg.rs b/vendor/windows-bindgen/src/rust/cfg.rs
new file mode 100644
index 000000000..db77497bf
--- /dev/null
+++ b/vendor/windows-bindgen/src/rust/cfg.rs
@@ -0,0 +1,169 @@
+use super::*;
+
+#[derive(Default, Clone)]
+pub struct Cfg<'a> {
+ pub types: BTreeMap<&'a str, BTreeSet<TypeDef>>,
+ pub core_types: BTreeSet<Type>,
+ pub arches: BTreeSet<&'static str>,
+ pub implement: bool,
+}
+
+impl<'a> Cfg<'a> {
+ pub fn add_feature(&mut self, feature: &'a str) {
+ self.types.entry(feature).or_default();
+ }
+ pub fn union(&self, other: &Self) -> Self {
+ let mut union = Self::default();
+ self.types.keys().for_each(|feature| {
+ union.types.entry(feature).or_default();
+ });
+ other.types.keys().for_each(|feature| {
+ union.types.entry(feature).or_default();
+ });
+ self.arches.iter().for_each(|arch| {
+ union.arches.insert(arch);
+ });
+ other.arches.iter().for_each(|arch| {
+ union.arches.insert(arch);
+ });
+ union
+ }
+}
+
+pub fn field_cfg<'a>(reader: &'a Reader<'a>, row: Field) -> Cfg<'a> {
+ let mut cfg = Cfg::default();
+ field_cfg_combine(reader, row, None, &mut cfg);
+ cfg
+}
+fn field_cfg_combine<'a>(reader: &'a Reader, row: Field, enclosing: Option<TypeDef>, cfg: &mut Cfg<'a>) {
+ type_cfg_combine(reader, &reader.field_type(row, enclosing), cfg)
+}
+
+pub fn type_def_cfg<'a>(reader: &'a Reader, row: TypeDef, generics: &[Type]) -> Cfg<'a> {
+ let mut cfg = Cfg::default();
+ type_def_cfg_combine(reader, row, generics, &mut cfg);
+ cfg_add_attributes(reader, &mut cfg, row);
+ cfg
+}
+pub fn type_def_cfg_impl<'a>(reader: &'a Reader, def: TypeDef, generics: &[Type]) -> Cfg<'a> {
+ let mut cfg = Cfg { implement: true, ..Default::default() };
+
+ fn combine<'a>(reader: &'a Reader, def: TypeDef, generics: &[Type], cfg: &mut Cfg<'a>) {
+ type_def_cfg_combine(reader, def, generics, cfg);
+
+ for method in reader.type_def_methods(def) {
+ signature_cfg_combine(reader, &reader.method_def_signature(method, generics), cfg);
+ }
+ }
+
+ combine(reader, def, generics, &mut cfg);
+
+ for def in type_def_vtables(reader, def) {
+ if let Type::TypeDef(def, generics) = def {
+ combine(reader, def, &generics, &mut cfg);
+ }
+ }
+
+ if reader.type_def_flags(def).contains(TypeAttributes::WindowsRuntime) {
+ for interface in type_def_interfaces(reader, def, generics) {
+ if let Type::TypeDef(def, generics) = interface {
+ combine(reader, def, &generics, &mut cfg);
+ }
+ }
+ }
+
+ cfg_add_attributes(reader, &mut cfg, def);
+ cfg
+}
+pub fn type_def_cfg_combine<'a>(reader: &'a Reader, row: TypeDef, generics: &[Type], cfg: &mut Cfg<'a>) {
+ let type_name = reader.type_def_type_name(row);
+
+ for generic in generics {
+ type_cfg_combine(reader, generic, cfg);
+ }
+
+ if cfg.types.entry(type_name.namespace).or_default().insert(row) {
+ match reader.type_def_kind(row) {
+ TypeKind::Class => {
+ if let Some(default_interface) = type_def_default_interface(reader, row) {
+ type_cfg_combine(reader, &default_interface, cfg);
+ }
+ }
+ TypeKind::Interface => {
+ if !reader.type_def_flags(row).contains(TypeAttributes::WindowsRuntime) {
+ for def in type_def_vtables(reader, row) {
+ if let Type::TypeDef(def, _) = def {
+ cfg.add_feature(reader.type_def_namespace(def));
+ }
+ }
+ }
+ }
+ TypeKind::Struct => {
+ reader.type_def_fields(row).for_each(|field| field_cfg_combine(reader, field, Some(row), cfg));
+ if !type_name.namespace.is_empty() {
+ for def in reader.get_type_def(type_name) {
+ if def != row {
+ type_def_cfg_combine(reader, def, &[], cfg);
+ }
+ }
+ }
+ }
+ TypeKind::Delegate => signature_cfg_combine(reader, &reader.method_def_signature(type_def_invoke_method(reader, row), generics), cfg),
+ _ => {}
+ }
+ }
+}
+
+pub fn signature_cfg<'a>(reader: &'a Reader, method: MethodDef) -> Cfg<'a> {
+ let mut cfg = Cfg::default();
+ signature_cfg_combine(reader, &reader.method_def_signature(method, &[]), &mut cfg);
+ cfg_add_attributes(reader, &mut cfg, method);
+ cfg
+}
+fn signature_cfg_combine<'a>(reader: &'a Reader, signature: &MethodDefSig, cfg: &mut Cfg<'a>) {
+ type_cfg_combine(reader, &signature.return_type, cfg);
+ signature.params.iter().for_each(|param| type_cfg_combine(reader, param, cfg));
+}
+
+fn cfg_add_attributes<R: AsRow + Into<HasAttribute>>(reader: &Reader, cfg: &mut Cfg, row: R) {
+ for attribute in reader.attributes(row) {
+ match reader.attribute_name(attribute) {
+ "SupportedArchitectureAttribute" => {
+ if let Some((_, Value::EnumDef(_, value))) = reader.attribute_args(attribute).get(0) {
+ if let Value::I32(value) = **value {
+ if value & 1 == 1 {
+ cfg.arches.insert("x86");
+ }
+ if value & 2 == 2 {
+ cfg.arches.insert("x86_64");
+ }
+ if value & 4 == 4 {
+ cfg.arches.insert("aarch64");
+ }
+ }
+ }
+ }
+ "DeprecatedAttribute" => {
+ cfg.add_feature("deprecated");
+ }
+ _ => {}
+ }
+ }
+}
+
+pub fn type_cfg<'a>(reader: &'a Reader, ty: &Type) -> Cfg<'a> {
+ let mut cfg = Cfg::default();
+ type_cfg_combine(reader, ty, &mut cfg);
+ cfg
+}
+fn type_cfg_combine<'a>(reader: &'a Reader, ty: &Type, cfg: &mut Cfg<'a>) {
+ match ty {
+ Type::TypeDef(row, generics) => type_def_cfg_combine(reader, *row, generics, cfg),
+ Type::Win32Array(ty, _) => type_cfg_combine(reader, ty, cfg),
+ Type::ConstPtr(ty, _) => type_cfg_combine(reader, ty, cfg),
+ Type::MutPtr(ty, _) => type_cfg_combine(reader, ty, cfg),
+ Type::WinrtArray(ty) => type_cfg_combine(reader, ty, cfg),
+ Type::WinrtArrayRef(ty) => type_cfg_combine(reader, ty, cfg),
+ ty => _ = cfg.core_types.insert(ty.clone()),
+ }
+}
diff --git a/vendor/windows-bindgen/src/rust/classes.rs b/vendor/windows-bindgen/src/rust/classes.rs
new file mode 100644
index 000000000..397abff10
--- /dev/null
+++ b/vendor/windows-bindgen/src/rust/classes.rs
@@ -0,0 +1,160 @@
+use super::*;
+
+pub fn writer(writer: &Writer, def: TypeDef) -> TokenStream {
+ if writer.sys {
+ if type_def_has_default_interface(writer.reader, def) {
+ let name = to_ident(writer.reader.type_def_name(def));
+ quote! {
+ pub type #name = *mut ::core::ffi::c_void;
+ }
+ } else {
+ quote! {}
+ }
+ } else {
+ gen_class(writer, def)
+ }
+}
+
+fn gen_class(writer: &Writer, def: TypeDef) -> TokenStream {
+ if writer.reader.type_def_extends(def) == Some(TypeName::Attribute) {
+ return TokenStream::new();
+ }
+
+ let name = to_ident(writer.reader.type_def_name(def));
+ let interfaces = type_interfaces(writer.reader, &Type::TypeDef(def, Vec::new()));
+ let mut methods = quote! {};
+ let mut method_names = MethodNames::new();
+
+ let cfg = type_def_cfg(writer.reader, def, &[]);
+ let doc = writer.cfg_doc(&cfg);
+ let features = writer.cfg_features(&cfg);
+
+ for interface in &interfaces {
+ if let Type::TypeDef(def, generics) = &interface.ty {
+ let mut virtual_names = MethodNames::new();
+
+ for method in writer.reader.type_def_methods(*def) {
+ methods.combine(&winrt_methods::writer(writer, *def, generics, interface.kind, method, &mut method_names, &mut virtual_names));
+ }
+ }
+ }
+
+ let factories = interfaces.iter().filter_map(|interface| match interface.kind {
+ InterfaceKind::Static => {
+ if let Type::TypeDef(def, generics) = &interface.ty {
+ if writer.reader.type_def_methods(*def).next().is_some() {
+ let interface_type = writer.type_name(&interface.ty);
+ let features = writer.cfg_features(&type_def_cfg(writer.reader, *def, generics));
+
+ return Some(quote! {
+ #[doc(hidden)]
+ #features
+ pub fn #interface_type<R, F: FnOnce(&#interface_type) -> ::windows_core::Result<R>>(
+ callback: F,
+ ) -> ::windows_core::Result<R> {
+ static SHARED: ::windows_core::imp::FactoryCache<#name, #interface_type> =
+ ::windows_core::imp::FactoryCache::new();
+ SHARED.call(callback)
+ }
+ });
+ }
+ }
+ None
+ }
+ _ => None,
+ });
+
+ if type_def_has_default_interface(writer.reader, def) {
+ let new = if type_def_has_default_constructor(writer.reader, def) {
+ quote! {
+ pub fn new() -> ::windows_core::Result<Self> {
+ Self::IActivationFactory(|f| f.ActivateInstance::<Self>())
+ }
+ fn IActivationFactory<R, F: FnOnce(&::windows_core::imp::IGenericFactory) -> ::windows_core::Result<R>>(
+ callback: F,
+ ) -> ::windows_core::Result<R> {
+ static SHARED: ::windows_core::imp::FactoryCache<#name, ::windows_core::imp::IGenericFactory> =
+ ::windows_core::imp::FactoryCache::new();
+ SHARED.call(callback)
+ }
+ }
+ } else {
+ quote! {}
+ };
+
+ let mut tokens = quote! {
+ #doc
+ #features
+ #[repr(transparent)]
+ pub struct #name(::windows_core::IUnknown);
+ #features
+ impl #name {
+ #new
+ #methods
+ #(#factories)*
+ }
+ };
+
+ tokens.combine(&writer.interface_core_traits(def, &[], &name, &TokenStream::new(), &TokenStream::new(), &features));
+ tokens.combine(&writer.interface_winrt_trait(def, &[], &name, &TokenStream::new(), &TokenStream::new(), &features));
+ tokens.combine(&writer.interface_trait(def, &[], &name, &TokenStream::new(), &features, true));
+ tokens.combine(&writer.runtime_name_trait(def, &[], &name, &TokenStream::new(), &features));
+ tokens.combine(&writer.async_get(def, &[], &name, &TokenStream::new(), &TokenStream::new(), &features));
+ tokens.combine(&iterators::writer(writer, def, &[], &name, &TokenStream::new(), &TokenStream::new(), &cfg));
+ tokens.combine(&gen_conversions(writer, def, &name, &interfaces, &cfg));
+ tokens.combine(&writer.agile(def, &name, &TokenStream::new(), &features));
+ tokens
+ } else {
+ let mut tokens = quote! {
+ #doc
+ #features
+ pub struct #name;
+ #features
+ impl #name {
+ #methods
+ #(#factories)*
+ }
+ };
+
+ tokens.combine(&writer.runtime_name_trait(def, &[], &name, &TokenStream::new(), &features));
+ tokens
+ }
+}
+
+fn gen_conversions(writer: &Writer, def: TypeDef, name: &TokenStream, interfaces: &[Interface], cfg: &Cfg) -> TokenStream {
+ let features = writer.cfg_features(cfg);
+ let mut tokens = quote! {
+ #features
+ ::windows_core::imp::interface_hierarchy!(#name, ::windows_core::IUnknown, ::windows_core::IInspectable);
+ };
+
+ for interface in interfaces {
+ if type_is_exclusive(writer.reader, &interface.ty) {
+ continue;
+ }
+
+ if interface.kind != InterfaceKind::Default && interface.kind != InterfaceKind::None && interface.kind != InterfaceKind::Base {
+ continue;
+ }
+
+ let into = writer.type_name(&interface.ty);
+ let features = writer.cfg_features(&cfg.union(&type_cfg(writer.reader, &interface.ty)));
+
+ tokens.combine(&quote! {
+ #features
+ impl ::windows_core::CanTryInto<#into> for #name {}
+ });
+ }
+
+ for def in type_def_bases(writer.reader, def) {
+ let into = writer.type_def_name(def, &[]);
+ let features = writer.cfg_features(&cfg.union(&type_def_cfg(writer.reader, def, &[])));
+
+ tokens.combine(&quote! {
+ #features
+ impl ::windows_core::CanTryInto<#into> for #name {}
+ });
+ }
+
+ tokens
+}
diff --git a/vendor/windows-bindgen/src/rust/com_methods.rs b/vendor/windows-bindgen/src/rust/com_methods.rs
new file mode 100644
index 000000000..132e7f220
--- /dev/null
+++ b/vendor/windows-bindgen/src/rust/com_methods.rs
@@ -0,0 +1,207 @@
+use super::*;
+
+pub fn writer(writer: &Writer, def: TypeDef, kind: InterfaceKind, method: MethodDef, method_names: &mut MethodNames, virtual_names: &mut MethodNames, base_count: usize) -> TokenStream {
+ let signature = method_def_signature(writer.reader, writer.reader.type_def_namespace(def), method, &[]);
+
+ let name = method_names.add(writer, method);
+ let vname = virtual_names.add(writer, method);
+ let generics = writer.constraint_generics(&signature.params);
+ let where_clause = writer.where_clause(&signature.params);
+ let mut cfg = signature_cfg(writer.reader, method);
+ cfg.add_feature(writer.reader.type_def_namespace(def));
+ let doc = writer.cfg_method_doc(&cfg);
+ let features = writer.cfg_features(&cfg);
+
+ if kind == InterfaceKind::None {
+ return quote! {};
+ }
+
+ let mut bases = quote! {};
+
+ for _ in 0..base_count {
+ bases.combine(&quote! { .base__ });
+ }
+
+ let kind = signature_kind(writer.reader, &signature);
+ match kind {
+ SignatureKind::Query(_) => {
+ let args = writer.win32_args(&signature.params, kind);
+ let params = writer.win32_params(&signature.params, kind);
+ let generics = expand_generics(generics, quote!(T));
+ let where_clause = expand_where_clause(where_clause, quote!(T: ::windows_core::ComInterface));
+
+ quote! {
+ #doc
+ #features
+ pub unsafe fn #name<#generics>(&self, #params) -> ::windows_core::Result<T> #where_clause {
+ let mut result__ = ::std::ptr::null_mut();
+ (::windows_core::Interface::vtable(self)#bases.#vname)(::windows_core::Interface::as_raw(self), #args).from_abi(result__)
+ }
+ }
+ }
+ SignatureKind::QueryOptional(_) => {
+ let args = writer.win32_args(&signature.params, kind);
+ let params = writer.win32_params(&signature.params, kind);
+ let generics = expand_generics(generics, quote!(T));
+ let where_clause = expand_where_clause(where_clause, quote!(T: ::windows_core::ComInterface));
+
+ quote! {
+ #doc
+ #features
+ pub unsafe fn #name<#generics>(&self, #params result__: *mut ::core::option::Option<T>) -> ::windows_core::Result<()> #where_clause {
+ (::windows_core::Interface::vtable(self)#bases.#vname)(::windows_core::Interface::as_raw(self), #args).ok()
+ }
+ }
+ }
+ SignatureKind::ResultValue => {
+ let args = writer.win32_args(&signature.params, kind);
+ let params = writer.win32_params(&signature.params, kind);
+ let return_type = signature.params[signature.params.len() - 1].ty.deref();
+ let return_type = writer.type_name(&return_type);
+
+ quote! {
+ #doc
+ #features
+ pub unsafe fn #name<#generics>(&self, #params) -> ::windows_core::Result<#return_type> #where_clause {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(self)#bases.#vname)(::windows_core::Interface::as_raw(self), #args).from_abi(result__)
+ }
+ }
+ }
+ SignatureKind::ResultVoid => {
+ let args = writer.win32_args(&signature.params, kind);
+ let params = writer.win32_params(&signature.params, kind);
+
+ quote! {
+ #doc
+ #features
+ pub unsafe fn #name<#generics>(&self, #params) -> ::windows_core::Result<()> #where_clause {
+ (::windows_core::Interface::vtable(self)#bases.#vname)(::windows_core::Interface::as_raw(self), #args).ok()
+ }
+ }
+ }
+ SignatureKind::ReturnValue => {
+ let args = writer.win32_args(&signature.params, kind);
+ let params = writer.win32_params(&signature.params, kind);
+ let return_type = signature.params[signature.params.len() - 1].ty.deref();
+ let is_nullable = type_is_nullable(writer.reader, &return_type);
+ let return_type = writer.type_name(&return_type);
+
+ if is_nullable {
+ quote! {
+ #doc
+ #features
+ pub unsafe fn #name<#generics>(&self, #params) -> ::windows_core::Result<#return_type> #where_clause {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(self)#bases.#vname)(::windows_core::Interface::as_raw(self), #args);
+ ::windows_core::from_abi(result__)
+ }
+ }
+ } else {
+ quote! {
+ #doc
+ #features
+ pub unsafe fn #name<#generics>(&self, #params) -> #return_type #where_clause {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(self)#bases.#vname)(::windows_core::Interface::as_raw(self), #args);
+ ::std::mem::transmute(result__)
+ }
+ }
+ }
+ }
+ SignatureKind::ReturnStruct => {
+ let args = writer.win32_args(&signature.params, kind);
+ let params = writer.win32_params(&signature.params, kind);
+ let return_type = writer.type_name(&signature.return_type);
+
+ quote! {
+ #doc
+ #features
+ pub unsafe fn #name<#generics>(&self, #params) -> #return_type #where_clause {
+ let mut result__: #return_type = ::core::mem::zeroed();
+ (::windows_core::Interface::vtable(self)#bases.#vname)(::windows_core::Interface::as_raw(self), &mut result__, #args);
+ result__
+ }
+ }
+ }
+ SignatureKind::PreserveSig => {
+ let args = writer.win32_args(&signature.params, kind);
+ let params = writer.win32_params(&signature.params, kind);
+ let return_type = writer.return_sig(&signature);
+
+ quote! {
+ #doc
+ #features
+ pub unsafe fn #name<#generics>(&self, #params) #return_type #where_clause {
+ (::windows_core::Interface::vtable(self)#bases.#vname)(::windows_core::Interface::as_raw(self), #args)
+ }
+ }
+ }
+ SignatureKind::ReturnVoid => {
+ let args = writer.win32_args(&signature.params, kind);
+ let params = writer.win32_params(&signature.params, kind);
+
+ quote! {
+ #doc
+ #features
+ pub unsafe fn #name<#generics>(&self, #params) #where_clause {
+ (::windows_core::Interface::vtable(self)#bases.#vname)(::windows_core::Interface::as_raw(self), #args)
+ }
+ }
+ }
+ }
+}
+
+pub fn gen_upcall(writer: &Writer, sig: &Signature, inner: TokenStream) -> TokenStream {
+ match signature_kind(writer.reader, sig) {
+ SignatureKind::ResultValue => {
+ let invoke_args = sig.params[..sig.params.len() - 1].iter().map(|param| gen_win32_invoke_arg(writer, param));
+
+ let result = writer.param_name(sig.params[sig.params.len() - 1].def);
+
+ quote! {
+ match #inner(#(#invoke_args,)*) {
+ ::core::result::Result::Ok(ok__) => {
+ // use `core::ptr::write` since the result could be uninitialized
+ ::core::ptr::write(#result, ::core::mem::transmute(ok__));
+ ::windows_core::HRESULT(0)
+ }
+ ::core::result::Result::Err(err) => err.into()
+ }
+ }
+ }
+ SignatureKind::Query(_) | SignatureKind::QueryOptional(_) | SignatureKind::ResultVoid => {
+ let invoke_args = sig.params.iter().map(|param| gen_win32_invoke_arg(writer, param));
+
+ quote! {
+ #inner(#(#invoke_args,)*).into()
+ }
+ }
+ SignatureKind::ReturnStruct => {
+ let invoke_args = sig.params.iter().map(|param| gen_win32_invoke_arg(writer, param));
+
+ quote! {
+ *result__ = #inner(#(#invoke_args,)*)
+ }
+ }
+ _ => {
+ let invoke_args = sig.params.iter().map(|param| gen_win32_invoke_arg(writer, param));
+
+ quote! {
+ #inner(#(#invoke_args,)*)
+ }
+ }
+ }
+}
+
+fn gen_win32_invoke_arg(writer: &Writer, param: &SignatureParam) -> TokenStream {
+ let name = writer.param_name(param.def);
+
+ if writer.reader.param_flags(param.def).contains(ParamAttributes::In) && type_is_nullable(writer.reader, &param.ty) {
+ quote! { ::windows_core::from_raw_borrowed(&#name) }
+ } else if (!param.ty.is_pointer() && type_is_nullable(writer.reader, &param.ty)) || (writer.reader.param_flags(param.def).contains(ParamAttributes::In) && !type_is_primitive(writer.reader, &param.ty)) {
+ quote! { ::core::mem::transmute(&#name) }
+ } else {
+ quote! { ::core::mem::transmute_copy(&#name) }
+ }
+}
diff --git a/vendor/windows-bindgen/src/constants.rs b/vendor/windows-bindgen/src/rust/constants.rs
index 1a08db0ae..672dbcc8a 100644
--- a/vendor/windows-bindgen/src/constants.rs
+++ b/vendor/windows-bindgen/src/rust/constants.rs
@@ -1,27 +1,27 @@
use super::*;
-pub fn gen(gen: &Gen, def: Field) -> TokenStream {
- let name = to_ident(gen.reader.field_name(def));
- let ty = gen.reader.field_type(def, None).to_const_type();
- let cfg = gen.reader.field_cfg(def);
- let doc = gen.cfg_doc(&cfg);
- let features = gen.cfg_features(&cfg);
+pub fn writer(writer: &Writer, def: Field) -> TokenStream {
+ let name = to_ident(writer.reader.field_name(def));
+ let ty = writer.reader.field_type(def, None).to_const_type();
+ let cfg = field_cfg(writer.reader, def);
+ let doc = writer.cfg_doc(&cfg);
+ let features = writer.cfg_features(&cfg);
- if let Some(constant) = gen.reader.field_constant(def) {
- let constant_type = gen.reader.constant_type(constant);
+ if let Some(constant) = writer.reader.field_constant(def) {
+ let constant_type = writer.reader.constant_type(constant);
if ty == constant_type {
if ty == Type::String {
- let crate_name = gen.crate_name();
- if gen.reader.field_is_ansi(def) {
- let value = gen.value(&gen.reader.constant_value(constant));
+ let crate_name = writer.crate_name();
+ if field_is_ansi(writer.reader, def) {
+ let value = writer.value(&writer.reader.constant_value(constant));
quote! {
#doc
#features
pub const #name: #crate_name PCSTR = #crate_name s!(#value);
}
} else {
- let value = gen.value(&gen.reader.constant_value(constant));
+ let value = writer.value(&writer.reader.constant_value(constant));
quote! {
#doc
#features
@@ -29,7 +29,7 @@ pub fn gen(gen: &Gen, def: Field) -> TokenStream {
}
}
} else {
- let value = gen.typed_value(&gen.reader.constant_value(constant));
+ let value = writer.typed_value(&writer.reader.constant_value(constant));
quote! {
#doc
#features
@@ -37,19 +37,19 @@ pub fn gen(gen: &Gen, def: Field) -> TokenStream {
}
}
} else {
- let kind = gen.type_default_name(&ty);
- let value = gen.value(&gen.reader.constant_value(constant));
- let underlying_type = gen.reader.type_underlying_type(&ty);
+ let kind = writer.type_default_name(&ty);
+ let value = writer.value(&writer.reader.constant_value(constant));
+ let underlying_type = type_underlying_type(writer.reader, &ty);
let value = if underlying_type == constant_type {
value
- } else if gen.std && underlying_type == Type::ISize {
+ } else if writer.std && underlying_type == Type::ISize {
quote! { ::core::ptr::invalid_mut(#value as _) }
} else {
quote! { #value as _ }
};
- if !gen.sys && gen.reader.type_has_replacement(&ty) {
+ if !writer.sys && type_has_replacement(writer.reader, &ty) {
quote! {
#doc
#features
@@ -63,15 +63,15 @@ pub fn gen(gen: &Gen, def: Field) -> TokenStream {
}
}
}
- } else if let Some(guid) = gen.reader.field_guid(def) {
- let value = gen.guid(&guid);
- let guid = gen.type_name(&Type::GUID);
+ } else if let Some(guid) = field_guid(writer.reader, def) {
+ let value = writer.guid(&guid);
+ let guid = writer.type_name(&Type::GUID);
quote! {
#doc
pub const #name: #guid = #value;
}
- } else if let Some(value) = initializer(gen, def) {
- let kind = gen.type_default_name(&ty);
+ } else if let Some(value) = initializer(writer, def) {
+ let kind = writer.type_default_name(&ty);
quote! {
#doc
@@ -83,21 +83,21 @@ pub fn gen(gen: &Gen, def: Field) -> TokenStream {
}
}
-fn initializer(gen: &Gen, def: Field) -> Option<TokenStream> {
- let Some(value) = constant(gen, def) else {
+fn initializer(writer: &Writer, def: Field) -> Option<TokenStream> {
+ let Some(value) = constant(writer, def) else {
return None;
};
let mut input = value.as_str();
- let Type::TypeDef((def, _)) = gen.reader.field_type(def, None) else {
+ let Type::TypeDef(def, _) = writer.reader.field_type(def, None) else {
unimplemented!();
};
let mut result = quote! {};
- for field in gen.reader.type_def_fields(def) {
- let (value, rest) = field_initializer(gen, field, input);
+ for field in writer.reader.type_def_fields(def) {
+ let (value, rest) = field_initializer(writer, field, input);
input = rest;
result.combine(&value);
}
@@ -105,16 +105,16 @@ fn initializer(gen: &Gen, def: Field) -> Option<TokenStream> {
Some(result)
}
-fn field_initializer<'a>(gen: &Gen, field: Field, input: &'a str) -> (TokenStream, &'a str) {
- let name = to_ident(gen.reader.field_name(field));
+fn field_initializer<'a>(writer: &Writer, field: Field, input: &'a str) -> (TokenStream, &'a str) {
+ let name = to_ident(writer.reader.field_name(field));
- match gen.reader.field_type(field, None) {
+ match writer.reader.field_type(field, None) {
Type::GUID => {
let (literals, rest) = read_literal_array(input, 11);
- let value = gen.guid(&GUID::from_string_args(&literals));
+ let value = writer.guid(&GUID::from_string_args(&literals));
(quote! { #name: #value, }, rest)
}
- Type::Win32Array((_, len)) => {
+ Type::Win32Array(_, len) => {
let (literals, rest) = read_literal_array(input, len);
let literals = literals.iter().map(|literal| TokenStream::from(*literal));
(quote! { #name: [#(#literals,)*], }, rest)
@@ -127,17 +127,14 @@ fn field_initializer<'a>(gen: &Gen, field: Field, input: &'a str) -> (TokenStrea
}
}
-fn constant(gen: &Gen, def: Field) -> Option<String> {
- gen.reader
- .field_attributes(def)
- .find(|attribute| gen.reader.attribute_name(*attribute) == "ConstantAttribute")
- .map(|attribute| {
- let args = gen.reader.attribute_args(attribute);
- match &args[0].1 {
- Value::String(value) => value.clone(),
- _ => unimplemented!(),
- }
- })
+fn constant(writer: &Writer, def: Field) -> Option<String> {
+ writer.reader.find_attribute(def, "ConstantAttribute").map(|attribute| {
+ let args = writer.reader.attribute_args(attribute);
+ match &args[0].1 {
+ Value::String(value) => value.clone(),
+ rest => unimplemented!("{rest:?}"),
+ }
+ })
}
fn read_literal(input: &str) -> (&str, &str) {
diff --git a/vendor/windows-bindgen/src/rust/delegates.rs b/vendor/windows-bindgen/src/rust/delegates.rs
new file mode 100644
index 000000000..5b1b12022
--- /dev/null
+++ b/vendor/windows-bindgen/src/rust/delegates.rs
@@ -0,0 +1,156 @@
+use super::*;
+
+pub fn writer(writer: &Writer, def: TypeDef) -> TokenStream {
+ if writer.reader.type_def_flags(def).contains(TypeAttributes::WindowsRuntime) {
+ gen_delegate(writer, def)
+ } else {
+ gen_callback(writer, def)
+ }
+}
+
+fn gen_callback(writer: &Writer, def: TypeDef) -> TokenStream {
+ let name = to_ident(writer.reader.type_def_name(def));
+ let method = type_def_invoke_method(writer.reader, def);
+
+ let signature = method_def_signature(writer.reader, writer.reader.type_def_namespace(def), method, &[]);
+
+ let return_type = writer.return_sig(&signature);
+ let cfg = type_def_cfg(writer.reader, def, &[]);
+ let doc = writer.cfg_doc(&cfg);
+ let features = writer.cfg_features(&cfg);
+
+ let params = signature.params.iter().map(|p| {
+ let name = writer.param_name(p.def);
+ let tokens = writer.type_default_name(&p.ty);
+ quote! { #name: #tokens }
+ });
+
+ quote! {
+ #doc
+ #features
+ pub type #name = ::core::option::Option<unsafe extern "system" fn(#(#params),*) #return_type>;
+ }
+}
+
+fn gen_delegate(writer: &Writer, def: TypeDef) -> TokenStream {
+ if writer.sys {
+ let name = to_ident(writer.reader.type_def_name(def));
+ quote! {
+ pub type #name = *mut ::core::ffi::c_void;
+ }
+ } else {
+ gen_win_delegate(writer, def)
+ }
+}
+
+fn gen_win_delegate(writer: &Writer, def: TypeDef) -> TokenStream {
+ let name = to_ident(writer.reader.type_def_name(def));
+ let vtbl = name.join("_Vtbl");
+ let boxed = name.join("Box");
+
+ let generics = &type_def_generics(writer.reader, def);
+ let phantoms = writer.generic_phantoms(generics);
+ let named_phantoms = writer.generic_named_phantoms(generics);
+ let constraints = writer.generic_constraints(generics);
+ let generic_names = writer.generic_names(generics);
+
+ let ident = writer.type_def_name(def, generics);
+ let method = type_def_invoke_method(writer.reader, def);
+
+ let signature = method_def_signature(writer.reader, writer.reader.type_def_namespace(def), method, generics);
+
+ let fn_constraint = gen_fn_constraint(writer, def, &signature);
+ let cfg = type_def_cfg(writer.reader, def, generics);
+ let doc = writer.cfg_doc(&cfg);
+ let features = writer.cfg_features(&cfg);
+
+ let vtbl_signature = writer.vtbl_signature(def, generics, &signature);
+ let invoke = winrt_methods::writer(writer, def, generics, InterfaceKind::Default, method, &mut MethodNames::new(), &mut MethodNames::new());
+ let invoke_upcall = winrt_methods::gen_upcall(writer, &signature, quote! { ((*this).invoke) });
+
+ let mut tokens = quote! {
+ #doc
+ #features
+ #[repr(transparent)]
+ pub struct #ident(pub ::windows_core::IUnknown, #phantoms) where #constraints;
+ #features
+ impl<#constraints> #ident {
+ pub fn new<#fn_constraint>(invoke: F) -> Self {
+ let com = #boxed::<#generic_names F> {
+ vtable: &#boxed::<#generic_names F>::VTABLE,
+ count: ::windows_core::imp::RefCount::new(1),
+ invoke,
+ };
+ unsafe {
+ ::core::mem::transmute(::std::boxed::Box::new(com))
+ }
+ }
+ #invoke
+ }
+ #features
+ #[repr(C)]
+ struct #boxed<#generic_names #fn_constraint> where #constraints {
+ vtable: *const #vtbl<#generic_names>,
+ invoke: F,
+ count: ::windows_core::imp::RefCount,
+ }
+ #features
+ impl<#constraints #fn_constraint> #boxed<#generic_names F> {
+ const VTABLE: #vtbl<#generic_names> = #vtbl::<#generic_names>{
+ base__: ::windows_core::IUnknown_Vtbl{QueryInterface: Self::QueryInterface, AddRef: Self::AddRef, Release: Self::Release},
+ Invoke: Self::Invoke,
+ #(#named_phantoms)*
+ };
+ unsafe extern "system" fn QueryInterface(this: *mut ::core::ffi::c_void, iid: &::windows_core::GUID, interface: *mut *const ::core::ffi::c_void) -> ::windows_core::HRESULT {
+ let this = this as *mut *mut ::core::ffi::c_void as *mut Self;
+
+ *interface = if iid == &<#ident as ::windows_core::ComInterface>::IID ||
+ iid == &<::windows_core::IUnknown as ::windows_core::ComInterface>::IID ||
+ iid == &<::windows_core::imp::IAgileObject as ::windows_core::ComInterface>::IID {
+ &mut (*this).vtable as *mut _ as _
+ } else {
+ ::core::ptr::null_mut()
+ };
+
+ // TODO: implement IMarshal
+
+ if (*interface).is_null() {
+ ::windows_core::HRESULT(-2147467262) // E_NOINTERFACE
+ } else {
+ (*this).count.add_ref();
+ ::windows_core::HRESULT(0)
+ }
+ }
+ unsafe extern "system" fn AddRef(this: *mut ::core::ffi::c_void) -> u32 {
+ let this = this as *mut *mut ::core::ffi::c_void as *mut Self;
+ (*this).count.add_ref()
+ }
+ unsafe extern "system" fn Release(this: *mut ::core::ffi::c_void) -> u32 {
+ let this = this as *mut *mut ::core::ffi::c_void as *mut Self;
+ let remaining = (*this).count.release();
+
+ if remaining == 0 {
+ let _ = ::std::boxed::Box::from_raw(this);
+ }
+
+ remaining
+ }
+ unsafe extern "system" fn Invoke #vtbl_signature {
+ let this = this as *mut *mut ::core::ffi::c_void as *mut Self;
+ #invoke_upcall
+ }
+ }
+ };
+
+ tokens.combine(&writer.interface_core_traits(def, generics, &ident, &constraints, &phantoms, &features));
+ tokens.combine(&writer.interface_trait(def, generics, &ident, &constraints, &features, true));
+ tokens.combine(&writer.interface_winrt_trait(def, generics, &ident, &constraints, &phantoms, &features));
+ tokens.combine(&writer.interface_vtbl(def, generics, &ident, &constraints, &features));
+ tokens
+}
+
+fn gen_fn_constraint(writer: &Writer, def: TypeDef, signature: &Signature) -> TokenStream {
+ let signature = writer.impl_signature(def, signature);
+
+ quote! { F: FnMut #signature + ::core::marker::Send + 'static }
+}
diff --git a/vendor/windows-bindgen/src/enums.rs b/vendor/windows-bindgen/src/rust/enums.rs
index ee7616fda..344ca28ae 100644
--- a/vendor/windows-bindgen/src/enums.rs
+++ b/vendor/windows-bindgen/src/rust/enums.rs
@@ -1,27 +1,26 @@
use super::*;
-pub fn gen(gen: &Gen, def: TypeDef) -> TokenStream {
- let type_name = gen.reader.type_def_type_name(def);
+pub fn writer(writer: &Writer, def: TypeDef) -> TokenStream {
+ let type_name = writer.reader.type_def_type_name(def);
let ident = to_ident(type_name.name);
- let underlying_type = gen.reader.type_def_underlying_type(def);
- let underlying_type = gen.type_name(&underlying_type);
- let is_scoped = gen.reader.type_def_is_scoped(def);
- let cfg = gen.reader.type_def_cfg(def, &[]);
- let doc = gen.cfg_doc(&cfg);
- let features = gen.cfg_features(&cfg);
-
- let fields: Vec<(TokenStream, TokenStream)> = gen
+ let underlying_type = writer.reader.type_def_underlying_type(def);
+ let underlying_type = writer.type_name(&underlying_type);
+
+ // TODO: unscoped enums should be removed from metadata
+ let is_scoped = writer.reader.type_def_flags(def).contains(TypeAttributes::WindowsRuntime) || writer.reader.has_attribute(def, "ScopedEnumAttribute");
+
+ let cfg = type_def_cfg(writer.reader, def, &[]);
+ let doc = writer.cfg_doc(&cfg);
+ let features = writer.cfg_features(&cfg);
+
+ let fields: Vec<(TokenStream, TokenStream)> = writer
.reader
.type_def_fields(def)
.filter_map(|field| {
- if gen
- .reader
- .field_flags(field)
- .contains(FieldAttributes::LITERAL)
- {
- let field_name = to_ident(gen.reader.field_name(field));
- let constant = gen.reader.field_constant(field).unwrap();
- let value = gen.value(&gen.reader.constant_value(constant));
+ if writer.reader.field_flags(field).contains(FieldAttributes::Literal) {
+ let field_name = to_ident(writer.reader.field_name(field));
+ let constant = writer.reader.field_constant(field).unwrap();
+ let value = writer.value(&writer.reader.constant_value(constant));
Some((field_name, value))
} else {
@@ -30,7 +29,7 @@ pub fn gen(gen: &Gen, def: TypeDef) -> TokenStream {
})
.collect();
- let eq = if gen.sys {
+ let eq = if writer.sys {
quote! {}
} else {
quote! {
@@ -39,7 +38,7 @@ pub fn gen(gen: &Gen, def: TypeDef) -> TokenStream {
}
};
- let mut tokens = if is_scoped || !gen.sys {
+ let mut tokens = if is_scoped || !writer.sys {
quote! {
#doc
#features
@@ -55,48 +54,22 @@ pub fn gen(gen: &Gen, def: TypeDef) -> TokenStream {
}
};
- tokens.combine(&if is_scoped {
+ if is_scoped {
let fields = fields.iter().map(|(field_name, value)| {
quote! {
pub const #field_name: Self = Self(#value);
}
});
- quote! {
+ tokens.combine(&quote! {
#features
impl #ident {
#(#fields)*
}
- }
- } else if !gen.sys {
- let fields = fields.iter().map(|(field_name, value)| {
- quote! {
- #doc
- #features
- pub const #field_name: #ident = #ident(#value);
- }
});
+ }
- quote! {
- #(#fields)*
- }
- } else if !gen.standalone {
- let fields = fields.iter().map(|(field_name, value)| {
- quote! {
- #doc
- #features
- pub const #field_name: #ident = #value;
- }
- });
-
- quote! {
- #(#fields)*
- }
- } else {
- quote! {}
- });
-
- if is_scoped || !gen.sys {
+ if is_scoped || !writer.sys {
tokens.combine(&quote! {
#features
impl ::core::marker::Copy for #ident {}
@@ -109,7 +82,7 @@ pub fn gen(gen: &Gen, def: TypeDef) -> TokenStream {
});
}
- if !gen.sys {
+ if !writer.sys {
tokens.combine(&quote! {
#features
impl ::core::default::Default for #ident {
@@ -120,12 +93,12 @@ pub fn gen(gen: &Gen, def: TypeDef) -> TokenStream {
});
}
- if !gen.sys {
+ if !writer.sys {
let name = type_name.name;
tokens.combine(&quote! {
#features
- impl ::windows::core::TypeKind for #ident {
- type TypeKind = ::windows::core::CopyType;
+ impl ::windows_core::TypeKind for #ident {
+ type TypeKind = ::windows_core::CopyType;
}
#features
impl ::core::fmt::Debug for #ident {
@@ -135,7 +108,12 @@ pub fn gen(gen: &Gen, def: TypeDef) -> TokenStream {
}
});
- if gen.reader.type_def_is_flags(def) {
+ // Win32 enums use the Flags attribute. WinRT enums don't have the Flags attribute but are paritioned merely based
+ // on whether they are signed.
+ // TODO: Win32 metadata should just follow WinRT's example here.
+ let type_def_is_flags = writer.reader.has_attribute(def, "FlagsAttribute") || (writer.reader.type_def_flags(def).contains(TypeAttributes::WindowsRuntime) && writer.reader.type_def_underlying_type(def) == Type::U32);
+
+ if type_def_is_flags {
tokens.combine(&quote! {
#features
impl #ident {
@@ -182,18 +160,13 @@ pub fn gen(gen: &Gen, def: TypeDef) -> TokenStream {
});
}
- if gen
- .reader
- .type_def_flags(def)
- .contains(TypeAttributes::WINRT)
- {
- let signature =
- Literal::byte_string(gen.reader.type_def_signature(def, &[]).as_bytes());
+ if writer.reader.type_def_flags(def).contains(TypeAttributes::WindowsRuntime) {
+ let signature = Literal::byte_string(type_def_signature(writer.reader, def, &[]).as_bytes());
tokens.combine(&quote! {
#features
- impl ::windows::core::RuntimeType for #ident {
- const SIGNATURE: ::windows::imp::ConstBuffer = ::windows::imp::ConstBuffer::from_slice(#signature);
+ impl ::windows_core::RuntimeType for #ident {
+ const SIGNATURE: ::windows_core::imp::ConstBuffer = ::windows_core::imp::ConstBuffer::from_slice(#signature);
}
});
}
diff --git a/vendor/windows-bindgen/src/extensions/impl/Foundation/Collections/Iterable.rs b/vendor/windows-bindgen/src/rust/extensions/impl/Foundation/Collections/Iterable.rs
index 7d379fdf6..6bed10d68 100644
--- a/vendor/windows-bindgen/src/extensions/impl/Foundation/Collections/Iterable.rs
+++ b/vendor/windows-bindgen/src/rust/extensions/impl/Foundation/Collections/Iterable.rs
@@ -1,18 +1,18 @@
-#[::windows::core::implement(IIterable<T>)]
+#[::windows_implement::implement(IIterable<T>)]
struct StockIterable<T>
where
- T: ::windows::core::RuntimeType + 'static,
- <T as ::windows::core::Type<T>>::Default: ::std::clone::Clone,
+ T: ::windows_core::RuntimeType + 'static,
+ <T as ::windows_core::Type<T>>::Default: ::std::clone::Clone,
{
values: std::vec::Vec<T::Default>,
}
impl<T> IIterable_Impl<T> for StockIterable<T>
where
- T: ::windows::core::RuntimeType,
- <T as ::windows::core::Type<T>>::Default: ::std::clone::Clone,
+ T: ::windows_core::RuntimeType,
+ <T as ::windows_core::Type<T>>::Default: ::std::clone::Clone,
{
- fn First(&self) -> ::windows::core::Result<IIterator<T>> {
+ fn First(&self) -> ::windows_core::Result<IIterator<T>> {
unsafe {
// TODO: ideally we can do an AddRef rather than a QI here (via cast)...
// and then we can get rid of the unsafe as well.
@@ -25,11 +25,11 @@ where
}
}
-#[::windows::core::implement(IIterator<T>)]
+#[::windows_implement::implement(IIterator<T>)]
struct StockIterator<T>
where
- T: ::windows::core::RuntimeType + 'static,
- <T as ::windows::core::Type<T>>::Default: ::std::clone::Clone,
+ T: ::windows_core::RuntimeType + 'static,
+ <T as ::windows_core::Type<T>>::Default: ::std::clone::Clone,
{
owner: IIterable<T>,
current: ::std::sync::atomic::AtomicUsize,
@@ -37,29 +37,29 @@ where
impl<T> IIterator_Impl<T> for StockIterator<T>
where
- T: ::windows::core::RuntimeType,
- <T as ::windows::core::Type<T>>::Default: ::std::clone::Clone,
+ T: ::windows_core::RuntimeType,
+ <T as ::windows_core::Type<T>>::Default: ::std::clone::Clone,
{
- fn Current(&self) -> ::windows::core::Result<T> {
- let owner: &StockIterable<T> = ::windows::core::AsImpl::as_impl(&self.owner);
+ fn Current(&self) -> ::windows_core::Result<T> {
+ let owner: &StockIterable<T> = unsafe { ::windows_core::AsImpl::as_impl(&self.owner) };
let current = self.current.load(::std::sync::atomic::Ordering::Relaxed);
if owner.values.len() > current {
T::from_default(&owner.values[current])
} else {
- Err(::windows::imp::E_BOUNDS.into())
+ Err(::windows_core::Error::from(::windows_core::imp::E_BOUNDS))
}
}
- fn HasCurrent(&self) -> ::windows::core::Result<bool> {
- let owner: &StockIterable<T> = ::windows::core::AsImpl::as_impl(&self.owner);
+ fn HasCurrent(&self) -> ::windows_core::Result<bool> {
+ let owner: &StockIterable<T> = unsafe { ::windows_core::AsImpl::as_impl(&self.owner) };
let current = self.current.load(::std::sync::atomic::Ordering::Relaxed);
Ok(owner.values.len() > current)
}
- fn MoveNext(&self) -> ::windows::core::Result<bool> {
- let owner: &StockIterable<T> = ::windows::core::AsImpl::as_impl(&self.owner);
+ fn MoveNext(&self) -> ::windows_core::Result<bool> {
+ let owner: &StockIterable<T> = unsafe { ::windows_core::AsImpl::as_impl(&self.owner) };
let current = self.current.load(::std::sync::atomic::Ordering::Relaxed);
if current < owner.values.len() {
@@ -70,8 +70,8 @@ where
Ok(owner.values.len() > current + 1)
}
- fn GetMany(&self, values: &mut [T::Default]) -> ::windows::core::Result<u32> {
- let owner: &StockIterable<T> = ::windows::core::AsImpl::as_impl(&self.owner);
+ fn GetMany(&self, values: &mut [T::Default]) -> ::windows_core::Result<u32> {
+ let owner: &StockIterable<T> = unsafe { ::windows_core::AsImpl::as_impl(&self.owner) };
let current = self.current.load(::std::sync::atomic::Ordering::Relaxed);
let actual = std::cmp::min(owner.values.len() - current, values.len());
@@ -79,17 +79,17 @@ where
values.clone_from_slice(&owner.values[current..current + actual]);
self.current
.fetch_add(actual, ::std::sync::atomic::Ordering::Relaxed);
- Ok(actual as _)
+ Ok(actual as u32)
}
}
impl<T> ::core::convert::TryFrom<::std::vec::Vec<T::Default>> for IIterable<T>
where
- T: ::windows::core::RuntimeType,
- <T as ::windows::core::Type<T>>::Default: ::std::clone::Clone,
+ T: ::windows_core::RuntimeType,
+ <T as ::windows_core::Type<T>>::Default: ::std::clone::Clone,
{
- type Error = ::windows::core::Error;
- fn try_from(values: ::std::vec::Vec<T::Default>) -> ::windows::core::Result<Self> {
+ type Error = ::windows_core::Error;
+ fn try_from(values: ::std::vec::Vec<T::Default>) -> ::windows_core::Result<Self> {
// TODO: should provide a fallible try_into or more explicit allocator
Ok(StockIterable { values }.into())
}
diff --git a/vendor/windows-bindgen/src/extensions/impl/Foundation/Collections/MapView.rs b/vendor/windows-bindgen/src/rust/extensions/impl/Foundation/Collections/MapView.rs
index e8980e4d2..72b39f56e 100644
--- a/vendor/windows-bindgen/src/extensions/impl/Foundation/Collections/MapView.rs
+++ b/vendor/windows-bindgen/src/rust/extensions/impl/Foundation/Collections/MapView.rs
@@ -1,22 +1,22 @@
-#[windows::core::implement(IMapView<K, V>, IIterable<IKeyValuePair<K, V>>)]
+#[::windows_implement::implement(IMapView<K, V>, IIterable<IKeyValuePair<K, V>>)]
struct StockMapView<K, V>
where
- K: windows::core::RuntimeType + 'static,
- V: windows::core::RuntimeType + 'static,
- <K as windows::core::Type<K>>::Default: std::clone::Clone + std::cmp::Ord,
- <V as windows::core::Type<V>>::Default: std::clone::Clone,
+ K: ::windows_core::RuntimeType + 'static,
+ V: ::windows_core::RuntimeType + 'static,
+ <K as ::windows_core::Type<K>>::Default: std::clone::Clone + std::cmp::Ord,
+ <V as ::windows_core::Type<V>>::Default: std::clone::Clone,
{
map: std::collections::BTreeMap<K::Default, V::Default>,
}
impl<K, V> IIterable_Impl<IKeyValuePair<K, V>> for StockMapView<K, V>
where
- K: windows::core::RuntimeType,
- V: windows::core::RuntimeType,
- <K as windows::core::Type<K>>::Default: std::clone::Clone + std::cmp::Ord,
- <V as windows::core::Type<V>>::Default: std::clone::Clone,
+ K: ::windows_core::RuntimeType,
+ V: ::windows_core::RuntimeType,
+ <K as ::windows_core::Type<K>>::Default: std::clone::Clone + std::cmp::Ord,
+ <V as ::windows_core::Type<V>>::Default: std::clone::Clone,
{
- fn First(&self) -> windows::core::Result<IIterator<IKeyValuePair<K, V>>> {
+ fn First(&self) -> ::windows_core::Result<IIterator<IKeyValuePair<K, V>>> {
unsafe {
// TODO: ideally we can do an AddRef rather than a QI here (via cast)...
// and then we can get rid of the unsafe as well.
@@ -31,42 +31,42 @@ where
impl<K, V> IMapView_Impl<K, V> for StockMapView<K, V>
where
- K: windows::core::RuntimeType,
- V: windows::core::RuntimeType,
- <K as windows::core::Type<K>>::Default: std::clone::Clone + std::cmp::Ord,
- <V as windows::core::Type<V>>::Default: std::clone::Clone,
+ K: ::windows_core::RuntimeType,
+ V: ::windows_core::RuntimeType,
+ <K as ::windows_core::Type<K>>::Default: std::clone::Clone + std::cmp::Ord,
+ <V as ::windows_core::Type<V>>::Default: std::clone::Clone,
{
- fn Lookup(&self, key: &K::Default) -> windows::core::Result<V> {
+ fn Lookup(&self, key: &K::Default) -> ::windows_core::Result<V> {
let value = self
.map
.get(key)
- .ok_or_else(|| windows::core::Error::from(windows::imp::E_BOUNDS))?;
+ .ok_or_else(|| ::windows_core::Error::from(::windows_core::imp::E_BOUNDS))?;
V::from_default(value)
}
- fn Size(&self) -> windows::core::Result<u32> {
- Ok(self.map.len() as _)
+ fn Size(&self) -> ::windows_core::Result<u32> {
+ Ok(self.map.len() as u32)
}
- fn HasKey(&self, key: &K::Default) -> windows::core::Result<bool> {
+ fn HasKey(&self, key: &K::Default) -> ::windows_core::Result<bool> {
Ok(self.map.contains_key(key))
}
fn Split(
&self,
first: &mut std::option::Option<IMapView<K, V>>,
second: &mut std::option::Option<IMapView<K, V>>,
- ) -> windows::core::Result<()> {
+ ) -> ::windows_core::Result<()> {
*first = None;
*second = None;
Ok(())
}
}
-#[::windows::core::implement(IIterator<IKeyValuePair<K, V>>)]
+#[::windows_implement::implement(IIterator<IKeyValuePair<K, V>>)]
struct StockMapViewIterator<'a, K, V>
where
- K: windows::core::RuntimeType + 'static,
- V: windows::core::RuntimeType + 'static,
- <K as windows::core::Type<K>>::Default: std::clone::Clone + std::cmp::Ord,
- <V as windows::core::Type<V>>::Default: std::clone::Clone,
+ K: ::windows_core::RuntimeType + 'static,
+ V: ::windows_core::RuntimeType + 'static,
+ <K as ::windows_core::Type<K>>::Default: std::clone::Clone + std::cmp::Ord,
+ <V as ::windows_core::Type<V>>::Default: std::clone::Clone,
{
_owner: IIterable<IKeyValuePair<K, V>>,
current: ::std::sync::RwLock<std::collections::btree_map::Iter<'a, K::Default, V::Default>>,
@@ -74,12 +74,12 @@ where
impl<'a, K, V> IIterator_Impl<IKeyValuePair<K, V>> for StockMapViewIterator<'a, K, V>
where
- K: windows::core::RuntimeType,
- V: windows::core::RuntimeType,
- <K as windows::core::Type<K>>::Default: std::clone::Clone + std::cmp::Ord,
- <V as windows::core::Type<V>>::Default: std::clone::Clone,
+ K: ::windows_core::RuntimeType,
+ V: ::windows_core::RuntimeType,
+ <K as ::windows_core::Type<K>>::Default: std::clone::Clone + std::cmp::Ord,
+ <V as ::windows_core::Type<V>>::Default: std::clone::Clone,
{
- fn Current(&self) -> ::windows::core::Result<IKeyValuePair<K, V>> {
+ fn Current(&self) -> ::windows_core::Result<IKeyValuePair<K, V>> {
let mut current = self.current.read().unwrap().clone().peekable();
if let Some((key, value)) = current.peek() {
@@ -89,24 +89,24 @@ where
}
.into())
} else {
- Err(windows::core::Error::from(windows::imp::E_BOUNDS))
+ Err(::windows_core::Error::from(::windows_core::imp::E_BOUNDS))
}
}
- fn HasCurrent(&self) -> ::windows::core::Result<bool> {
+ fn HasCurrent(&self) -> ::windows_core::Result<bool> {
let mut current = self.current.read().unwrap().clone().peekable();
Ok(current.peek().is_some())
}
- fn MoveNext(&self) -> ::windows::core::Result<bool> {
+ fn MoveNext(&self) -> ::windows_core::Result<bool> {
let mut current = self.current.write().unwrap();
current.next();
Ok(current.clone().peekable().peek().is_some())
}
- fn GetMany(&self, pairs: &mut [Option<IKeyValuePair<K, V>>]) -> ::windows::core::Result<u32> {
+ fn GetMany(&self, pairs: &mut [Option<IKeyValuePair<K, V>>]) -> ::windows_core::Result<u32> {
let mut current = self.current.write().unwrap();
let mut actual = 0;
@@ -125,17 +125,17 @@ where
}
}
- Ok(actual as _)
+ Ok(actual)
}
}
-#[windows::core::implement(IKeyValuePair<K, V>)]
+#[::windows_implement::implement(IKeyValuePair<K, V>)]
struct StockKeyValuePair<K, V>
where
- K: windows::core::RuntimeType + 'static,
- V: windows::core::RuntimeType + 'static,
- <K as windows::core::Type<K>>::Default: std::clone::Clone,
- <V as windows::core::Type<V>>::Default: std::clone::Clone,
+ K: ::windows_core::RuntimeType + 'static,
+ V: ::windows_core::RuntimeType + 'static,
+ <K as ::windows_core::Type<K>>::Default: std::clone::Clone,
+ <V as ::windows_core::Type<V>>::Default: std::clone::Clone,
{
key: K::Default,
value: V::Default,
@@ -143,15 +143,15 @@ where
impl<K, V> IKeyValuePair_Impl<K, V> for StockKeyValuePair<K, V>
where
- K: windows::core::RuntimeType,
- V: windows::core::RuntimeType,
- <K as windows::core::Type<K>>::Default: std::clone::Clone,
- <V as windows::core::Type<V>>::Default: std::clone::Clone,
+ K: ::windows_core::RuntimeType,
+ V: ::windows_core::RuntimeType,
+ <K as ::windows_core::Type<K>>::Default: std::clone::Clone,
+ <V as ::windows_core::Type<V>>::Default: std::clone::Clone,
{
- fn Key(&self) -> windows::core::Result<K> {
+ fn Key(&self) -> ::windows_core::Result<K> {
K::from_default(&self.key)
}
- fn Value(&self) -> windows::core::Result<V> {
+ fn Value(&self) -> ::windows_core::Result<V> {
V::from_default(&self.value)
}
}
@@ -159,15 +159,15 @@ where
impl<K, V> ::core::convert::TryFrom<std::collections::BTreeMap<K::Default, V::Default>>
for IMapView<K, V>
where
- K: windows::core::RuntimeType,
- V: windows::core::RuntimeType,
- <K as windows::core::Type<K>>::Default: std::clone::Clone + std::cmp::Ord,
- <V as windows::core::Type<V>>::Default: std::clone::Clone,
+ K: ::windows_core::RuntimeType,
+ V: ::windows_core::RuntimeType,
+ <K as ::windows_core::Type<K>>::Default: std::clone::Clone + std::cmp::Ord,
+ <V as ::windows_core::Type<V>>::Default: std::clone::Clone,
{
- type Error = ::windows::core::Error;
+ type Error = ::windows_core::Error;
fn try_from(
map: std::collections::BTreeMap<K::Default, V::Default>,
- ) -> windows::core::Result<Self> {
+ ) -> ::windows_core::Result<Self> {
// TODO: should provide a fallible try_into or more explicit allocator
Ok(StockMapView { map }.into())
}
diff --git a/vendor/windows-bindgen/src/extensions/impl/Foundation/Collections/VectorView.rs b/vendor/windows-bindgen/src/rust/extensions/impl/Foundation/Collections/VectorView.rs
index c51dc0c8c..cc482b70f 100644
--- a/vendor/windows-bindgen/src/extensions/impl/Foundation/Collections/VectorView.rs
+++ b/vendor/windows-bindgen/src/rust/extensions/impl/Foundation/Collections/VectorView.rs
@@ -1,18 +1,18 @@
-#[windows::core::implement(IVectorView<T>, IIterable<T>)]
+#[::windows_implement::implement(IVectorView<T>, IIterable<T>)]
struct StockVectorView<T>
where
- T: windows::core::RuntimeType + 'static,
- <T as windows::core::Type<T>>::Default: std::clone::Clone + std::cmp::PartialEq,
+ T: ::windows_core::RuntimeType + 'static,
+ <T as ::windows_core::Type<T>>::Default: std::clone::Clone + std::cmp::PartialEq,
{
values: std::vec::Vec<T::Default>,
}
impl<T> IIterable_Impl<T> for StockVectorView<T>
where
- T: windows::core::RuntimeType,
- <T as windows::core::Type<T>>::Default: std::clone::Clone + std::cmp::PartialEq,
+ T: ::windows_core::RuntimeType,
+ <T as ::windows_core::Type<T>>::Default: std::clone::Clone + std::cmp::PartialEq,
{
- fn First(&self) -> windows::core::Result<IIterator<T>> {
+ fn First(&self) -> ::windows_core::Result<IIterator<T>> {
unsafe {
// TODO: ideally we can do an AddRef rather than a QI here (via cast)...
// and then we can get rid of the unsafe as well.
@@ -27,29 +27,29 @@ where
impl<T> IVectorView_Impl<T> for StockVectorView<T>
where
- T: windows::core::RuntimeType,
- <T as windows::core::Type<T>>::Default: std::clone::Clone + std::cmp::PartialEq,
+ T: ::windows_core::RuntimeType,
+ <T as ::windows_core::Type<T>>::Default: std::clone::Clone + std::cmp::PartialEq,
{
- fn GetAt(&self, index: u32) -> windows::core::Result<T> {
+ fn GetAt(&self, index: u32) -> ::windows_core::Result<T> {
let item = self
.values
.get(index as usize)
- .ok_or_else(|| windows::core::Error::from(windows::imp::E_BOUNDS))?;
+ .ok_or_else(|| ::windows_core::Error::from(::windows_core::imp::E_BOUNDS))?;
T::from_default(item)
}
- fn Size(&self) -> windows::core::Result<u32> {
- Ok(self.values.len() as _)
+ fn Size(&self) -> ::windows_core::Result<u32> {
+ Ok(self.values.len() as u32)
}
- fn IndexOf(&self, value: &T::Default, result: &mut u32) -> windows::core::Result<bool> {
+ fn IndexOf(&self, value: &T::Default, result: &mut u32) -> ::windows_core::Result<bool> {
match self.values.iter().position(|element| element == value) {
Some(index) => {
- *result = index as _;
+ *result = index as u32;
Ok(true)
}
None => Ok(false),
}
}
- fn GetMany(&self, current: u32, values: &mut [T::Default]) -> windows::core::Result<u32> {
+ fn GetMany(&self, current: u32, values: &mut [T::Default]) -> ::windows_core::Result<u32> {
let current = current as usize;
if current >= self.values.len() {
return Ok(0);
@@ -57,15 +57,15 @@ where
let actual = std::cmp::min(self.values.len() - current, values.len());
let (values, _) = values.split_at_mut(actual);
values.clone_from_slice(&self.values[current..current + actual]);
- Ok(actual as _)
+ Ok(actual as u32)
}
}
-#[::windows::core::implement(IIterator<T>)]
+#[::windows_implement::implement(IIterator<T>)]
struct StockVectorViewIterator<T>
where
- T: ::windows::core::RuntimeType + 'static,
- <T as ::windows::core::Type<T>>::Default: std::clone::Clone + std::cmp::PartialEq,
+ T: ::windows_core::RuntimeType + 'static,
+ <T as ::windows_core::Type<T>>::Default: std::clone::Clone + std::cmp::PartialEq,
{
owner: IIterable<T>,
current: ::std::sync::atomic::AtomicUsize,
@@ -73,29 +73,29 @@ where
impl<T> IIterator_Impl<T> for StockVectorViewIterator<T>
where
- T: ::windows::core::RuntimeType,
- <T as ::windows::core::Type<T>>::Default: std::clone::Clone + std::cmp::PartialEq,
+ T: ::windows_core::RuntimeType,
+ <T as ::windows_core::Type<T>>::Default: std::clone::Clone + std::cmp::PartialEq,
{
- fn Current(&self) -> ::windows::core::Result<T> {
- let owner: &StockVectorView<T> = ::windows::core::AsImpl::as_impl(&self.owner);
+ fn Current(&self) -> ::windows_core::Result<T> {
+ let owner: &StockVectorView<T> = unsafe { ::windows_core::AsImpl::as_impl(&self.owner) };
let current = self.current.load(::std::sync::atomic::Ordering::Relaxed);
if owner.values.len() > current {
T::from_default(&owner.values[current])
} else {
- Err(windows::core::Error::from(windows::imp::E_BOUNDS))
+ Err(::windows_core::Error::from(::windows_core::imp::E_BOUNDS))
}
}
- fn HasCurrent(&self) -> ::windows::core::Result<bool> {
- let owner: &StockVectorView<T> = ::windows::core::AsImpl::as_impl(&self.owner);
+ fn HasCurrent(&self) -> ::windows_core::Result<bool> {
+ let owner: &StockVectorView<T> = unsafe { ::windows_core::AsImpl::as_impl(&self.owner) };
let current = self.current.load(::std::sync::atomic::Ordering::Relaxed);
Ok(owner.values.len() > current)
}
- fn MoveNext(&self) -> ::windows::core::Result<bool> {
- let owner: &StockVectorView<T> = ::windows::core::AsImpl::as_impl(&self.owner);
+ fn MoveNext(&self) -> ::windows_core::Result<bool> {
+ let owner: &StockVectorView<T> = unsafe { ::windows_core::AsImpl::as_impl(&self.owner) };
let current = self.current.load(::std::sync::atomic::Ordering::Relaxed);
if current < owner.values.len() {
@@ -106,8 +106,8 @@ where
Ok(owner.values.len() > current + 1)
}
- fn GetMany(&self, values: &mut [T::Default]) -> ::windows::core::Result<u32> {
- let owner: &StockVectorView<T> = ::windows::core::AsImpl::as_impl(&self.owner);
+ fn GetMany(&self, values: &mut [T::Default]) -> ::windows_core::Result<u32> {
+ let owner: &StockVectorView<T> = unsafe { ::windows_core::AsImpl::as_impl(&self.owner) };
let current = self.current.load(::std::sync::atomic::Ordering::Relaxed);
let actual = std::cmp::min(owner.values.len() - current, values.len());
@@ -115,17 +115,17 @@ where
values.clone_from_slice(&owner.values[current..current + actual]);
self.current
.fetch_add(actual, ::std::sync::atomic::Ordering::Relaxed);
- Ok(actual as _)
+ Ok(actual as u32)
}
}
impl<T> ::core::convert::TryFrom<::std::vec::Vec<T::Default>> for IVectorView<T>
where
- T: ::windows::core::RuntimeType,
- <T as ::windows::core::Type<T>>::Default: std::clone::Clone + std::cmp::PartialEq,
+ T: ::windows_core::RuntimeType,
+ <T as ::windows_core::Type<T>>::Default: std::clone::Clone + std::cmp::PartialEq,
{
- type Error = ::windows::core::Error;
- fn try_from(values: ::std::vec::Vec<T::Default>) -> ::windows::core::Result<Self> {
+ type Error = ::windows_core::Error;
+ fn try_from(values: ::std::vec::Vec<T::Default>) -> ::windows_core::Result<Self> {
// TODO: should provide a fallible try_into or more explicit allocator
Ok(StockVectorView { values }.into())
}
diff --git a/vendor/windows-bindgen/src/rust/extensions/mod.rs b/vendor/windows-bindgen/src/rust/extensions/mod.rs
new file mode 100644
index 000000000..8d8f71ed6
--- /dev/null
+++ b/vendor/windows-bindgen/src/rust/extensions/mod.rs
@@ -0,0 +1,31 @@
+use super::*;
+
+pub fn gen_mod(writer: &Writer, namespace: &str) -> TokenStream {
+ if namespace == "Windows.Win32.UI.WindowsAndMessaging" {
+ return include_str!("mod/Win32/UI/WindowsAndMessaging/WindowLong.rs").into();
+ }
+
+ if writer.sys {
+ return "".into();
+ }
+
+ match namespace {
+ "Windows.Foundation.Numerics" => concat!(include_str!("mod/Foundation/Numerics/Matrix3x2.rs"), include_str!("mod/Foundation/Numerics/Matrix4x4.rs"), include_str!("mod/Foundation/Numerics/Vector2.rs"), include_str!("mod/Foundation/Numerics/Vector3.rs"), include_str!("mod/Foundation/Numerics/Vector4.rs"),),
+ "Windows.Foundation" => concat!(include_str!("mod/Foundation/TimeSpan.rs"),),
+ "Windows.Win32.Foundation" => concat!(include_str!("mod/Win32/Foundation/BOOL.rs"), include_str!("mod/Win32/Foundation/BOOLEAN.rs"), include_str!("mod/Win32/Foundation/NTSTATUS.rs"), include_str!("mod/Win32/Foundation/VARIANT_BOOL.rs"), include_str!("mod/Win32/Foundation/WIN32_ERROR.rs"),),
+ "Windows.Win32.Networking.WinSock" => concat!(include_str!("mod/Win32/Networking/WinSock/IN_ADDR.rs"), include_str!("mod/Win32/Networking/WinSock/IN6_ADDR.rs"), include_str!("mod/Win32/Networking/WinSock/SOCKADDR_IN.rs"), include_str!("mod/Win32/Networking/WinSock/SOCKADDR_IN6.rs"), include_str!("mod/Win32/Networking/WinSock/SOCKADDR_INET.rs"),),
+ "Windows.Win32.UI.WindowsAndMessaging" => {
+ include_str!("mod/Win32/UI/WindowsAndMessaging/WindowLong.rs")
+ }
+ _ => "",
+ }
+ .into()
+}
+
+pub fn gen_impl(namespace: &str) -> TokenStream {
+ match namespace {
+ "Windows.Foundation.Collections" => concat!(include_str!("impl/Foundation/Collections/Iterable.rs"), include_str!("impl/Foundation/Collections/MapView.rs"), include_str!("impl/Foundation/Collections/VectorView.rs"),),
+ _ => "",
+ }
+ .into()
+}
diff --git a/vendor/windows-bindgen/src/extensions/mod/Foundation/Numerics/Matrix3x2.rs b/vendor/windows-bindgen/src/rust/extensions/mod/Foundation/Numerics/Matrix3x2.rs
index 98be80636..98be80636 100644
--- a/vendor/windows-bindgen/src/extensions/mod/Foundation/Numerics/Matrix3x2.rs
+++ b/vendor/windows-bindgen/src/rust/extensions/mod/Foundation/Numerics/Matrix3x2.rs
diff --git a/vendor/windows-bindgen/src/extensions/mod/Foundation/Numerics/Matrix4x4.rs b/vendor/windows-bindgen/src/rust/extensions/mod/Foundation/Numerics/Matrix4x4.rs
index fb5d60866..fb5d60866 100644
--- a/vendor/windows-bindgen/src/extensions/mod/Foundation/Numerics/Matrix4x4.rs
+++ b/vendor/windows-bindgen/src/rust/extensions/mod/Foundation/Numerics/Matrix4x4.rs
diff --git a/vendor/windows-bindgen/src/extensions/mod/Foundation/Numerics/Vector2.rs b/vendor/windows-bindgen/src/rust/extensions/mod/Foundation/Numerics/Vector2.rs
index f37b4620b..f37b4620b 100644
--- a/vendor/windows-bindgen/src/extensions/mod/Foundation/Numerics/Vector2.rs
+++ b/vendor/windows-bindgen/src/rust/extensions/mod/Foundation/Numerics/Vector2.rs
diff --git a/vendor/windows-bindgen/src/extensions/mod/Foundation/Numerics/Vector3.rs b/vendor/windows-bindgen/src/rust/extensions/mod/Foundation/Numerics/Vector3.rs
index 58dcf9653..58dcf9653 100644
--- a/vendor/windows-bindgen/src/extensions/mod/Foundation/Numerics/Vector3.rs
+++ b/vendor/windows-bindgen/src/rust/extensions/mod/Foundation/Numerics/Vector3.rs
diff --git a/vendor/windows-bindgen/src/extensions/mod/Foundation/Numerics/Vector4.rs b/vendor/windows-bindgen/src/rust/extensions/mod/Foundation/Numerics/Vector4.rs
index 69609d906..69609d906 100644
--- a/vendor/windows-bindgen/src/extensions/mod/Foundation/Numerics/Vector4.rs
+++ b/vendor/windows-bindgen/src/rust/extensions/mod/Foundation/Numerics/Vector4.rs
diff --git a/vendor/windows-bindgen/src/extensions/mod/Foundation/TimeSpan.rs b/vendor/windows-bindgen/src/rust/extensions/mod/Foundation/TimeSpan.rs
index 814b3d45b..814b3d45b 100644
--- a/vendor/windows-bindgen/src/extensions/mod/Foundation/TimeSpan.rs
+++ b/vendor/windows-bindgen/src/rust/extensions/mod/Foundation/TimeSpan.rs
diff --git a/vendor/windows-bindgen/src/extensions/mod/Win32/Foundation/BOOL.rs b/vendor/windows-bindgen/src/rust/extensions/mod/Win32/Foundation/BOOL.rs
index f09ae9111..2499fa964 100644
--- a/vendor/windows-bindgen/src/extensions/mod/Win32/Foundation/BOOL.rs
+++ b/vendor/windows-bindgen/src/rust/extensions/mod/Win32/Foundation/BOOL.rs
@@ -4,11 +4,11 @@ impl BOOL {
self.0 != 0
}
#[inline]
- pub fn ok(self) -> ::windows::core::Result<()> {
+ pub fn ok(self) -> ::windows_core::Result<()> {
if self.as_bool() {
Ok(())
} else {
- Err(::windows::core::Error::from_win32())
+ Err(::windows_core::Error::from_win32())
}
}
#[inline]
@@ -66,8 +66,8 @@ impl ::core::ops::Not for BOOL {
}
}
}
-impl windows::core::IntoParam<BOOL> for bool {
- fn into_param(self) -> windows::core::Param<BOOL> {
- windows::core::Param::Owned(self.into())
+impl ::windows_core::IntoParam<BOOL> for bool {
+ fn into_param(self) -> ::windows_core::Param<BOOL> {
+ ::windows_core::Param::Owned(self.into())
}
}
diff --git a/vendor/windows-bindgen/src/extensions/mod/Win32/Foundation/BOOLEAN.rs b/vendor/windows-bindgen/src/rust/extensions/mod/Win32/Foundation/BOOLEAN.rs
index 44afc65c2..dd113d100 100644
--- a/vendor/windows-bindgen/src/extensions/mod/Win32/Foundation/BOOLEAN.rs
+++ b/vendor/windows-bindgen/src/rust/extensions/mod/Win32/Foundation/BOOLEAN.rs
@@ -4,11 +4,11 @@ impl BOOLEAN {
self.0 != 0
}
#[inline]
- pub fn ok(self) -> ::windows::core::Result<()> {
+ pub fn ok(self) -> ::windows_core::Result<()> {
if self.as_bool() {
Ok(())
} else {
- Err(::windows::core::Error::from_win32())
+ Err(::windows_core::Error::from_win32())
}
}
#[inline]
diff --git a/vendor/windows-bindgen/src/rust/extensions/mod/Win32/Foundation/NTSTATUS.rs b/vendor/windows-bindgen/src/rust/extensions/mod/Win32/Foundation/NTSTATUS.rs
new file mode 100644
index 000000000..324b4e3d5
--- /dev/null
+++ b/vendor/windows-bindgen/src/rust/extensions/mod/Win32/Foundation/NTSTATUS.rs
@@ -0,0 +1,32 @@
+impl NTSTATUS {
+ #[inline]
+ pub const fn is_ok(self) -> bool {
+ self.0 >= 0
+ }
+ #[inline]
+ pub const fn is_err(self) -> bool {
+ !self.is_ok()
+ }
+ #[inline]
+ pub const fn to_hresult(self) -> ::windows_core::HRESULT {
+ ::windows_core::HRESULT(self.0 | 0x1000_0000)
+ }
+ #[inline]
+ pub fn ok(self) -> ::windows_core::Result<()> {
+ if self.is_ok() {
+ Ok(())
+ } else {
+ Err(self.to_hresult().into())
+ }
+ }
+}
+impl ::core::convert::From<NTSTATUS> for ::windows_core::HRESULT {
+ fn from(value: NTSTATUS) -> Self {
+ value.to_hresult()
+ }
+}
+impl ::core::convert::From<NTSTATUS> for ::windows_core::Error {
+ fn from(value: NTSTATUS) -> Self {
+ value.to_hresult().into()
+ }
+}
diff --git a/vendor/windows-bindgen/src/extensions/mod/Win32/Foundation/VARIANT_BOOL.rs b/vendor/windows-bindgen/src/rust/extensions/mod/Win32/Foundation/VARIANT_BOOL.rs
index 3015224ef..7952f005e 100644
--- a/vendor/windows-bindgen/src/extensions/mod/Win32/Foundation/VARIANT_BOOL.rs
+++ b/vendor/windows-bindgen/src/rust/extensions/mod/Win32/Foundation/VARIANT_BOOL.rs
@@ -4,11 +4,11 @@ impl VARIANT_BOOL {
self.0 != 0
}
#[inline]
- pub fn ok(self) -> ::windows::core::Result<()> {
+ pub fn ok(self) -> ::windows_core::Result<()> {
if self.as_bool() {
Ok(())
} else {
- Err(::windows::core::Error::from_win32())
+ Err(::windows_core::Error::from_win32())
}
}
#[inline]
diff --git a/vendor/windows-bindgen/src/extensions/mod/Win32/Foundation/WIN32_ERROR.rs b/vendor/windows-bindgen/src/rust/extensions/mod/Win32/Foundation/WIN32_ERROR.rs
index d875953b2..2c9441efb 100644
--- a/vendor/windows-bindgen/src/extensions/mod/Win32/Foundation/WIN32_ERROR.rs
+++ b/vendor/windows-bindgen/src/rust/extensions/mod/Win32/Foundation/WIN32_ERROR.rs
@@ -8,11 +8,11 @@ impl WIN32_ERROR {
!self.is_ok()
}
#[inline]
- pub const fn to_hresult(self) -> ::windows::core::HRESULT {
- ::windows::core::HRESULT(if self.0 == 0 { self.0 } else { (self.0 & 0x0000_FFFF) | (7 << 16) | 0x8000_0000 } as _)
+ pub const fn to_hresult(self) -> ::windows_core::HRESULT {
+ ::windows_core::HRESULT(if self.0 == 0 { self.0 } else { (self.0 & 0x0000_FFFF) | (7 << 16) | 0x8000_0000 } as i32)
}
#[inline]
- pub fn from_error(error: &::windows::core::Error) -> ::core::option::Option<Self> {
+ pub fn from_error(error: &::windows_core::Error) -> ::core::option::Option<Self> {
let hresult = error.code().0 as u32;
if ((hresult >> 16) & 0x7FF) == 7 {
Some(Self(hresult & 0xFFFF))
@@ -21,21 +21,21 @@ impl WIN32_ERROR {
}
}
#[inline]
- pub const fn ok(self) -> ::windows::core::Result<()> {
+ pub fn ok(self) -> ::windows_core::Result<()> {
if self.is_ok() {
Ok(())
} else {
- Err(::windows::core::Error { code: self.to_hresult(), info: None })
+ Err(self.to_hresult().into())
}
}
}
-impl ::core::convert::From<WIN32_ERROR> for ::windows::core::HRESULT {
+impl ::core::convert::From<WIN32_ERROR> for ::windows_core::HRESULT {
fn from(value: WIN32_ERROR) -> Self {
value.to_hresult()
}
}
-impl ::core::convert::From<WIN32_ERROR> for ::windows::core::Error {
+impl ::core::convert::From<WIN32_ERROR> for ::windows_core::Error {
fn from(value: WIN32_ERROR) -> Self {
- Self { code: value.to_hresult(), info: None }
+ value.to_hresult().into()
}
}
diff --git a/vendor/windows-bindgen/src/extensions/mod/Win32/Networking/WinSock/IN6_ADDR.rs b/vendor/windows-bindgen/src/rust/extensions/mod/Win32/Networking/WinSock/IN6_ADDR.rs
index f4290fba6..f4290fba6 100644
--- a/vendor/windows-bindgen/src/extensions/mod/Win32/Networking/WinSock/IN6_ADDR.rs
+++ b/vendor/windows-bindgen/src/rust/extensions/mod/Win32/Networking/WinSock/IN6_ADDR.rs
diff --git a/vendor/windows-bindgen/src/extensions/mod/Win32/Networking/WinSock/IN_ADDR.rs b/vendor/windows-bindgen/src/rust/extensions/mod/Win32/Networking/WinSock/IN_ADDR.rs
index d12af968b..d12af968b 100644
--- a/vendor/windows-bindgen/src/extensions/mod/Win32/Networking/WinSock/IN_ADDR.rs
+++ b/vendor/windows-bindgen/src/rust/extensions/mod/Win32/Networking/WinSock/IN_ADDR.rs
diff --git a/vendor/windows-bindgen/src/extensions/mod/Win32/Networking/WinSock/SOCKADDR_IN.rs b/vendor/windows-bindgen/src/rust/extensions/mod/Win32/Networking/WinSock/SOCKADDR_IN.rs
index 68bfdc76d..68bfdc76d 100644
--- a/vendor/windows-bindgen/src/extensions/mod/Win32/Networking/WinSock/SOCKADDR_IN.rs
+++ b/vendor/windows-bindgen/src/rust/extensions/mod/Win32/Networking/WinSock/SOCKADDR_IN.rs
diff --git a/vendor/windows-bindgen/src/extensions/mod/Win32/Networking/WinSock/SOCKADDR_IN6.rs b/vendor/windows-bindgen/src/rust/extensions/mod/Win32/Networking/WinSock/SOCKADDR_IN6.rs
index 7b76f2f7d..7b76f2f7d 100644
--- a/vendor/windows-bindgen/src/extensions/mod/Win32/Networking/WinSock/SOCKADDR_IN6.rs
+++ b/vendor/windows-bindgen/src/rust/extensions/mod/Win32/Networking/WinSock/SOCKADDR_IN6.rs
diff --git a/vendor/windows-bindgen/src/extensions/mod/Win32/Networking/WinSock/SOCKADDR_INET.rs b/vendor/windows-bindgen/src/rust/extensions/mod/Win32/Networking/WinSock/SOCKADDR_INET.rs
index ccaf570c0..ccaf570c0 100644
--- a/vendor/windows-bindgen/src/extensions/mod/Win32/Networking/WinSock/SOCKADDR_INET.rs
+++ b/vendor/windows-bindgen/src/rust/extensions/mod/Win32/Networking/WinSock/SOCKADDR_INET.rs
diff --git a/vendor/windows-bindgen/src/extensions/mod/Win32/UI/WindowsAndMessaging/WindowLong.rs b/vendor/windows-bindgen/src/rust/extensions/mod/Win32/UI/WindowsAndMessaging/WindowLong.rs
index cf1cc08d9..cf1cc08d9 100644
--- a/vendor/windows-bindgen/src/extensions/mod/Win32/UI/WindowsAndMessaging/WindowLong.rs
+++ b/vendor/windows-bindgen/src/rust/extensions/mod/Win32/UI/WindowsAndMessaging/WindowLong.rs
diff --git a/vendor/windows-bindgen/src/rust/functions.rs b/vendor/windows-bindgen/src/rust/functions.rs
new file mode 100644
index 000000000..2dd4e0157
--- /dev/null
+++ b/vendor/windows-bindgen/src/rust/functions.rs
@@ -0,0 +1,275 @@
+use super::*;
+
+pub fn writer(writer: &Writer, namespace: &str, def: MethodDef) -> TokenStream {
+ // TODO: remove inline functions from metadata
+ if writer.reader.method_def_module_name(def) == "forceinline" {
+ return quote! {};
+ }
+
+ // TODO: remove ordinal functions from metadata
+ if let Some(impl_map) = writer.reader.method_def_impl_map(def) {
+ if writer.reader.impl_map_import_name(impl_map).starts_with('#') {
+ return quote! {};
+ }
+ }
+
+ if writer.sys {
+ gen_sys_function(writer, namespace, def)
+ } else {
+ gen_win_function(writer, namespace, def)
+ }
+}
+
+fn gen_sys_function(writer: &Writer, namespace: &str, def: MethodDef) -> TokenStream {
+ let signature = method_def_signature(writer.reader, namespace, def, &[]);
+ let cfg = signature_cfg(writer.reader, def);
+ let mut tokens = writer.cfg_features(&cfg);
+ tokens.combine(&gen_link(writer, namespace, &signature, &cfg));
+ tokens
+}
+
+fn gen_win_function(writer: &Writer, namespace: &str, def: MethodDef) -> TokenStream {
+ let name = to_ident(writer.reader.method_def_name(def));
+ let signature = method_def_signature(writer.reader, namespace, def, &[]);
+ let generics = writer.constraint_generics(&signature.params);
+ let where_clause = writer.where_clause(&signature.params);
+ let abi_return_type = writer.return_sig(&signature);
+ let cfg = signature_cfg(writer.reader, def);
+ let doc = writer.cfg_doc(&cfg);
+ let features = writer.cfg_features(&cfg);
+ let link = gen_link(writer, namespace, &signature, &cfg);
+
+ let kind = signature_kind(writer.reader, &signature);
+ match kind {
+ SignatureKind::Query(_) => {
+ let args = writer.win32_args(&signature.params, kind);
+ let params = writer.win32_params(&signature.params, kind);
+ let generics = expand_generics(generics, quote!(T));
+ let where_clause = expand_where_clause(where_clause, quote!(T: ::windows_core::ComInterface));
+
+ quote! {
+ #doc
+ #features
+ #[inline]
+ pub unsafe fn #name<#generics>(#params) -> ::windows_core::Result<T> #where_clause {
+ #link
+ let mut result__ = ::std::ptr::null_mut();
+ #name(#args).from_abi(result__)
+ }
+ }
+ }
+ SignatureKind::QueryOptional(_) => {
+ let args = writer.win32_args(&signature.params, kind);
+ let params = writer.win32_params(&signature.params, kind);
+ let generics = expand_generics(generics, quote!(T));
+ let where_clause = expand_where_clause(where_clause, quote!(T: ::windows_core::ComInterface));
+
+ quote! {
+ #doc
+ #features
+ #[inline]
+ pub unsafe fn #name<#generics>(#params result__: *mut ::core::option::Option<T>) -> ::windows_core::Result<()> #where_clause {
+ #link
+ #name(#args).ok()
+ }
+ }
+ }
+ SignatureKind::ResultValue => {
+ let args = writer.win32_args(&signature.params, kind);
+ let params = writer.win32_params(&signature.params, kind);
+ let return_type = signature.params[signature.params.len() - 1].ty.deref();
+ let return_type = writer.type_name(&return_type);
+
+ quote! {
+ #doc
+ #features
+ #[inline]
+ pub unsafe fn #name<#generics>(#params) -> ::windows_core::Result<#return_type> #where_clause {
+ #link
+ let mut result__ = ::std::mem::zeroed();
+ #name(#args).from_abi(result__)
+ }
+ }
+ }
+ SignatureKind::ResultVoid => {
+ let args = writer.win32_args(&signature.params, kind);
+ let params = writer.win32_params(&signature.params, kind);
+
+ quote! {
+ #doc
+ #features
+ #[inline]
+ pub unsafe fn #name<#generics>(#params) -> ::windows_core::Result<()> #where_clause {
+ #link
+ #name(#args).ok()
+ }
+ }
+ }
+ SignatureKind::ReturnValue => {
+ let args = writer.win32_args(&signature.params, kind);
+ let params = writer.win32_params(&signature.params, kind);
+ let return_type = signature.params[signature.params.len() - 1].ty.deref();
+ let is_nullable = type_is_nullable(writer.reader, &return_type);
+ let return_type = writer.type_name(&return_type);
+
+ if is_nullable {
+ quote! {
+ #doc
+ #features
+ #[inline]
+ pub unsafe fn #name<#generics>(#params) -> ::windows_core::Result<#return_type> #where_clause {
+ #link
+ let mut result__ = ::std::mem::zeroed();
+ #name(#args);
+ ::windows_core::from_abi(result__.assume_init())
+ }
+ }
+ } else {
+ quote! {
+ #doc
+ #features
+ #[inline]
+ pub unsafe fn #name<#generics>(#params) -> #return_type #where_clause {
+ #link
+ let mut result__ = ::std::mem::zeroed();
+ #name(#args);
+ ::std::mem::transmute(result__)
+ }
+ }
+ }
+ }
+ SignatureKind::ReturnStruct | SignatureKind::PreserveSig => {
+ if handle_last_error(writer, def, &signature) {
+ let args = writer.win32_args(&signature.params, kind);
+ let params = writer.win32_params(&signature.params, kind);
+ let return_type = writer.type_name(&signature.return_type);
+
+ quote! {
+ #doc
+ #features
+ #[inline]
+ pub unsafe fn #name<#generics>(#params) -> ::windows_core::Result<#return_type> #where_clause {
+ #link
+ let result__ = #name(#args);
+ (!result__.is_invalid()).then(|| result__).ok_or_else(::windows_core::Error::from_win32)
+ }
+ }
+ } else {
+ let args = writer.win32_args(&signature.params, kind);
+ let params = writer.win32_params(&signature.params, kind);
+
+ quote! {
+ #doc
+ #features
+ #[inline]
+ pub unsafe fn #name<#generics>(#params) #abi_return_type #where_clause {
+ #link
+ #name(#args)
+ }
+ }
+ }
+ }
+ SignatureKind::ReturnVoid => {
+ let args = writer.win32_args(&signature.params, kind);
+ let params = writer.win32_params(&signature.params, kind);
+ let does_not_return = does_not_return(writer, def);
+
+ quote! {
+ #doc
+ #features
+ #[inline]
+ pub unsafe fn #name<#generics>(#params) #does_not_return #where_clause {
+ #link
+ #name(#args)
+ }
+ }
+ }
+ }
+}
+
+fn gen_link(writer: &Writer, namespace: &str, signature: &Signature, cfg: &Cfg) -> TokenStream {
+ let name = writer.reader.method_def_name(signature.def);
+ let ident = to_ident(name);
+ let library = writer.reader.method_def_module_name(signature.def);
+ let abi = method_def_extern_abi(writer.reader, signature.def);
+
+ let symbol = if let Some(impl_map) = writer.reader.method_def_impl_map(signature.def) { writer.reader.impl_map_import_name(impl_map) } else { name };
+
+ let link_name = if symbol != name {
+ quote! { #[link_name = #symbol] }
+ } else {
+ quote! {}
+ };
+
+ let params = signature.params.iter().map(|p| {
+ let name = writer.param_name(p.def);
+ let tokens = if p.kind == SignatureParamKind::ValueType { writer.type_default_name(&p.ty) } else { writer.type_abi_name(&p.ty) };
+ quote! { #name: #tokens }
+ });
+
+ let return_type = writer.return_sig(signature);
+
+ let vararg = if writer.sys && signature.call_flags.contains(MethodCallAttributes::VARARG) {
+ "...".into()
+ } else {
+ quote! {}
+ };
+
+ if writer.std || !namespace.starts_with("Windows.") {
+ let library = library.trim_end_matches(".dll");
+
+ quote! {
+ #[link(name = #library)]
+ extern #abi {
+ #link_name
+ pub fn #ident(#(#params,)* #vararg) #return_type;
+ }
+ }
+ } else if let Some(library) = method_def_static_lib(writer.reader, signature.def) {
+ quote! {
+ #[link(name = #library, kind = "static")]
+ extern #abi {
+ #link_name
+ pub fn #ident(#(#params,)* #vararg) #return_type;
+ }
+ }
+ } else {
+ let symbol = if symbol != name { format!(" \"{symbol}\"") } else { String::new() };
+
+ let doc = if writer.sys { writer.cfg_doc(cfg).0 } else { String::new() };
+
+ let mut tokens = String::new();
+ for param in params {
+ tokens.push_str(&format!("{}, ", param.as_str()));
+ }
+ tokens.push_str(&vararg.0);
+ let tokens = tokens.trim_end_matches(", ");
+ format!(r#"::windows_targets::link!("{library}" "{abi}"{symbol}{doc} fn {name}({tokens}){return_type});"#).into()
+ }
+}
+
+fn does_not_return(writer: &Writer, def: MethodDef) -> TokenStream {
+ if writer.reader.has_attribute(def, "DoesNotReturnAttribute") {
+ quote! { -> ! }
+ } else {
+ quote! {}
+ }
+}
+
+fn handle_last_error(writer: &Writer, def: MethodDef, signature: &Signature) -> bool {
+ if let Some(map) = writer.reader.method_def_impl_map(def) {
+ if writer.reader.impl_map_flags(map).contains(PInvokeAttributes::SupportsLastError) {
+ if let Type::TypeDef(return_type, _) = &signature.return_type {
+ if type_def_is_handle(writer.reader, *return_type) {
+ if writer.reader.type_def_underlying_type(*return_type).is_pointer() {
+ return true;
+ }
+ if !type_def_invalid_values(writer.reader, *return_type).is_empty() {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ false
+}
diff --git a/vendor/windows-bindgen/src/handles.rs b/vendor/windows-bindgen/src/rust/handles.rs
index 9ace4a1b6..e213679e0 100644
--- a/vendor/windows-bindgen/src/handles.rs
+++ b/vendor/windows-bindgen/src/rust/handles.rs
@@ -1,27 +1,21 @@
use super::*;
-pub fn gen(gen: &Gen, def: TypeDef) -> TokenStream {
- if gen.sys {
- gen_sys_handle(gen, def)
+pub fn writer(writer: &Writer, def: TypeDef) -> TokenStream {
+ if writer.sys {
+ gen_sys_handle(writer, def)
} else {
- gen_win_handle(gen, def)
+ gen_win_handle(writer, def)
}
}
-pub fn gen_sys_handle(gen: &Gen, def: TypeDef) -> TokenStream {
- let ident = to_ident(gen.reader.type_def_name(def));
- match gen.reader.type_def_underlying_type(def) {
- Type::ISize if gen.std => quote! {
+pub fn gen_sys_handle(writer: &Writer, def: TypeDef) -> TokenStream {
+ let ident = to_ident(writer.reader.type_def_name(def));
+ match writer.reader.type_def_underlying_type(def) {
+ Type::ISize if writer.std => quote! {
pub type #ident = *mut ::core::ffi::c_void;
},
- Type::USize if gen.std => quote! {
- #[cfg(target_pointer_width = "32")]
- pub type #ident = u32;
- #[cfg(target_pointer_width = "64")]
- pub type #ident = u64;
- },
underlying_type => {
- let signature = gen.type_default_name(&underlying_type);
+ let signature = writer.type_default_name(&underlying_type);
quote! {
pub type #ident = #signature;
@@ -30,11 +24,11 @@ pub fn gen_sys_handle(gen: &Gen, def: TypeDef) -> TokenStream {
}
}
-pub fn gen_win_handle(gen: &Gen, def: TypeDef) -> TokenStream {
- let name = gen.reader.type_def_name(def);
+pub fn gen_win_handle(writer: &Writer, def: TypeDef) -> TokenStream {
+ let name = writer.reader.type_def_name(def);
let ident = to_ident(name);
- let underlying_type = gen.reader.type_def_underlying_type(def);
- let signature = gen.type_default_name(&underlying_type);
+ let underlying_type = writer.reader.type_def_underlying_type(def);
+ let signature = writer.type_default_name(&underlying_type);
let check = if underlying_type.is_pointer() {
quote! {
impl #ident {
@@ -44,7 +38,7 @@ pub fn gen_win_handle(gen: &Gen, def: TypeDef) -> TokenStream {
}
}
} else {
- let invalid = gen.reader.type_def_invalid_values(def);
+ let invalid = type_def_invalid_values(writer.reader, def);
if !invalid.is_empty() {
let invalid = invalid.iter().map(|value| {
@@ -90,18 +84,23 @@ pub fn gen_win_handle(gen: &Gen, def: TypeDef) -> TokenStream {
f.debug_tuple(#name).field(&self.0).finish()
}
}
- impl ::windows::core::TypeKind for #ident {
- type TypeKind = ::windows::core::CopyType;
+ impl ::windows_core::TypeKind for #ident {
+ type TypeKind = ::windows_core::CopyType;
}
};
- if let Some(dependency) = gen.reader.type_def_usable_for(def) {
- let type_name = gen.reader.type_def_type_name(dependency);
- let mut dependency = gen.namespace(type_name.namespace);
+ if let Some(dependency) = type_def_usable_for(writer.reader, def) {
+ let type_name = writer.reader.type_def_type_name(dependency);
+ let mut dependency = writer.namespace(type_name.namespace);
dependency.push_str(type_name.name);
tokens.combine(&quote! {
- impl windows::core::CanInto<#dependency> for #ident {}
+ impl ::windows_core::CanInto<#dependency> for #ident {}
+ impl ::core::convert::From<#ident> for #dependency {
+ fn from(value: #ident) -> Self {
+ Self(value.0)
+ }
+ }
});
}
diff --git a/vendor/windows-bindgen/src/implements.rs b/vendor/windows-bindgen/src/rust/implements.rs
index 3a3184b51..742ae9984 100644
--- a/vendor/windows-bindgen/src/implements.rs
+++ b/vendor/windows-bindgen/src/rust/implements.rs
@@ -1,92 +1,85 @@
use super::*;
-pub fn gen(gen: &Gen, def: TypeDef) -> TokenStream {
- if gen.reader.type_def_kind(def) != TypeKind::Interface
- || (!gen.component && !gen.reader.type_def_can_implement(def))
- {
+pub fn writer(writer: &Writer, def: TypeDef) -> TokenStream {
+ if writer.reader.type_def_kind(def) != TypeKind::Interface || (!writer.implement && writer.reader.has_attribute(def, "ExclusiveToAttribute")) {
return quote! {};
}
- let generics: &Vec<Type> = &gen.reader.type_def_generics(def).collect();
- let type_ident = to_ident(gen.reader.type_def_name(def));
+ let generics = &type_def_generics(writer.reader, def);
+ let type_ident = to_ident(writer.reader.type_def_name(def));
let impl_ident = type_ident.join("_Impl");
let vtbl_ident = type_ident.join("_Vtbl");
let implvtbl_ident = impl_ident.join("Vtbl");
- let constraints = gen.generic_constraints(generics);
- let generic_names = gen.generic_names(generics);
- let named_phantoms = gen.generic_named_phantoms(generics);
- let cfg = gen.reader.type_def_cfg_impl(def, generics);
- let doc = gen.cfg_doc(&cfg);
- let features = gen.cfg_features(&cfg);
+ let constraints = writer.generic_constraints(generics);
+ let generic_names = writer.generic_names(generics);
+ let named_phantoms = writer.generic_named_phantoms(generics);
+ let cfg = type_def_cfg_impl(writer.reader, def, generics);
+ let doc = writer.cfg_doc(&cfg);
+ let features = writer.cfg_features(&cfg);
let mut requires = quote! {};
let type_ident = quote! { #type_ident<#generic_names> };
- let vtables = gen.reader.type_def_vtables(def);
+ let vtables = type_def_vtables(writer.reader, def);
let has_unknown_base = matches!(vtables.first(), Some(Type::IUnknown));
- fn gen_required_trait(gen: &Gen, def: TypeDef, generics: &[Type]) -> TokenStream {
- let name = gen.type_def_name_imp(def, generics, "_Impl");
+ fn gen_required_trait(writer: &Writer, def: TypeDef, generics: &[Type]) -> TokenStream {
+ let name = writer.type_def_name_imp(def, generics, "_Impl");
quote! {
+ #name
}
}
- let mut matches = quote! { iid == &<#type_ident as ::windows::core::ComInterface>::IID };
+ let mut matches = quote! { iid == &<#type_ident as ::windows_core::ComInterface>::IID };
- if let Some(Type::TypeDef((def, _))) = vtables.last() {
- requires.combine(&gen_required_trait(gen, *def, &[]))
+ if let Some(Type::TypeDef(def, _)) = vtables.last() {
+ requires.combine(&gen_required_trait(writer, *def, &[]))
}
for def in &vtables {
- if let Type::TypeDef((def, generics)) = def {
- let name = gen.type_def_name(*def, generics);
+ if let Type::TypeDef(def, generics) = def {
+ let name = writer.type_def_name(*def, generics);
matches.combine(&quote! {
- || iid == &<#name as ::windows::core::ComInterface>::IID
+ || iid == &<#name as ::windows_core::ComInterface>::IID
})
}
}
- if gen
- .reader
- .type_def_flags(def)
- .contains(TypeAttributes::WINRT)
- {
+ if writer.reader.type_def_flags(def).contains(TypeAttributes::WindowsRuntime) {
// TODO: this awkward wrapping of TypeDefs needs fixing
- for interface in gen
- .reader
- .type_interfaces(&Type::TypeDef((def, generics.to_vec())))
- {
- if let Type::TypeDef((def, generics)) = interface.ty {
- requires.combine(&gen_required_trait(gen, def, &generics));
+ for interface in type_interfaces(writer.reader, &Type::TypeDef(def, generics.to_vec())) {
+ if let Type::TypeDef(def, generics) = interface.ty {
+ requires.combine(&gen_required_trait(writer, def, &generics));
}
}
}
- let runtime_name = gen.runtime_name_trait(def, generics, &type_ident, &constraints, &features);
+ let runtime_name = writer.runtime_name_trait(def, generics, &type_ident, &constraints, &features);
let mut method_names = MethodNames::new();
- method_names.add_vtable_types(gen, def);
+ method_names.add_vtable_types(writer, def);
- let method_traits = gen.reader.type_def_methods(def).map(|method| {
- let name = method_names.add(gen, method);
- let signature = gen.reader.method_def_signature(method, generics);
- let signature_tokens = gen.impl_signature(def, &signature);
+ let method_traits = writer.reader.type_def_methods(def).map(|method| {
+ let name = method_names.add(writer, method);
+
+ let signature = method_def_signature(writer.reader, writer.reader.type_def_namespace(def), method, generics);
+
+ let signature_tokens = writer.impl_signature(def, &signature);
quote! { fn #name #signature_tokens; }
});
let mut method_names = MethodNames::new();
- method_names.add_vtable_types(gen, def);
+ method_names.add_vtable_types(writer, def);
- let method_impls = gen.reader.type_def_methods(def).map(|method| {
- let name = method_names.add(gen, method);
- let signature = gen.reader.method_def_signature(method, generics);
- let vtbl_signature = gen.vtbl_signature(def, generics, &signature);
+ let method_impls = writer.reader.type_def_methods(def).map(|method| {
+ let name = method_names.add(writer, method);
+ let signature = method_def_signature(writer.reader, writer.reader.type_def_namespace(def), method, generics);
+ let vtbl_signature = writer.vtbl_signature(def, generics, &signature);
- let invoke_upcall = if gen.reader.type_def_flags(def).contains(TypeAttributes::WINRT) { winrt_methods::gen_upcall(gen, &signature, quote! { this.#name }) } else { com_methods::gen_upcall(gen, &signature, quote! { this.#name }) };
+ let invoke_upcall = if writer.reader.type_def_flags(def).contains(TypeAttributes::WindowsRuntime) { winrt_methods::gen_upcall(writer, &signature, quote! { this.#name }) } else { com_methods::gen_upcall(writer, &signature, quote! { this.#name }) };
if has_unknown_base {
quote! {
- unsafe extern "system" fn #name<#constraints Identity: ::windows::core::IUnknownImpl<Impl = Impl>, Impl: #impl_ident<#generic_names>, const OFFSET: isize> #vtbl_signature {
+ unsafe extern "system" fn #name<#constraints Identity: ::windows_core::IUnknownImpl<Impl = Impl>, Impl: #impl_ident<#generic_names>, const OFFSET: isize> #vtbl_signature {
// offset the `this` pointer by `OFFSET` times the size of a pointer and cast it as an IUnknown implementation
let this = (this as *const *const ()).offset(OFFSET) as *const Identity;
let this = (*this).get_impl();
@@ -96,7 +89,7 @@ pub fn gen(gen: &Gen, def: TypeDef) -> TokenStream {
} else {
quote! {
unsafe extern "system" fn #name<Impl: #impl_ident> #vtbl_signature {
- let this = (this as *mut *mut ::core::ffi::c_void) as *const ::windows::core::ScopedHeap;
+ let this = (this as *mut *mut ::core::ffi::c_void) as *const ::windows_core::ScopedHeap;
let this = &*((*this).this as *const Impl);
#invoke_upcall
}
@@ -107,10 +100,10 @@ pub fn gen(gen: &Gen, def: TypeDef) -> TokenStream {
let mut methods = quote! {};
match vtables.last() {
- Some(Type::IUnknown) => methods.combine(&quote! { base__: ::windows::core::IUnknown_Vtbl::new::<Identity, OFFSET>(), }),
- Some(Type::IInspectable) => methods.combine(&quote! { base__: ::windows::core::IInspectable_Vtbl::new::<Identity, #type_ident, OFFSET>(), }),
- Some(Type::TypeDef((def, generics))) => {
- let name = gen.type_def_name_imp(*def, generics, "_Vtbl");
+ Some(Type::IUnknown) => methods.combine(&quote! { base__: ::windows_core::IUnknown_Vtbl::new::<Identity, OFFSET>(), }),
+ Some(Type::IInspectable) => methods.combine(&quote! { base__: ::windows_core::IInspectable_Vtbl::new::<Identity, #type_ident, OFFSET>(), }),
+ Some(Type::TypeDef(def, generics)) => {
+ let name = writer.type_def_name_imp(*def, generics, "_Vtbl");
if has_unknown_base {
methods.combine(&quote! { base__: #name::new::<Identity, Impl, OFFSET>(), });
} else {
@@ -121,10 +114,10 @@ pub fn gen(gen: &Gen, def: TypeDef) -> TokenStream {
}
let mut method_names = MethodNames::new();
- method_names.add_vtable_types(gen, def);
+ method_names.add_vtable_types(writer, def);
- for method in gen.reader.type_def_methods(def) {
- let name = method_names.add(gen, method);
+ for method in writer.reader.type_def_methods(def) {
+ let name = method_names.add(writer, method);
if has_unknown_base {
methods.combine(&quote! { #name: #name::<#generic_names Identity, Impl, OFFSET>, });
} else {
@@ -142,14 +135,14 @@ pub fn gen(gen: &Gen, def: TypeDef) -> TokenStream {
#runtime_name
#features
impl<#constraints> #vtbl_ident<#generic_names> {
- pub const fn new<Identity: ::windows::core::IUnknownImpl<Impl = Impl>, Impl: #impl_ident<#generic_names>, const OFFSET: isize>() -> #vtbl_ident<#generic_names> {
+ pub const fn new<Identity: ::windows_core::IUnknownImpl<Impl = Impl>, Impl: #impl_ident<#generic_names>, const OFFSET: isize>() -> #vtbl_ident<#generic_names> {
#(#method_impls)*
Self{
#methods
#(#named_phantoms)*
}
}
- pub fn matches(iid: &windows::core::GUID) -> bool {
+ pub fn matches(iid: &::windows_core::GUID) -> bool {
#matches
}
}
@@ -180,10 +173,10 @@ pub fn gen(gen: &Gen, def: TypeDef) -> TokenStream {
}
#features
impl #type_ident {
- pub fn new<'a, T: #impl_ident>(this: &'a T) -> ::windows::core::ScopedInterface<'a, Self> {
- let this = ::windows::core::ScopedHeap { vtable: &#implvtbl_ident::<T>::VTABLE as *const _ as *const _, this: this as *const _ as *const _ };
+ pub fn new<'a, T: #impl_ident>(this: &'a T) -> ::windows_core::ScopedInterface<'a, Self> {
+ let this = ::windows_core::ScopedHeap { vtable: &#implvtbl_ident::<T>::VTABLE as *const _ as *const _, this: this as *const _ as *const _ };
let this = ::std::mem::ManuallyDrop::new(::std::boxed::Box::new(this));
- unsafe { ::windows::core::ScopedInterface::new(::std::mem::transmute(&this.vtable)) }
+ unsafe { ::windows_core::ScopedInterface::new(::std::mem::transmute(&this.vtable)) }
}
}
}
diff --git a/vendor/windows-bindgen/src/rust/interfaces.rs b/vendor/windows-bindgen/src/rust/interfaces.rs
new file mode 100644
index 000000000..a552af433
--- /dev/null
+++ b/vendor/windows-bindgen/src/rust/interfaces.rs
@@ -0,0 +1,149 @@
+use super::*;
+
+pub fn writer(writer: &Writer, def: TypeDef) -> TokenStream {
+ if writer.sys {
+ gen_sys_interface(writer, def)
+ } else {
+ gen_win_interface(writer, def)
+ }
+}
+
+fn gen_sys_interface(writer: &Writer, def: TypeDef) -> TokenStream {
+ let name = writer.reader.type_def_name(def);
+ let ident = to_ident(name);
+
+ if type_def_is_exclusive(writer.reader, def) {
+ quote! {}
+ } else {
+ quote! {
+ pub type #ident = *mut ::core::ffi::c_void;
+ }
+ }
+}
+
+fn gen_win_interface(writer: &Writer, def: TypeDef) -> TokenStream {
+ let generics = &type_def_generics(writer.reader, def);
+ let ident = writer.type_def_name(def, generics);
+ let is_exclusive = type_def_is_exclusive(writer.reader, def);
+ let phantoms = writer.generic_phantoms(generics);
+ let constraints = writer.generic_constraints(generics);
+ let cfg = type_def_cfg(writer.reader, def, &[]);
+ let doc = writer.cfg_doc(&cfg);
+ let features = writer.cfg_features(&cfg);
+ let interfaces = type_interfaces(writer.reader, &Type::TypeDef(def, generics.to_vec()));
+ let vtables = type_def_vtables(writer.reader, def);
+ let has_unknown_base = matches!(vtables.first(), Some(Type::IUnknown));
+
+ let mut tokens = if is_exclusive {
+ quote! { #[doc(hidden)] }
+ } else {
+ quote! { #doc }
+ };
+
+ if has_unknown_base {
+ tokens.combine(&quote! {
+ #features
+ #[repr(transparent)]
+ pub struct #ident(::windows_core::IUnknown, #phantoms) where #constraints;
+ });
+ } else {
+ tokens.combine(&quote! {
+ #features
+ #[repr(transparent)]
+ pub struct #ident(::std::ptr::NonNull<::std::ffi::c_void>);
+ });
+ }
+
+ if !is_exclusive {
+ let mut methods = quote! {};
+ // We need to distinguish between public and virtual methods because some WinRT type hierarchies inherit colliding (overloaded)
+ // methods that must be distinguishable.
+ let method_names = &mut MethodNames::new();
+ let virtual_names = &mut MethodNames::new();
+
+ if writer.reader.type_def_flags(def).contains(TypeAttributes::WindowsRuntime) {
+ for method in writer.reader.type_def_methods(def) {
+ methods.combine(&winrt_methods::writer(writer, def, generics, InterfaceKind::Default, method, method_names, virtual_names));
+ }
+ for interface in &interfaces {
+ if let Type::TypeDef(def, generics) = &interface.ty {
+ for method in writer.reader.type_def_methods(*def) {
+ methods.combine(&winrt_methods::writer(writer, *def, generics, InterfaceKind::None, method, method_names, virtual_names));
+ }
+ }
+ }
+ } else {
+ let mut bases = vtables.len();
+ for ty in &vtables {
+ match ty {
+ Type::IUnknown | Type::IInspectable => {}
+ Type::TypeDef(def, _) => {
+ let kind = if writer.reader.type_def_type_name(*def) == TypeName::IDispatch { InterfaceKind::None } else { InterfaceKind::Default };
+ for method in writer.reader.type_def_methods(*def) {
+ methods.combine(&com_methods::writer(writer, *def, kind, method, method_names, virtual_names, bases));
+ }
+ }
+ rest => unimplemented!("{rest:?}"),
+ }
+
+ bases -= 1;
+ }
+ for method in writer.reader.type_def_methods(def) {
+ methods.combine(&com_methods::writer(writer, def, InterfaceKind::Default, method, method_names, virtual_names, 0));
+ }
+ }
+
+ tokens.combine(&quote! {
+ #features
+ impl<#constraints> #ident {
+ #methods
+ }
+ });
+
+ if !vtables.is_empty() && generics.is_empty() {
+ let mut hierarchy = format!("::windows_core::imp::interface_hierarchy!({ident}");
+ let mut hierarchy_cfg = cfg.clone();
+
+ for ty in &vtables {
+ let into = writer.type_name(ty);
+
+ write!(&mut hierarchy, ", {into}").unwrap();
+ hierarchy_cfg = hierarchy_cfg.union(&type_cfg(writer.reader, ty));
+ }
+
+ hierarchy.push_str(");");
+ tokens.combine(&writer.cfg_features(&hierarchy_cfg));
+ tokens.push_str(&hierarchy);
+ } else {
+ for ty in &vtables {
+ let into = writer.type_name(ty);
+ let cfg = writer.cfg_features(&cfg.union(&type_cfg(writer.reader, ty)));
+ tokens.combine(&quote! {
+ #cfg
+ impl<#constraints> ::windows_core::CanInto<#into> for #ident {}
+ });
+ }
+ }
+
+ if writer.reader.type_def_flags(def).contains(TypeAttributes::WindowsRuntime) {
+ for interface in &interfaces {
+ let into = writer.type_name(&interface.ty);
+ let cfg = writer.cfg_features(&cfg.union(&type_cfg(writer.reader, &interface.ty)));
+ tokens.combine(&quote! {
+ #cfg
+ impl<#constraints> ::windows_core::CanTryInto<#into> for #ident {}
+ });
+ }
+ }
+
+ tokens.combine(&writer.interface_core_traits(def, generics, &ident, &constraints, &phantoms, &features));
+ tokens.combine(&writer.interface_winrt_trait(def, generics, &ident, &constraints, &phantoms, &features));
+ tokens.combine(&writer.async_get(def, generics, &ident, &constraints, &phantoms, &features));
+ tokens.combine(&iterators::writer(writer, def, generics, &ident, &constraints, &phantoms, &cfg));
+ tokens.combine(&writer.agile(def, &ident, &constraints, &features));
+ }
+
+ tokens.combine(&writer.interface_trait(def, generics, &ident, &constraints, &features, has_unknown_base));
+ tokens.combine(&writer.interface_vtbl(def, generics, &ident, &constraints, &features));
+ tokens
+}
diff --git a/vendor/windows-bindgen/src/iterators.rs b/vendor/windows-bindgen/src/rust/iterators.rs
index 49a90adf2..63ba56aaf 100644
--- a/vendor/windows-bindgen/src/iterators.rs
+++ b/vendor/windows-bindgen/src/rust/iterators.rs
@@ -1,19 +1,11 @@
use super::*;
-pub fn gen(
- gen: &Gen,
- def: TypeDef,
- generics: &[Type],
- ident: &TokenStream,
- constraints: &TokenStream,
- _phantoms: &TokenStream,
- cfg: &Cfg,
-) -> TokenStream {
- match gen.reader.type_def_type_name(def) {
+pub fn writer(writer: &Writer, def: TypeDef, generics: &[Type], ident: &TokenStream, constraints: &TokenStream, _phantoms: &TokenStream, cfg: &Cfg) -> TokenStream {
+ match writer.reader.type_def_type_name(def) {
// If the type is IIterator<T> then simply implement the Iterator trait over top.
TypeName::IIterator => {
return quote! {
- impl<T: ::windows::core::RuntimeType> ::core::iter::Iterator for IIterator<T> {
+ impl<T: ::windows_core::RuntimeType> ::core::iter::Iterator for IIterator<T> {
type Item = T;
fn next(&mut self) -> ::core::option::Option<Self::Item> {
@@ -32,7 +24,7 @@ pub fn gen(
// IIterator<T> returned by first() to implement the Iterator trait.
TypeName::IIterable => {
return quote! {
- impl<T: ::windows::core::RuntimeType> ::core::iter::IntoIterator for IIterable<T> {
+ impl<T: ::windows_core::RuntimeType> ::core::iter::IntoIterator for IIterable<T> {
type Item = T;
type IntoIter = IIterator<Self::Item>;
@@ -40,7 +32,7 @@ pub fn gen(
::core::iter::IntoIterator::into_iter(&self)
}
}
- impl<T: ::windows::core::RuntimeType> ::core::iter::IntoIterator for &IIterable<T> {
+ impl<T: ::windows_core::RuntimeType> ::core::iter::IntoIterator for &IIterable<T> {
type Item = T;
type IntoIter = IIterator<Self::Item>;
@@ -54,18 +46,18 @@ pub fn gen(
// If the type is IVectorView<T> then provide the VectorViewIterator fast iterator.
TypeName::IVectorView => {
return quote! {
- pub struct VectorViewIterator<T: ::windows::core::RuntimeType + 'static> {
+ pub struct VectorViewIterator<T: ::windows_core::RuntimeType + 'static> {
vector: ::core::option::Option<IVectorView<T>>,
current: u32,
}
- impl<T: ::windows::core::RuntimeType> VectorViewIterator<T> {
+ impl<T: ::windows_core::RuntimeType> VectorViewIterator<T> {
pub fn new(vector: ::core::option::Option<IVectorView<T>>) -> Self {
Self { vector, current: 0 }
}
}
- impl<T: ::windows::core::RuntimeType> ::core::iter::Iterator for VectorViewIterator<T> {
+ impl<T: ::windows_core::RuntimeType> ::core::iter::Iterator for VectorViewIterator<T> {
type Item = T;
fn next(&mut self) -> ::core::option::Option<Self::Item> {
@@ -80,7 +72,7 @@ pub fn gen(
}
}
- impl<T: ::windows::core::RuntimeType> ::core::iter::IntoIterator for IVectorView<T> {
+ impl<T: ::windows_core::RuntimeType> ::core::iter::IntoIterator for IVectorView<T> {
type Item = T;
type IntoIter = VectorViewIterator<Self::Item>;
@@ -88,7 +80,7 @@ pub fn gen(
::core::iter::IntoIterator::into_iter(&self)
}
}
- impl<T: ::windows::core::RuntimeType> ::core::iter::IntoIterator for &IVectorView<T> {
+ impl<T: ::windows_core::RuntimeType> ::core::iter::IntoIterator for &IVectorView<T> {
type Item = T;
type IntoIter = VectorViewIterator<Self::Item>;
@@ -101,18 +93,18 @@ pub fn gen(
}
TypeName::IVector => {
return quote! {
- pub struct VectorIterator<T: ::windows::core::RuntimeType + 'static> {
+ pub struct VectorIterator<T: ::windows_core::RuntimeType + 'static> {
vector: ::core::option::Option<IVector<T>>,
current: u32,
}
- impl<T: ::windows::core::RuntimeType> VectorIterator<T> {
+ impl<T: ::windows_core::RuntimeType> VectorIterator<T> {
pub fn new(vector: ::core::option::Option<IVector<T>>) -> Self {
Self { vector, current: 0 }
}
}
- impl<T: ::windows::core::RuntimeType> ::core::iter::Iterator for VectorIterator<T> {
+ impl<T: ::windows_core::RuntimeType> ::core::iter::Iterator for VectorIterator<T> {
type Item = T;
fn next(&mut self) -> ::core::option::Option<Self::Item> {
@@ -127,7 +119,7 @@ pub fn gen(
}
}
- impl<T: ::windows::core::RuntimeType> ::core::iter::IntoIterator for IVector<T> {
+ impl<T: ::windows_core::RuntimeType> ::core::iter::IntoIterator for IVector<T> {
type Item = T;
type IntoIter = VectorIterator<Self::Item>;
@@ -135,7 +127,7 @@ pub fn gen(
::core::iter::IntoIterator::into_iter(&self)
}
}
- impl<T: ::windows::core::RuntimeType> ::core::iter::IntoIterator for &IVector<T> {
+ impl<T: ::windows_core::RuntimeType> ::core::iter::IntoIterator for &IVector<T> {
type Item = T;
type IntoIter = VectorIterator<Self::Item>;
@@ -149,23 +141,20 @@ pub fn gen(
_ => {}
}
- let wfc = gen.namespace("Windows.Foundation.Collections");
+ let wfc = writer.namespace("Windows.Foundation.Collections");
let mut iterable = None;
- let interfaces = gen
- .reader
- .type_interfaces(&Type::TypeDef((def, generics.to_vec())));
+ let interfaces = type_interfaces(writer.reader, &Type::TypeDef(def, generics.to_vec()));
// If the class or interface is not one of the well-known collection interfaces, we then see whether it
// implements any one of them. Here is where we favor IVectorView/IVector over IIterable.
for interface in interfaces {
- if let Type::TypeDef((interface, interface_generics)) = &interface.ty {
- match gen.reader.type_def_type_name(*interface) {
+ if let Type::TypeDef(interface, interface_generics) = &interface.ty {
+ match writer.reader.type_def_type_name(*interface) {
TypeName::IVectorView => {
- let item = gen.type_name(&interface_generics[0]);
+ let item = writer.type_name(&interface_generics[0]);
let mut cfg = cfg.clone();
- gen.reader
- .type_def_cfg_combine(*interface, interface_generics, &mut cfg);
- let features = gen.cfg_features(&cfg);
+ type_def_cfg_combine(writer.reader, *interface, interface_generics, &mut cfg);
+ let features = writer.cfg_features(&cfg);
return quote! {
#features
@@ -183,17 +172,16 @@ pub fn gen(
type IntoIter = #wfc VectorViewIterator<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
- #wfc VectorViewIterator::new(::windows::core::ComInterface::cast(self).ok())
+ #wfc VectorViewIterator::new(::windows_core::ComInterface::cast(self).ok())
}
}
};
}
TypeName::IVector => {
- let item = gen.type_name(&interface_generics[0]);
+ let item = writer.type_name(&interface_generics[0]);
let mut cfg = cfg.clone();
- gen.reader
- .type_def_cfg_combine(*interface, interface_generics, &mut cfg);
- let features = gen.cfg_features(&cfg);
+ type_def_cfg_combine(writer.reader, *interface, interface_generics, &mut cfg);
+ let features = writer.cfg_features(&cfg);
return quote! {
#features
@@ -211,7 +199,7 @@ pub fn gen(
type IntoIter = #wfc VectorIterator<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
- #wfc VectorIterator::new(::windows::core::ComInterface::cast(self).ok())
+ #wfc VectorIterator::new(::windows_core::ComInterface::cast(self).ok())
}
}
};
@@ -227,11 +215,10 @@ pub fn gen(
match iterable {
None => TokenStream::new(),
Some((interface, interface_generics)) => {
- let item = gen.type_name(&interface_generics[0]);
+ let item = writer.type_name(&interface_generics[0]);
let mut cfg = cfg.clone();
- gen.reader
- .type_def_cfg_combine(interface, &interface_generics, &mut cfg);
- let features = gen.cfg_features(&cfg);
+ type_def_cfg_combine(writer.reader, interface, &interface_generics, &mut cfg);
+ let features = writer.cfg_features(&cfg);
quote! {
#features
diff --git a/vendor/windows-bindgen/src/rust/method_names.rs b/vendor/windows-bindgen/src/rust/method_names.rs
new file mode 100644
index 000000000..2d5a508ae
--- /dev/null
+++ b/vendor/windows-bindgen/src/rust/method_names.rs
@@ -0,0 +1,30 @@
+use super::*;
+
+pub struct MethodNames(BTreeMap<String, u32>);
+
+impl MethodNames {
+ pub fn new() -> Self {
+ Self(BTreeMap::new())
+ }
+
+ pub fn add(&mut self, writer: &Writer, method: MethodDef) -> TokenStream {
+ let name = method_def_special_name(writer.reader, method);
+ let overload = self.0.entry(name.to_string()).or_insert(0);
+ *overload += 1;
+ if *overload > 1 {
+ format!("{name}{overload}").into()
+ } else {
+ to_ident(&name)
+ }
+ }
+
+ pub fn add_vtable_types(&mut self, writer: &Writer, def: TypeDef) {
+ for def in type_def_vtables(writer.reader, def) {
+ if let Type::TypeDef(def, _) = def {
+ for method in writer.reader.type_def_methods(def) {
+ self.add(writer, method);
+ }
+ }
+ }
+ }
+}
diff --git a/vendor/windows-bindgen/src/rust/mod.rs b/vendor/windows-bindgen/src/rust/mod.rs
new file mode 100644
index 000000000..0f781c8f8
--- /dev/null
+++ b/vendor/windows-bindgen/src/rust/mod.rs
@@ -0,0 +1,280 @@
+mod cfg;
+mod classes;
+mod com_methods;
+mod constants;
+mod delegates;
+mod enums;
+mod extensions;
+mod functions;
+mod handles;
+mod implements;
+mod interfaces;
+mod iterators;
+mod method_names;
+mod standalone;
+mod structs;
+mod try_format;
+mod winrt_methods;
+mod writer;
+use super::*;
+use crate::{Error, Result, Tree};
+use cfg::*;
+use rayon::prelude::*;
+
+pub fn from_reader(reader: &metadata::Reader, filter: &metadata::Filter, mut config: std::collections::BTreeMap<&str, &str>, output: &str) -> Result<()> {
+ let mut writer = Writer::new(reader, filter, output);
+ writer.package = config.remove("package").is_some();
+ writer.flatten = config.remove("flatten").is_some();
+ writer.std = config.remove("std").is_some();
+ writer.sys = writer.std || config.remove("sys").is_some();
+ writer.implement = config.remove("implement").is_some();
+ writer.minimal = config.remove("minimal").is_some();
+
+ if writer.package && writer.flatten {
+ return Err(Error::new("cannot combine `package` and `flatten` configuration values"));
+ }
+
+ if writer.implement && writer.sys {
+ return Err(Error::new("cannot combine `implement` and `sys` configuration values"));
+ }
+
+ if let Some((key, _)) = config.first_key_value() {
+ return Err(Error::new(&format!("invalid configuration value `{key}`")));
+ }
+
+ if writer.package {
+ gen_package(&writer)
+ } else {
+ gen_file(&writer)
+ }
+}
+
+fn gen_file(writer: &Writer) -> Result<()> {
+ // TODO: harmonize this output code so we don't need these two wildly differnt code paths
+ // there should be a simple way to generate the with or without namespaces.
+
+ if writer.flatten {
+ let tokens = standalone::standalone_imp(writer);
+ crate::write_to_file(writer.output, try_format(writer, &tokens))
+ } else {
+ let mut tokens = String::new();
+ let root = Tree::new(writer.reader, writer.filter);
+
+ for tree in root.nested.values() {
+ tokens.push_str(&namespace(writer, tree));
+ }
+
+ crate::write_to_file(writer.output, try_format(writer, &tokens))
+ }
+}
+
+fn gen_package(writer: &Writer) -> Result<()> {
+ let directory = crate::directory(writer.output);
+ let root = Tree::new(writer.reader, writer.filter);
+ let mut root_len = 0;
+
+ for tree in root.nested.values() {
+ root_len = tree.namespace.len();
+ _ = std::fs::remove_dir_all(format!("{directory}/{}", tree.namespace));
+ }
+
+ let trees = root.flatten();
+
+ trees.par_iter().try_for_each(|tree| {
+ let directory = format!("{directory}/{}", tree.namespace.replace('.', "/"));
+ let mut tokens = namespace(writer, tree);
+
+ let tokens_impl = if !writer.sys { namespace_impl(writer, tree) } else { String::new() };
+
+ if !writer.sys && !tokens_impl.is_empty() {
+ tokens.push_str("#[cfg(feature = \"implement\")]\n::core::include!(\"impl.rs\");\n");
+ }
+
+ let output = format!("{directory}/mod.rs");
+ crate::write_to_file(&output, try_format(writer, &tokens))?;
+
+ if !writer.sys && !tokens_impl.is_empty() {
+ let output = format!("{directory}/impl.rs");
+ crate::write_to_file(&output, try_format(writer, &tokens_impl))?;
+ }
+
+ Ok::<(), Error>(())
+ })?;
+
+ let cargo_toml = format!("{}/Cargo.toml", crate::directory(directory));
+ let mut toml = String::new();
+
+ for line in crate::read_file_lines(&cargo_toml)? {
+ toml.push_str(&line);
+ toml.push('\n');
+
+ if line == "# generated features" {
+ break;
+ }
+ }
+
+ for tree in trees.iter().skip(1) {
+ let feature = tree.namespace[root_len + 1..].replace('.', "_");
+
+ if let Some(pos) = feature.rfind('_') {
+ let dependency = &feature[..pos];
+
+ toml.push_str(&format!("{feature} = [\"{dependency}\"]\n"));
+ } else {
+ toml.push_str(&format!("{feature} = []\n"));
+ }
+ }
+
+ crate::write_to_file(&cargo_toml, toml)
+}
+
+use crate::tokens::*;
+use metadata::*;
+use method_names::*;
+use std::collections::*;
+use std::fmt::Write;
+use try_format::*;
+use writer::*;
+
+fn namespace(writer: &Writer, tree: &Tree) -> String {
+ let writer = &mut writer.clone();
+ writer.namespace = tree.namespace;
+ let mut tokens = TokenStream::new();
+
+ for (name, tree) in &tree.nested {
+ let name = to_ident(name);
+ let namespace_feature = tree.namespace[tree.namespace.find('.').unwrap() + 1..].replace('.', "_");
+ if writer.package {
+ tokens.combine(&quote! {
+ #[cfg(feature = #namespace_feature)]
+ pub mod #name;
+ });
+ } else {
+ tokens.combine(&quote! { pub mod #name });
+ tokens.push_str("{");
+ tokens.push_str(&namespace(writer, tree));
+ tokens.push_str("}");
+ }
+ }
+
+ let mut functions = BTreeMap::<&str, TokenStream>::new();
+ let mut types = BTreeMap::<TypeKind, BTreeMap<&str, TokenStream>>::new();
+
+ for item in writer.reader.namespace_items(writer.namespace, writer.filter) {
+ match item {
+ Item::Type(def) => {
+ let type_name = writer.reader.type_def_type_name(def);
+ if REMAP_TYPES.iter().any(|(x, _)| x == &type_name) {
+ continue;
+ }
+ if CORE_TYPES.iter().any(|(x, _)| x == &type_name) {
+ continue;
+ }
+ let name = type_name.name;
+ let kind = writer.reader.type_def_kind(def);
+ match kind {
+ TypeKind::Class => {
+ if writer.reader.type_def_flags(def).contains(TypeAttributes::WindowsRuntime) {
+ types.entry(kind).or_default().insert(name, classes::writer(writer, def));
+ }
+ }
+ TypeKind::Interface => types.entry(kind).or_default().entry(name).or_default().combine(&interfaces::writer(writer, def)),
+ TypeKind::Enum => types.entry(kind).or_default().entry(name).or_default().combine(&enums::writer(writer, def)),
+ TypeKind::Struct => {
+ if writer.reader.type_def_fields(def).next().is_none() {
+ if let Some(guid) = type_def_guid(writer.reader, def) {
+ let ident = to_ident(name);
+ let value = writer.guid(&guid);
+ let guid = writer.type_name(&Type::GUID);
+ let cfg = type_def_cfg(writer.reader, def, &[]);
+ let doc = writer.cfg_doc(&cfg);
+ let constant = quote! {
+ #doc
+ pub const #ident: #guid = #value;
+ };
+ types.entry(TypeKind::Class).or_default().entry(name).or_default().combine(&constant);
+ continue;
+ }
+ }
+ types.entry(kind).or_default().entry(name).or_default().combine(&structs::writer(writer, def));
+ }
+ TypeKind::Delegate => types.entry(kind).or_default().entry(name).or_default().combine(&delegates::writer(writer, def)),
+ }
+ }
+ Item::Fn(def, namespace) => {
+ let name = writer.reader.method_def_name(def);
+ functions.entry(name).or_default().combine(&functions::writer(writer, &namespace, def));
+ }
+ Item::Const(def) => {
+ let name = writer.reader.field_name(def);
+ types.entry(TypeKind::Class).or_default().entry(name).or_default().combine(&constants::writer(writer, def));
+ }
+ }
+ }
+
+ for function in functions.values() {
+ tokens.combine(function);
+ }
+
+ for ty in types.values().flat_map(|v| v.values()) {
+ tokens.combine(ty);
+ }
+
+ tokens.combine(&extensions::gen_mod(writer, tree.namespace));
+
+ if writer.implement {
+ tokens.push_str(&namespace_impl(writer, tree));
+ }
+
+ tokens.into_string()
+}
+
+fn namespace_impl(writer: &Writer, tree: &Tree) -> String {
+ let writer = &mut writer.clone();
+ writer.namespace = tree.namespace;
+ let mut types = BTreeMap::<&str, TokenStream>::new();
+
+ for item in writer.reader.namespace_items(writer.namespace, writer.filter) {
+ if let Item::Type(def) = item {
+ let type_name = writer.reader.type_def_type_name(def);
+ if CORE_TYPES.iter().any(|(x, _)| x == &type_name) {
+ continue;
+ }
+ if writer.reader.type_def_kind(def) != TypeKind::Interface {
+ continue;
+ }
+ let tokens = implements::writer(writer, def);
+
+ if !tokens.is_empty() {
+ types.insert(type_name.name, tokens);
+ }
+ }
+ }
+
+ let types = types.values();
+
+ let mut tokens = quote! {
+ #(#types)*
+ };
+
+ tokens.combine(&extensions::gen_impl(tree.namespace));
+ tokens.into_string()
+}
+
+/// Expand a possibly empty generics list with a new generic
+fn expand_generics(generics: TokenStream, new: TokenStream) -> TokenStream {
+ if generics.is_empty() {
+ quote!(#new)
+ } else {
+ quote!(#generics, #new)
+ }
+}
+
+/// Expand a possibly emppty where clause with a new generic constraint
+fn expand_where_clause(where_clause: TokenStream, generic: TokenStream) -> TokenStream {
+ if where_clause.is_empty() {
+ quote!(where #generic)
+ } else {
+ quote!(#where_clause #generic)
+ }
+}
diff --git a/vendor/windows-bindgen/src/rust/standalone.rs b/vendor/windows-bindgen/src/rust/standalone.rs
new file mode 100644
index 000000000..f74c34647
--- /dev/null
+++ b/vendor/windows-bindgen/src/rust/standalone.rs
@@ -0,0 +1,217 @@
+use super::*;
+
+pub fn standalone_imp(writer: &Writer) -> String {
+ let mut types = BTreeSet::new();
+ let mut functions = BTreeSet::new();
+ let mut constants = BTreeSet::new();
+
+ for item in writer.reader.items(writer.filter) {
+ item_collect_standalone(writer.reader, item.clone(), &mut types);
+
+ match item {
+ Item::Type(_) => {}
+ Item::Fn(def, namespace) => _ = functions.insert((def, namespace.clone())),
+ Item::Const(def) => _ = constants.insert(def),
+ }
+ }
+
+ let mut sorted = SortedTokens::default();
+
+ for ty in types {
+ match ty {
+ Type::HRESULT if writer.sys => sorted.insert("HRESULT", quote! { pub type HRESULT = i32; }),
+ Type::String if writer.sys => sorted.insert("HSTRING", quote! { pub type HSTRING = *mut ::core::ffi::c_void; }),
+ Type::IUnknown if writer.sys => sorted.insert("IUnknown", quote! { pub type IUnknown = *mut ::core::ffi::c_void; }),
+ Type::IInspectable if writer.sys => sorted.insert("IInspectable", quote! { pub type IInspectable = *mut ::core::ffi::c_void; }),
+ Type::PSTR if writer.sys => sorted.insert("PSTR", quote! { pub type PSTR = *mut u8; }),
+ Type::PWSTR if writer.sys => sorted.insert("PWSTR", quote! { pub type PWSTR = *mut u16; }),
+ Type::PCSTR if writer.sys => sorted.insert("PCSTR", quote! { pub type PCSTR = *const u8; }),
+ Type::PCWSTR if writer.sys => sorted.insert("PCWSTR", quote! { pub type PCWSTR = *const u16; }),
+ Type::BSTR if writer.sys => sorted.insert("BSTR", quote! { pub type BSTR = *const u16; }),
+ Type::GUID if writer.sys => {
+ sorted.insert(
+ "GUID",
+ quote! {
+ #[repr(C)]
+ pub struct GUID {
+ pub data1: u32,
+ pub data2: u16,
+ pub data3: u16,
+ pub data4: [u8; 8],
+ }
+ impl ::core::marker::Copy for GUID {}
+ impl ::core::clone::Clone for GUID {
+ fn clone(&self) -> Self {
+ *self
+ }
+ }
+ impl GUID {
+ pub const fn from_u128(uuid: u128) -> Self {
+ Self { data1: (uuid >> 96) as u32, data2: (uuid >> 80 & 0xffff) as u16, data3: (uuid >> 64 & 0xffff) as u16, data4: (uuid as u64).to_be_bytes() }
+ }
+ }
+ },
+ );
+ }
+ Type::TypeDef(def, _) => {
+ let kind = writer.reader.type_def_kind(def);
+ match kind {
+ TypeKind::Class => {
+ let name = writer.reader.type_def_name(def);
+ if writer.sys {
+ let ident = to_ident(name);
+ sorted.insert(name, quote! { pub type #ident = *mut ::core::ffi::c_void; });
+ } else {
+ sorted.insert(name, classes::writer(writer, def));
+ }
+ }
+ TypeKind::Interface => {
+ let name = writer.reader.type_def_name(def);
+ if writer.sys {
+ let ident = to_ident(name);
+ sorted.insert(name, quote! { pub type #ident = *mut ::core::ffi::c_void; });
+ } else {
+ sorted.insert(name, interfaces::writer(writer, def));
+ }
+ }
+ TypeKind::Enum => {
+ sorted.insert(writer.reader.type_def_name(def), enums::writer(writer, def));
+ }
+ TypeKind::Struct => {
+ let name = writer.reader.type_def_name(def);
+ if writer.reader.type_def_fields(def).next().is_none() {
+ if let Some(guid) = type_def_guid(writer.reader, def) {
+ let ident = to_ident(name);
+ let value = writer.guid(&guid);
+ let guid = writer.type_name(&Type::GUID);
+ sorted.insert(
+ name,
+ quote! {
+ pub const #ident: #guid = #value;
+ },
+ );
+ continue;
+ }
+ }
+ sorted.insert(name, structs::writer(writer, def));
+ }
+ TypeKind::Delegate => {
+ sorted.insert(writer.reader.type_def_name(def), delegates::writer(writer, def));
+ }
+ }
+ }
+ _ => {}
+ }
+ }
+
+ for (function, namespace) in functions {
+ sorted.insert(&format!(".{}.{}", writer.reader.method_def_module_name(function), writer.reader.method_def_name(function)), functions::writer(writer, &namespace, function));
+ }
+
+ for constant in constants {
+ sorted.insert(writer.reader.field_name(constant), constants::writer(writer, constant));
+ }
+
+ let mut tokens = TokenStream::new();
+ sorted.0.values().for_each(|value| tokens.combine(value));
+ tokens.into_string()
+}
+
+#[derive(Default)]
+struct SortedTokens(BTreeMap<String, TokenStream>);
+
+impl SortedTokens {
+ fn insert(&mut self, key: &str, tokens: TokenStream) {
+ self.0.entry(key.to_string()).or_default().combine(&tokens);
+ }
+}
+
+fn item_collect_standalone(reader: &Reader, item: Item, set: &mut BTreeSet<Type>) {
+ match item {
+ Item::Type(def) => type_collect_standalone(reader, &Type::TypeDef(def, vec![]), set),
+ Item::Const(def) => type_collect_standalone(reader, &reader.field_type(def, None).to_const_type(), set),
+ Item::Fn(def, namespace) => {
+ let signature = method_def_signature(reader, &namespace, def, &[]);
+ type_collect_standalone(reader, &signature.return_type, set);
+ signature.params.iter().for_each(|param| type_collect_standalone(reader, &param.ty, set));
+ }
+ }
+}
+// TODO: remove or move to riddle
+fn type_collect_standalone(reader: &Reader, ty: &Type, set: &mut BTreeSet<Type>) {
+ let ty = ty.to_underlying_type();
+ if !set.insert(ty.clone()) {
+ return;
+ }
+
+ let Type::TypeDef(def, generics) = &ty else {
+ return;
+ };
+
+ let def = *def;
+
+ // Ensure that we collect all the typedefs of the same name. We need to
+ // do this in the case where the user specifies a top level item that
+ // references a typedef by name, but that name resolves to more than 1
+ // Type based on target architecture (typically)
+ //
+ // Note this is a bit overeager as we can collect a typedef that is used
+ // by one architecture but not by another
+ let type_name = reader.type_def_type_name(def);
+ if !type_name.namespace.is_empty() {
+ for row in reader.get_type_def(type_name) {
+ if def != row {
+ type_collect_standalone(reader, &Type::TypeDef(row, Vec::new()), set);
+ }
+ }
+ }
+
+ for generic in generics {
+ type_collect_standalone(reader, generic, set);
+ }
+ for field in reader.type_def_fields(def) {
+ let ty = reader.field_type(field, Some(def));
+ if let Type::TypeDef(def, _) = &ty {
+ if reader.type_def_namespace(*def).is_empty() {
+ continue;
+ }
+ }
+ type_collect_standalone(reader, &ty, set);
+ }
+ for method in reader.type_def_methods(def) {
+ // Skip delegate pseudo-constructors.
+ if reader.method_def_name(method) == ".ctor" {
+ continue;
+ }
+ let signature = method_def_signature(reader, reader.type_def_namespace(def), method, generics);
+ type_collect_standalone(reader, &signature.return_type, set);
+ signature.params.iter().for_each(|param| type_collect_standalone(reader, &param.ty, set));
+ }
+ for interface in type_interfaces(reader, &ty) {
+ type_collect_standalone(reader, &interface.ty, set);
+ }
+ if reader.type_def_kind(def) == TypeKind::Struct && reader.type_def_fields(def).next().is_none() && type_def_guid(reader, def).is_some() {
+ set.insert(Type::GUID);
+ }
+
+ type_collect_standalone_nested(reader, def, set);
+}
+
+fn type_collect_standalone_nested(reader: &Reader, td: TypeDef, set: &mut BTreeSet<Type>) {
+ for nested in reader.nested_types(td) {
+ type_collect_standalone_nested(reader, nested, set);
+
+ for field in reader.type_def_fields(nested) {
+ let ty = reader.field_type(field, Some(nested));
+ if let Type::TypeDef(def, _) = &ty {
+ // Skip the fields that actually refer to the anonymous nested
+ // type, otherwise it will get added to the typeset and emitted
+ if reader.type_def_namespace(*def).is_empty() {
+ continue;
+ }
+
+ type_collect_standalone(reader, &ty, set);
+ }
+ }
+ }
+}
diff --git a/vendor/windows-bindgen/src/rust/structs.rs b/vendor/windows-bindgen/src/rust/structs.rs
new file mode 100644
index 000000000..249b293dc
--- /dev/null
+++ b/vendor/windows-bindgen/src/rust/structs.rs
@@ -0,0 +1,288 @@
+use super::*;
+
+pub fn writer(writer: &Writer, def: TypeDef) -> TokenStream {
+ if writer.reader.has_attribute(def, "ApiContractAttribute") {
+ return quote! {};
+ }
+
+ if type_def_is_handle(writer.reader, def) {
+ return handles::writer(writer, def);
+ }
+
+ gen_struct_with_name(writer, def, writer.reader.type_def_name(def), &Cfg::default())
+}
+
+fn gen_struct_with_name(writer: &Writer, def: TypeDef, struct_name: &str, cfg: &Cfg) -> TokenStream {
+ let name = to_ident(struct_name);
+
+ if writer.reader.type_def_fields(def).next().is_none() {
+ let mut tokens = quote! {
+ #[repr(C)]
+ pub struct #name(pub u8);
+ impl ::core::marker::Copy for #name {}
+ impl ::core::clone::Clone for #name {
+ fn clone(&self) -> Self {
+ *self
+ }
+ }
+ };
+ if !writer.sys {
+ tokens.combine(&quote! {
+ impl ::windows_core::TypeKind for #name {
+ type TypeKind = ::windows_core::CopyType;
+ }
+ });
+ }
+ return tokens;
+ }
+
+ let flags = writer.reader.type_def_flags(def);
+ let cfg = cfg.union(&type_def_cfg(writer.reader, def, &[]));
+
+ let repr = if let Some(layout) = writer.reader.type_def_class_layout(def) {
+ let packing = Literal::usize_unsuffixed(writer.reader.class_layout_packing_size(layout));
+ quote! { #[repr(C, packed(#packing))] }
+ } else {
+ quote! { #[repr(C)] }
+ };
+
+ let fields = writer.reader.type_def_fields(def).map(|f| {
+ let name = to_ident(writer.reader.field_name(f));
+ let ty = writer.reader.field_type(f, Some(def));
+
+ if writer.reader.field_flags(f).contains(FieldAttributes::Literal) {
+ quote! {}
+ } else if !writer.sys && flags.contains(TypeAttributes::ExplicitLayout) && !field_is_copyable(writer.reader, f, def) {
+ let ty = writer.type_default_name(&ty);
+ quote! { pub #name: ::std::mem::ManuallyDrop<#ty>, }
+ } else if !writer.sys && !flags.contains(TypeAttributes::WindowsRuntime) && !field_is_blittable(writer.reader, f, def) {
+ if let Type::Win32Array(ty, len) = ty {
+ let ty = writer.type_default_name(&ty);
+ quote! { pub #name: [::std::mem::ManuallyDrop<#ty>; #len], }
+ } else {
+ let ty = writer.type_default_name(&ty);
+ quote! { pub #name: ::std::mem::ManuallyDrop<#ty>, }
+ }
+ } else {
+ let ty = writer.type_default_name(&ty);
+ quote! { pub #name: #ty, }
+ }
+ });
+
+ let struct_or_union = if flags.contains(TypeAttributes::ExplicitLayout) {
+ quote! { union }
+ } else {
+ quote! { struct }
+ };
+
+ let doc = writer.cfg_doc(&cfg);
+ let features = writer.cfg_features(&cfg);
+
+ let mut tokens = quote! {
+ #repr
+ #doc
+ #features
+ pub #struct_or_union #name {#(#fields)*}
+ };
+
+ tokens.combine(&gen_struct_constants(writer, def, &name, &cfg));
+ tokens.combine(&gen_copy_clone(writer, def, &name, &cfg));
+ tokens.combine(&gen_debug(writer, def, &name, &cfg));
+ tokens.combine(&gen_windows_traits(writer, def, &name, &cfg));
+ tokens.combine(&gen_compare_traits(writer, def, &name, &cfg));
+
+ if !writer.sys {
+ tokens.combine(&quote! {
+ #features
+ impl ::core::default::Default for #name {
+ fn default() -> Self {
+ unsafe { ::core::mem::zeroed() }
+ }
+ }
+ });
+ }
+
+ for (index, nested_type) in writer.reader.nested_types(def).enumerate() {
+ let nested_name = format!("{struct_name}_{index}");
+ tokens.combine(&gen_struct_with_name(writer, nested_type, &nested_name, &cfg));
+ }
+
+ tokens
+}
+
+fn gen_windows_traits(writer: &Writer, def: TypeDef, name: &TokenStream, cfg: &Cfg) -> TokenStream {
+ if writer.sys {
+ quote! {}
+ } else {
+ let features = writer.cfg_features(cfg);
+ let is_copy = type_def_is_blittable(writer.reader, def);
+
+ let type_kind = if is_copy {
+ quote! { CopyType }
+ } else {
+ quote! { ValueType }
+ };
+
+ let mut tokens = quote! {
+ #features
+ impl ::windows_core::TypeKind for #name {
+ type TypeKind = ::windows_core::#type_kind;
+ }
+ };
+
+ if writer.reader.type_def_flags(def).contains(TypeAttributes::WindowsRuntime) {
+ let signature = Literal::byte_string(type_def_signature(writer.reader, def, &[]).as_bytes());
+
+ tokens.combine(&quote! {
+ #features
+ impl ::windows_core::RuntimeType for #name {
+ const SIGNATURE: ::windows_core::imp::ConstBuffer = ::windows_core::imp::ConstBuffer::from_slice(#signature);
+ }
+ });
+ }
+
+ tokens
+ }
+}
+
+fn gen_compare_traits(writer: &Writer, def: TypeDef, name: &TokenStream, cfg: &Cfg) -> TokenStream {
+ let features = writer.cfg_features(cfg);
+
+ if writer.sys || type_def_has_explicit_layout(writer.reader, def) || type_def_has_packing(writer.reader, def) || type_def_has_callback(writer.reader, def) {
+ quote! {}
+ } else {
+ let fields = writer.reader.type_def_fields(def).filter_map(|f| {
+ let name = to_ident(writer.reader.field_name(f));
+ if writer.reader.field_flags(f).contains(FieldAttributes::Literal) {
+ None
+ } else {
+ Some(quote! { self.#name == other.#name })
+ }
+ });
+
+ quote! {
+ #features
+ impl ::core::cmp::PartialEq for #name {
+ fn eq(&self, other: &Self) -> bool {
+ #(#fields)&&*
+ }
+ }
+ #features
+ impl ::core::cmp::Eq for #name {}
+ }
+ }
+}
+
+fn gen_debug(writer: &Writer, def: TypeDef, ident: &TokenStream, cfg: &Cfg) -> TokenStream {
+ if writer.sys || type_def_has_explicit_layout(writer.reader, def) || type_def_has_packing(writer.reader, def) {
+ quote! {}
+ } else {
+ let name = ident.as_str();
+ let features = writer.cfg_features(cfg);
+
+ let fields = writer.reader.type_def_fields(def).filter_map(|f| {
+ if writer.reader.field_flags(f).contains(FieldAttributes::Literal) {
+ None
+ } else {
+ let name = writer.reader.field_name(f);
+ let ident = to_ident(name);
+ let ty = writer.reader.field_type(f, Some(def));
+ if type_has_callback(writer.reader, &ty) {
+ None
+ } else {
+ Some(quote! { .field(#name, &self.#ident) })
+ }
+ }
+ });
+
+ quote! {
+ #features
+ impl ::core::fmt::Debug for #ident {
+ fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
+ f.debug_struct(#name) #(#fields)* .finish()
+ }
+ }
+ }
+ }
+}
+
+fn gen_copy_clone(writer: &Writer, def: TypeDef, name: &TokenStream, cfg: &Cfg) -> TokenStream {
+ let features = writer.cfg_features(cfg);
+
+ if writer.sys || type_def_is_copyable(writer.reader, def) {
+ quote! {
+ #features
+ impl ::core::marker::Copy for #name {}
+ #features
+ impl ::core::clone::Clone for #name {
+ fn clone(&self) -> Self {
+ *self
+ }
+ }
+ }
+ } else if writer.reader.type_def_class_layout(def).is_some() {
+ // Don't support copy/clone of packed structs: https://github.com/rust-lang/rust/issues/82523
+ quote! {}
+ } else if !writer.reader.type_def_flags(def).contains(TypeAttributes::WindowsRuntime) {
+ quote! {
+ #features
+ impl ::core::clone::Clone for #name {
+ fn clone(&self) -> Self {
+ unsafe { ::core::mem::transmute_copy(self) }
+ }
+ }
+ }
+ } else {
+ let fields = writer.reader.type_def_fields(def).map(|f| {
+ let name = to_ident(writer.reader.field_name(f));
+ if writer.reader.field_flags(f).contains(FieldAttributes::Literal) {
+ quote! {}
+ } else if field_is_blittable(writer.reader, f, def) {
+ quote! { #name: self.#name }
+ } else {
+ quote! { #name: self.#name.clone() }
+ }
+ });
+
+ quote! {
+ #features
+ impl ::core::clone::Clone for #name {
+ fn clone(&self) -> Self {
+ Self { #(#fields),* }
+ }
+ }
+ }
+ }
+}
+
+fn gen_struct_constants(writer: &Writer, def: TypeDef, struct_name: &TokenStream, cfg: &Cfg) -> TokenStream {
+ let features = writer.cfg_features(cfg);
+
+ let constants = writer.reader.type_def_fields(def).filter_map(|f| {
+ if writer.reader.field_flags(f).contains(FieldAttributes::Literal) {
+ if let Some(constant) = writer.reader.field_constant(f) {
+ let name = to_ident(writer.reader.field_name(f));
+ let value = writer.typed_value(&writer.reader.constant_value(constant));
+
+ return Some(quote! {
+ pub const #name: #value;
+ });
+ }
+ }
+
+ None
+ });
+
+ let mut tokens = quote! { #(#constants)* };
+
+ if !tokens.is_empty() {
+ tokens = quote! {
+ #features
+ impl #struct_name {
+ #tokens
+ }
+ };
+ }
+
+ tokens
+}
diff --git a/vendor/windows-bindgen/src/rust/try_format.rs b/vendor/windows-bindgen/src/rust/try_format.rs
new file mode 100644
index 000000000..c871517b1
--- /dev/null
+++ b/vendor/windows-bindgen/src/rust/try_format.rs
@@ -0,0 +1,49 @@
+use std::io::Write;
+
+pub fn try_format(writer: &super::Writer, tokens: &str) -> String {
+ let preamble = if writer.package {
+ String::new()
+ } else {
+ let name = std::env!("CARGO_PKG_NAME");
+ let version = std::env!("CARGO_PKG_VERSION");
+
+ format!(
+ r#"// Bindings generated by `{name}` {version}
+
+
+"#
+ )
+ };
+
+ // Packaging - e.g. windows/windows-sys crates - assumes the crate will allow whatever warnings it deems fit.
+ let allow = if writer.package { "" } else { "#![allow(non_snake_case, non_upper_case_globals, non_camel_case_types, dead_code, clippy::all)]\n" };
+ let tokens = format!("{preamble}{allow}{tokens}");
+
+ let Ok(mut child) = std::process::Command::new("rustfmt").stdin(std::process::Stdio::piped()).stdout(std::process::Stdio::piped()).stderr(std::process::Stdio::null()).spawn() else {
+ return tokens;
+ };
+
+ let Some(mut stdin) = child.stdin.take() else {
+ return tokens;
+ };
+
+ if stdin.write_all(tokens.as_bytes()).is_err() {
+ return tokens;
+ }
+
+ drop(stdin);
+
+ let Ok(output) = child.wait_with_output() else {
+ return tokens;
+ };
+
+ if !output.status.success() {
+ return tokens;
+ }
+
+ if let Ok(result) = String::from_utf8(output.stdout) {
+ result
+ } else {
+ tokens
+ }
+}
diff --git a/vendor/windows-bindgen/src/rust/winrt_methods.rs b/vendor/windows-bindgen/src/rust/winrt_methods.rs
new file mode 100644
index 000000000..f98843e66
--- /dev/null
+++ b/vendor/windows-bindgen/src/rust/winrt_methods.rs
@@ -0,0 +1,242 @@
+use super::*;
+
+// TODO take Signature instead of MethodDef (wherever MethodDef is found)
+pub fn writer(writer: &Writer, def: TypeDef, generic_types: &[Type], kind: InterfaceKind, method: MethodDef, method_names: &mut MethodNames, virtual_names: &mut MethodNames) -> TokenStream {
+ let signature = method_def_signature(writer.reader, writer.reader.type_def_namespace(def), method, generic_types);
+ let params = &signature.params;
+ let name = method_names.add(writer, method);
+ let interface_name = writer.type_def_name(def, generic_types);
+ let vname = virtual_names.add(writer, method);
+ let generics = writer.constraint_generics(params);
+ let where_clause = writer.where_clause(params);
+ let mut cfg = signature_cfg(writer.reader, method);
+ type_def_cfg_combine(writer.reader, def, generic_types, &mut cfg);
+ let doc = writer.cfg_method_doc(&cfg);
+ let features = writer.cfg_features(&cfg);
+ let args = gen_winrt_abi_args(writer, params);
+ let params = gen_winrt_params(writer, params);
+
+ let return_type_tokens = match &signature.return_type {
+ Type::Void => quote! { () },
+ _ => {
+ let tokens = writer.type_name(&signature.return_type);
+ if signature.return_type.is_winrt_array() {
+ quote! { ::windows_core::Array<#tokens> }
+ } else {
+ quote! { #tokens }
+ }
+ }
+ };
+
+ let return_arg = match &signature.return_type {
+ Type::Void => quote! {},
+ _ => {
+ if signature.return_type.is_winrt_array() {
+ let return_type = writer.type_name(&signature.return_type);
+ quote! { ::windows_core::Array::<#return_type>::set_abi_len(::std::mem::transmute(&mut result__)), result__.as_mut_ptr() as *mut _ as _ }
+ } else {
+ quote! { &mut result__ }
+ }
+ }
+ };
+
+ let vcall = match &signature.return_type {
+ Type::Void => {
+ quote! {
+ (::windows_core::Interface::vtable(this).#vname)(::windows_core::Interface::as_raw(this), #args).ok()
+ }
+ }
+ _ if signature.return_type.is_winrt_array() => {
+ quote! {
+ let mut result__ = ::core::mem::MaybeUninit::zeroed();
+ (::windows_core::Interface::vtable(this).#vname)(::windows_core::Interface::as_raw(this), #args #return_arg)
+ .and_then(|| result__.assume_init())
+ }
+ }
+ _ => {
+ quote! {
+ let mut result__ = ::std::mem::zeroed();
+ (::windows_core::Interface::vtable(this).#vname)(::windows_core::Interface::as_raw(this), #args #return_arg)
+ .from_abi(result__)
+ }
+ }
+ };
+
+ match kind {
+ InterfaceKind::Default => quote! {
+ #doc
+ #features
+ pub fn #name<#generics>(&self, #params) -> ::windows_core::Result<#return_type_tokens> #where_clause {
+ let this = self;
+ unsafe {
+ #vcall
+ }
+ }
+ },
+ InterfaceKind::None | InterfaceKind::Base | InterfaceKind::Overridable => {
+ quote! {
+ #doc
+ #features
+ pub fn #name<#generics>(&self, #params) -> ::windows_core::Result<#return_type_tokens> #where_clause {
+ let this = &::windows_core::ComInterface::cast::<#interface_name>(self)?;
+ unsafe {
+ #vcall
+ }
+ }
+ }
+ }
+ InterfaceKind::Static => {
+ quote! {
+ #doc
+ #features
+ pub fn #name<#generics>(#params) -> ::windows_core::Result<#return_type_tokens> #where_clause {
+ Self::#interface_name(|this| unsafe { #vcall })
+ }
+ }
+ }
+ }
+}
+
+fn gen_winrt_params(writer: &Writer, params: &[SignatureParam]) -> TokenStream {
+ let mut result = quote! {};
+
+ let mut generic_params = writer.generic_params(params);
+ for param in params.iter() {
+ let name = writer.param_name(param.def);
+ let kind = writer.type_name(&param.ty);
+ let default_type = writer.type_default_name(&param.ty);
+
+ if writer.reader.param_flags(param.def).contains(ParamAttributes::In) {
+ if param.ty.is_winrt_array() {
+ result.combine(&quote! { #name: &[#default_type], });
+ } else if signature_param_is_convertible(writer.reader, param) {
+ let (position, _) = generic_params.next().unwrap();
+ let kind: TokenStream = format!("P{position}").into();
+ result.combine(&quote! { #name: #kind, });
+ } else if type_is_blittable(writer.reader, &param.ty) {
+ result.combine(&quote! { #name: #kind, });
+ } else {
+ result.combine(&quote! { #name: &#kind, });
+ }
+ } else if param.ty.is_winrt_array() {
+ result.combine(&quote! { #name: &mut [#default_type], });
+ } else if param.ty.is_winrt_array_ref() {
+ result.combine(&quote! { #name: &mut ::windows_core::Array<#kind>, });
+ } else {
+ result.combine(&quote! { #name: &mut #default_type, });
+ }
+ }
+
+ result
+}
+
+fn gen_winrt_abi_args(writer: &Writer, params: &[SignatureParam]) -> TokenStream {
+ let mut tokens = TokenStream::new();
+ for param in params {
+ let name = writer.param_name(param.def);
+
+ let param = if writer.reader.param_flags(param.def).contains(ParamAttributes::In) {
+ if param.ty.is_winrt_array() {
+ if type_is_blittable(writer.reader, &param.ty) {
+ quote! { #name.len() as u32, #name.as_ptr(), }
+ } else {
+ quote! { #name.len() as u32, ::core::mem::transmute(#name.as_ptr()), }
+ }
+ } else if type_is_non_exclusive_winrt_interface(writer.reader, &param.ty) {
+ quote! { #name.try_into_param()?.abi(), }
+ } else if signature_param_is_borrowed(writer.reader, param) {
+ quote! { #name.into_param().abi(), }
+ } else if type_is_blittable(writer.reader, &param.ty) {
+ if param.ty.is_const_ref() {
+ quote! { &#name, }
+ } else {
+ quote! { #name, }
+ }
+ } else {
+ quote! { ::core::mem::transmute_copy(#name), }
+ }
+ } else if param.ty.is_winrt_array() {
+ if type_is_blittable(writer.reader, &param.ty) {
+ quote! { #name.len() as u32, #name.as_mut_ptr(), }
+ } else {
+ quote! { #name.len() as u32, ::core::mem::transmute_copy(&#name), }
+ }
+ } else if param.ty.is_winrt_array_ref() {
+ quote! { #name.set_abi_len(), #name as *mut _ as _, }
+ } else if type_is_blittable(writer.reader, &param.ty) {
+ quote! { #name, }
+ } else {
+ quote! { #name as *mut _ as _, }
+ };
+ tokens.combine(&param);
+ }
+ tokens
+}
+
+pub fn gen_upcall(writer: &Writer, sig: &Signature, inner: TokenStream) -> TokenStream {
+ let invoke_args = sig.params.iter().map(|param| gen_winrt_invoke_arg(writer, param));
+
+ match &sig.return_type {
+ Type::Void => quote! {
+ #inner(#(#invoke_args,)*).into()
+ },
+ _ if sig.return_type.is_winrt_array() => {
+ quote! {
+ match #inner(#(#invoke_args,)*) {
+ ::core::result::Result::Ok(ok__) => {
+ let (ok_data__, ok_data_len__) = ok__.into_abi();
+ // use `core::ptr::write` since `result` could be uninitialized
+ ::core::ptr::write(result__, ok_data__);
+ ::core::ptr::write(result_size__, ok_data_len__);
+ ::windows_core::HRESULT(0)
+ }
+ ::core::result::Result::Err(err) => err.into()
+ }
+ }
+ }
+ _ => {
+ let forget = if type_is_blittable(writer.reader, &sig.return_type) {
+ quote! {}
+ } else {
+ quote! { ::core::mem::forget(ok__); }
+ };
+
+ quote! {
+ match #inner(#(#invoke_args,)*) {
+ ::core::result::Result::Ok(ok__) => {
+ // use `core::ptr::write` since `result` could be uninitialized
+ ::core::ptr::write(result__, ::core::mem::transmute_copy(&ok__));
+ #forget
+ ::windows_core::HRESULT(0)
+ }
+ ::core::result::Result::Err(err) => err.into()
+ }
+ }
+ }
+ }
+}
+
+fn gen_winrt_invoke_arg(writer: &Writer, param: &SignatureParam) -> TokenStream {
+ let name = writer.param_name(param.def);
+ let abi_size_name: TokenStream = format!("{}_array_size", writer.reader.param_name(param.def)).into();
+
+ if writer.reader.param_flags(param.def).contains(ParamAttributes::In) {
+ if param.ty.is_winrt_array() {
+ quote! { ::core::slice::from_raw_parts(::core::mem::transmute_copy(&#name), #abi_size_name as usize) }
+ } else if type_is_primitive(writer.reader, &param.ty) {
+ quote! { #name }
+ } else if param.ty.is_const_ref() {
+ quote! { ::core::mem::transmute_copy(&#name) }
+ } else if type_is_nullable(writer.reader, &param.ty) {
+ quote! { ::windows_core::from_raw_borrowed(&#name) }
+ } else {
+ quote! { ::core::mem::transmute(&#name) }
+ }
+ } else if param.ty.is_winrt_array() {
+ quote! { ::core::slice::from_raw_parts_mut(::core::mem::transmute_copy(&#name), #abi_size_name as usize) }
+ } else if param.ty.is_winrt_array_ref() {
+ quote! { ::windows_core::ArrayProxy::from_raw_parts(::core::mem::transmute_copy(&#name), #abi_size_name).as_array() }
+ } else {
+ quote! { ::core::mem::transmute_copy(&#name) }
+ }
+}
diff --git a/vendor/windows-bindgen/src/gen.rs b/vendor/windows-bindgen/src/rust/writer.rs
index 30d4150e6..9d81c9951 100644
--- a/vendor/windows-bindgen/src/gen.rs
+++ b/vendor/windows-bindgen/src/rust/writer.rs
@@ -1,28 +1,28 @@
use super::*;
-pub struct Gen<'a> {
+#[derive(Clone)]
+pub struct Writer<'a> {
pub reader: &'a Reader<'a>,
+ pub filter: &'a metadata::Filter<'a>,
+ pub output: &'a str,
pub namespace: &'a str,
- pub sys: bool,
- pub cfg: bool,
- pub doc: bool,
- pub component: bool,
- pub standalone: bool,
- pub std: bool,
+ pub implement: bool, // TODO: ideally we can use this to generate implementation traits on the fly and
+ // and have a single interface definition macro for consumption that expands to include
+ // impl traits when the `implement` cfg flag is set and then this writer option would be
+ // unecessary.
+ //
+ // Maybe this macro is the embedable version of the IDL format?! like a more intelligient
+ // version of the existing interface macro...
+ pub std: bool, // tweaks for internal std library support
+ pub sys: bool, // writer sys-style bindings
+ pub flatten: bool, // strips out namespaces - implies !package
+ pub package: bool, // default is single file with no cfg - implies !flatten
+ pub minimal: bool, // strips out enumerators - in future possibly other helpers as well
}
-impl<'a> Gen<'a> {
- pub fn new(reader: &'a Reader) -> Self {
- Self {
- reader,
- namespace: "",
- sys: false,
- cfg: false,
- doc: false,
- component: false,
- standalone: false,
- std: false,
- }
+impl<'a> Writer<'a> {
+ pub fn new(reader: &'a Reader, filter: &'a metadata::Filter, output: &'a str) -> Self {
+ Self { reader, filter, output, namespace: "", implement: false, std: false, sys: false, flatten: false, package: false, minimal: false }
}
//
@@ -72,8 +72,8 @@ impl<'a> Gen<'a> {
let kind = self.type_name(ty);
if ty.is_generic() {
- quote! { <#kind as ::windows::core::Type<#kind>>::Default }
- } else if self.reader.type_is_nullable(ty) && !self.sys {
+ quote! { <#kind as ::windows_core::Type<#kind>>::Default }
+ } else if type_is_nullable(self.reader, ty) && !self.sys {
quote! { ::core::option::Option<#kind> }
} else {
kind
@@ -138,38 +138,42 @@ impl<'a> Gen<'a> {
let crate_name = self.crate_name();
quote! { #crate_name PCWSTR }
}
- Type::Win32Array((ty, len)) => {
+ Type::Win32Array(ty, len) => {
let name = self.type_default_name(ty);
let len = Literal::usize_unsuffixed(*len);
quote! { [#name; #len] }
}
Type::GenericParam(generic) => self.reader.generic_param_name(*generic).into(),
- Type::TypeDef((def, generics)) => self.type_def_name(*def, generics),
- Type::MutPtr((ty, pointers)) => {
+ Type::TypeDef(def, generics) => self.type_def_name(*def, generics),
+ Type::MutPtr(ty, pointers) => {
let pointers = mut_ptrs(*pointers);
let ty = self.type_default_name(ty);
quote! { #pointers #ty }
}
- Type::ConstPtr((ty, pointers)) => {
+ Type::ConstPtr(ty, pointers) => {
let pointers = const_ptrs(*pointers);
let ty = self.type_default_name(ty);
quote! { #pointers #ty }
}
Type::WinrtArray(ty) => self.type_name(ty),
Type::WinrtArrayRef(ty) => self.type_name(ty),
- Type::WinrtConstRef(ty) => self.type_name(ty),
- _ => unimplemented!(),
+ Type::ConstRef(ty) => self.type_name(ty),
+ Type::PrimitiveOrEnum(_, ty) => self.type_name(ty),
+ rest => unimplemented!("{rest:?}"),
}
}
pub fn type_vtbl_name(&self, ty: &Type) -> TokenStream {
match ty {
- Type::TypeDef((def, generics)) => self.type_def_vtbl_name(*def, generics),
- _ => unimplemented!(),
+ Type::TypeDef(def, generics) => self.type_def_vtbl_name(*def, generics),
+ rest => unimplemented!("{rest:?}"),
}
}
pub fn type_abi_name(&self, ty: &Type) -> TokenStream {
if self.sys {
- return self.type_default_name(ty);
+ return match ty {
+ Type::PrimitiveOrEnum(ty, _) => self.type_default_name(ty),
+ _ => self.type_default_name(ty),
+ };
}
match ty {
@@ -177,36 +181,32 @@ impl<'a> Gen<'a> {
quote! { *mut ::core::ffi::c_void }
}
Type::String => {
- quote! { ::std::mem::MaybeUninit<::windows::core::HSTRING> }
+ quote! { ::std::mem::MaybeUninit<::windows_core::HSTRING> }
}
Type::BSTR => {
- quote! { ::std::mem::MaybeUninit<::windows::core::BSTR> }
+ quote! { ::std::mem::MaybeUninit<::windows_core::BSTR> }
}
- Type::Win32Array((kind, len)) => {
+ Type::Win32Array(kind, len) => {
let name = self.type_abi_name(kind);
let len = Literal::usize_unsuffixed(*len);
quote! { [#name; #len] }
}
Type::GenericParam(generic) => {
let name = to_ident(self.reader.generic_param_name(*generic));
- quote! { ::windows::core::AbiType<#name> }
+ quote! { ::windows_core::AbiType<#name> }
}
- Type::TypeDef((def, _)) => match self.reader.type_def_kind(*def) {
+ Type::TypeDef(def, _) => match self.reader.type_def_kind(*def) {
TypeKind::Enum => self.type_def_name(*def, &[]),
TypeKind::Struct => {
let tokens = self.type_def_name(*def, &[]);
- if self.reader.type_def_is_blittable(*def) {
+ if type_def_is_blittable(self.reader, *def) {
tokens
} else {
quote! { ::std::mem::MaybeUninit<#tokens> }
}
}
TypeKind::Delegate => {
- if self
- .reader
- .type_def_flags(*def)
- .contains(TypeAttributes::WINRT)
- {
+ if self.reader.type_def_flags(*def).contains(TypeAttributes::WindowsRuntime) {
quote! { *mut ::core::ffi::c_void }
} else {
self.type_def_name(*def, &[])
@@ -214,26 +214,19 @@ impl<'a> Gen<'a> {
}
_ => quote! { *mut ::core::ffi::c_void },
},
- Type::MutPtr((kind, pointers)) => {
+ Type::MutPtr(kind, pointers) => {
let pointers_tokens = gen_mut_ptrs(*pointers);
- let kind = if *pointers > 1 {
- self.type_name(kind)
- } else {
- self.type_abi_name(kind)
- };
+ let kind = if *pointers > 1 { self.type_name(kind) } else { self.type_abi_name(kind) };
quote! { #pointers_tokens #kind }
}
- Type::ConstPtr((kind, pointers)) => {
+ Type::ConstPtr(kind, pointers) => {
let pointers_tokens = gen_const_ptrs(*pointers);
- let kind = if *pointers > 1 {
- self.type_name(kind)
- } else {
- self.type_abi_name(kind)
- };
+ let kind = if *pointers > 1 { self.type_name(kind) } else { self.type_abi_name(kind) };
quote! { #pointers_tokens #kind }
}
Type::WinrtArray(kind) => self.type_abi_name(kind),
Type::WinrtArrayRef(kind) => self.type_abi_name(kind),
+ Type::PrimitiveOrEnum(ty, _) => self.type_name(ty),
_ => self.type_name(ty),
}
}
@@ -263,7 +256,7 @@ impl<'a> Gen<'a> {
let mut tokens = TokenStream::new();
for generic in generics {
let generic = self.type_name(generic);
- tokens.combine(&quote! { #generic: ::windows::core::RuntimeType + 'static, });
+ tokens.combine(&quote! { #generic: ::windows_core::RuntimeType + 'static, });
}
tokens
}
@@ -276,21 +269,12 @@ impl<'a> Gen<'a> {
tokens
}
/// The signature params which are generic (along with their relative index)
- pub fn generic_params<'b>(
- &'b self,
- params: &'b [SignatureParam],
- ) -> impl Iterator<Item = (usize, &SignatureParam)> + 'b {
- params
- .iter()
- .filter(move |param| self.reader.signature_param_is_convertible(param))
- .enumerate()
+ pub fn generic_params<'b>(&'b self, params: &'b [SignatureParam]) -> impl Iterator<Item = (usize, &SignatureParam)> + 'b {
+ params.iter().filter(move |param| signature_param_is_convertible(self.reader, param)).enumerate()
}
/// The generic param names (i.e., `T` in `fn foo<T>()`)
pub fn constraint_generics(&self, params: &[SignatureParam]) -> TokenStream {
- let mut generics = self
- .generic_params(params)
- .map(|(position, _)| -> TokenStream { format!("P{position}").into() })
- .peekable();
+ let mut generics = self.generic_params(params).map(|(position, _)| -> TokenStream { format!("P{position}").into() }).peekable();
if generics.peek().is_some() {
quote!(#(#generics),*)
@@ -319,12 +303,12 @@ impl<'a> Gen<'a> {
SignatureParamKind::TryInto => {
let name: TokenStream = gen_name(position);
let into = self.type_name(&param.ty);
- tokens.combine(&quote! { #name: ::windows::core::TryIntoParam<#into>, });
+ tokens.combine(&quote! { #name: ::windows_core::TryIntoParam<#into>, });
}
SignatureParamKind::IntoParam => {
let name: TokenStream = gen_name(position);
let into = self.type_name(&param.ty);
- tokens.combine(&quote! { #name: ::windows::core::IntoParam<#into>, });
+ tokens.combine(&quote! { #name: ::windows_core::IntoParam<#into>, });
}
_ => {}
}
@@ -338,7 +322,7 @@ impl<'a> Gen<'a> {
/// Generates doc comments for types, free functions, and constants.
pub(crate) fn cfg_doc(&self, cfg: &Cfg) -> TokenStream {
- if !self.doc {
+ if !self.package {
quote! {}
} else {
let mut tokens = format!(r#"`\"{}\"`"#, to_feature(self.namespace));
@@ -359,7 +343,7 @@ impl<'a> Gen<'a> {
/// Generates doc comments for member functions (methods) and avoids redundantly declaring the
/// enclosing module feature required by the method's type.
pub(crate) fn cfg_method_doc(&self, cfg: &Cfg) -> TokenStream {
- if !self.doc {
+ if !self.package {
quote! {}
} else {
let features = self.cfg_features_imp(cfg, self.namespace);
@@ -407,7 +391,7 @@ impl<'a> Gen<'a> {
fn cfg_features_imp(&self, cfg: &'a Cfg, namespace: &'a str) -> Vec<&'a str> {
let mut compact = Vec::<&'static str>::new();
- if !self.standalone && !self.component {
+ if self.package {
for feature in cfg.types.keys() {
if !feature.is_empty() && !starts_with(namespace, feature) {
for pos in 0..compact.len() {
@@ -447,11 +431,10 @@ impl<'a> Gen<'a> {
//
pub(crate) fn namespace(&self, namespace: &str) -> TokenStream {
- if self.standalone || namespace == self.namespace {
+ if self.flatten || namespace == self.namespace {
quote! {}
} else {
- let is_external =
- namespace.starts_with("Windows.") && !self.namespace.starts_with("Windows");
+ let is_external = namespace.starts_with("Windows.") && !self.namespace.starts_with("Windows");
let mut relative = self.namespace.split('.').peekable();
let mut namespace = namespace.split('.').peekable();
@@ -483,12 +466,14 @@ impl<'a> Gen<'a> {
}
}
pub fn crate_name(&self) -> TokenStream {
- if self.standalone {
- TokenStream::new()
- } else if self.sys {
- "::windows_sys::core::".into()
+ if self.sys {
+ if self.flatten {
+ TokenStream::new()
+ } else {
+ "::windows_sys::core::".into()
+ }
} else {
- "::windows::core::".into()
+ "::windows_core::".into()
}
}
fn scoped_name(&self, def: TypeDef) -> String {
@@ -524,7 +509,7 @@ impl<'a> Gen<'a> {
tokens.push('\"');
tokens.into()
}
- _ => unimplemented!(),
+ rest => unimplemented!("{rest:?}"),
}
}
pub fn typed_value(&self, value: &Value) -> TokenStream {
@@ -544,7 +529,7 @@ impl<'a> Gen<'a> {
Value::String(_) => {
quote! { &str = #literal }
}
- _ => unimplemented!(),
+ rest => unimplemented!("{rest:?}"),
}
}
@@ -552,16 +537,8 @@ impl<'a> Gen<'a> {
let guid = self.type_name(&Type::GUID);
format!("{}::from_u128(0x{:08x?}_{:04x?}_{:04x?}_{:02x?}{:02x?}_{:02x?}{:02x?}{:02x?}{:02x?}{:02x?}{:02x?})", guid.into_string(), value.0, value.1, value.2, value.3, value.4, value.5, value.6, value.7, value.8, value.9, value.10).into()
}
- pub fn interface_core_traits(
- &self,
- def: TypeDef,
- _generics: &[Type],
- ident: &TokenStream,
- constraints: &TokenStream,
- _phantoms: &TokenStream,
- features: &TokenStream,
- ) -> TokenStream {
- let name = trim_tick(self.reader.type_def_name(def));
+ pub fn interface_core_traits(&self, def: TypeDef, _generics: &[Type], ident: &TokenStream, constraints: &TokenStream, _phantoms: &TokenStream, features: &TokenStream) -> TokenStream {
+ let name = crate::trim_tick(self.reader.type_def_name(def));
quote! {
#features
impl<#constraints> ::core::cmp::PartialEq for #ident {
@@ -579,14 +556,8 @@ impl<'a> Gen<'a> {
}
}
}
- pub fn agile(
- &self,
- def: TypeDef,
- ident: &TokenStream,
- constraints: &TokenStream,
- features: &TokenStream,
- ) -> TokenStream {
- if self.reader.type_def_is_agile(def) {
+ pub fn agile(&self, def: TypeDef, ident: &TokenStream, constraints: &TokenStream, features: &TokenStream) -> TokenStream {
+ if type_def_is_agile(self.reader, def) {
quote! {
#features
unsafe impl<#constraints> ::core::marker::Send for #ident {}
@@ -597,22 +568,14 @@ impl<'a> Gen<'a> {
quote! {}
}
}
- pub fn async_get(
- &self,
- def: TypeDef,
- generics: &[Type],
- ident: &TokenStream,
- constraints: &TokenStream,
- _phantoms: &TokenStream,
- features: &TokenStream,
- ) -> TokenStream {
- let mut kind = self.reader.type_def_async_kind(def);
+ pub fn async_get(&self, def: TypeDef, generics: &[Type], ident: &TokenStream, constraints: &TokenStream, _phantoms: &TokenStream, features: &TokenStream) -> TokenStream {
+ let mut kind = type_def_async_kind(self.reader, def);
let mut async_generics = generics.to_vec();
if kind == AsyncKind::None {
- for interface in self.reader.type_def_interfaces(def, generics) {
- if let Type::TypeDef((interface_def, interface_generics)) = &interface.ty {
- kind = self.reader.type_def_async_kind(*interface_def);
+ for interface in type_def_interfaces(self.reader, def, generics) {
+ if let Type::TypeDef(interface_def, interface_generics) = &interface {
+ kind = type_def_async_kind(self.reader, *interface_def);
if kind != AsyncKind::None {
async_generics = interface_generics.to_vec();
break;
@@ -625,9 +588,7 @@ impl<'a> Gen<'a> {
quote! {}
} else {
let return_type = match kind {
- AsyncKind::Operation | AsyncKind::OperationWithProgress => {
- self.type_name(&async_generics[0])
- }
+ AsyncKind::Operation | AsyncKind::OperationWithProgress => self.type_name(&async_generics[0]),
_ => quote! { () },
};
@@ -638,7 +599,7 @@ impl<'a> Gen<'a> {
AsyncKind::OperationWithProgress => {
quote! { AsyncOperationWithProgressCompletedHandler }
}
- _ => unimplemented!(),
+ rest => unimplemented!("{rest:?}"),
};
let namespace = self.namespace("Windows.Foundation");
@@ -646,9 +607,9 @@ impl<'a> Gen<'a> {
quote! {
#features
impl<#constraints> #ident {
- pub fn get(&self) -> ::windows::core::Result<#return_type> {
+ pub fn get(&self) -> ::windows_core::Result<#return_type> {
if self.Status()? == #namespace AsyncStatus::Started {
- let (_waiter, signaler) = ::windows::imp::Waiter::new()?;
+ let (_waiter, signaler) = ::windows_core::imp::Waiter::new()?;
self.SetCompleted(&#namespace #handler::new(move |_sender, _args| {
// Safe because the waiter will only be dropped after being signaled.
unsafe { signaler.signal(); }
@@ -660,7 +621,7 @@ impl<'a> Gen<'a> {
}
#features
impl<#constraints> ::std::future::Future for #ident {
- type Output = ::windows::core::Result<#return_type>;
+ type Output = ::windows_core::Result<#return_type>;
fn poll(self: ::std::pin::Pin<&mut Self>, context: &mut ::std::task::Context) -> ::std::task::Poll<Self::Output> {
if self.Status()? == #namespace AsyncStatus::Started {
@@ -680,31 +641,19 @@ impl<'a> Gen<'a> {
}
}
}
- pub fn interface_winrt_trait(
- &self,
- def: TypeDef,
- generics: &[Type],
- ident: &TokenStream,
- constraints: &TokenStream,
- _phantoms: &TokenStream,
- features: &TokenStream,
- ) -> TokenStream {
- if self
- .reader
- .type_def_flags(def)
- .contains(TypeAttributes::WINRT)
- {
+ pub fn interface_winrt_trait(&self, def: TypeDef, generics: &[Type], ident: &TokenStream, constraints: &TokenStream, _phantoms: &TokenStream, features: &TokenStream) -> TokenStream {
+ if self.reader.type_def_flags(def).contains(TypeAttributes::WindowsRuntime) {
let type_signature = if self.reader.type_def_kind(def) == TypeKind::Class {
- let type_signature =
- Literal::byte_string(self.reader.type_def_signature(def, generics).as_bytes());
- quote! { ::windows::imp::ConstBuffer::from_slice(#type_signature) }
+ let type_signature = Literal::byte_string(type_def_signature(self.reader, def, generics).as_bytes());
+ quote! { ::windows_core::imp::ConstBuffer::from_slice(#type_signature) }
} else {
let signature = Literal::byte_string(
- format!("{{{:#?}}}", self.reader.type_def_guid(def).unwrap()).as_bytes(),
+ // TODO: workaround for riddle winmd generation (no attribute support)
+ if let Some(guid) = type_def_guid(self.reader, def) { format!("{{{:#?}}}", guid) } else { "TODO".to_string() }.as_bytes(),
);
if generics.is_empty() {
- quote! { ::windows::imp::ConstBuffer::from_slice(#signature) }
+ quote! { ::windows_core::imp::ConstBuffer::from_slice(#signature) }
} else {
let generics = generics.iter().enumerate().map(|(index, g)| {
let g = self.type_name(g);
@@ -717,14 +666,14 @@ impl<'a> Gen<'a> {
};
quote! {
- .push_other(<#g as ::windows::core::RuntimeType>::SIGNATURE)
+ .push_other(<#g as ::windows_core::RuntimeType>::SIGNATURE)
#semi
}
});
quote! {
{
- ::windows::imp::ConstBuffer::new()
+ ::windows_core::imp::ConstBuffer::new()
.push_slice(b"pinterface(")
.push_slice(#signature)
.push_slice(b";")
@@ -737,54 +686,35 @@ impl<'a> Gen<'a> {
quote! {
#features
- impl<#constraints> ::windows::core::RuntimeType for #ident {
- const SIGNATURE: ::windows::imp::ConstBuffer = #type_signature;
+ impl<#constraints> ::windows_core::RuntimeType for #ident {
+ const SIGNATURE: ::windows_core::imp::ConstBuffer = #type_signature;
}
}
} else {
quote! {}
}
}
- pub fn runtime_name_trait(
- &self,
- def: TypeDef,
- _generics: &[Type],
- name: &TokenStream,
- constraints: &TokenStream,
- features: &TokenStream,
- ) -> TokenStream {
- if self
- .reader
- .type_def_flags(def)
- .contains(TypeAttributes::WINRT)
- {
+ pub fn runtime_name_trait(&self, def: TypeDef, _generics: &[Type], name: &TokenStream, constraints: &TokenStream, features: &TokenStream) -> TokenStream {
+ if self.reader.type_def_flags(def).contains(TypeAttributes::WindowsRuntime) {
// TODO: this needs to use a ConstBuffer-like facility to accomodate generics
let runtime_name = format!("{}", self.reader.type_def_type_name(def));
quote! {
#features
- impl<#constraints> ::windows::core::RuntimeName for #name {
+ impl<#constraints> ::windows_core::RuntimeName for #name {
const NAME: &'static str = #runtime_name;
}
}
} else {
quote! {
#features
- impl ::windows::core::RuntimeName for #name {}
+ impl ::windows_core::RuntimeName for #name {}
}
}
}
- pub fn interface_trait(
- &self,
- def: TypeDef,
- generics: &[Type],
- ident: &TokenStream,
- constraints: &TokenStream,
- features: &TokenStream,
- has_unknown_base: bool,
- ) -> TokenStream {
- if let Some(default) = self.reader.type_def_default_interface(def) {
+ pub fn interface_trait(&self, def: TypeDef, generics: &[Type], ident: &TokenStream, constraints: &TokenStream, features: &TokenStream, has_unknown_base: bool) -> TokenStream {
+ if let Some(default) = type_def_default_interface(self.reader, def) {
let default_name = self.type_name(&default);
let vtbl = self.type_vtbl_name(&default);
quote! {
@@ -795,28 +725,28 @@ impl<'a> Gen<'a> {
}
}
#features
- unsafe impl ::windows::core::Interface for #ident {
+ unsafe impl ::windows_core::Interface for #ident {
type Vtable = #vtbl;
}
#features
- unsafe impl ::windows::core::ComInterface for #ident {
- const IID: ::windows::core::GUID = <#default_name as ::windows::core::ComInterface>::IID;
+ unsafe impl ::windows_core::ComInterface for #ident {
+ const IID: ::windows_core::GUID = <#default_name as ::windows_core::ComInterface>::IID;
}
}
} else {
let vtbl = self.type_def_vtbl_name(def, generics);
let guid = if generics.is_empty() {
- match self.reader.type_def_guid(def) {
+ match type_def_guid(self.reader, def) {
Some(guid) => self.guid(&guid),
None => {
quote! {
- ::windows::core::GUID::zeroed()
+ ::windows_core::GUID::zeroed()
}
}
}
} else {
quote! {
- ::windows::core::GUID::from_signature(<Self as ::windows::core::RuntimeType>::SIGNATURE)
+ ::windows_core::GUID::from_signature(<Self as ::windows_core::RuntimeType>::SIGNATURE)
}
};
@@ -824,7 +754,7 @@ impl<'a> Gen<'a> {
let mut tokens = quote! {
#features
- unsafe impl<#constraints> ::windows::core::Interface for #ident {
+ unsafe impl<#constraints> ::windows_core::Interface for #ident {
type Vtable = #vtbl;
}
#features
@@ -838,8 +768,8 @@ impl<'a> Gen<'a> {
if has_unknown_base {
tokens.combine(&quote! {
#features
- unsafe impl<#constraints> ::windows::core::ComInterface for #ident {
- const IID: ::windows::core::GUID = #guid;
+ unsafe impl<#constraints> ::windows_core::ComInterface for #ident {
+ const IID: ::windows_core::GUID = #guid;
}
});
}
@@ -847,28 +777,17 @@ impl<'a> Gen<'a> {
tokens
}
}
- pub fn interface_vtbl(
- &self,
- def: TypeDef,
- generics: &[Type],
- _ident: &TokenStream,
- constraints: &TokenStream,
- features: &TokenStream,
- ) -> TokenStream {
+ pub fn interface_vtbl(&self, def: TypeDef, generics: &[Type], _ident: &TokenStream, constraints: &TokenStream, features: &TokenStream) -> TokenStream {
let vtbl = self.type_def_vtbl_name(def, generics);
let mut methods = quote! {};
let mut method_names = MethodNames::new();
method_names.add_vtable_types(self, def);
let phantoms = self.generic_named_phantoms(generics);
- match self.reader.type_def_vtables(def).last() {
- Some(Type::IUnknown) => {
- methods.combine(&quote! { pub base__: ::windows::core::IUnknown_Vtbl, })
- }
- Some(Type::IInspectable) => {
- methods.combine(&quote! { pub base__: ::windows::core::IInspectable_Vtbl, })
- }
- Some(Type::TypeDef((def, _))) => {
+ match type_def_vtables(self.reader, def).last() {
+ Some(Type::IUnknown) => methods.combine(&quote! { pub base__: ::windows_core::IUnknown_Vtbl, }),
+ Some(Type::IInspectable) => methods.combine(&quote! { pub base__: ::windows_core::IInspectable_Vtbl, }),
+ Some(Type::TypeDef(def, _)) => {
let vtbl = self.type_def_vtbl_name(*def, &[]);
methods.combine(&quote! { pub base__: #vtbl, });
}
@@ -880,8 +799,8 @@ impl<'a> Gen<'a> {
continue;
}
let name = method_names.add(self, method);
- let signature = self.reader.method_def_signature(method, generics);
- let mut cfg = self.reader.signature_cfg(&signature);
+ let signature = method_def_signature(self.reader, self.reader.type_def_namespace(def), method, generics);
+ let mut cfg = signature_cfg(self.reader, method);
let signature = self.vtbl_signature(def, generics, &signature);
cfg.add_feature(self.reader.type_def_namespace(def));
let cfg_all = self.cfg_features(&cfg);
@@ -909,65 +828,42 @@ impl<'a> Gen<'a> {
}
}
}
- pub fn vtbl_signature(
- &self,
- def: TypeDef,
- _generics: &[Type],
- signature: &Signature,
- ) -> TokenStream {
- let is_winrt = self
- .reader
- .type_def_flags(def)
- .contains(TypeAttributes::WINRT);
- let hresult = self.type_name(&Type::HRESULT);
-
- let (trailing_return_type, return_type, udt_return_type) = if is_winrt {
- if let Some(return_type) = &signature.return_type {
- if let Type::WinrtArray(kind) = return_type {
- let tokens = self.type_abi_name(kind);
- (
- quote! { result_size__: *mut u32, result__: *mut *mut #tokens },
- quote! { -> #hresult },
- quote! {},
- )
- } else {
- let tokens = self.type_abi_name(return_type);
- (
- quote! { result__: *mut #tokens },
- quote! { -> #hresult },
- quote! {},
- )
- }
- } else {
- (quote! {}, quote! { -> #hresult }, quote! {})
+ pub fn vtbl_signature(&self, def: TypeDef, _generics: &[Type], signature: &Signature) -> TokenStream {
+ let is_winrt = self.reader.type_def_flags(def).contains(TypeAttributes::WindowsRuntime);
+
+ let crate_name = self.crate_name();
+
+ let (trailing_return_type, return_type, udt_return_type) = match &signature.return_type {
+ Type::Void if is_winrt => (quote! {}, quote! { -> #crate_name HRESULT }, quote! {}),
+ Type::Void => (quote! {}, quote! {}, quote! {}),
+ Type::WinrtArray(kind) => {
+ let tokens = self.type_abi_name(kind);
+ (quote! { result_size__: *mut u32, result__: *mut *mut #tokens }, quote! { -> #crate_name HRESULT }, quote! {})
}
- } else if let Some(return_type) = &signature.return_type {
- if self.reader.type_is_struct(return_type) {
- let tokens = self.type_abi_name(return_type);
+ _ if is_winrt => {
+ let tokens = self.type_abi_name(&signature.return_type);
+ (quote! { result__: *mut #tokens }, quote! { -> #crate_name HRESULT }, quote! {})
+ }
+ _ if type_is_struct(self.reader, &signature.return_type) => {
+ let tokens = self.type_abi_name(&signature.return_type);
(quote! {}, quote! {}, quote! { result__: *mut #tokens, })
- } else {
- let tokens = self.type_default_name(return_type);
+ }
+ _ => {
+ let tokens = self.type_default_name(&signature.return_type);
(quote! {}, quote! { -> #tokens }, quote! {})
}
- } else {
- (quote! {}, quote! {}, quote! {})
};
let params = signature.params.iter().map(|p| {
let name = self.param_name(p.def);
if is_winrt {
let abi = self.type_abi_name(&p.ty);
- let abi_size_name: TokenStream =
- format!("{}_array_size", self.reader.param_name(p.def)).into();
-
- if self
- .reader
- .param_flags(p.def)
- .contains(ParamAttributes::INPUT)
- {
+ let abi_size_name: TokenStream = format!("{}_array_size", self.reader.param_name(p.def)).into();
+
+ if self.reader.param_flags(p.def).contains(ParamAttributes::In) {
if p.ty.is_winrt_array() {
quote! { #abi_size_name: u32, #name: *const #abi, }
- } else if p.ty.is_winrt_const_ref() {
+ } else if p.ty.is_const_ref() {
quote! { #name: &#abi, }
} else {
quote! { #name: #abi, }
@@ -1001,13 +897,13 @@ impl<'a> Gen<'a> {
to_ident(&self.reader.param_name(param).to_lowercase())
}
pub fn return_sig(&self, signature: &Signature) -> TokenStream {
- if let Some(return_type) = &signature.return_type {
- let tokens = self.type_default_name(return_type);
- format!(" -> {}", tokens.as_str()).into()
- } else if self.reader.method_def_does_not_return(signature.def) {
- " -> !".into()
- } else {
- " -> ()".into()
+ match &signature.return_type {
+ Type::Void if self.reader.has_attribute(signature.def, "DoesNotReturnAttribute") => " -> !".into(),
+ Type::Void => " -> ()".into(),
+ _ => {
+ let tokens = self.type_default_name(&signature.return_type);
+ format!(" -> {}", tokens.as_str()).into()
+ }
}
}
pub fn win32_args(&self, params: &[SignatureParam], kind: SignatureKind) -> TokenStream {
@@ -1018,27 +914,21 @@ impl<'a> Gen<'a> {
SignatureKind::Query(query) if query.object == position => {
quote! { &mut result__, }
}
- SignatureKind::ReturnValue | SignatureKind::ResultValue
- if params.len() - 1 == position =>
- {
+ SignatureKind::ReturnValue | SignatureKind::ResultValue if params.len() - 1 == position => {
quote! { &mut result__, }
}
SignatureKind::QueryOptional(query) if query.object == position => {
quote! { result__ as *mut _ as *mut _, }
}
- SignatureKind::Query(query) | SignatureKind::QueryOptional(query)
- if query.guid == position =>
- {
- quote! { &<T as ::windows::core::ComInterface>::IID, }
+ SignatureKind::Query(query) | SignatureKind::QueryOptional(query) if query.guid == position => {
+ quote! { &<T as ::windows_core::ComInterface>::IID, }
}
_ => {
let name = self.param_name(param.def);
let flags = self.reader.param_flags(param.def);
match param.kind {
- SignatureParamKind::ArrayFixed(_)
- | SignatureParamKind::ArrayRelativeLen(_)
- | SignatureParamKind::ArrayRelativeByteLen(_) => {
- let map = if flags.contains(ParamAttributes::OPTIONAL) {
+ SignatureParamKind::ArrayFixed(_) | SignatureParamKind::ArrayRelativeLen(_) | SignatureParamKind::ArrayRelativeByteLen(_) => {
+ let map = if flags.contains(ParamAttributes::Optional) {
quote! { #name.as_deref().map_or(::core::ptr::null(), |slice|slice.as_ptr()) }
} else {
quote! { #name.as_ptr() }
@@ -1048,7 +938,7 @@ impl<'a> Gen<'a> {
SignatureParamKind::ArrayRelativePtr(relative) => {
let name = self.param_name(params[relative].def);
let flags = self.reader.param_flags(params[relative].def);
- if flags.contains(ParamAttributes::OPTIONAL) {
+ if flags.contains(ParamAttributes::Optional) {
quote! { #name.as_deref().map_or(0, |slice|slice.len() as _), }
} else {
quote! { #name.len() as _, }
@@ -1061,7 +951,7 @@ impl<'a> Gen<'a> {
quote! { #name.into_param().abi(), }
}
SignatureParamKind::OptionalPointer => {
- if flags.contains(ParamAttributes::OUTPUT) {
+ if flags.contains(ParamAttributes::Out) {
quote! { ::core::mem::transmute(#name.unwrap_or(::std::ptr::null_mut())), }
} else {
quote! { ::core::mem::transmute(#name.unwrap_or(::std::ptr::null())), }
@@ -1071,7 +961,11 @@ impl<'a> Gen<'a> {
quote! { #name, }
}
SignatureParamKind::Blittable => {
- quote! { ::core::mem::transmute(#name), }
+ if matches!(param.ty, Type::PrimitiveOrEnum(_, _)) {
+ quote! { #name.0 as _, }
+ } else {
+ quote! { ::core::mem::transmute(#name), }
+ }
}
SignatureParamKind::Other => {
quote! { ::core::mem::transmute_copy(#name), }
@@ -1095,9 +989,7 @@ impl<'a> Gen<'a> {
continue;
}
}
- SignatureKind::ReturnValue | SignatureKind::ResultValue
- if params.len() - 1 == position =>
- {
+ SignatureKind::ReturnValue | SignatureKind::ResultValue if params.len() - 1 == position => {
continue;
}
_ => {}
@@ -1109,21 +1001,13 @@ impl<'a> Gen<'a> {
SignatureParamKind::ArrayFixed(fixed) => {
let ty = param.ty.deref();
let ty = self.type_default_name(&ty);
- let len = Literal::u32_unsuffixed(fixed as _);
- let ty = if self
- .reader
- .param_flags(param.def)
- .contains(ParamAttributes::OUTPUT)
- {
+ let len = Literal::u32_unsuffixed(fixed as u32);
+ let ty = if self.reader.param_flags(param.def).contains(ParamAttributes::Out) {
quote! { &mut [#ty; #len] }
} else {
quote! { &[#ty; #len] }
};
- if self
- .reader
- .param_flags(param.def)
- .contains(ParamAttributes::OPTIONAL)
- {
+ if self.reader.param_flags(param.def).contains(ParamAttributes::Optional) {
tokens.combine(&quote! { #name: ::core::option::Option<#ty>, });
} else {
tokens.combine(&quote! { #name: #ty, });
@@ -1132,40 +1016,24 @@ impl<'a> Gen<'a> {
SignatureParamKind::ArrayRelativeLen(_) => {
let ty = param.ty.deref();
let ty = self.type_default_name(&ty);
- let ty = if self
- .reader
- .param_flags(param.def)
- .contains(ParamAttributes::OUTPUT)
- {
+ let ty = if self.reader.param_flags(param.def).contains(ParamAttributes::Out) {
quote! { &mut [#ty] }
} else {
quote! { &[#ty] }
};
- if self
- .reader
- .param_flags(param.def)
- .contains(ParamAttributes::OPTIONAL)
- {
+ if self.reader.param_flags(param.def).contains(ParamAttributes::Optional) {
tokens.combine(&quote! { #name: ::core::option::Option<#ty>, });
} else {
tokens.combine(&quote! { #name: #ty, });
}
}
SignatureParamKind::ArrayRelativeByteLen(_) => {
- let ty = if self
- .reader
- .param_flags(param.def)
- .contains(ParamAttributes::OUTPUT)
- {
+ let ty = if self.reader.param_flags(param.def).contains(ParamAttributes::Out) {
quote! { &mut [u8] }
} else {
quote! { &[u8] }
};
- if self
- .reader
- .param_flags(param.def)
- .contains(ParamAttributes::OPTIONAL)
- {
+ if self.reader.param_flags(param.def).contains(ParamAttributes::Optional) {
tokens.combine(&quote! { #name: ::core::option::Option<#ty>, });
} else {
tokens.combine(&quote! { #name: #ty, });
@@ -1196,27 +1064,21 @@ impl<'a> Gen<'a> {
}
pub fn impl_signature(&self, def: TypeDef, signature: &Signature) -> TokenStream {
- if self
- .reader
- .type_def_flags(def)
- .contains(TypeAttributes::WINRT)
- {
+ if self.reader.type_def_flags(def).contains(TypeAttributes::WindowsRuntime) {
let is_delegate = self.reader.type_def_kind(def) == TypeKind::Delegate;
- let params = signature
- .params
- .iter()
- .map(|p| self.winrt_produce_type(p, !is_delegate));
+ let params = signature.params.iter().map(|p| self.winrt_produce_type(p, !is_delegate));
- let return_type = if let Some(return_type) = &signature.return_type {
- let tokens = self.type_name(return_type);
+ let return_type = match &signature.return_type {
+ Type::Void => quote! { () },
+ _ => {
+ let tokens = self.type_name(&signature.return_type);
- if return_type.is_winrt_array() {
- quote! { ::windows::core::Array<#tokens> }
- } else {
- tokens
+ if signature.return_type.is_winrt_array() {
+ quote! { ::windows_core::Array<#tokens> }
+ } else {
+ tokens
+ }
}
- } else {
- quote! { () }
};
let this = if is_delegate {
@@ -1225,9 +1087,9 @@ impl<'a> Gen<'a> {
quote! { &self, }
};
- quote! { (#this #(#params),*) -> ::windows::core::Result<#return_type> }
+ quote! { (#this #(#params),*) -> ::windows_core::Result<#return_type> }
} else {
- let signature_kind = self.reader.signature_kind(signature);
+ let signature_kind = signature_kind(self.reader, signature);
let mut params = quote! {};
if signature_kind == SignatureKind::ResultValue {
@@ -1242,14 +1104,12 @@ impl<'a> Gen<'a> {
let return_type = match signature_kind {
SignatureKind::ReturnVoid => quote! {},
- SignatureKind::Query(_)
- | SignatureKind::QueryOptional(_)
- | SignatureKind::ResultVoid => quote! { -> ::windows::core::Result<()> },
+ SignatureKind::Query(_) | SignatureKind::QueryOptional(_) | SignatureKind::ResultVoid => quote! { -> ::windows_core::Result<()> },
SignatureKind::ResultValue => {
let return_type = signature.params[signature.params.len() - 1].ty.deref();
let return_type = self.type_name(&return_type);
- quote! { -> ::windows::core::Result<#return_type> }
+ quote! { -> ::windows_core::Result<#return_type> }
}
_ => self.return_sig(signature),
};
@@ -1260,16 +1120,12 @@ impl<'a> Gen<'a> {
fn winrt_produce_type(&self, param: &SignatureParam, include_param_names: bool) -> TokenStream {
let default_type = self.type_default_name(&param.ty);
- let sig = if self
- .reader
- .param_flags(param.def)
- .contains(ParamAttributes::INPUT)
- {
+ let sig = if self.reader.param_flags(param.def).contains(ParamAttributes::In) {
if param.ty.is_winrt_array() {
quote! { &[#default_type] }
- } else if self.reader.type_is_primitive(&param.ty) {
+ } else if type_is_primitive(self.reader, &param.ty) {
quote! { #default_type }
- } else if self.reader.type_is_nullable(&param.ty) {
+ } else if type_is_nullable(self.reader, &param.ty) {
let type_name = self.type_name(&param.ty);
quote! { ::core::option::Option<&#type_name> }
} else {
@@ -1279,7 +1135,7 @@ impl<'a> Gen<'a> {
quote! { &mut [#default_type] }
} else if param.ty.is_winrt_array_ref() {
let kind = self.type_name(&param.ty);
- quote! { &mut ::windows::core::Array<#kind> }
+ quote! { &mut ::windows_core::Array<#kind> }
} else {
quote! { &mut #default_type }
};
@@ -1295,14 +1151,10 @@ impl<'a> Gen<'a> {
let name = self.param_name(param.def);
let kind = self.type_default_name(&param.ty);
- if self
- .reader
- .param_flags(param.def)
- .contains(ParamAttributes::INPUT)
- {
- if self.reader.type_is_primitive(&param.ty) {
+ if self.reader.param_flags(param.def).contains(ParamAttributes::In) {
+ if type_is_primitive(self.reader, &param.ty) {
quote! { #name: #kind, }
- } else if self.reader.type_is_nullable(&param.ty) {
+ } else if type_is_nullable(self.reader, &param.ty) {
let kind = self.type_name(&param.ty);
quote! { #name: ::core::option::Option<&#kind>, }
} else {
@@ -1314,21 +1166,6 @@ impl<'a> Gen<'a> {
}
}
-pub fn to_ident(name: &str) -> TokenStream {
- // keywords list based on https://doc.rust-lang.org/reference/keywords.html
- match name {
- "abstract" | "as" | "become" | "box" | "break" | "const" | "continue" | "crate" | "do"
- | "else" | "enum" | "extern" | "false" | "final" | "fn" | "for" | "if" | "impl" | "in"
- | "let" | "loop" | "macro" | "match" | "mod" | "move" | "mut" | "override" | "priv"
- | "pub" | "ref" | "return" | "static" | "struct" | "super" | "trait" | "true" | "type"
- | "typeof" | "unsafe" | "unsized" | "use" | "virtual" | "where" | "while" | "yield"
- | "try" | "async" | "await" | "dyn" => format!("r#{name}").into(),
- "Self" | "self" => format!("{name}_").into(),
- "_" => "unused".into(),
- _ => trim_tick(name).into(),
- }
-}
-
fn mut_ptrs(pointers: usize) -> TokenStream {
"*mut ".repeat(pointers).into()
}
@@ -1380,21 +1217,9 @@ mod tests {
#[test]
fn test_starts_with() {
- assert!(starts_with(
- "Windows.Win32.Graphics.Direct3D11on12",
- "Windows.Win32.Graphics.Direct3D11on12"
- ));
- assert!(starts_with(
- "Windows.Win32.Graphics.Direct3D11on12",
- "Windows.Win32.Graphics"
- ));
- assert!(!starts_with(
- "Windows.Win32.Graphics.Direct3D11on12",
- "Windows.Win32.Graphics.Direct3D11"
- ));
- assert!(!starts_with(
- "Windows.Win32.Graphics.Direct3D",
- "Windows.Win32.Graphics.Direct3D11"
- ));
+ assert!(starts_with("Windows.Win32.Graphics.Direct3D11on12", "Windows.Win32.Graphics.Direct3D11on12"));
+ assert!(starts_with("Windows.Win32.Graphics.Direct3D11on12", "Windows.Win32.Graphics"));
+ assert!(!starts_with("Windows.Win32.Graphics.Direct3D11on12", "Windows.Win32.Graphics.Direct3D11"));
+ assert!(!starts_with("Windows.Win32.Graphics.Direct3D", "Windows.Win32.Graphics.Direct3D11"));
}
}
diff --git a/vendor/windows-bindgen/src/standalone.rs b/vendor/windows-bindgen/src/standalone.rs
deleted file mode 100644
index e8db2fca7..000000000
--- a/vendor/windows-bindgen/src/standalone.rs
+++ /dev/null
@@ -1,266 +0,0 @@
-use super::*;
-
-/// Generates standalone Windows bindings.
-pub fn standalone(names: &[&str]) -> String {
- let files = &File::with_default(&[]).unwrap();
- let reader = &Reader::new(files);
- let gen = &mut Gen::new(reader);
- standalone_imp(gen, names)
-}
-
-/// Generates standalone Windows bindings for the Rust Standard Library.
-pub fn standalone_std(names: &[&str]) -> String {
- let files = &File::with_default(&[]).unwrap();
- let reader = &Reader::new(files);
- let gen = &mut Gen::new(reader);
- gen.std = true;
- standalone_imp(gen, names)
-}
-
-fn standalone_imp(gen: &mut Gen, names: &[&str]) -> String {
- gen.namespace = "Windows.";
- gen.standalone = true;
- gen.sys = true;
-
- let mut type_names = BTreeSet::new();
- let mut core_types = BTreeSet::new();
- let mut enums = BTreeSet::new();
-
- for name in names {
- let type_name = TypeName::parse(name);
- let mut found = false;
-
- if let Some(def) = gen.reader.get(type_name).next() {
- found = true;
- type_names.insert(type_name);
- let mut cfg = gen.reader.type_def_cfg(def, &[]);
- core_types.append(&mut cfg.core_types);
- for def in cfg.types.values().flatten() {
- type_names.insert(gen.reader.type_def_type_name(*def));
- }
- if gen.reader.type_def_kind(def) == TypeKind::Struct
- && gen.reader.type_def_fields(def).next().is_none()
- && gen.reader.type_def_guid(def).is_some()
- {
- core_types.insert(Type::GUID);
- }
- }
-
- if !found {
- for method in gen.reader.namespace_functions(type_name.namespace) {
- if found {
- break;
- }
- let name = gen.reader.method_def_name(method);
- if name == type_name.name {
- found = true;
- type_names.insert(type_name);
- let mut cfg = gen
- .reader
- .signature_cfg(&gen.reader.method_def_signature(method, &[]));
- core_types.append(&mut cfg.core_types);
- for def in cfg.types.values().flatten() {
- type_names.insert(gen.reader.type_def_type_name(*def));
- }
- }
- }
- for field in gen.reader.namespace_constants(type_name.namespace) {
- if found {
- break;
- }
- let name = gen.reader.field_name(field);
- if name == type_name.name {
- found = true;
- type_names.insert(type_name);
- let mut cfg = gen.reader.field_cfg(field);
- core_types.append(&mut cfg.core_types);
- for def in cfg.types.values().flatten() {
- type_names.insert(gen.reader.type_def_type_name(*def));
- }
- }
- }
- }
-
- if !found {
- for def in gen
- .reader
- .namespace_types(type_name.namespace, &Default::default())
- {
- if found {
- break;
- }
- if gen.reader.type_def_kind(def) == TypeKind::Enum {
- for field in gen.reader.type_def_fields(def) {
- if found {
- break;
- }
- let name = gen.reader.field_name(field);
- if name == type_name.name {
- found = true;
- let enum_name = gen.reader.type_def_type_name(def);
- type_names.insert(enum_name);
- enums.insert((enum_name, type_name.name));
- }
- }
- }
- }
- }
- }
-
- let mut sorted = SortedTokens::default();
-
- for ty in core_types {
- match ty {
- Type::HRESULT => sorted.insert("HRESULT", quote! { pub type HRESULT = i32; }),
- Type::String => sorted.insert(
- "HSTRING",
- quote! { pub type HSTRING = *mut ::core::ffi::c_void; },
- ),
- Type::IUnknown => sorted.insert(
- "IUnknown",
- quote! { pub type IUnknown = *mut ::core::ffi::c_void; },
- ),
- Type::IInspectable => sorted.insert(
- "IInspectable",
- quote! { pub type IInspectable = *mut ::core::ffi::c_void; },
- ),
- Type::PSTR => sorted.insert("PSTR", quote! { pub type PSTR = *mut u8; }),
- Type::PWSTR => sorted.insert("PWSTR", quote! { pub type PWSTR = *mut u16; }),
- Type::PCSTR => sorted.insert("PCSTR", quote! { pub type PCSTR = *const u8; }),
- Type::PCWSTR => sorted.insert("PCWSTR", quote! { pub type PCWSTR = *const u16; }),
- Type::BSTR => sorted.insert("BSTR", quote! { pub type BSTR = *const u16; }),
- Type::GUID => {
- sorted.insert("GUID", quote! {
- #[repr(C)]
- pub struct GUID {
- pub data1: u32,
- pub data2: u16,
- pub data3: u16,
- pub data4: [u8; 8],
- }
- impl GUID {
- pub const fn from_u128(uuid: u128) -> Self {
- Self { data1: (uuid >> 96) as u32, data2: (uuid >> 80 & 0xffff) as u16, data3: (uuid >> 64 & 0xffff) as u16, data4: (uuid as u64).to_be_bytes() }
- }
- }
- impl ::core::marker::Copy for GUID {}
- impl ::core::clone::Clone for GUID {
- fn clone(&self) -> Self {
- *self
- }
- }
- });
- }
- _ => {}
- }
- }
-
- for type_name in type_names {
- let mut found = false;
-
- for def in gen.reader.get(type_name) {
- found = true;
- let kind = gen.reader.type_def_kind(def);
-
- match kind {
- TypeKind::Class | TypeKind::Interface => unimplemented!(),
- TypeKind::Enum => {
- sorted.insert(gen.reader.type_def_name(def), enums::gen(gen, def));
- }
- TypeKind::Struct => {
- if gen.reader.type_def_fields(def).next().is_none() {
- if let Some(guid) = gen.reader.type_def_guid(def) {
- let ident = to_ident(type_name.name);
- let value = gen.guid(&guid);
- let guid = gen.type_name(&Type::GUID);
- sorted.insert(
- type_name.name,
- quote! {
- pub const #ident: #guid = #value;
- },
- );
- continue;
- }
- }
- sorted.insert(gen.reader.type_def_name(def), structs::gen(gen, def));
- }
- TypeKind::Delegate => {
- sorted.insert(gen.reader.type_def_name(def), delegates::gen(gen, def));
- }
- }
- }
-
- if !found {
- for method in gen.reader.namespace_functions(type_name.namespace) {
- if found {
- break;
- }
- let name = gen.reader.method_def_name(method);
- if name == type_name.name {
- found = true;
- sorted.insert(
- &format!(".{}.{name}", gen.reader.method_def_module_name(method)),
- functions::gen(gen, method),
- );
- }
- }
- for field in gen.reader.namespace_constants(type_name.namespace) {
- if found {
- break;
- }
- let name = gen.reader.field_name(field);
- if name == type_name.name {
- found = true;
- sorted.insert(name, constants::gen(gen, field));
- }
- }
- }
- }
-
- for (enum_type, field_name) in enums {
- if let Some(def) = gen.reader.get(enum_type).next() {
- for field in gen.reader.type_def_fields(def) {
- if gen.reader.field_name(field) == field_name {
- let ident = to_ident(field_name);
- let ty = to_ident(enum_type.name);
- let constant = gen.reader.field_constant(field).unwrap();
- let value = gen.value(&gen.reader.constant_value(constant));
-
- sorted.insert(
- field_name,
- quote! {
- pub const #ident: #ty = #value;
- },
- );
-
- break;
- }
- }
- }
- }
-
- let mut tokens: TokenStream = format!(
- r#"// Bindings generated by `windows-bindgen` {}
-
-"#,
- std::env!("CARGO_PKG_VERSION")
- )
- .into();
-
- tokens.combine(&allow());
-
- for value in sorted.0.values() {
- tokens.combine(value);
- }
-
- try_format(tokens.into_string())
-}
-
-#[derive(Default)]
-struct SortedTokens(BTreeMap<String, TokenStream>);
-
-impl SortedTokens {
- fn insert(&mut self, key: &str, tokens: TokenStream) {
- self.0.entry(key.to_string()).or_default().combine(&tokens);
- }
-}
diff --git a/vendor/windows-bindgen/src/structs.rs b/vendor/windows-bindgen/src/structs.rs
deleted file mode 100644
index 89670bdb5..000000000
--- a/vendor/windows-bindgen/src/structs.rs
+++ /dev/null
@@ -1,316 +0,0 @@
-use super::*;
-
-pub fn gen(gen: &Gen, def: TypeDef) -> TokenStream {
- if gen.reader.type_def_is_contract(def) {
- return quote! {};
- }
-
- if gen.reader.type_def_is_handle(def) {
- return handles::gen(gen, def);
- }
-
- gen_struct_with_name(gen, def, gen.reader.type_def_name(def), &Cfg::default())
-}
-
-fn gen_struct_with_name(gen: &Gen, def: TypeDef, struct_name: &str, cfg: &Cfg) -> TokenStream {
- let name = to_ident(struct_name);
-
- if gen.reader.type_def_fields(def).next().is_none() {
- let mut tokens = quote! {
- #[repr(C)]
- pub struct #name(pub u8);
- impl ::core::marker::Copy for #name {}
- impl ::core::clone::Clone for #name {
- fn clone(&self) -> Self {
- *self
- }
- }
- };
- if !gen.sys {
- tokens.combine(&quote! {
- impl ::windows::core::TypeKind for #name {
- type TypeKind = ::windows::core::CopyType;
- }
- });
- }
- return tokens;
- }
-
- let flags = gen.reader.type_def_flags(def);
- let cfg = cfg.union(&gen.reader.type_def_cfg(def, &[]));
-
- let repr = if let Some(layout) = gen.reader.type_def_class_layout(def) {
- let packing = Literal::usize_unsuffixed(gen.reader.class_layout_packing_size(layout));
- quote! { #[repr(C, packed(#packing))] }
- } else {
- quote! { #[repr(C)] }
- };
-
- let fields = gen.reader.type_def_fields(def).map(|f| {
- let name = to_ident(gen.reader.field_name(f));
- let ty = gen.reader.field_type(f, Some(def));
-
- if gen.reader.field_flags(f).contains(FieldAttributes::LITERAL) {
- quote! {}
- } else if !gen.sys
- && flags.contains(TypeAttributes::EXPLICIT_LAYOUT)
- && !gen.reader.field_is_copyable(f, def)
- {
- // Rust can't tell that the type is copyable and won't accept windows::core::ManuallyDrop
- let ty = gen.type_default_name(&ty);
- quote! { pub #name: ::std::mem::ManuallyDrop<#ty>, }
- } else if !gen.sys
- && !flags.contains(TypeAttributes::WINRT)
- && !gen.reader.field_is_blittable(f, def)
- {
- if let Type::Win32Array((ty, len)) = ty {
- let ty = gen.type_default_name(&ty);
- quote! { pub #name: [::std::mem::ManuallyDrop<#ty>; #len], }
- } else {
- let ty = gen.type_default_name(&ty);
- quote! { pub #name: ::std::mem::ManuallyDrop<#ty>, }
- }
- } else {
- let ty = gen.type_default_name(&ty);
- quote! { pub #name: #ty, }
- }
- });
-
- let struct_or_union = if flags.contains(TypeAttributes::EXPLICIT_LAYOUT) {
- quote! { union }
- } else {
- quote! { struct }
- };
-
- let doc = gen.cfg_doc(&cfg);
- let features = gen.cfg_features(&cfg);
-
- let mut tokens = quote! {
- #repr
- #doc
- #features
- pub #struct_or_union #name {#(#fields)*}
- };
-
- tokens.combine(&gen_struct_constants(gen, def, &name, &cfg));
- tokens.combine(&gen_copy_clone(gen, def, &name, &cfg));
- tokens.combine(&gen_debug(gen, def, &name, &cfg));
- tokens.combine(&gen_windows_traits(gen, def, &name, &cfg));
- tokens.combine(&gen_compare_traits(gen, def, &name, &cfg));
-
- if !gen.sys {
- tokens.combine(&quote! {
- #features
- impl ::core::default::Default for #name {
- fn default() -> Self {
- unsafe { ::core::mem::zeroed() }
- }
- }
- });
- }
-
- for (index, nested_type) in gen.reader.nested_types(def).enumerate() {
- let nested_name = format!("{struct_name}_{index}");
- tokens.combine(&gen_struct_with_name(gen, nested_type, &nested_name, &cfg));
- }
-
- tokens
-}
-
-fn gen_windows_traits(gen: &Gen, def: TypeDef, name: &TokenStream, cfg: &Cfg) -> TokenStream {
- if gen.sys {
- quote! {}
- } else {
- let features = gen.cfg_features(cfg);
- let is_copy = gen.reader.type_def_is_blittable(def);
-
- let type_kind = if is_copy {
- quote! { CopyType }
- } else {
- quote! { ValueType }
- };
-
- let mut tokens = quote! {
- #features
- impl ::windows::core::TypeKind for #name {
- type TypeKind = ::windows::core::#type_kind;
- }
- };
-
- if gen
- .reader
- .type_def_flags(def)
- .contains(TypeAttributes::WINRT)
- {
- let signature =
- Literal::byte_string(gen.reader.type_def_signature(def, &[]).as_bytes());
-
- tokens.combine(&quote! {
- #features
- impl ::windows::core::RuntimeType for #name {
- const SIGNATURE: ::windows::imp::ConstBuffer = ::windows::imp::ConstBuffer::from_slice(#signature);
- }
- });
- }
-
- tokens
- }
-}
-
-fn gen_compare_traits(gen: &Gen, def: TypeDef, name: &TokenStream, cfg: &Cfg) -> TokenStream {
- let features = gen.cfg_features(cfg);
-
- if gen.sys
- || gen.reader.type_def_has_explicit_layout(def)
- || gen.reader.type_def_has_packing(def)
- || gen.reader.type_def_has_callback(def)
- {
- quote! {}
- } else {
- let fields = gen.reader.type_def_fields(def).filter_map(|f| {
- let name = to_ident(gen.reader.field_name(f));
- if gen.reader.field_flags(f).contains(FieldAttributes::LITERAL) {
- None
- } else {
- Some(quote! { self.#name == other.#name })
- }
- });
-
- quote! {
- #features
- impl ::core::cmp::PartialEq for #name {
- fn eq(&self, other: &Self) -> bool {
- #(#fields)&&*
- }
- }
- #features
- impl ::core::cmp::Eq for #name {}
- }
- }
-}
-
-fn gen_debug(gen: &Gen, def: TypeDef, ident: &TokenStream, cfg: &Cfg) -> TokenStream {
- if gen.sys
- || gen.reader.type_def_has_explicit_layout(def)
- || gen.reader.type_def_has_packing(def)
- {
- quote! {}
- } else {
- let name = ident.as_str();
- let features = gen.cfg_features(cfg);
-
- let fields = gen.reader.type_def_fields(def).filter_map(|f| {
- if gen.reader.field_flags(f).contains(FieldAttributes::LITERAL) {
- None
- } else {
- let name = gen.reader.field_name(f);
- let ident = to_ident(name);
- let ty = gen.reader.field_type(f, Some(def));
- if gen.reader.type_has_callback(&ty) {
- None
- } else {
- Some(quote! { .field(#name, &self.#ident) })
- }
- }
- });
-
- quote! {
- #features
- impl ::core::fmt::Debug for #ident {
- fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
- f.debug_struct(#name) #(#fields)* .finish()
- }
- }
- }
- }
-}
-
-fn gen_copy_clone(gen: &Gen, def: TypeDef, name: &TokenStream, cfg: &Cfg) -> TokenStream {
- let features = gen.cfg_features(cfg);
-
- if gen.sys || gen.reader.type_def_is_copyable(def) {
- quote! {
- #features
- impl ::core::marker::Copy for #name {}
- #features
- impl ::core::clone::Clone for #name {
- fn clone(&self) -> Self {
- *self
- }
- }
- }
- } else if gen.reader.type_def_class_layout(def).is_some() {
- // Don't support copy/clone of packed structs: https://github.com/rust-lang/rust/issues/82523
- quote! {}
- } else if !gen
- .reader
- .type_def_flags(def)
- .contains(TypeAttributes::WINRT)
- {
- quote! {
- #features
- impl ::core::clone::Clone for #name {
- fn clone(&self) -> Self {
- unsafe { ::core::mem::transmute_copy(self) }
- }
- }
- }
- } else {
- let fields = gen.reader.type_def_fields(def).map(|f| {
- let name = to_ident(gen.reader.field_name(f));
- if gen.reader.field_flags(f).contains(FieldAttributes::LITERAL) {
- quote! {}
- } else if gen.reader.field_is_blittable(f, def) {
- quote! { #name: self.#name }
- } else {
- quote! { #name: self.#name.clone() }
- }
- });
-
- quote! {
- #features
- impl ::core::clone::Clone for #name {
- fn clone(&self) -> Self {
- Self { #(#fields),* }
- }
- }
- }
- }
-}
-
-fn gen_struct_constants(
- gen: &Gen,
- def: TypeDef,
- struct_name: &TokenStream,
- cfg: &Cfg,
-) -> TokenStream {
- let features = gen.cfg_features(cfg);
-
- let constants = gen.reader.type_def_fields(def).filter_map(|f| {
- if gen.reader.field_flags(f).contains(FieldAttributes::LITERAL) {
- if let Some(constant) = gen.reader.field_constant(f) {
- let name = to_ident(gen.reader.field_name(f));
- let value = gen.typed_value(&gen.reader.constant_value(constant));
-
- return Some(quote! {
- pub const #name: #value;
- });
- }
- }
-
- None
- });
-
- let mut tokens = quote! { #(#constants)* };
-
- if !tokens.is_empty() {
- tokens = quote! {
- #features
- impl #struct_name {
- #tokens
- }
- };
- }
-
- tokens
-}
diff --git a/vendor/windows-bindgen/src/tokens/mod.rs b/vendor/windows-bindgen/src/tokens/mod.rs
new file mode 100644
index 000000000..e5f019a8b
--- /dev/null
+++ b/vendor/windows-bindgen/src/tokens/mod.rs
@@ -0,0 +1,443 @@
+#![allow(dead_code)]
+
+mod to_tokens;
+mod token_stream;
+
+pub mod runtime;
+pub use to_tokens::*;
+pub use token_stream::*;
+
+/// The whole point.
+///
+/// Performs variable interpolation against the input and produces it as
+/// [`TokenStream`].
+///
+/// # Interpolation
+///
+/// Variable interpolation is done with `#var` (similar to `$var` in
+/// `macro_rules!` macros). This grabs the `var` variable that is currently in
+/// scope and inserts it in that location in the output tokens. Any type
+/// implementing the [`ToTokens`] trait can be interpolated. This includes most
+/// Rust primitive types.
+///
+/// [`ToTokens`]: trait.ToTokens.html
+///
+/// Repetition is done using `#(...)*` or `#(...),*` again similar to
+/// `macro_rules!`. This iterates through the elements of any variable
+/// interpolated within the repetition and inserts a copy of the repetition body
+/// for each one. The variables in an interpolation may be a `Vec`, slice,
+/// `BTreeSet`, or any `Iterator`.
+///
+/// - `#(#var)*` — no separators
+/// - `#(#var),*` — the character before the asterisk is used as a separator
+/// - `#( struct #var; )*` — the repetition can contain other tokens
+/// - `#( #k => println!("{}", #v), )*` — even multiple interpolations
+#[macro_export]
+#[doc(hidden)]
+macro_rules! quote {
+ () => {
+ $crate::tokens::TokenStream::new()
+ };
+ ($($tt:tt)*) => {{
+ let mut _s = $crate::tokens::TokenStream::new();
+ $crate::quote_each_token!(_s $($tt)*);
+ _s
+ }};
+}
+
+pub use quote;
+
+/// Formatting macro for constructing a `TokenStream`.
+///
+/// <br>
+///
+/// # Syntax
+///
+/// Syntax is copied from the [`format!`] macro, supporting both positional and
+/// named arguments.
+#[macro_export]
+#[doc(hidden)]
+macro_rules! format_token {
+ ($($fmt:tt)*) => {
+ $crate::TokenStream::from(format!($($fmt)*))
+ };
+}
+
+// Extract the names of all #metavariables and pass them to the $call macro.
+//
+// in: pounded_var_names!(then!(...) a #b c #( #d )* #e)
+// out: then!(... b);
+// then!(... d);
+// then!(... e);
+#[macro_export]
+#[doc(hidden)]
+macro_rules! pounded_var_names {
+ ($call:ident! $extra:tt $($tts:tt)*) => {
+ $crate::pounded_var_names_with_context!($call! $extra
+ (@ $($tts)*)
+ ($($tts)* @)
+ )
+ };
+}
+
+#[macro_export]
+#[doc(hidden)]
+macro_rules! pounded_var_names_with_context {
+ ($call:ident! $extra:tt ($($b1:tt)*) ($($curr:tt)*)) => {
+ $(
+ $crate::pounded_var_with_context!($call! $extra $b1 $curr);
+ )*
+ };
+}
+
+#[macro_export]
+#[doc(hidden)]
+macro_rules! pounded_var_with_context {
+ ($call:ident! $extra:tt $b1:tt ( $($inner:tt)* )) => {
+ $crate::pounded_var_names!($call! $extra $($inner)*);
+ };
+
+ ($call:ident! $extra:tt $b1:tt [ $($inner:tt)* ]) => {
+ $crate::pounded_var_names!($call! $extra $($inner)*);
+ };
+
+ ($call:ident! $extra:tt $b1:tt { $($inner:tt)* }) => {
+ $crate::pounded_var_names!($call! $extra $($inner)*);
+ };
+
+ ($call:ident!($($extra:tt)*) # $var:ident) => {
+ $crate::$call!($($extra)* $var);
+ };
+
+ ($call:ident! $extra:tt $b1:tt $curr:tt) => {};
+}
+
+#[macro_export]
+#[doc(hidden)]
+macro_rules! quote_bind_into_iter {
+ ($has_iter:ident $var:ident) => {
+ // `mut` may be unused if $var occurs multiple times in the list.
+ #[allow(unused_mut)]
+ let (mut $var, i) = $var.quote_into_iter();
+ let $has_iter = $has_iter | i;
+ };
+}
+
+#[macro_export]
+#[doc(hidden)]
+macro_rules! quote_bind_next_or_break {
+ ($var:ident) => {
+ let $var = match $var.next() {
+ Some(_x) => $crate::tokens::runtime::RepInterp(_x),
+ None => break,
+ };
+ };
+}
+
+#[macro_export]
+#[doc(hidden)]
+macro_rules! quote_each_token {
+ ($tokens:ident $($tts:tt)*) => {
+ $crate::quote_tokens_with_context!($tokens
+ (@ @ @ @ @ @ $($tts)*)
+ (@ @ @ @ @ $($tts)* @)
+ (@ @ @ @ $($tts)* @ @)
+ (@ @ @ $(($tts))* @ @ @)
+ (@ @ $($tts)* @ @ @ @)
+ (@ $($tts)* @ @ @ @ @)
+ ($($tts)* @ @ @ @ @ @)
+ );
+ };
+}
+
+#[macro_export]
+#[doc(hidden)]
+macro_rules! quote_tokens_with_context {
+ ($tokens:ident
+ ($($b3:tt)*) ($($b2:tt)*) ($($b1:tt)*)
+ ($($curr:tt)*)
+ ($($a1:tt)*) ($($a2:tt)*) ($($a3:tt)*)
+ ) => {
+ $(
+ $crate::quote_token_with_context!($tokens $b3 $b2 $b1 $curr $a1 $a2 $a3);
+ )*
+ };
+}
+
+#[macro_export]
+#[doc(hidden)]
+macro_rules! quote_token_with_context {
+ ($tokens:ident $b3:tt $b2:tt $b1:tt @ $a1:tt $a2:tt $a3:tt) => {};
+
+ ($tokens:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) * $a3:tt) => {{
+ use $crate::tokens::runtime::ext::*;
+ let has_iter = $crate::tokens::runtime::ThereIsNoIteratorInRepetition;
+ $crate::pounded_var_names!(quote_bind_into_iter!(has_iter) () $($inner)*);
+ let _: $crate::tokens::runtime::HasIterator = has_iter;
+ // This is `while true` instead of `loop` because if there are no
+ // iterators used inside of this repetition then the body would not
+ // contain any `break`, so the compiler would emit unreachable code
+ // warnings on anything below the loop. We use has_iter to detect and
+ // fail to compile when there are no iterators, so here we just work
+ // around the unneeded extra warning.
+ while true {
+ $crate::pounded_var_names!(quote_bind_next_or_break!() () $($inner)*);
+ $crate::quote_each_token!($tokens $($inner)*);
+ }
+ }};
+ ($tokens:ident $b3:tt $b2:tt # (( $($inner:tt)* )) * $a2:tt $a3:tt) => {};
+ ($tokens:ident $b3:tt # ( $($inner:tt)* ) (*) $a1:tt $a2:tt $a3:tt) => {};
+
+ ($tokens:ident $b3:tt $b2:tt $b1:tt (#) ( $($inner:tt)* ) $sep:tt *) => {{
+ use $crate::tokens::runtime::ext::*;
+ let mut _i = 0usize;
+ let has_iter = $crate::tokens::runtime::ThereIsNoIteratorInRepetition;
+ $crate::pounded_var_names!(quote_bind_into_iter!(has_iter) () $($inner)*);
+ let _: $crate::tokens::runtime::HasIterator = has_iter;
+ while true {
+ $crate::pounded_var_names!(quote_bind_next_or_break!() () $($inner)*);
+ if _i > 0 {
+ $crate::quote_token!($tokens $sep);
+ }
+ _i += 1;
+ $crate::quote_each_token!($tokens $($inner)*);
+ }
+ }};
+ ($tokens:ident $b3:tt $b2:tt # (( $($inner:tt)* )) $sep:tt * $a3:tt) => {};
+ ($tokens:ident $b3:tt # ( $($inner:tt)* ) ($sep:tt) * $a2:tt $a3:tt) => {};
+ ($tokens:ident # ( $($inner:tt)* ) * (*) $a1:tt $a2:tt $a3:tt) => {
+ // https://github.com/dtolnay/quote/issues/130
+ $crate::quote_token!($tokens *);
+ };
+ ($tokens:ident # ( $($inner:tt)* ) $sep:tt (*) $a1:tt $a2:tt $a3:tt) => {};
+
+ ($tokens:ident $b3:tt $b2:tt $b1:tt (#) $var:ident $a2:tt $a3:tt) => {
+ $crate::tokens::ToTokens::to_tokens(&$var, &mut $tokens);
+ };
+ ($tokens:ident $b3:tt $b2:tt # ($var:ident) $a1:tt $a2:tt $a3:tt) => {};
+ ($tokens:ident $b3:tt $b2:tt $b1:tt ($curr:tt) $a1:tt $a2:tt $a3:tt) => {
+ $crate::quote_token!($tokens $curr);
+ };
+}
+
+#[macro_export]
+#[doc(hidden)]
+macro_rules! quote_token {
+ ($tokens:ident ( $($inner:tt)* )) => {
+ $crate::tokens::runtime::push_group(
+ &mut $tokens,
+ $crate::tokens::Delimiter::Parenthesis,
+ $crate::quote!($($inner)*),
+ );
+ };
+
+ ($tokens:ident [ $($inner:tt)* ]) => {
+ $crate::tokens::runtime::push_group(
+ &mut $tokens,
+ $crate::tokens::Delimiter::Bracket,
+ $crate::quote!($($inner)*),
+ );
+ };
+
+ ($tokens:ident { $($inner:tt)* }) => {
+ $crate::tokens::runtime::push_group(
+ &mut $tokens,
+ $crate::tokens::Delimiter::Brace,
+ $crate::quote!($($inner)*),
+ );
+ };
+
+ ($tokens:ident +) => {
+ $crate::tokens::runtime::push_add(&mut $tokens);
+ };
+
+ ($tokens:ident +=) => {
+ $crate::tokens::runtime::push_add_eq(&mut $tokens);
+ };
+
+ ($tokens:ident &) => {
+ $crate::tokens::runtime::push_and(&mut $tokens);
+ };
+
+ ($tokens:ident &&) => {
+ $crate::tokens::runtime::push_and_and(&mut $tokens);
+ };
+
+ ($tokens:ident &=) => {
+ $crate::tokens::runtime::push_and_eq(&mut $tokens);
+ };
+
+ ($tokens:ident @) => {
+ $crate::tokens::runtime::push_at(&mut $tokens);
+ };
+
+ ($tokens:ident !) => {
+ $crate::tokens::runtime::push_bang(&mut $tokens);
+ };
+
+ ($tokens:ident ^) => {
+ $crate::tokens::runtime::push_caret(&mut $tokens);
+ };
+
+ ($tokens:ident ^=) => {
+ $crate::tokens::runtime::push_caret_eq(&mut $tokens);
+ };
+
+ ($tokens:ident :) => {
+ $crate::tokens::runtime::push_colon(&mut $tokens);
+ };
+
+ ($tokens:ident ::) => {
+ $crate::tokens::runtime::push_colon2(&mut $tokens);
+ };
+
+ ($tokens:ident ,) => {
+ $crate::tokens::runtime::push_comma(&mut $tokens);
+ };
+
+ ($tokens:ident /) => {
+ $crate::tokens::runtime::push_div(&mut $tokens);
+ };
+
+ ($tokens:ident /=) => {
+ $crate::tokens::runtime::push_div_eq(&mut $tokens);
+ };
+
+ ($tokens:ident .) => {
+ $crate::tokens::runtime::push_dot(&mut $tokens);
+ };
+
+ ($tokens:ident ..) => {
+ $crate::tokens::runtime::push_dot2(&mut $tokens);
+ };
+
+ ($tokens:ident ...) => {
+ $crate::tokens::runtime::push_dot3(&mut $tokens);
+ };
+
+ ($tokens:ident ..=) => {
+ $crate::tokens::runtime::push_dot_dot_eq(&mut $tokens);
+ };
+
+ ($tokens:ident =) => {
+ $crate::tokens::runtime::push_eq(&mut $tokens);
+ };
+
+ ($tokens:ident ==) => {
+ $crate::tokens::runtime::push_eq_eq(&mut $tokens);
+ };
+
+ ($tokens:ident >=) => {
+ $crate::tokens::runtime::push_ge(&mut $tokens);
+ };
+
+ ($tokens:ident >) => {
+ $crate::tokens::runtime::push_gt(&mut $tokens);
+ };
+
+ ($tokens:ident <=) => {
+ $crate::tokens::runtime::push_le(&mut $tokens);
+ };
+
+ ($tokens:ident <) => {
+ $crate::tokens::runtime::push_lt(&mut $tokens);
+ };
+
+ ($tokens:ident *=) => {
+ $crate::tokens::runtime::push_mul_eq(&mut $tokens);
+ };
+
+ ($tokens:ident !=) => {
+ $crate::tokens::runtime::push_ne(&mut $tokens);
+ };
+
+ ($tokens:ident |) => {
+ $crate::tokens::runtime::push_or(&mut $tokens);
+ };
+
+ ($tokens:ident |=) => {
+ $crate::tokens::runtime::push_or_eq(&mut $tokens);
+ };
+
+ ($tokens:ident ||) => {
+ $crate::tokens::runtime::push_or_or(&mut $tokens);
+ };
+
+ ($tokens:ident #) => {
+ $crate::tokens::runtime::push_pound(&mut $tokens);
+ };
+
+ ($tokens:ident ?) => {
+ $crate::tokens::runtime::push_question(&mut $tokens);
+ };
+
+ ($tokens:ident ->) => {
+ $crate::tokens::runtime::push_rarrow(&mut $tokens);
+ };
+
+ ($tokens:ident <-) => {
+ $crate::tokens::runtime::push_larrow(&mut $tokens);
+ };
+
+ ($tokens:ident %) => {
+ $crate::tokens::runtime::push_rem(&mut $tokens);
+ };
+
+ ($tokens:ident %=) => {
+ $crate::tokens::runtime::push_rem_eq(&mut $tokens);
+ };
+
+ ($tokens:ident =>) => {
+ $crate::tokens::runtime::push_fat_arrow(&mut $tokens);
+ };
+
+ ($tokens:ident ;) => {
+ $crate::tokens::runtime::push_semi(&mut $tokens);
+ };
+
+ ($tokens:ident <<) => {
+ $crate::tokens::runtime::push_shl(&mut $tokens);
+ };
+
+ ($tokens:ident <<=) => {
+ $crate::tokens::runtime::push_shl_eq(&mut $tokens);
+ };
+
+ ($tokens:ident >>) => {
+ $crate::tokens::runtime::push_shr(&mut $tokens);
+ };
+
+ ($tokens:ident >>=) => {
+ $crate::tokens::runtime::push_shr_eq(&mut $tokens);
+ };
+
+ ($tokens:ident *) => {
+ $crate::tokens::runtime::push_star(&mut $tokens);
+ };
+
+ ($tokens:ident -) => {
+ $crate::tokens::runtime::push_sub(&mut $tokens);
+ };
+
+ ($tokens:ident -=) => {
+ $crate::tokens::runtime::push_sub_eq(&mut $tokens);
+ };
+
+ ($tokens:ident $ident:ident) => {
+ $crate::tokens::runtime::push_ident(&mut $tokens, stringify!($ident));
+ };
+
+ ($tokens:ident $other:tt) => {
+ $crate::tokens::runtime::parse(&mut $tokens, stringify!($other));
+ };
+}
+
+pub fn to_ident(name: &str) -> TokenStream {
+ // keywords list based on https://doc.rust-lang.org/reference/keywords.html
+ match name {
+ "abstract" | "as" | "become" | "box" | "break" | "const" | "continue" | "crate" | "do" | "else" | "enum" | "extern" | "false" | "final" | "fn" | "for" | "if" | "impl" | "in" | "let" | "loop" | "macro" | "match" | "mod" | "move" | "mut" | "override" | "priv" | "pub" | "ref" | "return" | "static" | "struct" | "super" | "trait" | "true" | "type" | "typeof" | "unsafe" | "unsized" | "use" | "virtual" | "where" | "while" | "yield" | "try" | "async" | "await" | "dyn" => format!("r#{name}").into(),
+ "Self" | "self" => format!("{name}_").into(),
+ "_" => "unused".into(),
+ _ => crate::trim_tick(name).into(),
+ }
+}
diff --git a/vendor/windows-bindgen/src/tokens/runtime.rs b/vendor/windows-bindgen/src/tokens/runtime.rs
new file mode 100644
index 000000000..83bc42a04
--- /dev/null
+++ b/vendor/windows-bindgen/src/tokens/runtime.rs
@@ -0,0 +1,274 @@
+use super::{Delimiter, ToTokens, TokenStream};
+use core::ops::BitOr;
+
+pub struct HasIterator; // True
+pub struct ThereIsNoIteratorInRepetition; // False
+
+impl BitOr<ThereIsNoIteratorInRepetition> for ThereIsNoIteratorInRepetition {
+ type Output = ThereIsNoIteratorInRepetition;
+ fn bitor(self, _rhs: ThereIsNoIteratorInRepetition) -> ThereIsNoIteratorInRepetition {
+ ThereIsNoIteratorInRepetition
+ }
+}
+
+impl BitOr<ThereIsNoIteratorInRepetition> for HasIterator {
+ type Output = HasIterator;
+ fn bitor(self, _rhs: ThereIsNoIteratorInRepetition) -> HasIterator {
+ HasIterator
+ }
+}
+
+impl BitOr<HasIterator> for ThereIsNoIteratorInRepetition {
+ type Output = HasIterator;
+ fn bitor(self, _rhs: HasIterator) -> HasIterator {
+ HasIterator
+ }
+}
+
+impl BitOr<HasIterator> for HasIterator {
+ type Output = HasIterator;
+ fn bitor(self, _rhs: HasIterator) -> HasIterator {
+ HasIterator
+ }
+}
+
+/// Extension traits used by the implementation of `quote!`. These are defined
+/// in separate traits, rather than as a single trait due to ambiguity issues.
+///
+/// These traits expose a `quote_into_iter` method which should allow calling
+/// whichever impl happens to be applicable. Calling that method repeatedly on
+/// the returned value should be idempotent.
+pub mod ext {
+ use super::RepInterp;
+ use super::ToTokens;
+ use super::{HasIterator as HasIter, ThereIsNoIteratorInRepetition as DoesNotHaveIter};
+ use core::slice;
+ use std::collections::btree_set::{self, BTreeSet};
+
+ /// Extension trait providing the `quote_into_iter` method on iterators.
+ pub trait RepIteratorExt: Iterator + Sized {
+ fn quote_into_iter(self) -> (Self, HasIter) {
+ (self, HasIter)
+ }
+ }
+
+ impl<T: Iterator> RepIteratorExt for T {}
+
+ /// Extension trait providing the `quote_into_iter` method for
+ /// non-iterable types. These types interpolate the same value in each
+ /// iteration of the repetition.
+ pub trait RepToTokensExt {
+ /// Pretend to be an iterator for the purposes of `quote_into_iter`.
+ /// This allows repeated calls to `quote_into_iter` to continue
+ /// correctly returning DoesNotHaveIter.
+ fn next(&self) -> Option<&Self> {
+ Some(self)
+ }
+
+ fn quote_into_iter(&self) -> (&Self, DoesNotHaveIter) {
+ (self, DoesNotHaveIter)
+ }
+ }
+
+ impl<T: ToTokens + ?Sized> RepToTokensExt for T {}
+
+ /// Extension trait providing the `quote_into_iter` method for types that
+ /// can be referenced as an iterator.
+ pub trait RepAsIteratorExt<'q> {
+ type Iter: Iterator;
+
+ fn quote_into_iter(&'q self) -> (Self::Iter, HasIter);
+ }
+
+ impl<'q, 'a, T: RepAsIteratorExt<'q> + ?Sized> RepAsIteratorExt<'q> for &'a T {
+ type Iter = T::Iter;
+
+ fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) {
+ <T as RepAsIteratorExt>::quote_into_iter(*self)
+ }
+ }
+
+ impl<'q, 'a, T: RepAsIteratorExt<'q> + ?Sized> RepAsIteratorExt<'q> for &'a mut T {
+ type Iter = T::Iter;
+
+ fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) {
+ <T as RepAsIteratorExt>::quote_into_iter(*self)
+ }
+ }
+
+ impl<'q, T: 'q> RepAsIteratorExt<'q> for [T] {
+ type Iter = slice::Iter<'q, T>;
+
+ fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) {
+ (self.iter(), HasIter)
+ }
+ }
+
+ impl<'q, T: 'q> RepAsIteratorExt<'q> for Vec<T> {
+ type Iter = slice::Iter<'q, T>;
+
+ fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) {
+ (self.iter(), HasIter)
+ }
+ }
+
+ impl<'q, T: 'q> RepAsIteratorExt<'q> for BTreeSet<T> {
+ type Iter = btree_set::Iter<'q, T>;
+
+ fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) {
+ (self.iter(), HasIter)
+ }
+ }
+
+ macro_rules! array_rep_slice {
+ ($($l:tt)*) => {
+ $(
+ impl<'q, T: 'q> RepAsIteratorExt<'q> for [T; $l] {
+ type Iter = slice::Iter<'q, T>;
+
+ fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) {
+ (self.iter(), HasIter)
+ }
+ }
+ )*
+ }
+ }
+
+ array_rep_slice!(
+ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
+ 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
+ );
+
+ impl<'q, T: RepAsIteratorExt<'q>> RepAsIteratorExt<'q> for RepInterp<T> {
+ type Iter = T::Iter;
+
+ fn quote_into_iter(&'q self) -> (Self::Iter, HasIter) {
+ self.0.quote_into_iter()
+ }
+ }
+}
+
+// Helper type used within interpolations to allow for repeated binding names.
+// Implements the relevant traits, and exports a dummy `next()` method.
+#[derive(Copy, Clone)]
+pub struct RepInterp<T>(pub T);
+
+impl<T> RepInterp<T> {
+ // This method is intended to look like `Iterator::next`, and is called when
+ // a name is bound multiple times, as the previous binding will shadow the
+ // original `Iterator` object. This allows us to avoid advancing the
+ // iterator multiple times per iteration.
+ pub fn next(self) -> Option<T> {
+ Some(self.0)
+ }
+}
+
+impl<T: Iterator> Iterator for RepInterp<T> {
+ type Item = T::Item;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.0.next()
+ }
+}
+
+impl<T: ToTokens> ToTokens for RepInterp<T> {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.0.to_tokens(tokens);
+ }
+}
+
+pub fn push_group(tokens: &mut TokenStream, delimiter: Delimiter, inner: TokenStream) {
+ tokens.push_space();
+ tokens.push(delimiter.open());
+ tokens.combine(&inner);
+ tokens.push_space();
+ tokens.push(delimiter.close());
+}
+
+pub fn parse(tokens: &mut TokenStream, s: &str) {
+ tokens.push_space();
+ tokens.push_str(s);
+}
+
+pub fn push_ident(tokens: &mut TokenStream, s: &str) {
+ match tokens.0.chars().last() {
+ None | Some(':') => {}
+ _ => tokens.0.push(' '),
+ }
+ tokens.push_str(s);
+}
+
+pub fn push_colon2(tokens: &mut TokenStream) {
+ match tokens.0.chars().last() {
+ Some(':') => tokens.push_str(" ::"),
+ _ => tokens.push_str("::"),
+ }
+}
+
+macro_rules! push_punct {
+ ($name:ident $char1:tt) => {
+ pub fn $name(tokens: &mut TokenStream) {
+ tokens.push_space();
+ tokens.push($char1);
+ }
+ };
+ ($name:ident $char1:tt $char2:tt) => {
+ pub fn $name(tokens: &mut TokenStream) {
+ tokens.push_space();
+ tokens.push($char1);
+ tokens.push($char2);
+ }
+ };
+ ($name:ident $char1:tt $char2:tt $char3:tt) => {
+ pub fn $name(tokens: &mut TokenStream) {
+ tokens.push(' ');
+ tokens.push($char1);
+ tokens.push($char2);
+ tokens.push($char3);
+ }
+ };
+}
+
+push_punct!(push_add '+');
+push_punct!(push_add_eq '+' '=');
+push_punct!(push_and '&');
+push_punct!(push_and_and '&' '&');
+push_punct!(push_and_eq '&' '=');
+push_punct!(push_at '@');
+push_punct!(push_bang '!');
+push_punct!(push_caret '^');
+push_punct!(push_caret_eq '^' '=');
+push_punct!(push_colon ':');
+push_punct!(push_comma ',');
+push_punct!(push_div '/');
+push_punct!(push_div_eq '/' '=');
+push_punct!(push_dot '.');
+push_punct!(push_dot2 '.' '.');
+push_punct!(push_dot3 '.' '.' '.');
+push_punct!(push_dot_dot_eq '.' '.' '=');
+push_punct!(push_eq '=');
+push_punct!(push_eq_eq '=' '=');
+push_punct!(push_ge '>' '=');
+push_punct!(push_gt '>');
+push_punct!(push_le '<' '=');
+push_punct!(push_lt '<');
+push_punct!(push_mul_eq '*' '=');
+push_punct!(push_ne '!' '=');
+push_punct!(push_or '|');
+push_punct!(push_or_eq '|' '=');
+push_punct!(push_or_or '|' '|');
+push_punct!(push_pound '#');
+push_punct!(push_question '?');
+push_punct!(push_rarrow '-' '>');
+push_punct!(push_larrow '<' '-');
+push_punct!(push_rem '%');
+push_punct!(push_rem_eq '%' '=');
+push_punct!(push_fat_arrow '=' '>');
+push_punct!(push_semi ';');
+push_punct!(push_shl '<' '<');
+push_punct!(push_shl_eq '<' '<' '=');
+push_punct!(push_shr '>' '>');
+push_punct!(push_shr_eq '>' '>' '=');
+push_punct!(push_star '*');
+push_punct!(push_sub '-');
+push_punct!(push_sub_eq '-' '=');
diff --git a/vendor/windows-bindgen/src/tokens/to_tokens.rs b/vendor/windows-bindgen/src/tokens/to_tokens.rs
new file mode 100644
index 000000000..cb614f33d
--- /dev/null
+++ b/vendor/windows-bindgen/src/tokens/to_tokens.rs
@@ -0,0 +1,149 @@
+use std::borrow::Cow;
+use std::rc::Rc;
+
+use super::{Literal, TokenStream};
+
+/// Types that can be interpolated inside a `quote!` invocation.
+///
+/// [`quote!`]: macro.quote.html
+pub trait ToTokens {
+ /// Write `self` to the given `TokenStream`.
+ fn to_tokens(&self, tokens: &mut TokenStream);
+
+ /// Convert `self` directly into a `TokenStream` object.
+ ///
+ /// This method is implicitly implemented using `to_tokens`, and acts as a
+ /// convenience method for consumers of the `ToTokens` trait.
+ fn to_token_stream(&self) -> TokenStream {
+ let mut tokens = TokenStream::new();
+ self.to_tokens(&mut tokens);
+ tokens
+ }
+
+ /// Convert `self` directly into a `TokenStream` object.
+ ///
+ /// This method is implicitly implemented using `to_tokens`, and acts as a
+ /// convenience method for consumers of the `ToTokens` trait.
+ fn into_token_stream(self) -> TokenStream
+ where
+ Self: Sized,
+ {
+ self.to_token_stream()
+ }
+}
+
+impl<'a, T: ?Sized + ToTokens> ToTokens for &'a T {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ (**self).to_tokens(tokens);
+ }
+}
+
+impl<'a, T: ?Sized + ToTokens> ToTokens for &'a mut T {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ (**self).to_tokens(tokens);
+ }
+}
+
+impl<'a, T: ?Sized + ToOwned + ToTokens> ToTokens for Cow<'a, T> {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ (**self).to_tokens(tokens);
+ }
+}
+
+impl<T: ?Sized + ToTokens> ToTokens for Box<T> {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ (**self).to_tokens(tokens);
+ }
+}
+
+impl<T: ?Sized + ToTokens> ToTokens for Rc<T> {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ (**self).to_tokens(tokens);
+ }
+}
+
+impl<T: ToTokens> ToTokens for Option<T> {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ if let Some(ref t) = *self {
+ t.to_tokens(tokens);
+ }
+ }
+}
+
+impl ToTokens for str {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.push_str(" \"");
+ tokens.push_str(self);
+ tokens.push('"');
+ }
+}
+
+impl ToTokens for String {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ self.as_str().to_tokens(tokens);
+ }
+}
+
+macro_rules! primitive {
+ ($($t:ident => $name:ident)*) => ($(
+ impl ToTokens for $t {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.push_space();
+ tokens.push_str(&self.to_string());
+ tokens.push_str(stringify!($t));
+ }
+ }
+ )*)
+}
+
+primitive! {
+ i8 => i8_suffixed
+ i16 => i16_suffixed
+ i32 => i32_suffixed
+ i64 => i64_suffixed
+ i128 => i128_suffixed
+ isize => isize_suffixed
+
+ u8 => u8_suffixed
+ u16 => u16_suffixed
+ u32 => u32_suffixed
+ u64 => u64_suffixed
+ u128 => u128_suffixed
+ usize => usize_suffixed
+
+ f32 => f32_suffixed
+ f64 => f64_suffixed
+}
+
+impl ToTokens for char {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.push_space();
+ tokens.push('\'');
+ tokens.push(*self);
+ tokens.push('\'');
+ }
+}
+
+impl ToTokens for bool {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ let word = if *self { "true" } else { "false" };
+ tokens.push_space();
+ tokens.push_str(word);
+ }
+}
+
+impl ToTokens for Literal {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ tokens.push_str(self.as_str());
+ }
+}
+
+impl ToTokens for TokenStream {
+ fn to_tokens(&self, dst: &mut TokenStream) {
+ dst.combine(self);
+ }
+
+ fn into_token_stream(self) -> TokenStream {
+ self
+ }
+}
diff --git a/vendor/windows-bindgen/src/tokens/token_stream.rs b/vendor/windows-bindgen/src/tokens/token_stream.rs
new file mode 100644
index 000000000..3b3a09bdd
--- /dev/null
+++ b/vendor/windows-bindgen/src/tokens/token_stream.rs
@@ -0,0 +1,164 @@
+/// A stream of tokens
+#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
+pub struct TokenStream(pub String);
+
+impl From<String> for TokenStream {
+ fn from(tokens: String) -> Self {
+ Self(tokens)
+ }
+}
+
+impl From<&String> for TokenStream {
+ fn from(tokens: &String) -> Self {
+ Self(tokens.to_string())
+ }
+}
+
+impl From<&str> for TokenStream {
+ fn from(tokens: &str) -> Self {
+ Self(tokens.to_string())
+ }
+}
+
+impl TokenStream {
+ pub fn new() -> Self {
+ Self(String::new())
+ }
+
+ /// Appends another stream to the stream
+ ///
+ /// note: a space will be inserted before the other stream
+ pub fn combine(&mut self, other: &TokenStream) {
+ self.push_space();
+ self.0.push_str(&other.0)
+ }
+
+ #[must_use]
+ pub fn join(&self, value: &str) -> Self {
+ Self(format!("{}{value}", self.0))
+ }
+
+ pub fn is_empty(&self) -> bool {
+ self.0.is_empty()
+ }
+
+ /// View the stream as a string
+ pub fn as_str(&self) -> &str {
+ &self.0
+ }
+
+ /// Convert the stream into a `String`
+ pub fn into_string(self) -> String {
+ self.0
+ }
+
+ /// Parse the token stream as something
+ ///
+ /// Mostly used with `proc_macro2::TokenStream` or `proc_macro::TokenStream`
+ pub fn parse<T: core::str::FromStr>(self) -> Result<T, T::Err> {
+ self.into_string().parse()
+ }
+
+ pub(crate) fn push_space(&mut self) {
+ match self.last_char() {
+ None | Some(' ') => {}
+ _ => self.0.push(' '),
+ }
+ }
+
+ pub fn push(&mut self, c: char) {
+ self.0.push(c)
+ }
+
+ pub fn push_str(&mut self, str: &str) {
+ self.0.push_str(str)
+ }
+
+ fn last_char(&self) -> Option<char> {
+ self.0.chars().last()
+ }
+}
+
+impl Default for TokenStream {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
+impl core::iter::FromIterator<TokenStream> for TokenStream {
+ fn from_iter<I: IntoIterator<Item = TokenStream>>(iter: I) -> Self {
+ iter.into_iter()
+ .fold(None, |accum: Option<TokenStream>, n| {
+ let mut ts = accum.unwrap_or_default();
+ ts.combine(&n);
+ Some(ts)
+ })
+ .unwrap_or_else(TokenStream::new)
+ }
+}
+
+/// A delimiter around a block of code
+#[derive(Copy, Clone)]
+pub enum Delimiter {
+ /// `[]`
+ Bracket,
+ /// `{}`
+ Brace,
+ /// `()`
+ Parenthesis,
+}
+
+impl Delimiter {
+ /// The opening delimiter
+ pub fn open(self) -> char {
+ match self {
+ Delimiter::Bracket => '[',
+ Delimiter::Brace => '{',
+ Delimiter::Parenthesis => '(',
+ }
+ }
+
+ /// The closing delimiter
+ pub fn close(self) -> char {
+ match self {
+ Delimiter::Bracket => ']',
+ Delimiter::Brace => '}',
+ Delimiter::Parenthesis => ')',
+ }
+ }
+}
+
+/// A literal of some sort
+pub struct Literal {
+ inner: String,
+}
+
+macro_rules! unsuffixed {
+ ($ty:ty => $name:ident) => {
+ pub fn $name(n: $ty) -> Self {
+ Self { inner: n.to_string() }
+ }
+ };
+}
+
+impl Literal {
+ unsuffixed!(i64 => i64_unsuffixed);
+ unsuffixed!(usize => usize_unsuffixed);
+ unsuffixed!(u32 => u32_unsuffixed);
+ unsuffixed!(u16 => u16_unsuffixed);
+ unsuffixed!(u8 => u8_unsuffixed);
+
+ pub fn byte_string(s: &[u8]) -> Self {
+ Self { inner: format!("b\"{}\"", core::str::from_utf8(s).expect("Could not turn bytes into byte literal")) }
+ }
+
+ pub fn as_str(&self) -> &str {
+ &self.inner
+ }
+}
+
+impl core::fmt::Display for TokenStream {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+ write!(f, "{}", self.as_str())
+ }
+}
diff --git a/vendor/windows-bindgen/src/tree.rs b/vendor/windows-bindgen/src/tree.rs
new file mode 100644
index 000000000..474d2a271
--- /dev/null
+++ b/vendor/windows-bindgen/src/tree.rs
@@ -0,0 +1,36 @@
+use super::*;
+
+#[derive(Debug)]
+pub struct Tree<'a> {
+ pub namespace: &'a str,
+ pub nested: std::collections::BTreeMap<&'a str, Tree<'a>>,
+}
+
+impl<'a> Tree<'a> {
+ pub fn new(reader: &'a metadata::Reader, filter: &'a metadata::Filter) -> Self {
+ let mut tree = Tree::from_namespace("");
+ for ns in reader.namespaces() {
+ if filter.includes_namespace(ns) {
+ tree.insert_namespace(ns, 0);
+ }
+ }
+ tree
+ }
+
+ fn from_namespace(namespace: &'a str) -> Self {
+ Self { namespace, nested: std::collections::BTreeMap::new() }
+ }
+ fn insert_namespace(&mut self, namespace: &'a str, pos: usize) -> &mut Self {
+ if let Some(next) = namespace[pos..].find('.') {
+ let next = pos + next;
+ self.nested.entry(&namespace[pos..next]).or_insert_with(|| Self::from_namespace(&namespace[..next])).insert_namespace(namespace, next + 1)
+ } else {
+ self.nested.entry(&namespace[pos..]).or_insert_with(|| Self::from_namespace(namespace))
+ }
+ }
+ pub fn flatten(&self) -> Vec<&Self> {
+ let mut flatten = if self.namespace.is_empty() { vec![] } else { vec![self] };
+ flatten.extend(self.nested.values().flat_map(|tree| tree.flatten()));
+ flatten
+ }
+}
diff --git a/vendor/windows-bindgen/src/try_format.rs b/vendor/windows-bindgen/src/try_format.rs
deleted file mode 100644
index 493a8a842..000000000
--- a/vendor/windows-bindgen/src/try_format.rs
+++ /dev/null
@@ -1,31 +0,0 @@
-pub fn try_format(tokens: String) -> String {
- use std::io::Write;
-
- let Ok(mut child) = std::process::Command::new("rustfmt").stdin(std::process::Stdio::piped()).stdout(std::process::Stdio::piped()).stderr(std::process::Stdio::null()).spawn() else {
- return tokens;
- };
-
- let Some(mut stdin) = child.stdin.take() else {
- return tokens;
- };
-
- if stdin.write_all(tokens.as_bytes()).is_err() {
- return tokens;
- }
-
- drop(stdin);
-
- let Ok(output) = child.wait_with_output() else {
- return tokens;
- };
-
- if !output.status.success() {
- return tokens;
- }
-
- if let Ok(result) = String::from_utf8(output.stdout) {
- result
- } else {
- tokens
- }
-}
diff --git a/vendor/windows-bindgen/src/winmd/from_reader.rs b/vendor/windows-bindgen/src/winmd/from_reader.rs
new file mode 100644
index 000000000..b535caed0
--- /dev/null
+++ b/vendor/windows-bindgen/src/winmd/from_reader.rs
@@ -0,0 +1,141 @@
+use super::*;
+use crate::winmd::{self, writer};
+use metadata::RowReader;
+
+pub fn from_reader(reader: &metadata::Reader, filter: &metadata::Filter, config: std::collections::BTreeMap<&str, &str>, output: &str) -> crate::Result<()> {
+ let mut writer = winmd::Writer::new(output);
+
+ // TODO: do we need any configuration values for winmd generation?
+ // Maybe per-namespace winmd files for namespace-splitting - be sure to use
+ // the same key as for winmd generation.
+
+ if let Some((key, _)) = config.first_key_value() {
+ return Err(crate::Error::new(&format!("invalid configuration value `{key}`")));
+ }
+
+ // TODO: just use the reader directly since we now have everything in the reader, there's no need to abstract
+ // away the source format. Few reprs is always better.
+
+ for item in reader.items(filter) {
+ // TODO: cover all variants
+ let metadata::Item::Type(def) = item else {
+ continue;
+ };
+
+ let generics = &metadata::type_def_generics(reader, def);
+
+ let extends = if let Some(extends) = reader.type_def_extends(def) { writer.insert_type_ref(extends.namespace, extends.name) } else { 0 };
+
+ writer.tables.TypeDef.push(writer::TypeDef {
+ Extends: extends,
+ FieldList: writer.tables.Field.len() as u32,
+ Flags: reader.type_def_flags(def).0,
+ MethodList: writer.tables.MethodDef.len() as u32,
+ TypeName: writer.strings.insert(reader.type_def_name(def)),
+ TypeNamespace: writer.strings.insert(reader.type_def_namespace(def)),
+ });
+
+ for generic in reader.type_def_generics(def) {
+ writer.tables.GenericParam.push(writer::GenericParam {
+ Number: reader.generic_param_number(generic),
+ Flags: 0,
+ Owner: writer::TypeOrMethodDef::TypeDef(writer.tables.TypeDef.len() as u32 - 1).encode(),
+ Name: writer.strings.insert(reader.generic_param_name(generic)),
+ });
+ }
+
+ for imp in reader.type_def_interface_impls(def) {
+ let ty = reader.interface_impl_type(imp, generics);
+ let ty = winmd_type(reader, &ty);
+
+ let reference = match &ty {
+ winmd::Type::TypeRef(type_name) if type_name.generics.is_empty() => writer.insert_type_ref(&type_name.namespace, &type_name.name),
+ winmd::Type::TypeRef(_) => writer.insert_type_spec(ty),
+ winmd::Type::IUnknown => writer.insert_type_ref("Windows.Win32.System.Com", "IUnknown"),
+ winmd::Type::IInspectable => writer.insert_type_ref("Windows.Win32.System.WinRT", "IInspectable"),
+ rest => unimplemented!("{rest:?}"),
+ };
+
+ writer.tables.InterfaceImpl.push(writer::InterfaceImpl { Class: writer.tables.TypeDef.len() as u32 - 1, Interface: reference });
+ }
+
+ // TODO: if the class is "Apis" then should we sort the fields (constants) and methods (functions) for stability
+
+ for field in reader.type_def_fields(def) {
+ let ty = winmd_type(reader, &reader.field_type(field, Some(def)));
+ let signature = writer.insert_field_sig(&ty);
+
+ writer.tables.Field.push(writer::Field { Flags: reader.field_flags(field).0, Name: writer.strings.insert(reader.field_name(field)), Signature: signature });
+ }
+
+ for method in reader.type_def_methods(def) {
+ let signature = reader.method_def_signature(method, generics);
+ let return_type = winmd_type(reader, &signature.return_type);
+ let param_types: Vec<Type> = signature.params.iter().map(|param| winmd_type(reader, param)).collect();
+
+ let signature = writer.insert_method_sig(signature.call_flags, &return_type, &param_types);
+
+ writer.tables.MethodDef.push(winmd::MethodDef {
+ RVA: 0,
+ ImplFlags: reader.method_def_impl_flags(method).0,
+ Flags: reader.method_def_flags(method).0,
+ Name: writer.strings.insert(reader.method_def_name(method)),
+ Signature: signature,
+ ParamList: writer.tables.Param.len() as u32,
+ });
+
+ for param in reader.method_def_params(method) {
+ writer.tables.Param.push(writer::Param { Flags: reader.param_flags(param).0, Sequence: reader.param_sequence(param), Name: writer.strings.insert(reader.param_name(param)) });
+ }
+ }
+ }
+
+ // TODO: In theory, `config` could instruct this function to balance the types across a number of winmd files
+ // like mdmerge supports for namespace-splitting.
+ crate::write_to_file(output, writer.into_stream()).map_err(|err| err.with_path(output))
+}
+
+// TODO: keep the basic type conversion
+fn winmd_type(reader: &metadata::Reader, ty: &metadata::Type) -> winmd::Type {
+ match ty {
+ metadata::Type::Void => winmd::Type::Void,
+ metadata::Type::Bool => winmd::Type::Bool,
+ metadata::Type::Char => winmd::Type::Char,
+ metadata::Type::I8 => winmd::Type::I8,
+ metadata::Type::U8 => winmd::Type::U8,
+ metadata::Type::I16 => winmd::Type::I16,
+ metadata::Type::U16 => winmd::Type::U16,
+ metadata::Type::I32 => winmd::Type::I32,
+ metadata::Type::U32 => winmd::Type::U32,
+ metadata::Type::I64 => winmd::Type::I64,
+ metadata::Type::U64 => winmd::Type::U64,
+ metadata::Type::F32 => winmd::Type::F32,
+ metadata::Type::F64 => winmd::Type::F64,
+ metadata::Type::ISize => winmd::Type::ISize,
+ metadata::Type::USize => winmd::Type::USize,
+ metadata::Type::String => winmd::Type::String,
+ metadata::Type::GUID => winmd::Type::GUID,
+ metadata::Type::IUnknown => winmd::Type::IUnknown,
+ metadata::Type::IInspectable => winmd::Type::IInspectable,
+ metadata::Type::HRESULT => winmd::Type::HRESULT,
+ metadata::Type::PSTR => winmd::Type::PSTR,
+ metadata::Type::PWSTR => winmd::Type::PWSTR,
+ metadata::Type::PCSTR => winmd::Type::PCSTR,
+ metadata::Type::PCWSTR => winmd::Type::PCWSTR,
+ metadata::Type::BSTR => winmd::Type::BSTR,
+ metadata::Type::TypeName => winmd::Type::TypeName,
+ metadata::Type::TypeDef(def, generics) => winmd::Type::TypeRef(winmd::TypeName {
+ namespace: reader.type_def_namespace(*def).to_string(),
+ name: reader.type_def_name(*def).to_string(),
+ generics: generics.iter().map(|ty| winmd_type(reader, ty)).collect(),
+ }),
+ metadata::Type::GenericParam(generic) => winmd::Type::GenericParam(reader.generic_param_number(*generic)),
+ metadata::Type::ConstRef(ty) => winmd::Type::ConstRef(Box::new(winmd_type(reader, ty))),
+ metadata::Type::WinrtArrayRef(ty) => winmd::Type::WinrtArrayRef(Box::new(winmd_type(reader, ty))),
+ metadata::Type::WinrtArray(ty) => winmd::Type::WinrtArray(Box::new(winmd_type(reader, ty))),
+ metadata::Type::MutPtr(ty, pointers) => winmd::Type::MutPtr(Box::new(winmd_type(reader, ty)), *pointers),
+ metadata::Type::ConstPtr(ty, pointers) => winmd::Type::ConstPtr(Box::new(winmd_type(reader, ty)), *pointers),
+ metadata::Type::Win32Array(ty, len) => winmd::Type::Win32Array(Box::new(winmd_type(reader, ty)), *len),
+ rest => unimplemented!("{rest:?}"),
+ }
+}
diff --git a/vendor/windows-bindgen/src/winmd/mod.rs b/vendor/windows-bindgen/src/winmd/mod.rs
new file mode 100644
index 000000000..f01afa218
--- /dev/null
+++ b/vendor/windows-bindgen/src/winmd/mod.rs
@@ -0,0 +1,7 @@
+mod from_reader;
+mod verify;
+pub mod writer;
+use super::*;
+pub use from_reader::from_reader;
+pub use verify::verify;
+pub use writer::*;
diff --git a/vendor/windows-bindgen/src/winmd/verify.rs b/vendor/windows-bindgen/src/winmd/verify.rs
new file mode 100644
index 000000000..f10bd6524
--- /dev/null
+++ b/vendor/windows-bindgen/src/winmd/verify.rs
@@ -0,0 +1,31 @@
+use super::*;
+use metadata::RowReader;
+
+pub fn verify(reader: &metadata::Reader, filter: &metadata::Filter) -> crate::Result<()> {
+ for item in reader.items(filter) {
+ // TODO: cover all variants
+ let metadata::Item::Type(def) = item else {
+ continue;
+ };
+
+ let generics = &metadata::type_def_generics(reader, def);
+
+ reader.type_def_fields(def).try_for_each(|field| not_type_ref(reader, &reader.field_type(field, Some(def))))?;
+
+ reader.type_def_methods(def).try_for_each(|method| {
+ let sig = reader.method_def_signature(method, generics);
+ not_type_ref(reader, &sig.return_type)?;
+
+ sig.params.iter().try_for_each(|param| not_type_ref(reader, param))
+ })?;
+ }
+
+ Ok(())
+}
+
+fn not_type_ref(reader: &metadata::Reader, ty: &metadata::Type) -> crate::Result<()> {
+ if let metadata::Type::TypeRef(ty) = ty {
+ return Err(crate::Error::new(&format!("missing type definition `{}`", reader.type_def_or_ref(*ty))));
+ }
+ Ok(())
+}
diff --git a/vendor/windows-bindgen/src/winmd/writer/blobs.rs b/vendor/windows-bindgen/src/winmd/writer/blobs.rs
new file mode 100644
index 000000000..5201a32d0
--- /dev/null
+++ b/vendor/windows-bindgen/src/winmd/writer/blobs.rs
@@ -0,0 +1,48 @@
+use super::*;
+use std::collections::hash_map::*;
+
+pub struct Blobs {
+ map: HashMap<Vec<u8>, u32>,
+ stream: Vec<u8>,
+}
+
+impl Default for Blobs {
+ fn default() -> Self {
+ Self { map: Default::default(), stream: vec![0] }
+ }
+}
+
+impl Blobs {
+ pub fn insert(&mut self, value: &[u8]) -> u32 {
+ if value.is_empty() {
+ return 0;
+ }
+
+ match self.map.entry(value.to_vec()) {
+ Entry::Vacant(entry) => {
+ let offset = *entry.insert(self.stream.len() as u32);
+ let len = value.len();
+ match len {
+ 0..=0x7F => self.stream.push(len as u8),
+ 0x80..=0x3FFF => {
+ self.stream.push((0x80 | len >> 8) as u8);
+ self.stream.push((0xFF & len) as u8);
+ }
+ _ => {
+ self.stream.push((0xC0 | len >> 24) as u8);
+ self.stream.push((0xFF & len >> 16) as u8);
+ self.stream.push((0xFF & len >> 8) as u8);
+ self.stream.push((0xFF & len) as u8);
+ }
+ }
+ self.stream.extend_from_slice(value);
+ offset
+ }
+ Entry::Occupied(entry) => *entry.get(),
+ }
+ }
+
+ pub fn into_stream(self) -> Vec<u8> {
+ self.stream.into_stream()
+ }
+}
diff --git a/vendor/windows-bindgen/src/winmd/writer/codes.rs b/vendor/windows-bindgen/src/winmd/writer/codes.rs
new file mode 100644
index 000000000..c5aa789e0
--- /dev/null
+++ b/vendor/windows-bindgen/src/winmd/writer/codes.rs
@@ -0,0 +1,71 @@
+#![allow(dead_code, clippy::enum_variant_names)]
+
+/// A `ResolutionScope` is an index into a certain table indicating the scope in which a TypeRef can be resolved.
+#[derive(Clone)]
+pub enum ResolutionScope {
+ Module(u32),
+ ModuleRef(u32),
+ AssemblyRef(u32),
+ TypeRef(u32),
+}
+
+impl ResolutionScope {
+ pub fn encode(&self) -> u32 {
+ match self {
+ Self::Module(row) => (row + 1) << 2,
+ Self::ModuleRef(row) => ((row + 1) << 2) + 1,
+ Self::AssemblyRef(row) => ((row + 1) << 2) + 2,
+ Self::TypeRef(row) => ((row + 1) << 2) + 3,
+ }
+ }
+}
+
+/// A `TypeDefOrRef` is an index into a certain table used to locate a type definition.
+#[derive(Clone)]
+pub enum TypeDefOrRef {
+ TypeDef(u32),
+ TypeRef(u32),
+ TypeSpec(u32),
+}
+
+impl TypeDefOrRef {
+ pub fn encode(&self) -> u32 {
+ match self {
+ Self::TypeDef(row) => (row + 1) << 2,
+ Self::TypeRef(row) => ((row + 1) << 2) + 1,
+ Self::TypeSpec(row) => ((row + 1) << 2) + 2,
+ }
+ }
+}
+
+/// A `HasConstant` is an index into a certain table used to identify the parent of a row in the `Constant` table.
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
+pub enum HasConstant {
+ Field(u32),
+ Param(u32),
+ Property(u32),
+}
+
+impl HasConstant {
+ pub fn encode(&self) -> u32 {
+ match self {
+ Self::Field(row) => (row + 1) << 2,
+ Self::Param(row) => ((row + 1) << 2) + 1,
+ Self::Property(row) => ((row + 1) << 2) + 2,
+ }
+ }
+}
+
+/// A `TypeOrMethodDef` is an index into a certain table used to locate the owner of a generic parameter.
+#[derive(Clone)]
+pub enum TypeOrMethodDef {
+ TypeDef(u32),
+}
+
+impl TypeOrMethodDef {
+ pub fn encode(&self) -> u32 {
+ match self {
+ Self::TypeDef(row) => (row + 1) << 1,
+ }
+ }
+}
diff --git a/vendor/windows-bindgen/src/winmd/writer/file.rs b/vendor/windows-bindgen/src/winmd/writer/file.rs
new file mode 100644
index 000000000..b452ba559
--- /dev/null
+++ b/vendor/windows-bindgen/src/winmd/writer/file.rs
@@ -0,0 +1,134 @@
+use super::*;
+use metadata::imp::*;
+use std::mem::*;
+
+pub fn write(mut tables: Vec<u8>, mut strings: Vec<u8>, mut blobs: Vec<u8>) -> Vec<u8> {
+ if [tables.len(), strings.len(), blobs.len()].iter().any(|len| *len > u32::MAX as usize) {
+ panic!("heap too large");
+ }
+
+ unsafe {
+ let mut guids = vec![0; 16]; // zero guid
+ let size_of_streams = tables.len() + guids.len() + strings.len() + blobs.len();
+
+ let mut dos: IMAGE_DOS_HEADER = zeroed();
+ dos.e_magic = IMAGE_DOS_SIGNATURE;
+ dos.e_lfarlc = 64;
+ dos.e_lfanew = size_of::<IMAGE_DOS_HEADER>() as i32;
+
+ let mut file: IMAGE_FILE_HEADER = zeroed();
+ file.Machine = IMAGE_FILE_MACHINE_I386;
+ file.NumberOfSections = 1;
+ file.SizeOfOptionalHeader = size_of::<IMAGE_OPTIONAL_HEADER32>() as u16;
+ file.Characteristics = IMAGE_FILE_DLL | IMAGE_FILE_32BIT_MACHINE | IMAGE_FILE_EXECUTABLE_IMAGE;
+
+ let mut optional: IMAGE_OPTIONAL_HEADER32 = zeroed();
+ optional.Magic = IMAGE_NT_OPTIONAL_HDR32_MAGIC;
+ optional.MajorLinkerVersion = 11;
+ optional.SizeOfInitializedData = 1024;
+ optional.ImageBase = 0x400000;
+ optional.SectionAlignment = SECTION_ALIGNMENT;
+ optional.FileAlignment = 512;
+ optional.MajorOperatingSystemVersion = 6;
+ optional.MinorOperatingSystemVersion = 2;
+ optional.MajorSubsystemVersion = 6;
+ optional.MinorSubsystemVersion = 2;
+ optional.SizeOfHeaders = 512;
+ optional.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI;
+ optional.DllCharacteristics = IMAGE_DLLCHARACTERISTICS_NX_COMPAT | IMAGE_DLLCHARACTERISTICS_NO_SEH | IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE;
+ optional.SizeOfStackReserve = 0x100000;
+ optional.SizeOfHeapReserve = 4096;
+ optional.LoaderFlags = 0x100000;
+ optional.NumberOfRvaAndSizes = 16;
+
+ let mut section: IMAGE_SECTION_HEADER = zeroed();
+ section.Name = *b".text\0\0\0";
+ section.Characteristics = 0x4000_0020;
+ section.VirtualAddress = SECTION_ALIGNMENT;
+
+ let mut clr: IMAGE_COR20_HEADER = zeroed();
+ clr.cb = size_of::<IMAGE_COR20_HEADER>() as u32;
+ clr.MajorRuntimeVersion = 2;
+ clr.MinorRuntimeVersion = 5;
+ clr.Flags = 1;
+
+ let metadata = METADATA_HEADER {
+ signature: METADATA_SIGNATURE,
+ major_version: 1,
+ minor_version: 1,
+ length: 20,
+ version: *b"WindowsRuntime 1.4\0\0",
+ streams: 4,
+ ..Default::default()
+ };
+
+ type TablesHeader = StreamHeader<4>;
+ type StringsHeader = StreamHeader<12>;
+ type GuidsHeader = StreamHeader<8>;
+ type BlobsHeader = StreamHeader<8>;
+
+ let size_of_stream_headers = size_of::<TablesHeader>() + size_of::<StringsHeader>() + size_of::<GuidsHeader>() + size_of::<BlobsHeader>();
+ let size_of_image = optional.FileAlignment as usize + size_of::<IMAGE_COR20_HEADER>() + size_of::<METADATA_HEADER>() + size_of_stream_headers + size_of_streams;
+
+ optional.SizeOfImage = round(size_of_image, optional.SectionAlignment as usize) as u32;
+ section.Misc.VirtualSize = size_of_image as u32 - optional.FileAlignment;
+ section.SizeOfRawData = round(section.Misc.VirtualSize as usize, optional.FileAlignment as usize) as u32;
+
+ optional.DataDirectory[14] = IMAGE_DATA_DIRECTORY { VirtualAddress: SECTION_ALIGNMENT, Size: size_of::<IMAGE_COR20_HEADER>() as u32 };
+ section.PointerToRawData = optional.FileAlignment;
+ clr.MetaData.VirtualAddress = SECTION_ALIGNMENT + size_of::<IMAGE_COR20_HEADER>() as u32;
+ clr.MetaData.Size = section.Misc.VirtualSize - size_of::<IMAGE_COR20_HEADER>() as u32;
+
+ let mut buffer = Vec::<u8>::new();
+
+ buffer.write_header(&dos);
+ buffer.write_u32(IMAGE_NT_SIGNATURE);
+ buffer.write_header(&file);
+ buffer.write_header(&optional);
+ buffer.write_header(&section);
+ debug_assert!(buffer.len() < optional.FileAlignment as usize);
+ buffer.resize(optional.FileAlignment as usize, 0);
+ buffer.write_header(&clr);
+ let metadata_offset = buffer.len();
+ buffer.write_header(&metadata);
+
+ let stream_offset = buffer.len() - metadata_offset + size_of_stream_headers;
+ let tables_header = TablesHeader::new(stream_offset as u32, tables.len() as u32, b"#~\0\0");
+ let strings_header = StringsHeader::new(tables_header.next_offset(), strings.len() as u32, b"#Strings\0\0\0\0");
+ let guids_header = GuidsHeader::new(strings_header.next_offset(), guids.len() as u32, b"#GUID\0\0\0");
+ let blobs_header = BlobsHeader::new(guids_header.next_offset(), blobs.len() as u32, b"#Blob\0\0\0");
+
+ buffer.write_header(&tables_header);
+ buffer.write_header(&strings_header);
+ buffer.write_header(&guids_header);
+ buffer.write_header(&blobs_header);
+
+ buffer.append(&mut tables);
+ buffer.append(&mut strings);
+ buffer.append(&mut guids);
+ buffer.append(&mut blobs);
+
+ assert_eq!(clr.MetaData.Size as usize, buffer.len() - metadata_offset);
+ assert_eq!(size_of_image, buffer.len());
+
+ buffer
+ }
+}
+
+const SECTION_ALIGNMENT: u32 = 4096;
+
+#[repr(C)]
+struct StreamHeader<const LEN: usize> {
+ offset: u32,
+ size: u32,
+ name: [u8; LEN],
+}
+
+impl<const LEN: usize> StreamHeader<LEN> {
+ fn new(offset: u32, size: u32, name: &[u8; LEN]) -> Self {
+ Self { offset, size, name: *name }
+ }
+ fn next_offset(&self) -> u32 {
+ self.offset + self.size
+ }
+}
diff --git a/vendor/windows-bindgen/src/winmd/writer/mod.rs b/vendor/windows-bindgen/src/winmd/writer/mod.rs
new file mode 100644
index 000000000..af49ecfeb
--- /dev/null
+++ b/vendor/windows-bindgen/src/winmd/writer/mod.rs
@@ -0,0 +1,329 @@
+mod blobs;
+mod codes;
+mod file;
+mod strings;
+mod tables;
+mod traits;
+mod r#type;
+
+use super::*;
+use blobs::Blobs;
+pub use codes::*;
+use metadata::imp::*;
+pub use r#type::*;
+use std::collections::HashMap;
+use strings::Strings;
+pub use tables::*;
+use traits::*;
+
+pub struct Writer {
+ pub blobs: Blobs,
+ pub strings: Strings,
+ pub tables: Tables,
+ pub scopes: HashMap<String, u32>,
+ // TODO: is this faster than jsut using a single HashMap with a (String,String) key?
+ pub type_refs: HashMap<String, HashMap<String, u32>>,
+ pub type_specs: HashMap<Type, u32>,
+}
+
+impl Writer {
+ pub fn new(name: &str) -> Self {
+ let mut writer = Self {
+ blobs: Default::default(),
+ strings: Default::default(),
+ tables: Default::default(),
+ scopes: Default::default(),
+ type_refs: Default::default(),
+ type_specs: Default::default(),
+ };
+
+ writer.tables.TypeDef.push(TypeDef { TypeName: writer.strings.insert("<Module>"), ..Default::default() });
+
+ let name = name.rsplit_once(&['/', '\\']).map_or(name, |(_, name)| name);
+
+ writer.tables.Module.push(Module { Name: writer.strings.insert(name), Mvid: 1, ..Default::default() });
+
+ let name = name.rsplit_once('.').map_or(name, |(_, name)| name);
+
+ writer.tables.Assembly.push(Assembly {
+ Name: writer.strings.insert(name),
+ HashAlgId: 0x00008004,
+ MajorVersion: 0xFF,
+ MinorVersion: 0xFF,
+ BuildNumber: 0xFF,
+ RevisionNumber: 0xFF,
+ Flags: metadata::AssemblyFlags::WindowsRuntime.0,
+ ..Default::default()
+ });
+
+ // Some winmd parsers will fail to read without an `mscorlib` reference. The `insert_module_types` function will typically include it
+ // automatically but a minimal `Module` tree may not add this dependency.
+ writer.insert_scope("System");
+
+ writer
+ }
+
+ pub fn into_stream(self) -> Vec<u8> {
+ file::write(self.tables.into_stream(), self.strings.into_stream(), self.blobs.into_stream())
+ }
+
+ pub fn insert_method_sig(&mut self, call_flags: metadata::MethodCallAttributes, return_type: &Type, param_types: &[Type]) -> u32 {
+ let mut blob = vec![call_flags.0];
+ usize_blob(param_types.len(), &mut blob);
+ self.type_blob(return_type, &mut blob);
+
+ for ty in param_types {
+ self.type_blob(ty, &mut blob);
+ }
+
+ self.blobs.insert(&blob)
+ }
+
+ pub fn insert_field_sig(&mut self, ty: &Type) -> u32 {
+ // TODO: can either cache in Writer, like we do for scopes and type_refs, or regenerate each time.
+ // Profile once we can stress test this with field/method signatures.
+
+ let mut blob = vec![0x6]; // FIELD
+ self.type_blob(ty, &mut blob);
+
+ self.blobs.insert(&blob)
+ }
+
+ fn insert_scope(&mut self, namespace: &str) -> u32 {
+ if let Some(scope) = self.scopes.get(namespace) {
+ *scope
+ } else if namespace == "System" {
+ let scope = ResolutionScope::AssemblyRef(self.tables.AssemblyRef.push2(AssemblyRef {
+ Name: self.strings.insert("mscorlib"),
+ MajorVersion: 4,
+ PublicKeyOrToken: self.blobs.insert(&[0xB7, 0x7A, 0x5C, 0x56, 0x19, 0x34, 0xE0, 0x89]), // TODO: comment on this
+ ..Default::default()
+ }))
+ .encode();
+ self.scopes.insert(namespace.to_string(), scope);
+ scope
+ } else {
+ // TODO: may need to capture the original assembly info for external type_refs.
+ let scope = ResolutionScope::AssemblyRef(self.tables.AssemblyRef.push2(AssemblyRef {
+ Name: self.strings.insert(namespace),
+ MajorVersion: 0xFF,
+ MinorVersion: 0xFF,
+ BuildNumber: 0xFF,
+ RevisionNumber: 0xFF,
+ Flags: metadata::AssemblyFlags::WindowsRuntime.0,
+ ..Default::default()
+ }))
+ .encode();
+ self.scopes.insert(namespace.to_string(), scope);
+ scope
+ }
+ }
+
+ pub fn insert_type_ref(&mut self, namespace: &str, name: &str) -> u32 {
+ if let Some(key) = self.type_refs.get(namespace) {
+ if let Some(reference) = key.get(name) {
+ return *reference;
+ }
+ }
+
+ let scope = self.insert_scope(namespace);
+
+ let reference = TypeDefOrRef::TypeRef(self.tables.TypeRef.push2(TypeRef { TypeName: self.strings.insert(name), TypeNamespace: self.strings.insert(namespace), ResolutionScope: scope })).encode();
+ self.type_refs.entry(namespace.to_string()).or_default().insert(name.to_string(), reference);
+ reference
+ }
+
+ pub fn insert_type_spec(&mut self, ty: Type) -> u32 {
+ if let Some(key) = self.type_specs.get(&ty) {
+ return *key;
+ }
+
+ let mut blob = vec![];
+ self.type_blob(&ty, &mut blob);
+ let signature = self.blobs.insert(&blob);
+
+ let reference = TypeDefOrRef::TypeSpec(self.tables.TypeSpec.push2(TypeSpec { Signature: signature })).encode();
+
+ self.type_specs.insert(ty, reference);
+ reference
+ }
+
+ fn type_blob(&mut self, ty: &Type, blob: &mut Vec<u8>) {
+ match ty {
+ Type::Void => blob.push(ELEMENT_TYPE_VOID),
+ Type::Bool => blob.push(ELEMENT_TYPE_BOOLEAN),
+ Type::Char => blob.push(ELEMENT_TYPE_CHAR),
+ Type::I8 => blob.push(ELEMENT_TYPE_I1),
+ Type::U8 => blob.push(ELEMENT_TYPE_U1),
+ Type::I16 => blob.push(ELEMENT_TYPE_I2),
+ Type::U16 => blob.push(ELEMENT_TYPE_U2),
+ Type::I32 => blob.push(ELEMENT_TYPE_I4),
+ Type::U32 => blob.push(ELEMENT_TYPE_U4),
+ Type::I64 => blob.push(ELEMENT_TYPE_I8),
+ Type::U64 => blob.push(ELEMENT_TYPE_U8),
+ Type::F32 => blob.push(ELEMENT_TYPE_R4),
+ Type::F64 => blob.push(ELEMENT_TYPE_R8),
+ Type::ISize => blob.push(ELEMENT_TYPE_I),
+ Type::USize => blob.push(ELEMENT_TYPE_U),
+ Type::String => blob.push(ELEMENT_TYPE_STRING),
+ Type::IInspectable => blob.push(ELEMENT_TYPE_OBJECT),
+ Type::GUID => {
+ let code = self.insert_type_ref("System", "Guid");
+ blob.push(ELEMENT_TYPE_VALUETYPE);
+ usize_blob(code as usize, blob);
+ }
+ Type::HRESULT => {
+ let code = self.insert_type_ref("Windows.Foundation", "HResult");
+ blob.push(ELEMENT_TYPE_VALUETYPE);
+ usize_blob(code as usize, blob);
+ }
+ Type::TypeRef(ty) => {
+ if !ty.generics.is_empty() {
+ blob.push(ELEMENT_TYPE_GENERICINST);
+ }
+ let code = self.insert_type_ref(&ty.namespace, &ty.name);
+ blob.push(ELEMENT_TYPE_VALUETYPE);
+ usize_blob(code as usize, blob);
+
+ if !ty.generics.is_empty() {
+ usize_blob(ty.generics.len(), blob);
+
+ for ty in &ty.generics {
+ self.type_blob(ty, blob);
+ }
+ }
+ }
+ Type::BSTR => {
+ let code = self.insert_type_ref("Windows.Win32.Foundation", "BSTR");
+ blob.push(ELEMENT_TYPE_VALUETYPE);
+ usize_blob(code as usize, blob);
+ }
+ Type::IUnknown => {
+ let code = self.insert_type_ref("Windows.Win32.Foundation", "IUnknown");
+ blob.push(ELEMENT_TYPE_VALUETYPE);
+ usize_blob(code as usize, blob);
+ }
+ Type::PCWSTR | Type::PWSTR => {
+ let code = self.insert_type_ref("Windows.Win32.Foundation", "PWSTR");
+ blob.push(ELEMENT_TYPE_VALUETYPE);
+ usize_blob(code as usize, blob);
+ }
+ Type::PCSTR | Type::PSTR => {
+ let code = self.insert_type_ref("Windows.Win32.Foundation", "PSTR");
+ blob.push(ELEMENT_TYPE_VALUETYPE);
+ usize_blob(code as usize, blob);
+ }
+ Type::ConstRef(ty) => {
+ usize_blob(ELEMENT_TYPE_CMOD_OPT as usize, blob);
+ usize_blob(self.insert_type_ref("System.Runtime.CompilerServices", "IsConst") as usize, blob);
+ usize_blob(ELEMENT_TYPE_BYREF as usize, blob);
+ self.type_blob(ty, blob);
+ }
+ Type::WinrtArrayRef(ty) => {
+ usize_blob(ELEMENT_TYPE_BYREF as usize, blob);
+ usize_blob(ELEMENT_TYPE_SZARRAY as usize, blob);
+ self.type_blob(ty, blob);
+ }
+ Type::WinrtArray(ty) => {
+ usize_blob(ELEMENT_TYPE_SZARRAY as usize, blob);
+ self.type_blob(ty, blob);
+ }
+ Type::Win32Array(ty, bounds) => {
+ usize_blob(ELEMENT_TYPE_ARRAY as usize, blob);
+ self.type_blob(ty, blob);
+ usize_blob(1, blob); // rank
+ usize_blob(1, blob); // count
+ usize_blob(*bounds, blob);
+ }
+ Type::TypeName => {
+ let code = self.insert_type_ref("System", "Type");
+ blob.push(ELEMENT_TYPE_CLASS);
+ usize_blob(code as usize, blob);
+ }
+ Type::MutPtr(ty, pointers) | Type::ConstPtr(ty, pointers) => {
+ for _ in 0..*pointers {
+ usize_blob(ELEMENT_TYPE_PTR as usize, blob);
+ }
+ self.type_blob(ty, blob);
+ }
+ Type::GenericParam(index) => {
+ blob.push(ELEMENT_TYPE_VAR);
+ usize_blob(*index as usize, blob);
+ }
+ }
+ }
+}
+
+fn round(size: usize, round: usize) -> usize {
+ let round = round - 1;
+ (size + round) & !round
+}
+
+fn usize_blob(value: usize, blob: &mut Vec<u8>) {
+ // See II.23.2 in ECMA-335
+ assert!(value < 0x20000000);
+
+ if value < 0x80 {
+ blob.push(value as u8);
+ } else if value < 0x4000 {
+ blob.push((0x80 | (value & 0x3F00) >> 8) as u8);
+ blob.push((value & 0xFF) as u8);
+ } else {
+ blob.push((0xC0 | (value & 0x1F000000) >> 24) as u8);
+ blob.push(((value & 0xFF0000) >> 16) as u8);
+ blob.push(((value & 0xFF00) >> 8) as u8);
+ blob.push((value & 0xFF) as u8);
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_usize_blob() {
+ let mut blob = vec![];
+ usize_blob(0, &mut blob);
+ usize_blob(1, &mut blob);
+ usize_blob(2, &mut blob);
+
+ usize_blob(0x80 - 2, &mut blob);
+ usize_blob(0x80 - 1, &mut blob);
+ usize_blob(0x80, &mut blob);
+ usize_blob(0x80 + 1, &mut blob);
+ usize_blob(0x80 + 2, &mut blob);
+
+ usize_blob(0x4000 - 2, &mut blob);
+ usize_blob(0x4000 - 1, &mut blob);
+ usize_blob(0x4000, &mut blob);
+ usize_blob(0x4000 + 1, &mut blob);
+ usize_blob(0x4000 + 2, &mut blob);
+
+ usize_blob(0x20000000 - 3, &mut blob);
+ usize_blob(0x20000000 - 2, &mut blob);
+ usize_blob(0x20000000 - 1, &mut blob);
+
+ let mut blob = metadata::Blob::new(0, &blob);
+ assert_eq!(blob.read_usize(), 0);
+ assert_eq!(blob.read_usize(), 1);
+ assert_eq!(blob.read_usize(), 2);
+
+ assert_eq!(blob.read_usize(), 0x80 - 2);
+ assert_eq!(blob.read_usize(), 0x80 - 1);
+ assert_eq!(blob.read_usize(), 0x80);
+ assert_eq!(blob.read_usize(), 0x80 + 1);
+ assert_eq!(blob.read_usize(), 0x80 + 2);
+
+ assert_eq!(blob.read_usize(), 0x4000 - 2);
+ assert_eq!(blob.read_usize(), 0x4000 - 1);
+ assert_eq!(blob.read_usize(), 0x4000);
+ assert_eq!(blob.read_usize(), 0x4000 + 1);
+ assert_eq!(blob.read_usize(), 0x4000 + 2);
+
+ assert_eq!(blob.read_usize(), 0x20000000 - 3);
+ assert_eq!(blob.read_usize(), 0x20000000 - 2);
+ assert_eq!(blob.read_usize(), 0x20000000 - 1);
+
+ assert_eq!(blob.slice.len(), 0);
+ }
+}
diff --git a/vendor/windows-bindgen/src/winmd/writer/strings.rs b/vendor/windows-bindgen/src/winmd/writer/strings.rs
new file mode 100644
index 000000000..1eeae6d43
--- /dev/null
+++ b/vendor/windows-bindgen/src/winmd/writer/strings.rs
@@ -0,0 +1,35 @@
+use super::*;
+use std::collections::hash_map::*;
+
+pub struct Strings {
+ map: HashMap<String, u32>,
+ stream: Vec<u8>,
+}
+
+impl Default for Strings {
+ fn default() -> Self {
+ Self { map: Default::default(), stream: vec![0] }
+ }
+}
+
+impl Strings {
+ pub fn insert(&mut self, value: &str) -> u32 {
+ if value.is_empty() {
+ return 0;
+ }
+
+ match self.map.entry(value.to_string()) {
+ Entry::Vacant(entry) => {
+ let offset = *entry.insert(self.stream.len() as u32);
+ self.stream.extend_from_slice(value.as_bytes());
+ self.stream.push(0);
+ offset
+ }
+ Entry::Occupied(entry) => *entry.get(),
+ }
+ }
+
+ pub fn into_stream(self) -> Vec<u8> {
+ self.stream.into_stream()
+ }
+}
diff --git a/vendor/windows-bindgen/src/winmd/writer/tables.rs b/vendor/windows-bindgen/src/winmd/writer/tables.rs
new file mode 100644
index 000000000..4d4b8e354
--- /dev/null
+++ b/vendor/windows-bindgen/src/winmd/writer/tables.rs
@@ -0,0 +1,361 @@
+#![allow(non_snake_case)]
+
+use super::Write;
+use super::*;
+use metadata::imp::coded_index_size;
+
+#[derive(Default)]
+pub struct Tables {
+ // TODO: use BTreeSet for tables that have a primary key, unless they are naturally sorted.
+ pub Assembly: Vec<Assembly>,
+ pub AssemblyRef: Vec<AssemblyRef>,
+ pub ClassLayout: Vec<ClassLayout>,
+ pub Constant: Vec<Constant>,
+ pub CustomAttribute: Vec<CustomAttribute>,
+ pub Field: Vec<Field>,
+ pub GenericParam: Vec<GenericParam>,
+ pub ImplMap: Vec<ImplMap>,
+ pub InterfaceImpl: Vec<InterfaceImpl>,
+ pub MemberRef: Vec<MemberRef>,
+ pub MethodDef: Vec<MethodDef>,
+ pub Module: Vec<Module>,
+ pub ModuleRef: Vec<ModuleRef>,
+ pub NestedClass: Vec<NestedClass>,
+ pub Param: Vec<Param>,
+ pub Property: Vec<Property>,
+ pub TypeDef: Vec<TypeDef>,
+ pub TypeRef: Vec<TypeRef>,
+ pub TypeSpec: Vec<TypeSpec>,
+}
+
+#[derive(Default)]
+pub struct Assembly {
+ pub HashAlgId: u32,
+ pub MajorVersion: u16,
+ pub MinorVersion: u16,
+ pub BuildNumber: u16,
+ pub RevisionNumber: u16,
+ pub Flags: u32,
+ pub PublicKey: u32,
+ pub Name: u32,
+ pub Culture: u32,
+}
+
+#[derive(Default)]
+pub struct AssemblyRef {
+ pub MajorVersion: u16,
+ pub MinorVersion: u16,
+ pub BuildNumber: u16,
+ pub RevisionNumber: u16,
+ pub Flags: u32,
+ pub PublicKeyOrToken: u32,
+ pub Name: u32,
+ pub Culture: u32,
+ pub HashValue: u32,
+}
+
+#[derive(Default)]
+pub struct ClassLayout {
+ pub PackingSize: u16,
+ pub ClassSize: u32,
+ pub Parent: u32,
+}
+
+#[derive(Default)]
+pub struct Constant {
+ pub Type: u16,
+ pub Parent: u32,
+ pub Value: u32,
+}
+
+#[derive(Default)]
+pub struct CustomAttribute {
+ pub Parent: u32,
+ pub Type: u32,
+ pub Value: u32,
+}
+
+#[derive(Default)]
+pub struct Field {
+ pub Flags: u16,
+ pub Name: u32,
+ pub Signature: u32,
+}
+
+#[derive(Default)]
+pub struct GenericParam {
+ pub Number: u16,
+ pub Flags: u16,
+ pub Owner: u32,
+ pub Name: u32,
+}
+
+#[derive(Default)]
+pub struct ImplMap {
+ pub MappingFlags: u16,
+ pub MemberForwarded: u32,
+ pub ImportName: u32,
+ pub ImportScope: u32,
+}
+
+#[derive(Default)]
+pub struct InterfaceImpl {
+ pub Class: u32,
+ pub Interface: u32,
+}
+
+#[derive(Default)]
+pub struct MemberRef {
+ pub Class: u32,
+ pub Name: u32,
+ pub Signature: u32,
+}
+
+#[derive(Default)]
+pub struct MethodDef {
+ pub RVA: u32,
+ pub ImplFlags: u16,
+ pub Flags: u16,
+ pub Name: u32,
+ pub Signature: u32,
+ pub ParamList: u32,
+}
+
+#[derive(Default)]
+pub struct Module {
+ pub Generation: u16,
+ pub Name: u32,
+ pub Mvid: u32,
+ pub EncId: u32,
+ pub EncBaseId: u32,
+}
+
+#[derive(Default)]
+pub struct ModuleRef {
+ pub Name: u32,
+}
+
+#[derive(Default)]
+pub struct NestedClass {
+ pub NestedClass: u32,
+ pub EnclosingClass: u32,
+}
+
+#[derive(Default)]
+pub struct Param {
+ pub Flags: u16,
+ pub Sequence: u16,
+ pub Name: u32,
+}
+
+#[derive(Default)]
+pub struct Property {
+ pub Flags: u16,
+ pub Name: u32,
+ pub Type: u32,
+}
+
+#[derive(Default)]
+pub struct TypeDef {
+ pub Flags: u32,
+ pub TypeName: u32,
+ pub TypeNamespace: u32,
+ pub Extends: u32,
+ pub FieldList: u32,
+ pub MethodList: u32,
+}
+
+#[derive(Default)]
+pub struct TypeRef {
+ pub ResolutionScope: u32,
+ pub TypeName: u32,
+ pub TypeNamespace: u32,
+}
+
+#[derive(Default)]
+pub struct TypeSpec {
+ pub Signature: u32,
+}
+
+impl Tables {
+ pub fn into_stream(self) -> Vec<u8> {
+ if [self.AssemblyRef.len(), self.ClassLayout.len(), self.Constant.len(), self.CustomAttribute.len(), self.Field.len(), self.GenericParam.len(), self.ImplMap.len(), self.InterfaceImpl.len(), self.MemberRef.len(), self.MethodDef.len(), self.Module.len(), self.ModuleRef.len(), self.NestedClass.len(), self.Param.len(), self.Property.len(), self.TypeDef.len(), self.TypeRef.len(), self.TypeSpec.len()].iter().any(|len| *len > u32::MAX as usize) {
+ panic!("metadata table too large");
+ }
+
+ let resolution_scope = coded_index_size(&[self.Module.len(), self.ModuleRef.len(), self.AssemblyRef.len(), self.TypeRef.len()]);
+
+ let type_def_or_ref = coded_index_size(&[self.TypeDef.len(), self.TypeRef.len(), self.TypeSpec.len()]);
+
+ let has_constant = coded_index_size(&[self.Field.len(), self.Param.len(), self.Property.len()]);
+
+ let type_or_method_def = coded_index_size(&[self.TypeDef.len(), self.MethodDef.len()]);
+
+ let valid_tables: u64 = 1 << 0 | // Module
+ 1 << 0x01 | // TypeRef
+ 1 << 0x02 | // TypeDef
+ 1 << 0x04 | // Field
+ 1 << 0x06 | // MethodDef
+ 1 << 0x08 | // Param
+ 1 << 0x09 | // InterfaceImpl
+ 1 << 0x0A | // MemberRef
+ 1 << 0x0B | // Constant
+ 1 << 0x0C | // CustomAttribute
+ 1 << 0x0F | // ClassLayout
+ 1 << 0x17 | // Property
+ 1 << 0x1A | // ModuleRef
+ 1 << 0x1B | // TypeSpec
+ 1 << 0x1C | // ImplMap
+ 1 << 0x20 | // Assembly
+ 1 << 0x23 | // AssemblyRef
+ 1 << 0x29 | // NestedClass
+ 1 << 0x2A; // GenericParam
+
+ // The table stream header...
+
+ let mut buffer = Vec::new();
+ buffer.write_u32(0); // Reserved
+ buffer.write_u8(2); // MajorVersion
+ buffer.write_u8(0); // MinorVersion
+ buffer.write_u8(0b111); // HeapSizes
+ buffer.write_u8(0); // Reserved
+ buffer.write_u64(valid_tables);
+ buffer.write_u64(0); // Sorted
+
+ // Followed by the length of each of the valid tables...
+
+ buffer.write_u32(self.Module.len() as u32);
+ buffer.write_u32(self.TypeRef.len() as u32);
+ buffer.write_u32(self.TypeDef.len() as u32);
+ buffer.write_u32(self.Field.len() as u32);
+ buffer.write_u32(self.MethodDef.len() as u32);
+ buffer.write_u32(self.Param.len() as u32);
+ buffer.write_u32(self.InterfaceImpl.len() as u32);
+ buffer.write_u32(self.MemberRef.len() as u32);
+ buffer.write_u32(self.Constant.len() as u32);
+ buffer.write_u32(self.CustomAttribute.len() as u32);
+ buffer.write_u32(self.ClassLayout.len() as u32);
+ buffer.write_u32(self.Property.len() as u32);
+ buffer.write_u32(self.ModuleRef.len() as u32);
+ buffer.write_u32(self.TypeSpec.len() as u32);
+ buffer.write_u32(self.ImplMap.len() as u32);
+ buffer.write_u32(self.Assembly.len() as u32);
+ buffer.write_u32(self.AssemblyRef.len() as u32);
+ buffer.write_u32(self.NestedClass.len() as u32);
+ buffer.write_u32(self.GenericParam.len() as u32);
+
+ // Followed by each table's rows...
+
+ for x in self.Module {
+ buffer.write_u16(x.Generation);
+ buffer.write_u32(x.Name);
+ buffer.write_u32(x.Mvid);
+ buffer.write_u32(x.EncId);
+ buffer.write_u32(x.EncBaseId);
+ }
+
+ for x in self.TypeRef {
+ buffer.write_code(x.ResolutionScope, resolution_scope);
+ buffer.write_u32(x.TypeName);
+ buffer.write_u32(x.TypeNamespace);
+ }
+
+ for x in &self.TypeDef {
+ buffer.write_u32(x.Flags);
+ buffer.write_u32(x.TypeName);
+ buffer.write_u32(x.TypeNamespace);
+ buffer.write_code(x.Extends, type_def_or_ref);
+ buffer.write_index(x.FieldList, self.Field.len());
+ buffer.write_index(x.MethodList, self.MethodDef.len());
+ }
+
+ for x in self.Field {
+ buffer.write_u16(x.Flags);
+ buffer.write_u32(x.Name);
+ buffer.write_u32(x.Signature);
+ }
+
+ for x in self.MethodDef {
+ buffer.write_u32(x.RVA);
+ buffer.write_u16(x.ImplFlags);
+ buffer.write_u16(x.Flags);
+ buffer.write_u32(x.Name);
+ buffer.write_u32(x.Signature);
+ buffer.write_index(x.ParamList, self.Param.len());
+ }
+
+ for x in self.Param {
+ buffer.write_u16(x.Flags);
+ buffer.write_u16(x.Sequence);
+ buffer.write_u32(x.Name);
+ }
+
+ for x in self.InterfaceImpl {
+ buffer.write_index(x.Class, self.TypeDef.len());
+ buffer.write_code(x.Interface, type_def_or_ref);
+ }
+
+ for x in self.Constant {
+ buffer.write_u16(x.Type);
+ buffer.write_code(x.Parent, has_constant);
+ buffer.write_u32(x.Value);
+ }
+
+ for x in self.TypeSpec {
+ buffer.write_u32(x.Signature);
+ }
+
+ for x in self.Assembly {
+ buffer.write_u32(x.HashAlgId);
+ buffer.write_u16(x.MajorVersion);
+ buffer.write_u16(x.MinorVersion);
+ buffer.write_u16(x.BuildNumber);
+ buffer.write_u16(x.RevisionNumber);
+ buffer.write_u32(x.Flags);
+ buffer.write_u32(x.PublicKey);
+ buffer.write_u32(x.Name);
+ buffer.write_u32(x.Culture);
+ }
+
+ for x in self.AssemblyRef {
+ buffer.write_u16(x.MajorVersion);
+ buffer.write_u16(x.MinorVersion);
+ buffer.write_u16(x.BuildNumber);
+ buffer.write_u16(x.RevisionNumber);
+ buffer.write_u32(x.Flags);
+ buffer.write_u32(x.PublicKeyOrToken);
+ buffer.write_u32(x.Name);
+ buffer.write_u32(x.Culture);
+ buffer.write_u32(x.HashValue);
+ }
+
+ for x in self.GenericParam {
+ buffer.write_u16(x.Number);
+ buffer.write_u16(x.Flags);
+ buffer.write_code(x.Owner, type_or_method_def);
+ buffer.write_u32(x.Name);
+ }
+
+ // TODO: sort GenericParam table prior to writing. This needs to be done for all tables with a primary index. See II.22
+
+ // TODO: do these get naturally sorted by virtue of how they're pushed into "tables" in type def order?
+
+ // Table Primary Key Column
+ // ClassLayout Parent
+ // Constant Parent
+ // CustomAttribute Parent
+ // DeclSecurity Parent
+ // FieldLayout Field
+ // FieldMarshal Parent
+ // FieldRVA Field
+ // GenericParam Owner
+ // GenericParamConstraint Owner
+ // ImplMap MemberForwarded
+ // InterfaceImpl Class
+ // MethodImpl Class
+ // MethodSemantics Association
+ // NestedClass NestedClass
+
+ buffer.into_stream()
+ }
+}
diff --git a/vendor/windows-bindgen/src/winmd/writer/traits.rs b/vendor/windows-bindgen/src/winmd/writer/traits.rs
new file mode 100644
index 000000000..45304899a
--- /dev/null
+++ b/vendor/windows-bindgen/src/winmd/writer/traits.rs
@@ -0,0 +1,66 @@
+use super::*;
+
+pub trait Write {
+ unsafe fn write_header<T: Sized>(&mut self, value: &T);
+ fn write_u8(&mut self, value: u8);
+ fn write_u16(&mut self, value: u16);
+ fn write_u32(&mut self, value: u32);
+ fn write_u64(&mut self, value: u64);
+ fn write_code(&mut self, value: u32, size: usize);
+ fn write_index(&mut self, index: u32, len: usize);
+ fn into_stream(self) -> Self;
+}
+
+impl Write for Vec<u8> {
+ unsafe fn write_header<T: Sized>(&mut self, value: &T) {
+ self.extend_from_slice(std::slice::from_raw_parts(value as *const _ as _, std::mem::size_of::<T>()));
+ }
+
+ fn write_u8(&mut self, value: u8) {
+ self.extend_from_slice(&value.to_le_bytes());
+ }
+
+ fn write_u16(&mut self, value: u16) {
+ self.extend_from_slice(&value.to_le_bytes());
+ }
+
+ fn write_u32(&mut self, value: u32) {
+ self.extend_from_slice(&value.to_le_bytes());
+ }
+
+ fn write_u64(&mut self, value: u64) {
+ self.extend_from_slice(&value.to_le_bytes());
+ }
+
+ fn write_code(&mut self, value: u32, size: usize) {
+ if size == 2 {
+ self.write_u16(value as u16);
+ } else {
+ self.write_u32(value);
+ }
+ }
+
+ fn write_index(&mut self, index: u32, len: usize) {
+ if len < (1 << 16) {
+ self.write_u16(index as u16 + 1);
+ } else {
+ self.write_u32(index + 1);
+ }
+ }
+
+ fn into_stream(mut self) -> Self {
+ self.resize(round(self.len(), 4), 0);
+ self
+ }
+}
+
+pub trait Push2<T> {
+ fn push2(&mut self, value: T) -> u32;
+}
+
+impl<T> Push2<T> for Vec<T> {
+ fn push2(&mut self, value: T) -> u32 {
+ self.push(value);
+ (self.len() - 1) as u32
+ }
+}
diff --git a/vendor/windows-bindgen/src/winmd/writer/type.rs b/vendor/windows-bindgen/src/winmd/writer/type.rs
new file mode 100644
index 000000000..3f0178654
--- /dev/null
+++ b/vendor/windows-bindgen/src/winmd/writer/type.rs
@@ -0,0 +1,80 @@
+#![allow(dead_code, clippy::upper_case_acronyms)]
+
+#[derive(Clone, Debug, Hash, PartialEq, Eq)]
+pub struct TypeName {
+ pub namespace: String,
+ pub name: String,
+ pub generics: Vec<Type>,
+}
+
+#[derive(Clone, Debug, Hash, PartialEq, Eq)]
+pub enum Type {
+ Void,
+ Bool,
+ Char,
+ I8,
+ U8,
+ I16,
+ U16,
+ I32,
+ U32,
+ I64,
+ U64,
+ F32,
+ F64,
+ ISize,
+ USize,
+ String,
+ GUID,
+ IUnknown,
+ IInspectable,
+ HRESULT,
+ PSTR,
+ PWSTR,
+ PCSTR,
+ PCWSTR,
+ BSTR,
+ TypeName,
+ TypeRef(TypeName),
+ GenericParam(u16),
+ MutPtr(Box<Self>, usize),
+ ConstPtr(Box<Self>, usize),
+ Win32Array(Box<Self>, usize),
+ WinrtArray(Box<Self>),
+ WinrtArrayRef(Box<Self>),
+ ConstRef(Box<Self>),
+}
+
+impl Type {
+ pub fn into_mut_ptr(self) -> Self {
+ match self {
+ Self::MutPtr(ty, count) => Self::MutPtr(ty, count + 1),
+ Self::ConstPtr(ty, count) => Self::MutPtr(ty, count + 1),
+ _ => Self::MutPtr(Box::new(self), 1),
+ }
+ }
+
+ pub fn into_const_ptr(self) -> Self {
+ match self {
+ Self::MutPtr(ty, count) => Self::ConstPtr(ty, count + 1),
+ Self::ConstPtr(ty, count) => Self::ConstPtr(ty, count + 1),
+ _ => Self::ConstPtr(Box::new(self), 1),
+ }
+ }
+
+ pub fn into_array(self, len: usize) -> Self {
+ Self::Win32Array(Box::new(self), len)
+ }
+}
+
+pub struct Signature {
+ pub params: Vec<SignatureParam>,
+ pub return_type: Type,
+ pub call_flags: u8,
+}
+
+// TODO: just Param?
+pub struct SignatureParam {
+ pub name: String,
+ pub ty: Type,
+}
diff --git a/vendor/windows-bindgen/src/winrt_methods.rs b/vendor/windows-bindgen/src/winrt_methods.rs
deleted file mode 100644
index 457f70c38..000000000
--- a/vendor/windows-bindgen/src/winrt_methods.rs
+++ /dev/null
@@ -1,258 +0,0 @@
-use super::*;
-
-// TODO take Signature instead of MethodDef (wherever MethodDef is found)
-pub fn gen(
- gen: &Gen,
- def: TypeDef,
- generic_types: &[Type],
- kind: InterfaceKind,
- method: MethodDef,
- method_names: &mut MethodNames,
- virtual_names: &mut MethodNames,
-) -> TokenStream {
- let signature = gen.reader.method_def_signature(method, generic_types);
- let params = &signature.params;
- let name = method_names.add(gen, method);
- let interface_name = gen.type_def_name(def, generic_types);
- let vname = virtual_names.add(gen, method);
- let generics = gen.constraint_generics(params);
- let where_clause = gen.where_clause(params);
- let mut cfg = gen.reader.signature_cfg(&signature);
- gen.reader
- .type_def_cfg_combine(def, generic_types, &mut cfg);
- let doc = gen.cfg_method_doc(&cfg);
- let features = gen.cfg_features(&cfg);
- let args = gen_winrt_abi_args(gen, params);
- let params = gen_winrt_params(gen, params);
-
- let return_type_tokens = if let Some(return_type) = &signature.return_type {
- let tokens = gen.type_name(return_type);
- if return_type.is_winrt_array() {
- quote! { ::windows::core::Array<#tokens> }
- } else {
- quote! { #tokens }
- }
- } else {
- quote! { () }
- };
-
- let return_arg = if let Some(return_type) = &signature.return_type {
- if return_type.is_winrt_array() {
- let return_type = gen.type_name(return_type);
- quote! { ::windows::core::Array::<#return_type>::set_abi_len(::std::mem::transmute(&mut result__)), result__.as_mut_ptr() as *mut _ as _ }
- } else {
- quote! { &mut result__ }
- }
- } else {
- quote! {}
- };
-
- let vcall = if let Some(return_type) = &signature.return_type {
- if return_type.is_winrt_array() {
- quote! {
- let mut result__ = ::core::mem::MaybeUninit::zeroed();
- (::windows::core::Interface::vtable(this).#vname)(::windows::core::Interface::as_raw(this), #args #return_arg)
- .and_then(|| result__.assume_init())
- }
- } else {
- let return_type = gen.type_name(return_type);
- quote! {
- let mut result__ = ::windows::core::zeroed::<#return_type>();
- (::windows::core::Interface::vtable(this).#vname)(::windows::core::Interface::as_raw(this), #args #return_arg)
- .from_abi(result__)
- }
- }
- } else {
- quote! {
- (::windows::core::Interface::vtable(this).#vname)(::windows::core::Interface::as_raw(this), #args).ok()
- }
- };
-
- match kind {
- InterfaceKind::Default => quote! {
- #doc
- #features
- pub fn #name<#generics>(&self, #params) -> ::windows::core::Result<#return_type_tokens> #where_clause {
- let this = self;
- unsafe {
- #vcall
- }
- }
- },
- InterfaceKind::None | InterfaceKind::Base | InterfaceKind::Overridable => {
- quote! {
- #doc
- #features
- pub fn #name<#generics>(&self, #params) -> ::windows::core::Result<#return_type_tokens> #where_clause {
- let this = &::windows::core::ComInterface::cast::<#interface_name>(self)?;
- unsafe {
- #vcall
- }
- }
- }
- }
- InterfaceKind::Static => {
- quote! {
- #doc
- #features
- pub fn #name<#generics>(#params) -> ::windows::core::Result<#return_type_tokens> #where_clause {
- Self::#interface_name(|this| unsafe { #vcall })
- }
- }
- }
- }
-}
-
-fn gen_winrt_params(gen: &Gen, params: &[SignatureParam]) -> TokenStream {
- let mut result = quote! {};
-
- let mut generic_params = gen.generic_params(params);
- for param in params.iter() {
- let name = gen.param_name(param.def);
- let kind = gen.type_name(&param.ty);
- let default_type = gen.type_default_name(&param.ty);
-
- if gen
- .reader
- .param_flags(param.def)
- .contains(ParamAttributes::INPUT)
- {
- if param.ty.is_winrt_array() {
- result.combine(&quote! { #name: &[#default_type], });
- } else if gen.reader.signature_param_is_convertible(param) {
- let (position, _) = generic_params.next().unwrap();
- let kind: TokenStream = format!("P{position}").into();
- result.combine(&quote! { #name: #kind, });
- } else if gen.reader.type_is_blittable(&param.ty) {
- result.combine(&quote! { #name: #kind, });
- } else {
- result.combine(&quote! { #name: &#kind, });
- }
- } else if param.ty.is_winrt_array() {
- result.combine(&quote! { #name: &mut [#default_type], });
- } else if param.ty.is_winrt_array_ref() {
- result.combine(&quote! { #name: &mut ::windows::core::Array<#kind>, });
- } else {
- result.combine(&quote! { #name: &mut #default_type, });
- }
- }
-
- result
-}
-
-fn gen_winrt_abi_args(gen: &Gen, params: &[SignatureParam]) -> TokenStream {
- let mut tokens = TokenStream::new();
- for param in params {
- let name = gen.param_name(param.def);
-
- let param = if gen
- .reader
- .param_flags(param.def)
- .contains(ParamAttributes::INPUT)
- {
- if param.ty.is_winrt_array() {
- if gen.reader.type_is_blittable(&param.ty) {
- quote! { #name.len() as u32, #name.as_ptr(), }
- } else {
- quote! { #name.len() as u32, ::core::mem::transmute(#name.as_ptr()), }
- }
- } else if gen.reader.signature_param_is_failible_param(param) {
- quote! { #name.try_into_param()?.abi(), }
- } else if gen.reader.signature_param_is_borrowed(param) {
- quote! { #name.into_param().abi(), }
- } else if gen.reader.type_is_blittable(&param.ty) {
- if param.ty.is_winrt_const_ref() {
- quote! { &#name, }
- } else {
- quote! { #name, }
- }
- } else {
- quote! { ::core::mem::transmute_copy(#name), }
- }
- } else if param.ty.is_winrt_array() {
- if gen.reader.type_is_blittable(&param.ty) {
- quote! { #name.len() as u32, #name.as_mut_ptr(), }
- } else {
- quote! { #name.len() as u32, ::core::mem::transmute_copy(&#name), }
- }
- } else if param.ty.is_winrt_array_ref() {
- quote! { #name.set_abi_len(), #name as *mut _ as _, }
- } else if gen.reader.type_is_blittable(&param.ty) {
- quote! { #name, }
- } else {
- quote! { #name as *mut _ as _, }
- };
- tokens.combine(&param);
- }
- tokens
-}
-
-pub fn gen_upcall(gen: &Gen, sig: &Signature, inner: TokenStream) -> TokenStream {
- let invoke_args = sig
- .params
- .iter()
- .map(|param| gen_winrt_invoke_arg(gen, param));
-
- match &sig.return_type {
- Some(return_type) if return_type.is_winrt_array() => {
- quote! {
- match #inner(#(#invoke_args,)*) {
- ::core::result::Result::Ok(ok__) => {
- let (ok_data__, ok_data_len__) = ok__.into_abi();
- // use `core::ptr::write` since `result` could be uninitialized
- ::core::ptr::write(result__, ok_data__);
- ::core::ptr::write(result_size__, ok_data_len__);
- ::windows::core::HRESULT(0)
- }
- ::core::result::Result::Err(err) => err.into()
- }
- }
- }
- Some(_) => {
- quote! {
- match #inner(#(#invoke_args,)*) {
- ::core::result::Result::Ok(ok__) => {
- // use `core::ptr::write` since `result` could be uninitialized
- ::core::ptr::write(result__, ::core::mem::transmute_copy(&ok__));
- ::core::mem::forget(ok__);
- ::windows::core::HRESULT(0)
- }
- ::core::result::Result::Err(err) => err.into()
- }
- }
- }
- None => quote! {
- #inner(#(#invoke_args,)*).into()
- },
- }
-}
-
-fn gen_winrt_invoke_arg(gen: &Gen, param: &SignatureParam) -> TokenStream {
- let name = gen.param_name(param.def);
- let abi_size_name: TokenStream =
- format!("{}_array_size", gen.reader.param_name(param.def)).into();
-
- if gen
- .reader
- .param_flags(param.def)
- .contains(ParamAttributes::INPUT)
- {
- if param.ty.is_winrt_array() {
- quote! { ::core::slice::from_raw_parts(::core::mem::transmute_copy(&#name), #abi_size_name as _) }
- } else if gen.reader.type_is_primitive(&param.ty) {
- quote! { #name }
- } else if param.ty.is_winrt_const_ref() {
- quote! { ::core::mem::transmute_copy(&#name) }
- } else if gen.reader.type_is_nullable(&param.ty) {
- quote! { ::windows::core::from_raw_borrowed(&#name) }
- } else {
- quote! { ::core::mem::transmute(&#name) }
- }
- } else if param.ty.is_winrt_array() {
- quote! { ::core::slice::from_raw_parts_mut(::core::mem::transmute_copy(&#name), #abi_size_name as _) }
- } else if param.ty.is_winrt_array_ref() {
- quote! { ::windows::core::ArrayProxy::from_raw_parts(::core::mem::transmute_copy(&#name), #abi_size_name).as_array() }
- } else {
- quote! { ::core::mem::transmute_copy(&#name) }
- }
-}