]> git.proxmox.com Git - rustc.git/blob - vendor/windows-bindgen/src/enums.rs
New upstream version 1.71.1+dfsg1
[rustc.git] / vendor / windows-bindgen / src / enums.rs
1 use super::*;
2
3 pub fn gen(gen: &Gen, def: TypeDef) -> TokenStream {
4 let type_name = gen.reader.type_def_type_name(def);
5 let ident = to_ident(type_name.name);
6 let underlying_type = gen.reader.type_def_underlying_type(def);
7 let underlying_type = gen.type_name(&underlying_type);
8 let is_scoped = gen.reader.type_def_is_scoped(def);
9 let cfg = gen.reader.type_def_cfg(def, &[]);
10 let doc = gen.cfg_doc(&cfg);
11 let features = gen.cfg_features(&cfg);
12
13 let fields: Vec<(TokenStream, TokenStream)> = gen
14 .reader
15 .type_def_fields(def)
16 .filter_map(|field| {
17 if gen
18 .reader
19 .field_flags(field)
20 .contains(FieldAttributes::LITERAL)
21 {
22 let field_name = to_ident(gen.reader.field_name(field));
23 let constant = gen.reader.field_constant(field).unwrap();
24 let value = gen.value(&gen.reader.constant_value(constant));
25
26 Some((field_name, value))
27 } else {
28 None
29 }
30 })
31 .collect();
32
33 let eq = if gen.sys {
34 quote! {}
35 } else {
36 quote! {
37 // Unfortunately, Rust requires these to be derived to allow constant patterns.
38 #[derive(::core::cmp::PartialEq, ::core::cmp::Eq)]
39 }
40 };
41
42 let mut tokens = if is_scoped || !gen.sys {
43 quote! {
44 #doc
45 #features
46 #[repr(transparent)]
47 #eq
48 pub struct #ident(pub #underlying_type);
49 }
50 } else {
51 quote! {
52 #doc
53 #features
54 pub type #ident = #underlying_type;
55 }
56 };
57
58 tokens.combine(&if is_scoped {
59 let fields = fields.iter().map(|(field_name, value)| {
60 quote! {
61 pub const #field_name: Self = Self(#value);
62 }
63 });
64
65 quote! {
66 #features
67 impl #ident {
68 #(#fields)*
69 }
70 }
71 } else if !gen.sys {
72 let fields = fields.iter().map(|(field_name, value)| {
73 quote! {
74 #doc
75 #features
76 pub const #field_name: #ident = #ident(#value);
77 }
78 });
79
80 quote! {
81 #(#fields)*
82 }
83 } else if !gen.standalone {
84 let fields = fields.iter().map(|(field_name, value)| {
85 quote! {
86 #doc
87 #features
88 pub const #field_name: #ident = #value;
89 }
90 });
91
92 quote! {
93 #(#fields)*
94 }
95 } else {
96 quote! {}
97 });
98
99 if is_scoped || !gen.sys {
100 tokens.combine(&quote! {
101 #features
102 impl ::core::marker::Copy for #ident {}
103 #features
104 impl ::core::clone::Clone for #ident {
105 fn clone(&self) -> Self {
106 *self
107 }
108 }
109 });
110 }
111
112 if !gen.sys {
113 tokens.combine(&quote! {
114 #features
115 impl ::core::default::Default for #ident {
116 fn default() -> Self {
117 Self(0)
118 }
119 }
120 });
121 }
122
123 if !gen.sys {
124 let name = type_name.name;
125 tokens.combine(&quote! {
126 #features
127 impl ::windows::core::TypeKind for #ident {
128 type TypeKind = ::windows::core::CopyType;
129 }
130 #features
131 impl ::core::fmt::Debug for #ident {
132 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
133 f.debug_tuple(#name).field(&self.0).finish()
134 }
135 }
136 });
137
138 if gen.reader.type_def_is_flags(def) {
139 tokens.combine(&quote! {
140 #features
141 impl #ident {
142 pub const fn contains(&self, other: Self) -> bool {
143 self.0 & other.0 == other.0
144 }
145 }
146 #features
147 impl ::core::ops::BitOr for #ident {
148 type Output = Self;
149
150 fn bitor(self, other: Self) -> Self {
151 Self(self.0 | other.0)
152 }
153 }
154 #features
155 impl ::core::ops::BitAnd for #ident {
156 type Output = Self;
157
158 fn bitand(self, other: Self) -> Self {
159 Self(self.0 & other.0)
160 }
161 }
162 #features
163 impl ::core::ops::BitOrAssign for #ident {
164 fn bitor_assign(&mut self, other: Self) {
165 self.0.bitor_assign(other.0)
166 }
167 }
168 #features
169 impl ::core::ops::BitAndAssign for #ident {
170 fn bitand_assign(&mut self, other: Self) {
171 self.0.bitand_assign(other.0)
172 }
173 }
174 #features
175 impl ::core::ops::Not for #ident {
176 type Output = Self;
177
178 fn not(self) -> Self {
179 Self(self.0.not())
180 }
181 }
182 });
183 }
184
185 if gen
186 .reader
187 .type_def_flags(def)
188 .contains(TypeAttributes::WINRT)
189 {
190 let signature =
191 Literal::byte_string(gen.reader.type_def_signature(def, &[]).as_bytes());
192
193 tokens.combine(&quote! {
194 #features
195 impl ::windows::core::RuntimeType for #ident {
196 const SIGNATURE: ::windows::imp::ConstBuffer = ::windows::imp::ConstBuffer::from_slice(#signature);
197 }
198 });
199 }
200 }
201
202 tokens
203 }