taitan-orm-parser 0.1.12

Next Generation ORM based on sqlx
Documentation
use std::borrow::Cow;
use std::fmt::Debug;
use case::CaseExt;
use crate::{DatabaseType, FieldMapper, SqlGenerator, TableDef};
use proc_macro2::{Ident, TokenStream};
use quote::{format_ident, quote};

#[derive(Debug, Default)]
pub struct IndexStructGenerator;


#[derive(Debug, Clone)]
pub enum IndexEnum {
    Primary,
    Unique{name: String},
    Index{name: String},
}



impl IndexStructGenerator {

    fn impl_unique<'a>(db_types: &[DatabaseType], struct_name: &Cow<'a, str>,  struct_ident: &Ident) -> TokenStream {
        let mut stream = TokenStream::new();
        for db_type in db_types {
            let mutation_ident = format_ident!("{}Mutation", struct_name);
            let db_ident = db_type.gen_ident();
            stream.extend(quote! {
                impl taitan_orm::traits::Unique<sqlx::#db_ident> for #struct_ident {
                    type Mutation = #mutation_ident;
                }
            });
        }
        stream
    }

    pub fn generate(
        &self,
        table_def: &TableDef,
        index_enum: &IndexEnum,
        db_types: &[DatabaseType]
    ) -> TokenStream {

        let struct_name = &table_def.struct_name;


        let field_mapper = FieldMapper::new();
        let table_name =  &table_def.table_name;
        let table_name_ident= format_ident!("{}", table_name);
        let sql_generator = SqlGenerator::default();
        let struct_ident = match index_enum {
            IndexEnum::Primary => {format_ident!("{}Primary", struct_name)},
            IndexEnum::Unique{name} => {format_ident!("{}Unique{}", struct_name, name.to_camel())},
            IndexEnum::Index{name} => {format_ident!("{}Index{}", struct_name, name.to_camel())},
        };

        let fields_stream = match index_enum {
            IndexEnum::Primary => {
                let fields = table_def.get_primary_fields();
                let fields_stream = field_mapper.gen_struct_fields(fields, false);
                let impl_unique = IndexStructGenerator::impl_unique(db_types, struct_name, &struct_ident);
                quote! {
                    #[derive(Debug, Clone, taitan_orm::macros::Parameter, taitan_orm::macros::Location, serde::Serialize, serde::Deserialize)]
                    #[table(#table_name_ident)]
                    pub struct #struct_ident {
                        #fields_stream
                    }
                    #impl_unique
                }
            }
            IndexEnum::Unique {name} => {
                let fields = table_def.get_unique_fields(name);
                let fields_stream = field_mapper.gen_struct_fields(fields, false);
                let impl_unique = IndexStructGenerator::impl_unique(db_types, struct_name, &struct_ident);
                quote! {
                    #[derive(Debug, Clone, taitan_orm::macros::Parameter, taitan_orm::macros::Location, serde::Serialize, serde::Deserialize)]
                    #[table(#table_name_ident)]
                    pub struct #struct_ident {
                        #fields_stream
                    }
                    #impl_unique
                }
            }
            IndexEnum::Index {name} => {
                let fields = table_def.get_index_fields(name);
                let fields_stream = field_mapper.gen_enum_variants( fields);
                quote! {
                    #[derive(Debug, Clone, taitan_orm::macros::Parameter, taitan_orm::macros::Location, serde::Serialize, serde::Deserialize)]
                    #[table(#table_name_ident)]
                    pub enum #struct_ident {
                        #fields_stream
                    }
                }
            }
        };

        fields_stream
    }
}