pyo3_stub_gen/generate/
method.rs1use crate::{generate::*, type_info::*, TypeInfo};
2use std::{collections::HashSet, fmt};
3
4pub use crate::type_info::MethodType;
5
6#[derive(Debug, Clone, PartialEq)]
8pub struct MethodDef {
9 pub name: &'static str,
10 pub args: Vec<Arg>,
11 pub r#return: TypeInfo,
12 pub doc: &'static str,
13 pub r#type: MethodType,
14 pub is_async: bool,
15 pub deprecated: Option<DeprecatedInfo>,
16}
17
18impl Import for MethodDef {
19 fn import(&self) -> HashSet<ModuleRef> {
20 let mut import = self.r#return.import.clone();
21 for arg in &self.args {
22 import.extend(arg.import().into_iter());
23 }
24 if self.deprecated.is_some() {
26 import.insert("typing_extensions".into());
27 }
28 import
29 }
30}
31
32impl From<&MethodInfo> for MethodDef {
33 fn from(info: &MethodInfo) -> Self {
34 Self {
35 name: info.name,
36 args: info.args.iter().map(Arg::from).collect(),
37 r#return: (info.r#return)(),
38 doc: info.doc,
39 r#type: info.r#type,
40 is_async: info.is_async,
41 deprecated: info.deprecated.clone(),
42 }
43 }
44}
45
46impl fmt::Display for MethodDef {
47 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
48 let indent = indent();
49 let mut needs_comma = false;
50 let async_ = if self.is_async { "async " } else { "" };
51
52 if let Some(deprecated) = &self.deprecated {
54 writeln!(f, "{indent}{deprecated}")?;
55 }
56
57 match self.r#type {
58 MethodType::Static => {
59 writeln!(f, "{indent}@staticmethod")?;
60 write!(f, "{indent}{async_}def {}(", self.name)?;
61 }
62 MethodType::Class | MethodType::New => {
63 if self.r#type == MethodType::Class {
64 writeln!(f, "{indent}@classmethod")?;
66 }
67 write!(f, "{indent}{async_}def {}(cls", self.name)?;
68 needs_comma = true;
69 }
70 MethodType::Instance => {
71 write!(f, "{indent}{async_}def {}(self", self.name)?;
72 needs_comma = true;
73 }
74 }
75 for arg in &self.args {
76 if needs_comma {
77 write!(f, ", ")?;
78 }
79 write!(f, "{arg}")?;
80 needs_comma = true;
81 }
82 write!(f, ") -> {}:", self.r#return)?;
83
84 let doc = self.doc;
85 if !doc.is_empty() {
86 writeln!(f)?;
87 let double_indent = format!("{indent}{indent}");
88 docstring::write_docstring(f, self.doc, &double_indent)?;
89 } else {
90 writeln!(f, " ...")?;
91 }
92 Ok(())
93 }
94}