cpp_oop_macros 0.1.9

helper crate for 'oop_cpp' crate
Documentation
use quote::format_ident;
use syn::{parse_quote, Fields, ImplItem, ItemImpl};

use crate::utils::add_field;

use super::parsers::{BaseFnProps, BaseImplProps};

pub fn add_main_fields(main_fields: &mut Fields, impl_bases_inner: &[BaseImplProps], vtable: bool) {
    if !impl_bases_inner.is_empty() {
        for BaseImplProps {
            base_name,
            base_field_name,
            ..
        } in impl_bases_inner.iter().rev()
        {
            add_field(main_fields, base_field_name, base_name);
        }
    } else if vtable {
        add_field(main_fields, &format_ident!("vtbl"), &format_ident!("usize"));
    }
}

pub fn add_layout_fields(layout_fields: &mut Fields, impl_bases_inner: &[BaseImplProps]) {
    if let Some(BaseImplProps { fns, .. }) = impl_bases_inner.first() {
        let Fields::Named(fields) = layout_fields else {
            panic!("expected named fields");
        };
        for BaseFnProps {
            fn_name,
            inputs_inner,
            output,
            virt,
            ..
        } in fns.iter().rev()
        {
            if !virt {
                continue;
            }
            fields.named.insert(
                0,
                parse_quote! {
                    #fn_name: fn(#inputs_inner) #output
                },
            );
        }
    }
}

pub fn move_impls_to_main(impl_inner: &mut ItemImpl, impl_bases_inner: &[BaseImplProps]) {
    for BaseFnProps { fun, .. } in impl_bases_inner
        .iter()
        .flat_map(|BaseImplProps { fns, .. }| fns)
        .rev()
    {
        impl_inner.items.insert(0, ImplItem::Fn(fun.clone()));
    }
}