use std::collections::HashSet; use clap::Parser; use xtask::bench::BenchDeriveArgs; /// List features available in the workspace #[derive(Parser, Debug)] struct ListFeaturesDeriveArgs { /// Feature to exclude from the list. Repeat the argument to exclude multiple features #[arg(short, long)] exclude_feature: Vec, } /// Utilitary commands #[derive(Parser, Debug)] #[command(author, version, about, long_about)] #[command(name = "cargo xtask")] #[command(bin_name = "cargo xtask")] enum Command { ListFeatures(ListFeaturesDeriveArgs), Bench(BenchDeriveArgs), } fn main() -> anyhow::Result<()> { let args = Command::parse(); match args { Command::ListFeatures(args) => list_features(args), Command::Bench(args) => xtask::bench::run(args)?, } Ok(()) } fn list_features(args: ListFeaturesDeriveArgs) { let exclude_features: HashSet<_> = args.exclude_feature.into_iter().collect(); let metadata = cargo_metadata::MetadataCommand::new().no_deps().exec().unwrap(); let features: Vec = metadata .packages .iter() .flat_map(|package| package.features.keys()) .filter(|feature| !exclude_features.contains(feature.as_str())) .map(|s| s.to_owned()) .collect(); let features = features.join(" "); println!("{features}") }