pyo3_stub_gen/generate/
enum_.rs1use crate::generate::docstring::normalize_docstring;
2use crate::{generate::*, type_info::*};
3use std::fmt;
4
5#[derive(Debug, Clone, PartialEq)]
7pub struct EnumDef {
8 pub name: &'static str,
9 pub module: Option<&'static str>,
10 pub doc: &'static str,
11 pub variants: &'static [(&'static str, &'static str)],
12 pub methods: Vec<MethodDef>,
13 pub attrs: Vec<MemberDef>,
14 pub getters: Vec<MemberDef>,
15 pub setters: Vec<MemberDef>,
16}
17
18impl From<&PyEnumInfo> for EnumDef {
19 fn from(info: &PyEnumInfo) -> Self {
20 let doc = if info.doc.is_empty() {
21 ""
22 } else {
23 Box::leak(normalize_docstring(info.doc).into_boxed_str())
24 };
25
26 let variants_vec: Vec<(&'static str, &'static str)> = info
28 .variants
29 .iter()
30 .map(|(name, variant_doc)| {
31 let normalized_variant_doc = if variant_doc.is_empty() {
32 ""
33 } else {
34 Box::leak(normalize_docstring(variant_doc).into_boxed_str())
35 };
36 (*name, normalized_variant_doc)
37 })
38 .collect();
39 let variants: &'static [(&'static str, &'static str)] =
40 Box::leak(variants_vec.into_boxed_slice());
41
42 Self {
43 name: info.pyclass_name,
44 module: info.module,
45 doc,
46 variants,
47 methods: Vec::new(),
48 attrs: Vec::new(),
49 getters: Vec::new(),
50 setters: Vec::new(),
51 }
52 }
53}
54
55impl Import for EnumDef {
56 fn import(&self) -> HashSet<ImportRef> {
57 let mut import = HashSet::new();
58 import.insert("typing".into());
60 import.insert("enum".into());
62 for method in &self.methods {
63 import.extend(method.import());
64 }
65 for attr in &self.attrs {
66 import.extend(attr.import());
67 }
68 for getter in &self.getters {
69 import.extend(getter.import());
70 }
71 for setter in &self.setters {
72 import.extend(setter.import());
73 }
74 import
75 }
76}
77
78impl fmt::Display for EnumDef {
79 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
80 writeln!(f, "@typing.final")?;
81 writeln!(f, "class {}(enum.Enum):", self.name)?;
82 let indent = indent();
83 docstring::write_docstring(f, self.doc, indent)?;
84 for (variant, variant_doc) in self.variants {
85 writeln!(f, "{indent}{variant} = ...")?;
86 docstring::write_docstring(f, variant_doc, indent)?;
87 }
88 if !(self.attrs.is_empty()
89 && self.getters.is_empty()
90 && self.setters.is_empty()
91 && self.methods.is_empty())
92 {
93 writeln!(f)?;
94 for attr in &self.attrs {
95 attr.fmt(f)?;
96 }
97 for getter in &self.getters {
98 write!(
99 f,
100 "{}",
101 GetterDisplay {
102 member: getter,
103 target_module: self.module.unwrap_or(self.name)
104 }
105 )?;
106 }
107 for setter in &self.setters {
108 write!(
109 f,
110 "{}",
111 SetterDisplay {
112 member: setter,
113 target_module: self.module.unwrap_or(self.name)
114 }
115 )?;
116 }
117 for methods in &self.methods {
118 methods.fmt(f)?;
119 }
120 }
121 writeln!(f)?;
122 Ok(())
123 }
124}
125
126impl EnumDef {
127 pub fn fmt_for_module(&self, target_module: &str, f: &mut fmt::Formatter) -> fmt::Result {
134 writeln!(f, "@typing.final")?;
135 writeln!(f, "class {}(enum.Enum):", self.name)?;
136 let indent = indent();
137 docstring::write_docstring(f, self.doc, indent)?;
138 for (variant, variant_doc) in self.variants {
139 writeln!(f, "{indent}{variant} = ...")?;
140 docstring::write_docstring(f, variant_doc, indent)?;
141 }
142 if !(self.attrs.is_empty()
143 && self.getters.is_empty()
144 && self.setters.is_empty()
145 && self.methods.is_empty())
146 {
147 writeln!(f)?;
148 for attr in &self.attrs {
149 attr.fmt_for_module(target_module, f, indent)?;
150 }
151 for getter in &self.getters {
152 write!(
153 f,
154 "{}",
155 GetterDisplay {
156 member: getter,
157 target_module
158 }
159 )?;
160 }
161 for setter in &self.setters {
162 write!(
163 f,
164 "{}",
165 SetterDisplay {
166 member: setter,
167 target_module
168 }
169 )?;
170 }
171 for methods in &self.methods {
172 methods.fmt_for_module(target_module, f, indent)?;
173 }
174 }
175 writeln!(f)?;
176 Ok(())
177 }
178}