| 1 | use crate::{generate::*, type_info::*}; |
| 2 | use std::fmt; |
| 3 | |
| 4 | /// Definition of a Python class. |
| 5 | #[derive (Debug, Clone, PartialEq)] |
| 6 | pub struct ClassDef { |
| 7 | pub name: &'static str, |
| 8 | pub doc: &'static str, |
| 9 | pub new: Option<NewDef>, |
| 10 | pub members: Vec<MemberDef>, |
| 11 | pub methods: Vec<MethodDef>, |
| 12 | } |
| 13 | |
| 14 | impl Import for ClassDef { |
| 15 | fn import(&self) -> HashSet<ModuleRef> { |
| 16 | let mut import: HashSet = HashSet::new(); |
| 17 | if let Some(new: &NewDef) = &self.new { |
| 18 | import.extend(iter:new.import()); |
| 19 | } |
| 20 | for member: &MemberDef in &self.members { |
| 21 | import.extend(iter:member.import()); |
| 22 | } |
| 23 | for method: &MethodDef in &self.methods { |
| 24 | import.extend(iter:method.import()); |
| 25 | } |
| 26 | import |
| 27 | } |
| 28 | } |
| 29 | |
| 30 | impl From<&PyClassInfo> for ClassDef { |
| 31 | fn from(info: &PyClassInfo) -> Self { |
| 32 | // Since there are multiple `#[pymethods]` for a single class, we need to merge them. |
| 33 | // This is only an initializer. See `StubInfo::gather` for the actual merging. |
| 34 | Self { |
| 35 | name: info.pyclass_name, |
| 36 | new: None, |
| 37 | doc: info.doc, |
| 38 | members: info.members.iter().map(MemberDef::from).collect(), |
| 39 | methods: Vec::new(), |
| 40 | } |
| 41 | } |
| 42 | } |
| 43 | |
| 44 | impl fmt::Display for ClassDef { |
| 45 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
| 46 | writeln!(f, "class {}:" , self.name)?; |
| 47 | let indent = indent(); |
| 48 | let doc = self.doc.trim(); |
| 49 | if !doc.is_empty() { |
| 50 | writeln!(f, r#" {indent}r""""# )?; |
| 51 | for line in doc.lines() { |
| 52 | writeln!(f, " {indent}{}" , line)?; |
| 53 | } |
| 54 | writeln!(f, r#" {indent}""""# )?; |
| 55 | } |
| 56 | for member in &self.members { |
| 57 | member.fmt(f)?; |
| 58 | } |
| 59 | if let Some(new) = &self.new { |
| 60 | new.fmt(f)?; |
| 61 | } |
| 62 | for method in &self.methods { |
| 63 | method.fmt(f)?; |
| 64 | } |
| 65 | if self.members.is_empty() && self.methods.is_empty() { |
| 66 | writeln!(f, " {indent}..." )?; |
| 67 | } |
| 68 | writeln!(f)?; |
| 69 | Ok(()) |
| 70 | } |
| 71 | } |
| 72 | |