1use super::*;
2
3impl Writer {
4 pub fn write_cfg<R: HasAttributes>(
5 &self,
6 row: R,
7 namespace: &str,
8 dependencies: &TypeMap,
9 not: bool,
10 ) -> TokenStream {
11 let mut features = BTreeSet::new();
12 let mut arches = BTreeSet::new();
13
14 for attribute in row.attributes() {
15 match attribute.name() {
16 "SupportedArchitectureAttribute" => {
17 if let Some((_, Value::I32(value))) = attribute.args().first() {
18 if value & 1 == 1 {
19 arches.insert("x86");
20 }
21 if value & 2 == 2 {
22 arches.insert("x86_64");
23 arches.insert("arm64ec");
24 }
25 if value & 4 == 4 {
26 arches.insert("aarch64");
27 }
28 }
29 }
30 "DeprecatedAttribute" => {
31 features.insert("deprecated".to_string());
32 }
33 _ => {}
34 }
35 }
36
37 let mut tokens = quote! {};
38
39 match arches.len() {
40 0 => {}
41 1 => tokens.combine(quote! { #[cfg(#(target_arch = #arches),*)] }),
42 _ => tokens.combine(quote! { #[cfg(any(#(target_arch = #arches),*))] }),
43 }
44
45 let mut compact: Vec<&'static str> = dependencies.keys().map(|tn| tn.namespace()).collect();
46 compact.sort();
47 compact.dedup();
48
49 for pos in 0..compact.len() {
50 match (compact.get(pos), compact.get(pos + 1)) {
51 (Some(first), Some(second)) if namespace_starts_with(second, first) => {
52 compact.remove(pos);
53 }
54 (_, None) => break,
55 _ => continue,
56 }
57 }
58
59 for dependency in compact {
60 if dependency.is_empty()
61 || namespace_starts_with(namespace, dependency)
62 || dependency == "Windows.Foundation"
63 || dependency == "Windows.Win32.Foundation"
64 {
65 continue;
66 }
67
68 let mut feature = String::new();
69
70 for name in dependency.split('.').skip(1) {
71 feature.push_str(name);
72 feature.push('_');
73 }
74
75 feature.truncate(feature.len() - 1);
76 features.insert(feature);
77 }
78
79 match features.len() {
80 0 => {}
81 1 => {
82 if not {
83 tokens.combine(quote! { #[cfg(not(#(feature = #features)*))] });
84 } else {
85 tokens.combine(quote! { #[cfg(#(feature = #features)*)] });
86 }
87 }
88 _ => {
89 if not {
90 tokens.combine(quote! { #[cfg(not(all( #(feature = #features),* )))] });
91 } else {
92 tokens.combine(quote! { #[cfg(all( #(feature = #features),* ))] });
93 }
94 }
95 }
96
97 tokens
98 }
99}
100