enum_delegate_lib 0.2.0

Internal macro implementations for enum_delegate - use to implement your own macros
Documentation
use std::collections::HashMap;

use proc_macro2::{Ident, TokenStream};
use quote::quote;
use syn::{ItemEnum, ItemTrait, Path};

use crate::error::InvalidInput;
use crate::generate;
use crate::generate::enum_conversion::generate_enum_conversions;
use crate::generate::{delegate_trait_for_enum, helper_mod};
use crate::input::associated_type::parse_associated_type_configurations;
use crate::input::single_field_enum::{parse_enum_variants, SingleFieldEnum};
use crate::input::AssociatedTypeUnification;

pub struct DelegationOptions {
    /// Generate From<VariantTypes> and TryInto<...> implementations for the specified enum
    pub generate_from_into_conversions: bool,
}

impl Default for DelegationOptions {
    fn default() -> Self {
        Self {
            generate_from_into_conversions: true,
        }
    }
}

pub fn implement_delegation(
    trait_path: &Path,
    parsed_trait: &ItemTrait,
    enum_path: &Path,
    original_enum: &ItemEnum,
    options: DelegationOptions,
) -> Result<TokenStream, InvalidInput> {
    let associated_type_config = parse_associated_type_configurations(parsed_trait)?;

    let helper_mod_name = helper_mod::helper_mod_name(parsed_trait, original_enum);

    let helper_mod = helper_mod::generate_helper_mod(&helper_mod_name);

    let associated_type_enum_names =
        generate::enum_definitions::generate_associated_type_enum_names(
            parsed_trait,
            &associated_type_config,
            original_enum,
        );

    let context = MacroContext {
        options,
        trait_path,
        parsed_trait,
        associated_type_config,
        associated_type_enum_names,
        enum_path,
        parsed_enum: parse_enum_variants(original_enum)?,
        helper_mod_name,
    };

    let enum_definitions = generate::enum_definitions::generate_enum_definitions(&context);

    let main_enum_conversions = context
        .options
        .generate_from_into_conversions
        .then(|| generate_enum_conversions(context.enum_path, &context.parsed_enum));
    let trait_impl = delegate_trait_for_enum::generate_trait_impl(&context)?;

    Ok(quote! {
        #helper_mod
        #enum_definitions
        #main_enum_conversions
        #trait_impl
    })
}

pub(crate) struct MacroContext<'a> {
    pub options: DelegationOptions,

    pub trait_path: &'a Path,
    pub parsed_trait: &'a ItemTrait,
    pub associated_type_config: HashMap<Ident, AssociatedTypeUnification>,
    /// For each associated type marked with `enum_wrap`, map the associated type's name to the name of the corresponding generated enum
    pub associated_type_enum_names: HashMap<Ident, Ident>,

    pub enum_path: &'a Path,
    pub parsed_enum: SingleFieldEnum,

    pub helper_mod_name: Ident,
}