reflica 0.2.0

Automatically implements Deref / DerefMut / AsRef / AsMut from the given deref / deref_mut
Documentation
use proc_macro2::TokenStream;
use quote::quote;
use syn::{ImplItem, ItemImpl};

pub fn generate(input: &ItemImpl) -> TokenStream {
    let ItemImpl {
        generics,
        self_ty,
        items,
        ..
    } = input;

    let Some(deref_mut) = items.iter().find_map(|item| match item {
        ImplItem::Fn(fn_) if fn_.sig.ident == "deref_mut" => Some(fn_),
        _ => None,
    }) else {
        return TokenStream::new();
    };

    let fn_attrs = &deref_mut.attrs;
    let fn_stmts = &deref_mut.block.stmts;
    let (impl_generics, _, where_clause) = generics.split_for_impl();

    quote! {
        impl #impl_generics ::core::ops::DerefMut for #self_ty
        #where_clause {
            #(#fn_attrs)*
            fn deref_mut(&mut self) -> &mut Self::Target {
                #(#fn_stmts)*
            }
        }

        impl #impl_generics ::core::convert::AsMut<<Self as ::core::ops::Deref>::Target> for #self_ty
        #where_clause {
            fn as_mut(&mut self) -> &mut <Self as ::core::ops::Deref>::Target {
                <Self as ::core::ops::DerefMut>::deref_mut(self)
            }
        }
    }
}