winrt_gen/
dependencies.rs

1use std::collections::BTreeSet;
2use std::io;
3use std::path::{Path, PathBuf};
4
5/// Returns the paths to resolved dependencies
6pub fn expand_paths<P: AsRef<Path>>(
7    dependency: P,
8    result: &mut BTreeSet<PathBuf>,
9    recurse: bool,
10) -> io::Result<()> {
11    let path = dependency.as_ref();
12
13    if path.is_dir() {
14        let paths = std::fs::read_dir(path)?;
15        for path in paths {
16            let path = path.expect("Could not read directory entry");
17            let path = path.path();
18            if path.is_file() && path.extension() == Some(std::ffi::OsStr::new("winmd")) {
19                result.insert(path);
20            } else if path.is_dir() && recurse {
21                expand_paths(path, result, recurse)?
22            }
23        }
24        Ok(())
25    } else if path.is_file() && path.extension() == Some(std::ffi::OsStr::new("winmd")) {
26        result.insert(path.to_path_buf());
27        Ok(())
28    } else if !path.exists() {
29        Err(io::Error::new(
30            io::ErrorKind::NotFound,
31            format!("dependency path '{}' does not exist", path.display()),
32        ))
33    } else {
34        Err(io::Error::new(
35            io::ErrorKind::NotFound,
36            format!(
37                "dependency path '{}' is not a directory or winmd file",
38                path.display()
39            ),
40        ))
41    }
42}
43
44pub fn nuget_root() -> PathBuf {
45    let mut path = workspace_root();
46    path.push("target");
47    path.push("nuget");
48    path
49}
50
51pub fn system_metadata_root() -> Option<PathBuf> {
52    let wind_dir_env = std::env::var("windir").ok()?;
53    let mut path = PathBuf::from(wind_dir_env);
54    path.push(SYSTEM32);
55    path.push("winmetadata");
56
57    Some(path)
58}
59
60fn workspace_root() -> PathBuf {
61    let output = std::process::Command::new("cargo")
62        .args(&["metadata"])
63        .output()
64        .expect("Could not run `cargo metadata`")
65        .stdout;
66    let value: serde_json::Map<String, serde_json::Value> =
67        serde_json::from_slice(&output).expect("`cargo metadata` did not return json.");
68    let path = match value.get("workspace_root") {
69        Some(serde_json::Value::String(s)) => s,
70        _ => panic!("`cargo metadata` json was not in expected format"),
71    };
72    PathBuf::from(path)
73}
74
75#[cfg(target_pointer_width = "64")]
76const SYSTEM32: &str = "System32";
77
78#[cfg(target_pointer_width = "32")]
79const SYSTEM32: &str = "SysNative";