1extern crate proc_macro;
2use proc_macro::TokenStream;
3
4#[proc_macro]
5pub fn get_enabled_features(_cargo_file: TokenStream) -> TokenStream {
6 let features_gen_code = r#"
8 let enabled_features = (|| -> Vec<&'static str>{
9 macro_rules! make_feat_list {
10 ($($feat:expr),*) => {
11 vec![
12 $(
13 #[cfg(feature = $feat)]
14 $feat,
15 )*
16 ]
17 }
18 }
19 make_feat_list!(FEATURES)
20 })();
21 "#;
22
23 let mut args = std::env::args().skip_while(|val| !val.starts_with("--manifest-path"));
24
25 let mut cmd = cargo_metadata::MetadataCommand::new();
26 match args.next() {
27 Some(ref p) if p == "--manifest-path" => {
28 cmd.manifest_path(args.next().unwrap());
29 }
30 Some(p) => {
31 cmd.manifest_path(p.trim_start_matches("--manifest-path="));
32 }
33 None => {}
34 };
35
36 let metadata = cmd
37 .features(cargo_metadata::CargoOpt::AllFeatures)
38 .exec()
39 .unwrap();
40
41 let root_package_features = format!(
43 "{:?}",
44 metadata
45 .root_package()
46 .unwrap()
47 .features
48 .keys()
49 .cloned()
50 .collect::<Vec<String>>()
51 );
52
53 let slice_features = &root_package_features[1..root_package_features.len() - 1];
55
56 let features_gen_code = features_gen_code.replace("FEATURES", slice_features);
57
58 features_gen_code.parse().unwrap()
59}