Skip to main content

winpty_rs_cppwinrt/
lib.rs

1#![doc = include_str!("../readme.md")]
2#![cfg(windows)]
3
4/// Calls the C++/WinRT compiler with the given arguments.
5///
6/// Use `cppwinrt(["-help"])` for available options.
7#[track_caller]
8pub fn cppwinrt<I, S>(args: I) -> String
9where
10    I: IntoIterator<Item = S>,
11    S: AsRef<std::ffi::OsStr>,
12{
13    let mut path = std::env::temp_dir();
14    path.push(unique());
15    std::fs::create_dir_all(&path).unwrap();
16    path.push("cppwinrt.exe");
17    std::fs::write(&path, std::include_bytes!("../cppwinrt.exe")).unwrap();
18
19    let mut command = std::process::Command::new(&path);
20    command.args(args);
21    let output = command.output().expect("failed to run cppwinrt");
22    _ = std::fs::remove_file(path);
23
24    if output.status.success() {
25        String::from_utf8_lossy(&output.stdout).to_string()
26    } else {
27        panic!("{}", String::from_utf8_lossy(&output.stderr))
28    }
29}
30
31fn unique() -> String {
32    #[repr(C)]
33    #[derive(Default)]
34    pub struct Guid {
35        pub data1: u32,
36        pub data2: u16,
37        pub data3: u16,
38        pub data4: [u8; 8],
39    }
40
41     winpty_rs_windows_link::link!("ole32.dll" "system" fn CoCreateGuid(pguid: *mut Guid) -> i32);
42    let mut guid = Guid::default();
43    unsafe { CoCreateGuid(&mut guid) };
44
45    format!(
46        "{:08X?}-{:04X?}-{:04X?}-{:02X?}{:02X?}-{:02X?}{:02X?}{:02X?}{:02X?}{:02X?}{:02X?}",
47        guid.data1,
48        guid.data2,
49        guid.data3,
50        guid.data4[0],
51        guid.data4[1],
52        guid.data4[2],
53        guid.data4[3],
54        guid.data4[4],
55        guid.data4[5],
56        guid.data4[6],
57        guid.data4[7]
58    )
59}
60
61#[cfg(test)]
62mod tests {
63    use crate::*;
64
65    #[test]
66    #[should_panic(expected = "'-invalid' is not supported")]
67    fn invalid_arg() {
68        cppwinrt(["-invalid"]);
69    }
70
71    #[test]
72    fn unexpected_version() {
73        let ok = cppwinrt(["-help"]);
74        assert!(ok.contains("2.0.250303.1"), "unexpected version");
75    }
76}