pyo3_stub_gen_derive/gen_stub/
signature.rs

1use syn::{
2    parenthesized,
3    parse::{Parse, ParseStream},
4    punctuated::Punctuated,
5    token, Expr, Ident, Result, Token,
6};
7
8#[derive(Debug, Clone, PartialEq)]
9pub(crate) enum SignatureArg {
10    Ident(Ident),
11    Assign(Ident, Token![=], Expr),
12    Slash(Token![/]),
13    Star(Token![*]),
14    Args(Token![*], Ident),
15    Keywords(Token![*], Token![*], Ident),
16}
17
18impl Parse for SignatureArg {
19    fn parse(input: ParseStream) -> Result<Self> {
20        if input.peek(Token![/]) {
21            Ok(SignatureArg::Slash(input.parse()?))
22        } else if input.peek(Token![*]) {
23            let star = input.parse()?;
24            if input.peek(Token![*]) {
25                Ok(SignatureArg::Keywords(star, input.parse()?, input.parse()?))
26            } else if input.peek(Ident) {
27                Ok(SignatureArg::Args(star, input.parse()?))
28            } else {
29                Ok(SignatureArg::Star(star))
30            }
31        } else if input.peek(Ident) {
32            let ident = Ident::parse(input)?;
33            if input.peek(Token![=]) {
34                Ok(SignatureArg::Assign(ident, input.parse()?, input.parse()?))
35            } else {
36                Ok(SignatureArg::Ident(ident))
37            }
38        } else {
39            dbg!(input);
40            todo!()
41        }
42    }
43}
44
45#[derive(Debug, Clone, PartialEq)]
46pub struct Signature {
47    paren: token::Paren,
48    args: Punctuated<SignatureArg, Token![,]>,
49}
50
51impl Signature {
52    /// Access signature arguments
53    pub(crate) fn args(&self) -> impl Iterator<Item = &SignatureArg> {
54        self.args.iter()
55    }
56}
57
58impl Parse for Signature {
59    fn parse(input: ParseStream) -> Result<Self> {
60        let content;
61        let paren = parenthesized!(content in input);
62        let args = content.parse_terminated(SignatureArg::parse, Token![,])?;
63        Ok(Self { paren, args })
64    }
65}
66
67impl Signature {
68    pub fn overriding_operator(sig: &syn::Signature) -> Option<Self> {
69        if sig.ident == "__pow__" {
70            return Some(syn::parse_str("(exponent, modulo=None)").unwrap());
71        }
72        if sig.ident == "__rpow__" {
73            return Some(syn::parse_str("(base, modulo=None)").unwrap());
74        }
75        None
76    }
77}