pyo3_stub_gen_derive/gen_stub/
pymethods.rs

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