odra_ir/module_item/
delegate.rs

1use syn::Attribute;
2
3use super::utils;
4
5mod kw {
6    syn::custom_keyword!(to);
7}
8
9#[derive(Debug, Clone)]
10pub struct Delegate {
11    pub stmts: Vec<DelegationStatement>
12}
13
14#[derive(Debug, Clone)]
15pub struct DelegationStatement {
16    pub delegate_to: syn::ExprField,
17    pub delegation_block: DelegationBlock
18}
19
20#[derive(Debug, Clone)]
21pub struct DelegationBlock {
22    pub brace_token: syn::token::Brace,
23    pub functions: Vec<DelegatedFunction>
24}
25
26#[derive(Debug, Clone)]
27pub struct DelegatedFunction {
28    pub attrs: Vec<Attribute>,
29    pub ident: syn::Ident,
30    pub args: syn::punctuated::Punctuated<syn::PatType, syn::token::Comma>,
31    pub ret: syn::ReturnType,
32    pub full_sig: syn::Signature,
33    pub visibility: syn::Visibility
34}
35
36impl syn::parse::Parse for Delegate {
37    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
38        let mut stmts = vec![];
39        while !input.is_empty() {
40            stmts.push(input.parse::<DelegationStatement>()?);
41        }
42        Ok(Self { stmts })
43    }
44}
45
46impl syn::parse::Parse for DelegationStatement {
47    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
48        input.parse::<kw::to>()?;
49
50        let delegate_to = input.parse::<syn::ExprField>()?;
51        let delegation_block = input.parse::<DelegationBlock>()?;
52        Ok(Self {
53            delegate_to,
54            delegation_block
55        })
56    }
57}
58
59impl syn::parse::Parse for DelegationBlock {
60    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
61        let content;
62        let brace_token = syn::braced!(content in input);
63        let mut functions = vec![];
64        while !content.is_empty() {
65            functions.push(content.parse::<DelegatedFunction>()?);
66        }
67        Ok(Self {
68            brace_token,
69            functions
70        })
71    }
72}
73
74impl syn::parse::Parse for DelegatedFunction {
75    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
76        let attrs = input.call(syn::Attribute::parse_outer)?;
77        let visibility = input.parse::<syn::Visibility>()?;
78        let fn_item = input.parse::<syn::TraitItemMethod>()?;
79
80        let ident = fn_item.sig.ident.to_owned();
81        let args = utils::extract_typed_inputs(&fn_item.sig);
82        let ret = fn_item.clone().sig.output;
83        let full_sig = fn_item.sig;
84
85        Ok(Self {
86            attrs,
87            visibility,
88            ident,
89            args,
90            ret,
91            full_sig
92        })
93    }
94}