diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml index 3a630abaef..8cc66bdaf8 100644 --- a/.github/workflows/doc.yml +++ b/.github/workflows/doc.yml @@ -20,6 +20,13 @@ jobs: uses: actions/checkout@v4 - name: Check run: cargo doc --no-deps -p windows + - name: Doctests + run: > + cargo test --doc -p windows + -F Data_Xml_Dom + -F Win32_Security + -F Win32_System_Threading + -F Win32_UI_WindowsAndMessaging windows-sys: name: windows-sys @@ -29,3 +36,45 @@ jobs: uses: actions/checkout@v4 - name: Check run: cargo doc --no-deps -p windows-sys + - name: Doctests + run: > + cargo test --doc -p windows-sys + -F Win32_Security + -F Win32_System_Threading + -F Win32_UI_WindowsAndMessaging + + other-crates: + runs-on: windows-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Check + run: > + cargo doc --no-deps + -p windows-bindgen + -p windows-core + -p cppwinrt + -p windows-implement + -p windows-interface + -p windows-metadata + -p windows-registry + -p windows-result + -p windows-strings + -p windows-targets + -p windows-version + + - name: Doctests + run: > + cargo test --doc + -p windows-bindgen + -p windows-core + -p cppwinrt + -p windows-implement + -p windows-interface + -p windows-metadata + -p windows-registry + -p windows-result + -p windows-strings + -p windows-targets + -p windows-version diff --git a/crates/libs/bindgen/readme.md b/crates/libs/bindgen/readme.md index 5647260723..671a4c1531 100644 --- a/crates/libs/bindgen/readme.md +++ b/crates/libs/bindgen/readme.md @@ -18,7 +18,7 @@ version = "0.58" Generates Rust bindings in a build script or test as needed: -```rust,no_run +```rust,ignore #[test] fn bindgen() { let args = [ diff --git a/crates/libs/bindgen/src/lib.rs b/crates/libs/bindgen/src/lib.rs index e9db3a17b9..4ecdc572d9 100644 --- a/crates/libs/bindgen/src/lib.rs +++ b/crates/libs/bindgen/src/lib.rs @@ -1,6 +1,4 @@ -/*! -Learn more about Rust for Windows here: -*/ +#![doc = include_str!("../readme.md")] mod args; mod error; diff --git a/crates/libs/core/readme.md b/crates/libs/core/readme.md index 060034beba..0b7035b0d3 100644 --- a/crates/libs/core/readme.md +++ b/crates/libs/core/readme.md @@ -1,86 +1,7 @@ -## Rust for Windows +## windows-core -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. +Core primitives for the [windows](https://crates.io/crates/windows) crate. * [Getting started](https://kennykerr.ca/rust-getting-started/) * [Samples](https://github.com/microsoft/windows-rs/tree/0.58.0/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.58" -features = [ - "Data_Xml_Dom", - "Win32_Security", - "Win32_System_Threading", - "Win32_UI_WindowsAndMessaging", -] -``` - -Make use of any Windows APIs as needed: - -```rust,no_run -use windows::{ - core::*, Data::Xml::Dom::*, Win32::Foundation::*, Win32::System::Threading::*, - Win32::UI::WindowsAndMessaging::*, -}; - -fn main() -> Result<()> { - let doc = XmlDocument::new()?; - doc.LoadXml(h!("hello world"))?; - - let root = doc.DocumentElement()?; - assert!(root.NodeName()? == "html"); - assert!(root.InnerText()? == "hello world"); - - unsafe { - let event = CreateEventW(None, true, false, None)?; - SetEvent(event)?; - WaitForSingleObject(event, 0); - CloseHandle(event)?; - - MessageBoxA(None, s!("Ansi"), s!("Caption"), MB_OK); - MessageBoxW(None, w!("Wide"), w!("Caption"), MB_OK); - } - - Ok(()) -} -``` - -## windows-sys - -The `windows-sys` crate is a zero-overhead fallback for the most demanding situations and primarily where the absolute best compile time is essential. It only includes function declarations (externs), structs, and constants. No convenience helpers, traits, or wrappers are provided. - -Start by adding the following to your Cargo.toml file: - -```toml -[dependencies.windows-sys] -version = "0.59" -features = [ - "Win32_Security", - "Win32_System_Threading", - "Win32_UI_WindowsAndMessaging", -] -``` - -Make use of any Windows APIs as needed: - -```rust,no_run -use windows_sys::{ - core::*, Win32::Foundation::*, Win32::System::Threading::*, Win32::UI::WindowsAndMessaging::*, -}; - -fn main() { - unsafe { - let event = CreateEventW(std::ptr::null(), 1, 0, std::ptr::null()); - SetEvent(event); - WaitForSingleObject(event, 0); - CloseHandle(event); - - MessageBoxA(0 as _, s!("Ansi"), s!("Caption"), MB_OK); - MessageBoxW(0 as _, w!("Wide"), w!("Caption"), MB_OK); - } -} -``` diff --git a/crates/libs/core/src/lib.rs b/crates/libs/core/src/lib.rs index d8a2b77f87..962e2eb6af 100644 --- a/crates/libs/core/src/lib.rs +++ b/crates/libs/core/src/lib.rs @@ -1,7 +1,4 @@ -/*! -Learn more about Rust for Windows here: -*/ - +#![doc = include_str!("../readme.md")] #![doc(html_no_source)] #![allow(non_snake_case)] #![cfg_attr( diff --git a/crates/libs/cppwinrt/readme.md b/crates/libs/cppwinrt/readme.md index 2182d9ad8b..c05bcdcdba 100644 --- a/crates/libs/cppwinrt/readme.md +++ b/crates/libs/cppwinrt/readme.md @@ -16,12 +16,10 @@ version = "0.1" Use `cppwinrt` function as needed: ```rust -fn main() { - match cppwinrt::cppwinrt(["-help"]) { - Ok(output) => println!("{output}"), - Err(error) => println!("{error}"), - }; -} +match cppwinrt::cppwinrt(["-help"]) { + Ok(output) => println!("{output}"), + Err(error) => println!("{error}"), +}; ``` Source: diff --git a/crates/libs/cppwinrt/src/lib.rs b/crates/libs/cppwinrt/src/lib.rs index 655ccc2ca3..e82643e2da 100644 --- a/crates/libs/cppwinrt/src/lib.rs +++ b/crates/libs/cppwinrt/src/lib.rs @@ -1,7 +1,4 @@ -/*! -Learn more about Rust for Windows here: -*/ - +#![doc = include_str!("../readme.md")] #![cfg(windows)] const VERSION: &str = "2.0.240405.15"; diff --git a/crates/libs/implement/src/lib.rs b/crates/libs/implement/src/lib.rs index 024263085b..55847b8ecf 100644 --- a/crates/libs/implement/src/lib.rs +++ b/crates/libs/implement/src/lib.rs @@ -1,6 +1,8 @@ -/*! -Learn more about Rust for Windows here: -*/ +//! Implement COM interfaces for Rust types. +//! +//! Take a look at [macro@implement] for an example. +//! +//! Learn more about Rust for Windows here: use quote::{quote, ToTokens}; diff --git a/crates/libs/interface/src/lib.rs b/crates/libs/interface/src/lib.rs index 2e6307f200..c2341b6c85 100644 --- a/crates/libs/interface/src/lib.rs +++ b/crates/libs/interface/src/lib.rs @@ -1,6 +1,8 @@ -/*! -Learn more about Rust for Windows here: -*/ +//! Define COM interfaces to call or implement. +//! +//! Take a look at [macro@interface] for an example. +//! +//! Learn more about Rust for Windows here: use quote::quote; use syn::spanned::Spanned; diff --git a/crates/libs/metadata/src/lib.rs b/crates/libs/metadata/src/lib.rs index c7ef6c1f16..01ddd4728d 100644 --- a/crates/libs/metadata/src/lib.rs +++ b/crates/libs/metadata/src/lib.rs @@ -1,7 +1,4 @@ -/*! -Learn more about Rust for Windows here: -*/ - +#![doc = include_str!("../readme.md")] #![doc(hidden)] use std::cmp::Ordering; diff --git a/crates/libs/registry/src/lib.rs b/crates/libs/registry/src/lib.rs index 44ba2f4982..cf35f9d628 100644 --- a/crates/libs/registry/src/lib.rs +++ b/crates/libs/registry/src/lib.rs @@ -1,7 +1,4 @@ -/*! -Learn more about Rust for Windows here: -*/ - +#![doc = include_str!("../readme.md")] #![cfg(windows)] #![no_std] diff --git a/crates/libs/result/src/lib.rs b/crates/libs/result/src/lib.rs index c636a52c53..fcea7ce7b5 100644 --- a/crates/libs/result/src/lib.rs +++ b/crates/libs/result/src/lib.rs @@ -1,7 +1,4 @@ -/*! -Learn more about Rust for Windows here: -*/ - +#![doc = include_str!("../readme.md")] #![cfg_attr( windows_debugger_visualizer, debugger_visualizer(natvis_file = "../.natvis") diff --git a/crates/libs/strings/src/lib.rs b/crates/libs/strings/src/lib.rs index 19f84039ad..12dc81321e 100644 --- a/crates/libs/strings/src/lib.rs +++ b/crates/libs/strings/src/lib.rs @@ -1,7 +1,4 @@ -/*! -Learn more about Rust for Windows here: -*/ - +#![doc = include_str!("../readme.md")] #![cfg(windows)] #![allow(non_snake_case)] #![cfg_attr( diff --git a/crates/libs/sys/readme.md b/crates/libs/sys/readme.md index 7a1e893961..06076876ac 100644 --- a/crates/libs/sys/readme.md +++ b/crates/libs/sys/readme.md @@ -1,59 +1,12 @@ -## 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/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.59.0/crates/samples) -* [Releases](https://github.com/microsoft/windows-rs/releases) -* [Feature search](https://microsoft.github.io/windows-rs/features/#/0.59.0) - -Start by adding the following to your Cargo.toml file: - -```toml -[dependencies.windows] -version = "0.58" -features = [ - "Data_Xml_Dom", - "Win32_Security", - "Win32_System_Threading", - "Win32_UI_WindowsAndMessaging", -] -``` - -Make use of any Windows APIs as needed: - -```rust,no_run -use windows::{ - core::*, Data::Xml::Dom::*, Win32::Foundation::*, Win32::System::Threading::*, - Win32::UI::WindowsAndMessaging::*, -}; - -fn main() -> Result<()> { - let doc = XmlDocument::new()?; - doc.LoadXml(h!("hello world"))?; - - let root = doc.DocumentElement()?; - assert!(root.NodeName()? == "html"); - assert!(root.InnerText()? == "hello world"); - - unsafe { - let event = CreateEventW(None, true, false, None)?; - SetEvent(event)?; - WaitForSingleObject(event, 0); - CloseHandle(event)?; - - MessageBoxA(None, s!("Ansi"), s!("Caption"), MB_OK); - MessageBoxW(None, w!("Wide"), w!("Caption"), MB_OK); - } - - Ok(()) -} -``` - ## windows-sys The `windows-sys` crate is a zero-overhead fallback for the most demanding situations and primarily where the absolute best compile time is essential. It only includes function declarations (externs), structs, and constants. No convenience helpers, traits, or wrappers are provided. +- [Getting started](https://kennykerr.ca/rust-getting-started/) +- [Samples](https://github.com/microsoft/windows-rs/tree/0.59.0/crates/samples) +- [Releases](https://github.com/microsoft/windows-rs/releases) +- [Feature search](https://microsoft.github.io/windows-rs/features/#/0.59.0) + Start by adding the following to your Cargo.toml file: ```toml diff --git a/crates/libs/sys/src/lib.rs b/crates/libs/sys/src/lib.rs index 396dd24e1b..43fa45204e 100644 --- a/crates/libs/sys/src/lib.rs +++ b/crates/libs/sys/src/lib.rs @@ -1,9 +1,13 @@ -/*! -Learn more about Rust for Windows here: - -[Feature search](https://microsoft.github.io/windows-rs/features/#/0.59.0) -*/ - +#![cfg_attr( + all( + feature = "Win32_Security", + feature = "Win32_System_Threading", + feature = "Win32_UI_WindowsAndMessaging", + ), + doc = include_str!("../readme.md") +)] +// fallback if not all features are enabled +#![cfg_attr(not(all(feature = "Win32_Security", feature = "Win32_System_Threading", feature = "Win32_UI_WindowsAndMessaging",)), doc = "Learn more about Rust for Windows here: \n\n[Feature search](https://microsoft.github.io/windows-rs/features/#/0.58.0)")] #![no_std] #![doc(html_no_source)] #![allow(non_snake_case, non_upper_case_globals, non_camel_case_types, missing_docs, clippy::all)] diff --git a/crates/libs/targets/readme.md b/crates/libs/targets/readme.md index b7cb6979d7..7ac5c64cf8 100644 --- a/crates/libs/targets/readme.md +++ b/crates/libs/targets/readme.md @@ -1,10 +1,11 @@ ## Import libs for Windows -The [windows-targets](https://crates.io/crates/windows-targets) crate includes import libs, supports semantic versioning, and optional support for raw-dylib. +The [windows-targets](https://crates.io/crates/windows-targets) crate includes import libs, supports semantic versioning, and optional support for raw-dylib. * [Getting started](https://kennykerr.ca/rust-getting-started/) * [Samples](https://github.com/microsoft/windows-rs/tree/0.58.0/crates/samples) * [Releases](https://github.com/microsoft/windows-rs/releases) +* [Understanding the `windows-targets` crate](https://kennykerr.ca/rust-getting-started/understanding-windows-targets.html) Start by adding the following to your Cargo.toml file: @@ -15,14 +16,12 @@ version = "0.52" Use the `link` macro to define the external functions you wish to call: -```rust,no_run +```rust windows_targets::link!("kernel32.dll" "system" fn SetLastError(code: u32)); windows_targets::link!("kernel32.dll" "system" fn GetLastError() -> u32); -fn main() { - unsafe { - SetLastError(1234); - assert_eq!(GetLastError(), 1234); - } +unsafe { + SetLastError(1234); + assert_eq!(GetLastError(), 1234); } ``` diff --git a/crates/libs/targets/src/lib.rs b/crates/libs/targets/src/lib.rs index e4751989f1..39ae950e6c 100644 --- a/crates/libs/targets/src/lib.rs +++ b/crates/libs/targets/src/lib.rs @@ -1,7 +1,4 @@ -/*! -Learn more about Rust for Windows here: -*/ - +#![doc = include_str!("../readme.md")] #![no_std] /// Defines an external function to import. diff --git a/crates/libs/version/readme.md b/crates/libs/version/readme.md index 2d50f897de..344fae4675 100644 --- a/crates/libs/version/readme.md +++ b/crates/libs/version/readme.md @@ -2,9 +2,9 @@ The [windows-version](https://crates.io/crates/windows-version) crate provides reliable operating system version information without the need for application manifest files. -* [Getting started](https://kennykerr.ca/rust-getting-started/) -* [Samples](https://github.com/microsoft/windows-rs/tree/0.58.0/crates/samples) -* [Releases](https://github.com/microsoft/windows-rs/releases) +- [Getting started](https://kennykerr.ca/rust-getting-started/) +- [Samples](https://github.com/microsoft/windows-rs/tree/0.58.0/crates/samples) +- [Releases](https://github.com/microsoft/windows-rs/releases) Start by adding the following to your Cargo.toml file: @@ -15,18 +15,16 @@ version = "0.1" Make use of Windows version information as needed: -```rust,no_run +```rust use windows_version::*; -fn main() { - println!("Current version: {:?}", OsVersion::current()); +println!("Current version: {:?}", OsVersion::current()); - if is_server() { - println!("Running on a Windows Server release."); - } +if is_server() { + println!("Running on a Windows Server release."); +} - if OsVersion::current() >= OsVersion::new(10, 0, 0, 12345) { - println!("Can use a feature available on this version or later.") - } +if OsVersion::current() >= OsVersion::new(10, 0, 0, 12345) { + println!("Can use a feature available on this version or later.") } ``` diff --git a/crates/libs/version/src/lib.rs b/crates/libs/version/src/lib.rs index 3209fc1d72..5b197c9a44 100644 --- a/crates/libs/version/src/lib.rs +++ b/crates/libs/version/src/lib.rs @@ -1,7 +1,4 @@ -/*! -Learn more about Rust for Windows here: -*/ - +#![doc = include_str!("../readme.md")] #![cfg(windows)] #![cfg_attr(not(test), no_std)] diff --git a/crates/libs/windows/readme.md b/crates/libs/windows/readme.md index c61e93cbc9..3086da6113 100644 --- a/crates/libs/windows/readme.md +++ b/crates/libs/windows/readme.md @@ -49,39 +49,3 @@ fn main() -> Result<()> { Ok(()) } ``` - -## windows-sys - -The `windows-sys` crate is a zero-overhead fallback for the most demanding situations and primarily where the absolute best compile time is essential. It only includes function declarations (externs), structs, and constants. No convenience helpers, traits, or wrappers are provided. - -Start by adding the following to your Cargo.toml file: - -```toml -[dependencies.windows-sys] -version = "0.59" -features = [ - "Win32_Security", - "Win32_System_Threading", - "Win32_UI_WindowsAndMessaging", -] -``` - -Make use of any Windows APIs as needed: - -```rust,no_run -use windows_sys::{ - core::*, Win32::Foundation::*, Win32::System::Threading::*, Win32::UI::WindowsAndMessaging::*, -}; - -fn main() { - unsafe { - let event = CreateEventW(std::ptr::null(), 1, 0, std::ptr::null()); - SetEvent(event); - WaitForSingleObject(event, 0); - CloseHandle(event); - - MessageBoxA(0 as _, s!("Ansi"), s!("Caption"), MB_OK); - MessageBoxW(0 as _, w!("Wide"), w!("Caption"), MB_OK); - } -} -``` diff --git a/crates/libs/windows/src/lib.rs b/crates/libs/windows/src/lib.rs index 01e207a06d..7127344120 100644 --- a/crates/libs/windows/src/lib.rs +++ b/crates/libs/windows/src/lib.rs @@ -1,11 +1,16 @@ #![cfg_attr(docsrs, doc = "This is a stub. The latest API documentation is here: ")] #![cfg_attr(docsrs, doc = "")] -/*! -Learn more about Rust for Windows here: - -[Feature search](https://microsoft.github.io/windows-rs/features/#/0.58.0) -*/ - +#![cfg_attr( + all( + feature = "Data_Xml_Dom", + feature = "Win32_Security", + feature = "Win32_System_Threading", + feature = "Win32_UI_WindowsAndMessaging", + ), + doc = include_str!("../readme.md"), +)] +// fallback if not all features are enabled +#![cfg_attr(all(not(all(feature = "Data_Xml_Dom", feature = "Win32_Security", feature = "Win32_System_Threading", feature = "Win32_UI_WindowsAndMessaging",)), not(docsrs),), doc = "Learn more about Rust for Windows here: \n\n[Feature search](https://microsoft.github.io/windows-rs/features/#/0.58.0)")] #![cfg(windows)] #![doc(html_no_source)] #![allow(non_snake_case, clashing_extern_declarations, non_upper_case_globals, non_camel_case_types, missing_docs, clippy::all)]