1use super::*;
2
3#[derive(Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash)]
4pub struct Enum {
5 pub def: TypeDef,
6}
7
8impl Enum {
9 pub fn type_name(&self) -> TypeName {
10 self.def.type_name()
11 }
12
13 pub fn write_name(&self, writer: &Writer) -> TokenStream {
14 self.type_name().write(writer, &[])
15 }
16
17 pub fn write(&self, writer: &Writer) -> TokenStream {
18 let name = to_ident(self.def.name());
19 let underlying_type = self.def.underlying_type();
20
21 let mut derive = DeriveWriter::new(writer, self.type_name());
22 derive.extend(["Copy", "Clone"]);
23
24 if !writer.config.sys {
25 derive.extend(["Default", "Debug", "PartialEq", "Eq"]);
26 }
27
28 let fields = self
29 .def
30 .fields()
31 .filter(|field| field.flags().contains(FieldAttributes::Literal))
32 .map(|field| {
33 let name = to_ident(field.name());
34 let value = field.constant().unwrap().value().write();
35
36 quote! {
37 pub const #name: Self = Self(#value);
38 }
39 });
40
41 let flags = if writer.config.sys || underlying_type != Type::U32 {
42 quote! {}
43 } else {
44 quote! {
45 impl #name {
46 pub const fn contains(&self, other: Self) -> bool {
47 self.0 & other.0 == other.0
48 }
49 }
50 impl core::ops::BitOr for #name {
51 type Output = Self;
52 fn bitor(self, other: Self) -> Self {
53 Self(self.0 | other.0)
54 }
55 }
56 impl core::ops::BitAnd for #name {
57 type Output = Self;
58 fn bitand(self, other: Self) -> Self {
59 Self(self.0 & other.0)
60 }
61 }
62 impl core::ops::BitOrAssign for #name {
63 fn bitor_assign(&mut self, other: Self) {
64 self.0.bitor_assign(other.0)
65 }
66 }
67 impl core::ops::BitAndAssign for #name {
68 fn bitand_assign(&mut self, other: Self) {
69 self.0.bitand_assign(other.0)
70 }
71 }
72 impl core::ops::Not for #name {
73 type Output = Self;
74 fn not(self) -> Self {
75 Self(self.0.not())
76 }
77 }
78
79 }
80 };
81
82 let underlying_type = underlying_type.write_name(writer);
83
84 let win_traits = if writer.config.sys {
85 quote! {}
86 } else {
87 let signature = Literal::byte_string(&self.runtime_signature());
88
89 quote! {
90 impl windows_core::TypeKind for #name {
91 type TypeKind = windows_core::CopyType;
92 }
93 impl windows_core::RuntimeType for #name {
94 const SIGNATURE: windows_core::imp::ConstBuffer = windows_core::imp::ConstBuffer::from_slice(#signature);
95 }
96 }
97 };
98
99 quote! {
100 #[repr(transparent)]
101 #derive
102 pub struct #name(pub #underlying_type);
103 impl #name {
104 #(#fields)*
105 }
106 #win_traits
107 #flags
108 }
109 }
110
111 pub fn runtime_signature(&self) -> String {
112 format!(
113 "enum({};{})",
114 self.def.type_name(),
115 self.def.underlying_type().runtime_signature()
116 )
117 }
118}
119