accepts-codegen 0.0.1

Rust toolkit for composing synchronous and asynchronous acceptor pipelines
Documentation
use syn::{
    Attribute, Block, Expr, ExprField, ExprPath, ExprReference, FnArg, Ident, ImplItemFn, Member,
    Path, Receiver, ReturnType, Signature, Type, TypePath, TypeReference, Visibility,
    punctuated::Punctuated,
    token::{And, Mut, RArrow},
};

use crate::common::syn::ext::{
    BlockConstructExt, ExprFieldConstructExt, ExprPathConstructExt, ExprReferenceConstructExt,
    IdentConstructExt, PunctuatedConstructExt, ReceiverConstructExt, SignatureConstructExt,
    TypePathConstructExt, TypeReferenceConstructExt,
};

pub fn generate_getter_method(
    attrs: Vec<Attribute>,
    vis: Visibility,
    gen_fn_ident: Ident,
    field_ident: Ident,
    field_ty: Type,
    ref_: bool,
    mut_: bool,
) -> ImplItemFn {
    let mut_token = match mut_ {
        true => Some(Mut::default()),
        false => None,
    };

    let sig = {
        let inputs = Punctuated::from_value(FnArg::Receiver(Receiver::from_ref_mut_colon_ty(
            match ref_ {
                true => Some((And::default(), None)),
                false => None,
            },
            mut_token.clone(),
            None,
            Box::new({
                let mut ty = Type::Path(TypePath::from_path(Path::from(Ident::from_str("Self"))));

                if ref_ {
                    ty = Type::Reference(TypeReference::from_mutability_elem(
                        mut_token.clone(),
                        Box::new(ty),
                    ))
                }

                ty
            }),
        )));

        let output = {
            let mut ty = field_ty.clone();

            if ref_ {
                ty = Type::Reference(TypeReference::from_mutability_elem(
                    mut_token.clone(),
                    Box::new(ty),
                ))
            }

            ReturnType::Type(RArrow::default(), Box::new(ty))
        };

        Signature::from_ident_inputs_output(gen_fn_ident, inputs, output)
    };

    let block = {
        let stmt = {
            let mut expr = Expr::Field(ExprField::from_base_member(
                Box::new(Expr::Path(ExprPath::from_path(Path::from(
                    Ident::from_str("self"),
                )))),
                Member::Named(field_ident.clone()),
            ));

            if ref_ {
                expr = Expr::Reference(ExprReference::from_mutability_expr(
                    mut_token.clone(),
                    Box::new(expr),
                ))
            }

            syn::Stmt::Expr(expr, None)
        };

        Block::from_stmts(vec![stmt])
    };

    ImplItemFn {
        attrs,
        vis,
        defaultness: None,
        sig,
        block,
    }
}