use proc_macro2::{Ident, TokenStream};
use quote::quote;
use syn::{Path, Type};
use crate::input::single_field_enum::SingleFieldEnum;
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)*)
}
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(()),
}
}
}
}
}