cli_xtask/workspace/
package.rs1use cargo_metadata::{camino::Utf8Path, Package};
2
3pub trait PackageExt {
5 fn each_feature(&'_ self) -> EachFeature<'_>;
7
8 fn root_directory(&self) -> &Utf8Path;
10}
11
12impl PackageExt for Package {
13 fn each_feature(&'_ self) -> EachFeature<'_> {
14 let mut features = self.features.keys().collect::<Vec<_>>();
15 features.sort();
16 EachFeature {
17 all_features: true,
18 no_default_features: true,
19 features: features.into_iter(),
20 }
21 }
22
23 fn root_directory(&self) -> &Utf8Path {
24 self.manifest_path.parent().unwrap()
26 }
27}
28
29#[derive(Debug)]
33pub struct EachFeature<'a> {
34 all_features: bool,
35 features: std::vec::IntoIter<&'a String>,
36 no_default_features: bool,
37}
38
39impl<'a> Iterator for EachFeature<'a> {
40 type Item = FeatureOption<'a>;
41
42 fn next(&mut self) -> Option<Self::Item> {
43 if self.all_features {
44 self.all_features = false;
45 return Some(FeatureOption::AllFeatures);
46 }
47 if self.no_default_features {
48 self.no_default_features = false;
49 return Some(FeatureOption::NoDefaultFeatures);
50 }
51 if let Some(feature) = self.features.next() {
52 return Some(FeatureOption::Features(vec![feature]));
53 }
54 None
55 }
56}
57
58#[derive(Debug, Clone)]
60pub enum FeatureOption<'a> {
61 AllFeatures,
63 NoDefaultFeatures,
65 Features(Vec<&'a str>),
67}
68
69impl<'a> FeatureOption<'a> {
70 pub fn to_args(&self) -> Vec<&'a str> {
72 match self {
73 Self::AllFeatures => vec!["--all-features"],
74 Self::NoDefaultFeatures => vec!["--no-default-features"],
75 Self::Features(features) => {
76 let mut args = Vec::with_capacity(features.len() * 2 + 1);
77 for feature in features {
78 args.extend(["--features", feature]);
79 }
80 args.push("--no-default-features");
81 args
82 }
83 }
84 }
85}