use quote::quote;
use std::collections::HashMap;
pub fn get_impl(enum_ident: &syn::Ident, variant_idents: &HashMap<String, syn::Ident>, optional_variant: &Option<syn::Ident>) -> proc_macro2::TokenStream {
let mut variants: Vec<proc_macro2::TokenStream> = Vec::new();
variant_idents.keys().for_each(|variant_name| {
let variant_ident = variant_idents.get(variant_name).unwrap();
let variant_template = quote! {
#variant_name => Ok(#enum_ident::#variant_ident),
};
variants.push(variant_template.into());
});
if optional_variant.is_some() {
let optional_variant = optional_variant.clone().unwrap();
return quote! {
impl FromSql<Text, Mysql> for #enum_ident {
fn from_sql(bytes: Option<&<Mysql as Backend>::RawValue>) -> diesel::deserialize::Result<Self> {
return if bytes.is_none() {
Ok(#enum_ident::#optional_variant)
} else {
let mut value = bytes.unwrap();
let mut name = String::new();
let result = value.read_to_string(& mut name);
if result.is_err() {
Err(format!("Invalid value for {}", stringify!(#enum_ident)).into())
} else {
match name.as_str() {
#(#variants)*
_ => Err(format!("Invalid value for {}", stringify!(#enum_ident)).into())
}
}
}
}
}
};
} else {
return quote! {
impl FromSql<Text, Mysql> for #enum_ident {
fn from_sql(bytes: Option<&<Mysql as Backend>::RawValue>) -> diesel::deserialize::Result<Self> {
if bytes.is_some() {
let mut value = bytes.unwrap();
let mut name = String::new();
let result = value.read_to_string(& mut name);
if result.is_err() {
return Err(format!("Invalid value for {}", stringify!(#enum_ident)).into());
}
return match name.as_str() {
#(#variants)*
_ => Err(format!("Invalid value for {}", stringify!(#enum_ident)).into())
}
}
return Err(format!("Invalid value for {}", stringify!(#enum_ident)).into())
}
}
};
}
}