| 1 | use crate::{generate::*, type_info::*, TypeInfo}; |
| 2 | use std::{collections::HashSet, fmt}; |
| 3 | |
| 4 | /// Definition of a class method. |
| 5 | #[derive (Debug, Clone, PartialEq)] |
| 6 | pub struct MethodDef { |
| 7 | pub name: &'static str, |
| 8 | pub args: Vec<Arg>, |
| 9 | pub r#return: TypeInfo, |
| 10 | pub doc: &'static str, |
| 11 | pub is_static: bool, |
| 12 | pub is_class: bool, |
| 13 | } |
| 14 | |
| 15 | impl Import for MethodDef { |
| 16 | fn import(&self) -> HashSet<ModuleRef> { |
| 17 | let mut import: HashSet = self.r#return.import.clone(); |
| 18 | for arg: &Arg in &self.args { |
| 19 | import.extend(arg.import().into_iter()); |
| 20 | } |
| 21 | import |
| 22 | } |
| 23 | } |
| 24 | |
| 25 | impl From<&MethodInfo> for MethodDef { |
| 26 | fn from(info: &MethodInfo) -> Self { |
| 27 | Self { |
| 28 | name: info.name, |
| 29 | args: info.args.iter().map(Arg::from).collect(), |
| 30 | r#return: (info.r#return)(), |
| 31 | doc: info.doc, |
| 32 | is_static: info.is_static, |
| 33 | is_class: info.is_class, |
| 34 | } |
| 35 | } |
| 36 | } |
| 37 | |
| 38 | impl fmt::Display for MethodDef { |
| 39 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
| 40 | let indent = indent(); |
| 41 | let mut needs_comma = false; |
| 42 | if self.is_static { |
| 43 | writeln!(f, " {indent}@staticmethod" )?; |
| 44 | write!(f, " {indent}def {}(" , self.name)?; |
| 45 | } else if self.is_class { |
| 46 | writeln!(f, " {indent}@classmethod" )?; |
| 47 | write!(f, " {indent}def {}(cls" , self.name)?; |
| 48 | needs_comma = true; |
| 49 | } else { |
| 50 | write!(f, " {indent}def {}(self" , self.name)?; |
| 51 | needs_comma = true; |
| 52 | } |
| 53 | for arg in &self.args { |
| 54 | if needs_comma { |
| 55 | write!(f, ", " )?; |
| 56 | } |
| 57 | write!(f, " {}" , arg)?; |
| 58 | needs_comma = true; |
| 59 | } |
| 60 | writeln!(f, ") -> {}:" , self.r#return)?; |
| 61 | |
| 62 | let doc = self.doc; |
| 63 | if !doc.is_empty() { |
| 64 | writeln!(f, r#" {indent}{indent}r""""# )?; |
| 65 | for line in doc.lines() { |
| 66 | writeln!(f, " {indent}{indent}{}" , line)?; |
| 67 | } |
| 68 | writeln!(f, r#" {indent}{indent}""""# )?; |
| 69 | } |
| 70 | writeln!(f, " {indent}{indent}..." )?; |
| 71 | writeln!(f)?; |
| 72 | Ok(()) |
| 73 | } |
| 74 | } |
| 75 | |