odra_ir/module_item/
delegate.rs1use 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}