| 1 | use proc_macro2::TokenStream as TokenStream2; |
| 2 | use quote::{quote, ToTokens, TokenStreamExt}; |
| 3 | use syn::{Error, ImplItem, ItemImpl, Result, Type}; |
| 4 | |
| 5 | use super::{quote_option, MemberInfo, MethodInfo, NewInfo}; |
| 6 | |
| 7 | pub struct PyMethodsInfo { |
| 8 | struct_id: Type, |
| 9 | new: Option<NewInfo>, |
| 10 | getters: Vec<MemberInfo>, |
| 11 | methods: Vec<MethodInfo>, |
| 12 | } |
| 13 | |
| 14 | impl TryFrom<ItemImpl> for PyMethodsInfo { |
| 15 | type Error = Error; |
| 16 | fn try_from(item: ItemImpl) -> Result<Self> { |
| 17 | let struct_id = *item.self_ty.clone(); |
| 18 | let mut new = None; |
| 19 | let mut getters = Vec::new(); |
| 20 | let mut methods = Vec::new(); |
| 21 | |
| 22 | for inner in item.items { |
| 23 | if let ImplItem::Fn(item_fn) = inner { |
| 24 | if NewInfo::is_candidate(&item_fn)? { |
| 25 | new = Some(NewInfo::try_from(item_fn)?); |
| 26 | } else if MemberInfo::is_candidate_item(&item_fn)? { |
| 27 | getters.push(MemberInfo::try_from(item_fn)?); |
| 28 | } else { |
| 29 | let mut method = MethodInfo::try_from(item_fn)?; |
| 30 | method.replace_self(&item.self_ty); |
| 31 | methods.push(method); |
| 32 | } |
| 33 | } |
| 34 | } |
| 35 | Ok(Self { |
| 36 | struct_id, |
| 37 | new, |
| 38 | getters, |
| 39 | methods, |
| 40 | }) |
| 41 | } |
| 42 | } |
| 43 | |
| 44 | impl ToTokens for PyMethodsInfo { |
| 45 | fn to_tokens(&self, tokens: &mut TokenStream2) { |
| 46 | let Self { |
| 47 | struct_id: &Type, |
| 48 | new: &Option, |
| 49 | getters: &Vec, |
| 50 | methods: &Vec, |
| 51 | } = self; |
| 52 | let new_tt: TokenStream = quote_option(new); |
| 53 | tokens.append_all(iter:quote! { |
| 54 | ::pyo3_stub_gen::type_info::PyMethodsInfo { |
| 55 | struct_id: std::any::TypeId::of::<#struct_id>, |
| 56 | new: #new_tt, |
| 57 | getters: &[ #(#getters),* ], |
| 58 | methods: &[ #(#methods),* ], |
| 59 | } |
| 60 | }) |
| 61 | } |
| 62 | } |
| 63 | |