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<&'static str>,
15 pub deprecated: Option<DeprecatedInfo>,
16}
17
18impl Import for MemberDef {
19 fn import(&self) -> HashSet<ModuleRef> {
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(|s| s.as_str()),
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
63pub struct GetterDisplay<'a>(pub &'a MemberDef);
64pub struct SetterDisplay<'a>(pub &'a MemberDef);
65
66impl fmt::Display for GetterDisplay<'_> {
67 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
68 let indent = indent();
69 if let Some(deprecated) = &self.0.deprecated {
71 writeln!(f, "{indent}{deprecated}")?;
72 }
73 write!(
74 f,
75 "{indent}@property\n{indent}def {}(self) -> {}:",
76 self.0.name, self.0.r#type
77 )?;
78 let doc = if let Some(default) = self.0.default {
79 if default == "..." {
80 Cow::Borrowed(self.0.doc)
81 } else {
82 Cow::Owned(format!(
83 "{}\n```python\ndefault = {default}\n```",
84 self.0.doc
85 ))
86 }
87 } else {
88 Cow::Borrowed(self.0.doc)
89 };
90 if !doc.is_empty() {
91 writeln!(f)?;
92 let double_indent = format!("{indent}{indent}");
93 docstring::write_docstring(f, &doc, &double_indent)
94 } else {
95 writeln!(f, " ...")
96 }
97 }
98}
99
100impl fmt::Display for SetterDisplay<'_> {
101 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
102 let indent = indent();
103 if let Some(deprecated) = &self.0.deprecated {
105 writeln!(f, "{indent}{deprecated}")?;
106 }
107 write!(
108 f,
109 "{indent}@{}.setter\n{indent}def {}(self, value: {}) -> None:",
110 self.0.name, self.0.name, self.0.r#type
111 )?;
112 let doc = if let Some(default) = self.0.default {
113 if default == "..." {
114 Cow::Borrowed(self.0.doc)
115 } else {
116 Cow::Owned(format!(
117 "{}\n```python\ndefault = {default}\n```",
118 self.0.doc
119 ))
120 }
121 } else {
122 Cow::Borrowed(self.0.doc)
123 };
124 if !doc.is_empty() {
125 writeln!(f)?;
126 let double_indent = format!("{indent}{indent}");
127 docstring::write_docstring(f, &doc, &double_indent)
128 } else {
129 writeln!(f, " ...")
130 }
131 }
132}