recode-derive 0.4.1

`recode` macros. Not intended to be used directly
Documentation
#![allow(dead_code)]

use darling::util::Flag;

use crate::{decoder, encoder};

#[derive(Debug, darling::FromDeriveInput)]
#[darling(forward_attrs(allow, doc, cfg))]
#[darling(attributes(recode), supports(struct_named, struct_unit))]
pub(crate) struct Recode {
    ident: syn::Ident,
    generics: syn::Generics,
    data: darling::ast::Data<(), RecodeField>,
    error: Option<syn::Type>,
    buffer_name: Option<syn::Ident>,
    #[darling(default)]
    decoder: decoder::DecoderOpts,
    #[darling(default)]
    encoder: encoder::EncoderOpts,
}

#[derive(Debug, Clone, darling::FromField)]
#[darling(attributes(recode))]
struct RecodeField {
    ident: Option<syn::Ident>,
    ty: syn::Type,
    skip: Flag,
    skip_if: Option<syn::Expr>,
    with: Option<syn::Type>,
    #[darling(default)]
    decoder: decoder::DecoderFieldOpts,
    #[darling(default)]
    encoder: encoder::EncoderFieldOpts,
}

impl darling::ToTokens for Recode {
    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
        decoder::Decoder {
            ident: self.ident.clone(),
            generics: self.generics.clone(),
            data: self.get_decoder_data(),
            decoder: decoder::DecoderOpts {
                error: self.decoder.error.clone().or(self.error.clone()),
                buffer_name: self
                    .decoder
                    .buffer_name
                    .clone()
                    .or(self.buffer_name.clone()),
                ..self.decoder.clone()
            },
        }
        .to_tokens(tokens);

        encoder::Encoder {
            ident: self.ident.clone(),
            generics: self.generics.clone(),
            data: self.get_encoder_data(),
            encoder: encoder::EncoderOpts {
                error: self.encoder.error.clone().or(self.error.clone()),
                buffer_name: self
                    .encoder
                    .buffer_name
                    .clone()
                    .or(self.buffer_name.clone()),
                ..self.encoder.clone()
            },
        }
        .to_tokens(tokens);
    }
}

impl Recode {
    #[inline(always)]
    fn get_decoder_data(
        &self,
    ) -> darling::ast::Data<(), decoder::DecoderField> {
        self.data
            .clone()
            .map_struct_fields(|f| decoder::DecoderField {
                ident: f.ident,
                ty: f.ty,
                decoder: decoder::DecoderFieldOpts {
                    skip: if f.skip.is_present() {
                        Flag::present()
                    } else {
                        f.encoder.skip
                    },
                    skip_if: f.skip_if.or(f.encoder.skip_if),
                    with: f.decoder.with.or(f.with),
                    ..f.decoder
                },
            })
    }

    #[inline(always)]
    fn get_encoder_data(
        &self,
    ) -> darling::ast::Data<(), encoder::EncoderField> {
        self.data
            .clone()
            .map_struct_fields(|f| encoder::EncoderField {
                ident: f.ident,
                ty: f.ty,
                encoder: encoder::EncoderFieldOpts {
                    skip: if f.skip.is_present() {
                        Flag::present()
                    } else {
                        f.encoder.skip
                    },
                    skip_if: f.skip_if.or(f.encoder.skip_if),
                    with: f.encoder.with.or(f.with),
                    ..f.encoder
                },
            })
    }
}