pyo3_stub_gen/generate/
member.rs1use crate::{generate::*, type_info::*, TypeInfo};
2use std::{
3 borrow::Cow,
4 collections::HashSet,
5 fmt::{self},
6};
7
8#[derive(Debug, Clone, PartialEq)]
10pub struct MemberDef {
11 pub name: &'static str,
12 pub r#type: TypeInfo,
13 pub doc: &'static str,
14 pub default: Option<String>,
15 pub deprecated: Option<DeprecatedInfo>,
16}
17
18impl Import for MemberDef {
19 fn import(&self) -> HashSet<ImportRef> {
20 let mut import = self.r#type.import.clone();
21 if self.deprecated.is_some() {
23 import.insert("typing_extensions".into());
24 }
25 import
26 }
27}
28
29impl From<&MemberInfo> for MemberDef {
30 fn from(info: &MemberInfo) -> Self {
31 Self {
32 name: info.name,
33 r#type: (info.r#type)(),
34 doc: info.doc,
35 default: info.default.map(|f| f()),
36 deprecated: info.deprecated.clone(),
37 }
38 }
39}
40
41impl fmt::Display for MemberDef {
42 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
43 let indent = indent();
44 if let Some(_deprecated) = &self.deprecated {
47 log::warn!(
48 "Ignoring #[deprecated] on constant '{}': Python constants cannot have decorators. \
49 Consider using a function instead if deprecation is needed.",
50 self.name
51 );
52 }
53 write!(f, "{indent}{}: {}", self.name, self.r#type)?;
54 if let Some(default) = &self.default {
55 write!(f, " = {default}")?;
56 }
57 writeln!(f)?;
58 docstring::write_docstring(f, self.doc, indent)?;
59 Ok(())
60 }
61}
62
63impl MemberDef {
64 pub fn fmt_for_module(
69 &self,
70 target_module: &str,
71 f: &mut fmt::Formatter,
72 indent: &str,
73 ) -> fmt::Result {
74 if let Some(_deprecated) = &self.deprecated {
77 log::warn!(
78 "Ignoring #[deprecated] on constant '{}': Python constants cannot have decorators. \
79 Consider using a function instead if deprecation is needed.",
80 self.name
81 );
82 }
83 let qualified_type = self.r#type.qualified_for_module(target_module);
84 write!(f, "{indent}{}: {}", self.name, qualified_type)?;
85 if let Some(default) = &self.default {
86 write!(f, " = {default}")?;
87 }
88 writeln!(f)?;
89 docstring::write_docstring(f, self.doc, indent)?;
90 Ok(())
91 }
92}
93
94pub struct GetterDisplay<'a> {
95 pub member: &'a MemberDef,
96 pub target_module: &'a str,
97}
98
99pub struct SetterDisplay<'a> {
100 pub member: &'a MemberDef,
101 pub target_module: &'a str,
102}
103
104impl fmt::Display for GetterDisplay<'_> {
105 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
106 let indent = indent();
107 let qualified_type = self.member.r#type.qualified_for_module(self.target_module);
108 if let Some(deprecated) = &self.member.deprecated {
110 writeln!(f, "{indent}{deprecated}")?;
111 }
112 write!(
113 f,
114 "{indent}@property\n{indent}def {}(self) -> {}:",
115 self.member.name, qualified_type
116 )?;
117 let doc = if let Some(default) = &self.member.default {
118 if default == "..." {
119 Cow::Borrowed(self.member.doc)
120 } else {
121 Cow::Owned(format!(
122 "{}\n```python\ndefault = {default}\n```",
123 self.member.doc
124 ))
125 }
126 } else {
127 Cow::Borrowed(self.member.doc)
128 };
129 if !doc.is_empty() {
130 writeln!(f)?;
131 let double_indent = format!("{indent}{indent}");
132 docstring::write_docstring(f, &doc, &double_indent)
133 } else {
134 writeln!(f, " ...")
135 }
136 }
137}
138
139impl fmt::Display for SetterDisplay<'_> {
140 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
141 let indent = indent();
142 let qualified_type = self.member.r#type.qualified_for_module(self.target_module);
143 writeln!(f, "{indent}@{}.setter", self.member.name)?;
145 if let Some(deprecated) = &self.member.deprecated {
146 writeln!(f, "{indent}{deprecated}")?;
147 }
148 write!(
149 f,
150 "{indent}def {}(self, value: {}) -> None:",
151 self.member.name, qualified_type
152 )?;
153 let doc = if let Some(default) = &self.member.default {
154 if default == "..." {
155 Cow::Borrowed(self.member.doc)
156 } else {
157 Cow::Owned(format!(
158 "{}\n```python\ndefault = {default}\n```",
159 self.member.doc
160 ))
161 }
162 } else {
163 Cow::Borrowed(self.member.doc)
164 };
165 if !doc.is_empty() {
166 writeln!(f)?;
167 let double_indent = format!("{indent}{indent}");
168 docstring::write_docstring(f, &doc, &double_indent)
169 } else {
170 writeln!(f, " ...")
171 }
172 }
173}