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 | |