enum_delegate_lib 0.2.0

Internal macro implementations for enum_delegate - use to implement your own macros
Documentation
//! Code generation for enum [From] and [`TryInto`] implementations

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

use crate::input::single_field_enum::SingleFieldEnum;

/// Generate [From]<variant inner type> and [`TryInto`]<...> implementations for the specified enum
///
/// [`TryInto`] implementations are also generated for references and mutable references
pub(crate) fn generate_enum_conversions(
    enum_path: &Path,
    enum_declaration: &SingleFieldEnum,
) -> TokenStream {
    let variant_conversions = enum_declaration
        .variants()
        .iter()
        .map(|variant| generate_variant_conversions(enum_path, &variant.name, &variant.type_));

    quote!(#(#variant_conversions)*)
}

/// Generate [From]<variant inner type> and [`TryInto`]<...> implementations for the specified enum variant
///
/// [`TryInto`] implementations are also generated for references and mutable references
pub(crate) fn generate_variant_conversions(
    enum_path: &Path,
    variant_name: &Ident,
    variant_type: &Type,
) -> TokenStream {
    quote! {
        impl From<#variant_type> for #enum_path {
            fn from(inner: #variant_type) -> Self {
                #enum_path::#variant_name(inner)
            }
        }

        impl TryInto<#variant_type> for #enum_path {
            type Error = ();

            fn try_into(self) -> Result<#variant_type, Self::Error> {
                match self {
                    #enum_path::#variant_name(inner) => Ok(inner),
                    _ => Err(()),
                }
            }
        }

        impl<'a> TryInto<&'a #variant_type> for &'a #enum_path {
            type Error = ();

            fn try_into(self) -> Result<&'a #variant_type, Self::Error> {
                match self {
                    #enum_path::#variant_name(inner) => Ok(inner),
                    _ => Err(()),
                }
            }
        }

        impl<'a> TryInto<&'a mut #variant_type> for &'a mut #enum_path {
            type Error = ();

            fn try_into(self) -> Result<&'a mut #variant_type, Self::Error> {
                match self {
                    #enum_path::#variant_name(inner) => Ok(inner),
                    _ => Err(()),
                }
            }
        }
    }
}