derive_more/
deref_mut.rs

1use crate::utils::{add_extra_where_clauses, SingleFieldData, State};
2use proc_macro2::TokenStream;
3use quote::quote;
4use syn::{parse::Result, DeriveInput};
5
6/// Provides the hook to expand `#[derive(DerefMut)]` into an implementation of `DerefMut`
7pub fn expand(input: &DeriveInput, trait_name: &'static str) -> Result<TokenStream> {
8    let state = State::with_field_ignore_and_forward(
9        input,
10        trait_name,
11        quote!(::core::ops),
12        String::from("deref_mut"),
13    )?;
14    let SingleFieldData {
15        input_type,
16        trait_path,
17        casted_trait,
18        ty_generics,
19        field_type,
20        member,
21        info,
22        ..
23    } = state.assert_single_enabled_field();
24    let (body, generics) = if info.forward {
25        (
26            quote!(#casted_trait::deref_mut(&mut #member)),
27            add_extra_where_clauses(
28                &input.generics,
29                quote! {
30                    where #field_type: #trait_path
31                },
32            ),
33        )
34    } else {
35        (quote!(&mut #member), input.generics.clone())
36    };
37    let (impl_generics, _, where_clause) = generics.split_for_impl();
38
39    Ok(quote! {
40        impl#impl_generics #trait_path for #input_type#ty_generics #where_clause
41        {
42            #[inline]
43            fn deref_mut(&mut self) -> &mut Self::Target {
44                #body
45            }
46        }
47    })
48}