odra-ir 0.7.1

Data structures for Odra IR (intermediate representation).
Documentation
use syn::Attribute;

use super::utils;

mod kw {
    syn::custom_keyword!(to);
}

#[derive(Debug, Clone)]
pub struct Delegate {
    pub stmts: Vec<DelegationStatement>
}

#[derive(Debug, Clone)]
pub struct DelegationStatement {
    pub delegate_to: syn::ExprField,
    pub delegation_block: DelegationBlock
}

#[derive(Debug, Clone)]
pub struct DelegationBlock {
    pub brace_token: syn::token::Brace,
    pub functions: Vec<DelegatedFunction>
}

#[derive(Debug, Clone)]
pub struct DelegatedFunction {
    pub attrs: Vec<Attribute>,
    pub ident: syn::Ident,
    pub args: syn::punctuated::Punctuated<syn::PatType, syn::token::Comma>,
    pub ret: syn::ReturnType,
    pub full_sig: syn::Signature,
    pub visibility: syn::Visibility
}

impl syn::parse::Parse for Delegate {
    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
        let mut stmts = vec![];
        while !input.is_empty() {
            stmts.push(input.parse::<DelegationStatement>()?);
        }
        Ok(Self { stmts })
    }
}

impl syn::parse::Parse for DelegationStatement {
    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
        input.parse::<kw::to>()?;

        let delegate_to = input.parse::<syn::ExprField>()?;
        let delegation_block = input.parse::<DelegationBlock>()?;
        Ok(Self {
            delegate_to,
            delegation_block
        })
    }
}

impl syn::parse::Parse for DelegationBlock {
    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
        let content;
        let brace_token = syn::braced!(content in input);
        let mut functions = vec![];
        while !content.is_empty() {
            functions.push(content.parse::<DelegatedFunction>()?);
        }
        Ok(Self {
            brace_token,
            functions
        })
    }
}

impl syn::parse::Parse for DelegatedFunction {
    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
        let attrs = input.call(syn::Attribute::parse_outer)?;
        let visibility = input.parse::<syn::Visibility>()?;
        let fn_item = input.parse::<syn::TraitItemMethod>()?;

        let ident = fn_item.sig.ident.to_owned();
        let args = utils::extract_typed_inputs(&fn_item.sig);
        let ret = fn_item.clone().sig.output;
        let full_sig = fn_item.sig;

        Ok(Self {
            attrs,
            visibility,
            ident,
            args,
            ret,
            full_sig
        })
    }
}