1use proc_macro2::TokenStream as TokenStream2;
2use quote::{quote, ToTokens, TokenStreamExt};
3use syn::{Error, ImplItem, ItemImpl, Result, Type};
4
5use super::{quote_option, MemberInfo, MethodInfo, NewInfo};
6
7pub struct PyMethodsInfo {
8 struct_id: Type,
9 new: Option<NewInfo>,
10 getters: Vec<MemberInfo>,
11 methods: Vec<MethodInfo>,
12}
13
14impl 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
44impl 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