rorm-macro-impl 0.10.0

Macro implementations for rorm.
Documentation
use proc_macro2::TokenStream;
use quote::{format_ident, quote};

use crate::parse::db_enum::ParsedDbEnum;
use crate::MacroConfig;

pub fn generate_db_enum(parsed: &ParsedDbEnum, config: &MacroConfig) -> TokenStream {
    let MacroConfig {
        rorm_path,
        non_exhaustive: _,
    } = config;

    let ParsedDbEnum {
        vis,
        ident,
        variants,
    } = parsed;
    let decoder = format_ident!("__{ident}_Decoder");

    quote! {
        const _: () = {
            const CHOICES: &'static [&'static str] = &[
                #(stringify!(#variants)),*
            ];

            impl #rorm_path::fields::traits::FieldType for #ident {
                type Columns = #rorm_path::fields::traits::Array<1>;

                const NULL: #rorm_path::fields::traits::FieldColumns<Self, #rorm_path::db::sql::value::NullType> = [
                    #rorm_path::db::sql::value::NullType::Choice
                ];

                fn into_values<'a>(self) -> #rorm_path::fields::traits::FieldColumns<Self, #rorm_path::conditions::Value<'a>> {
                    [#rorm_path::conditions::Value::Choice(::std::borrow::Cow::Borrowed(match self {
                        #(
                            Self::#variants => stringify!(#variants),
                        )*
                    }))]
                }

                fn as_values(&self) -> #rorm_path::fields::traits::FieldColumns<Self, #rorm_path::conditions::Value<'_>> {
                    [#rorm_path::conditions::Value::Choice(::std::borrow::Cow::Borrowed(match self {
                        #(
                            Self::#variants => stringify!(#variants),
                        )*
                    }))]
                }

                type Decoder = #decoder;

                type GetAnnotations = get_db_enum_annotations;

                type Check = #rorm_path::fields::utils::check::shared_linter_check<1>;

                type GetNames = #rorm_path::fields::utils::get_names::single_column_name;
            }
            #rorm_path::new_converting_decoder!(
                #[doc(hidden)]
                #vis #decoder,
                |value: #rorm_path::db::choice::Choice| -> #ident {
                    let value: String = value.0;
                    match value.as_str() {
                        #(
                            stringify!(#variants) => Ok(#ident::#variants),
                        )*
                        _ => Err(format!("Invalid value '{}' for enum '{}'", value, stringify!(#ident))),
                    }
                }
            );
            impl<'rhs> #rorm_path::fields::traits::simple::SimpleFieldEq<'rhs, #ident> for #ident {
                fn into_value(rhs: #ident) -> #rorm_path::conditions::Value<'rhs> {
                    let [value] = <#ident as #rorm_path::fields::traits::FieldType>::into_values(rhs);
                    value
                }
            }

            #rorm_path::const_fn! {
                pub fn get_db_enum_annotations(
                    field: #rorm_path::internal::hmr::annotations::Annotations
                ) -> [#rorm_path::internal::hmr::annotations::Annotations; 1] {
                    let mut field = field;
                    field.choices = Some(#rorm_path::internal::hmr::annotations::Choices(CHOICES));
                    [field]
                }
            }
        };
    }
}