use std::{collections::HashMap, process::Command};
use serde::Deserialize;
#[derive(Clone, Debug, Default, Deserialize)]
pub struct Metadata {
pub packages: Vec<Package>,
}
#[derive(Clone, Debug, Default, Deserialize)]
pub struct Package {
pub name: String,
pub features: HashMap<String, Vec<String>>,
}
pub fn get_metadata(path: &str) -> Metadata {
let path = path.strip_prefix("file://").unwrap_or(path);
let Ok(out) = Command::new("cargo")
.args(["metadata", "--manifest-path", path])
.output()
else {
return Metadata::default();
};
let Ok(out) = str::from_utf8(&out.stdout) else {
return Metadata::default();
};
let Ok(metadata) = serde_json::from_str(out) else {
return Metadata::default();
};
metadata
}
#[cfg(test)]
mod test {
use crate::metadata::get_metadata;
#[test]
fn test() {
let md = get_metadata("test_fixtures/features/Cargo.toml");
assert!(!md.packages.is_empty());
let dep = md
.packages
.iter()
.find(|p| p.name == "serde")
.expect("serde package not found in metadata");
assert!(dep.features.contains_key("derive"));
}
#[test]
fn test_by_url() {
let md = get_metadata("file://test_fixtures/features/Cargo.toml");
assert!(!md.packages.is_empty());
let dep = md
.packages
.iter()
.find(|p| p.name == "serde")
.expect("serde package not found in metadata");
assert!(dep.features.contains_key("derive"));
}
}