use darling::FromDeriveInput;
use darling::ast::{Data, Fields};
use quote::quote;
use syn::{DeriveInput, Generics, Ident, Result, Type};

#[derive(FromDeriveInput)]
#[darling(supports(struct_newtype))]
struct DerefInput {
    ident: Ident,
    generics: Generics,
    data: Data<darling::util::Ignored, Type>,
}

pub fn expand_deref(input: &DeriveInput) -> Result<proc_macro2::TokenStream> {
    let parsed = DerefInput::from_derive_input(input)?;
    let name = &parsed.ident;
    let (impl_generics, ty_generics, where_clause) = parsed.generics.split_for_impl();

    let fields = parsed.data.take_struct().unwrap();
    let Fields { fields, .. } = fields;
    let field_ty = &fields[0];

    Ok(quote! {
        impl #impl_generics ::std::ops::Deref for #name #ty_generics #where_clause {
            type Target = #field_ty;

            fn deref(&self) -> &Self::Target {
                &self.0
            }
        }
    })
}
