Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
leovalais committed Jun 17, 2024
1 parent 38f002e commit 590c43f
Show file tree
Hide file tree
Showing 20 changed files with 309 additions and 79 deletions.
1 change: 1 addition & 0 deletions editoast/editoast_derive/src/modelv2.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
mod args;
mod codegen;
mod config;
mod crud;
mod identifier;
mod parsing;
mod utils;
Expand Down
24 changes: 23 additions & 1 deletion editoast/editoast_derive/src/modelv2/args.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::RawIdentifier;
use super::{crud::Crud, RawIdentifier};
use darling::{
ast,
util::{self, PathList},
Expand All @@ -20,11 +20,33 @@ pub(super) struct ModelArgs {
pub(super) changeset: GeneratedTypeArgs,
#[darling(multiple, rename = "identifier")]
pub(super) identifiers: Vec<RawIdentifier>,
#[darling(default, rename = "gen")]
pub(super) impl_plan: ImplPlan,
#[darling(default)]
pub(super) preferred: Option<RawIdentifier>,
pub(super) data: ast::Data<util::Ignored, ModelFieldArgs>,
}

#[derive(Debug, PartialEq, Eq, FromMeta)]
pub(super) struct ImplPlan {
#[darling(default)]
pub(super) ops: Crud,
#[darling(default)]
pub(super) batch_ops: Crud,
#[darling(default)]
pub(super) list: bool,
}

impl Default for ImplPlan {
fn default() -> Self {
ImplPlan {
ops: Crud::ALL,
batch_ops: Crud::ALL,
list: true,
}
}
}

#[derive(FromMeta, Default, Debug, PartialEq)]
pub(super) struct GeneratedTypeArgs {
#[darling(default)]
Expand Down
210 changes: 138 additions & 72 deletions editoast/editoast_derive/src/modelv2/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ mod row_decl;
mod update_batch_impl;
mod update_impl;

use quote::ToTokens;
use syn::parse_quote;

use self::changeset_builder_impl_block::BuilderType;
Expand Down Expand Up @@ -52,6 +53,7 @@ use self::row_decl::RowFieldDecl;
use self::update_batch_impl::UpdateBatchImpl;
use self::update_impl::UpdateImpl;

use super::args::ImplPlan;
use super::identifier::Identifier;
use super::utils::np;
use super::ModelConfig;
Expand Down Expand Up @@ -111,6 +113,24 @@ impl Identifier {
}
}

impl ImplPlan {
fn has_read(&self) -> bool {
self.ops.read || self.batch_ops.read
}

fn has_create(&self) -> bool {
self.ops.create || self.batch_ops.create
}

fn has_update(&self) -> bool {
self.ops.update || self.batch_ops.update
}

fn has_upsert(&self) -> bool {
self.has_update() || self.has_create()
}
}

impl ModelConfig {
pub(crate) fn model_impl(&self) -> ModelImpl {
ModelImpl {
Expand All @@ -135,11 +155,14 @@ impl ModelConfig {
}
}

pub(crate) fn model_field_api_impl_blocks(&self) -> Vec<ModelFieldApiImplBlock> {
pub(crate) fn model_field_api_impl_blocks(&self) -> Vec<Option<ModelFieldApiImplBlock>> {
self.iter_fields()
.map(|field| ModelFieldApiImplBlock {
model: self.model.clone(),
field: field.clone(),
.map(|field| {
ModelFieldApiImplBlock {
model: self.model.clone(),
field: field.clone(),
}
.tokens_if(self.impl_plan.list)
})
.collect()
}
Expand Down Expand Up @@ -180,19 +203,21 @@ impl ModelConfig {
}
}

pub(crate) fn changeset_builder_impl_block(&self) -> ChangesetBuilderImplBlock {
pub(crate) fn changeset_builder_impl_block(&self) -> Option<ChangesetBuilderImplBlock> {
ChangesetBuilderImplBlock {
builder_type: BuilderType::Changeset,
model: self.model.clone(),
changeset: self.changeset.ident(),
fields: self.changeset_fields().cloned().collect(),
}
.tokens_if(self.impl_plan.has_upsert())
}

pub(crate) fn patch_builder_impl_block(&self) -> ChangesetBuilderImplBlock {
let mut builder = self.changeset_builder_impl_block();
builder.builder_type = BuilderType::Patch;
builder
pub(crate) fn patch_builder_impl_block(&self) -> Option<ChangesetBuilderImplBlock> {
self.changeset_builder_impl_block().and_then(|mut builder| {
builder.builder_type = BuilderType::Patch;
builder.tokens_if(self.impl_plan.has_update())
})
}

pub(crate) fn identifiable_impls(&self) -> Vec<IdentifiableImpl> {
Expand Down Expand Up @@ -229,90 +254,106 @@ impl ModelConfig {
}
}

pub(crate) fn retrieve_impls(&self) -> Vec<RetrieveImpl> {
pub(crate) fn retrieve_impls(&self) -> Vec<Option<RetrieveImpl>> {
self.identifiers
.iter()
.map(|identifier| RetrieveImpl {
model: self.model.clone(),
table_name: self.table_name(),
table_mod: self.table.clone(),
row: self.row.ident(),
identifier: identifier.clone(),
.map(|identifier| {
RetrieveImpl {
model: self.model.clone(),
table_name: self.table_name(),
table_mod: self.table.clone(),
row: self.row.ident(),
identifier: identifier.clone(),
}
.tokens_if(self.impl_plan.ops.read)
})
.collect()
}

pub(crate) fn exists_impls(&self) -> Vec<ExistsImpl> {
pub(crate) fn exists_impls(&self) -> Vec<Option<ExistsImpl>> {
self.identifiers
.iter()
.map(|identifier| ExistsImpl {
model: self.model.clone(),
table_name: self.table_name(),
table_mod: self.table.clone(),
identifier: identifier.clone(),
.map(|identifier| {
ExistsImpl {
model: self.model.clone(),
table_name: self.table_name(),
table_mod: self.table.clone(),
identifier: identifier.clone(),
}
.tokens_if(self.impl_plan.has_read())
})
.collect()
}

pub(crate) fn update_impls(&self) -> Vec<UpdateImpl> {
pub(crate) fn update_impls(&self) -> Vec<Option<UpdateImpl>> {
self.identifiers
.iter()
.map(|identifier| UpdateImpl {
model: self.model.clone(),
table_name: self.table_name(),
table_mod: self.table.clone(),
row: self.row.ident(),
changeset: self.changeset.ident(),
identifier: identifier.clone(),
.map(|identifier| {
UpdateImpl {
model: self.model.clone(),
table_name: self.table_name(),
table_mod: self.table.clone(),
row: self.row.ident(),
changeset: self.changeset.ident(),
identifier: identifier.clone(),
}
.tokens_if(self.impl_plan.ops.update)
})
.collect()
}

pub(crate) fn delete_static_impls(&self) -> Vec<DeleteStaticImpl> {
pub(crate) fn delete_static_impls(&self) -> Vec<Option<DeleteStaticImpl>> {
self.identifiers
.iter()
.map(|identifier| DeleteStaticImpl {
model: self.model.clone(),
table_name: self.table_name(),
table_mod: self.table.clone(),
identifier: identifier.clone(),
.map(|identifier| {
DeleteStaticImpl {
model: self.model.clone(),
table_name: self.table_name(),
table_mod: self.table.clone(),
identifier: identifier.clone(),
}
.tokens_if(self.impl_plan.ops.delete)
})
.collect()
}

pub(crate) fn create_impl(&self) -> CreateImpl {
pub(crate) fn create_impl(&self) -> Option<CreateImpl> {
CreateImpl {
model: self.model.clone(),
table_mod: self.table.clone(),
row: self.row.ident(),
changeset: self.changeset.ident(),
}
.tokens_if(self.impl_plan.ops.create)
}

pub(crate) fn delete_impl(&self) -> DeleteImpl {
pub(crate) fn delete_impl(&self) -> Option<DeleteImpl> {
DeleteImpl {
model: self.model.clone(),
table_mod: self.table.clone(),
primary_key: self.get_primary_field_ident(),
}
.tokens_if(self.impl_plan.ops.delete)
}

pub(crate) fn list_impl(&self) -> ListImpl {
pub(crate) fn list_impl(&self) -> Option<ListImpl> {
ListImpl {
model: self.model.clone(),
table_mod: self.table.clone(),
row: self.row.ident(),
}
.tokens_if(self.impl_plan.list)
}

pub(crate) fn count_impl(&self) -> CountImpl {
pub(crate) fn count_impl(&self) -> Option<CountImpl> {
CountImpl {
model: self.model.clone(),
table_mod: self.table.clone(),
}
.tokens_if(self.impl_plan.list)
}

pub(crate) fn create_batch_impl(&self) -> CreateBatchImpl {
pub(crate) fn create_batch_impl(&self) -> Option<CreateBatchImpl> {
CreateBatchImpl {
model: self.model.clone(),
table_name: self.table_name(),
Expand All @@ -321,60 +362,85 @@ impl ModelConfig {
changeset: self.changeset.ident(),
field_count: self.changeset_fields().count(),
}
.tokens_if(self.impl_plan.batch_ops.create)
}

pub(crate) fn create_batch_with_key_impls(&self) -> Vec<CreateBatchWithKeyImpl> {
pub(crate) fn create_batch_with_key_impls(&self) -> Vec<Option<CreateBatchWithKeyImpl>> {
self.identifiers
.iter()
.map(|identifier| CreateBatchWithKeyImpl {
model: self.model.clone(),
table_name: self.table_name(),
table_mod: self.table.clone(),
row: self.row.ident(),
changeset: self.changeset.ident(),
identifier: identifier.clone(),
field_count: self.changeset_fields().count(),
.map(|identifier| {
CreateBatchWithKeyImpl {
model: self.model.clone(),
table_name: self.table_name(),
table_mod: self.table.clone(),
row: self.row.ident(),
changeset: self.changeset.ident(),
identifier: identifier.clone(),
field_count: self.changeset_fields().count(),
}
.tokens_if(self.impl_plan.batch_ops.create)
})
.collect()
}

pub(crate) fn retrieve_batch_impls(&self) -> Vec<RetrieveBatchImpl> {
pub(crate) fn retrieve_batch_impls(&self) -> Vec<Option<RetrieveBatchImpl>> {
self.identifiers
.iter()
.map(|identifier| RetrieveBatchImpl {
model: self.model.clone(),
table_name: self.table_name(),
table_mod: self.table.clone(),
row: self.row.ident(),
identifier: identifier.clone(),
.map(|identifier| {
RetrieveBatchImpl {
model: self.model.clone(),
table_name: self.table_name(),
table_mod: self.table.clone(),
row: self.row.ident(),
identifier: identifier.clone(),
}
.tokens_if(self.impl_plan.batch_ops.read)
})
.collect()
}

pub(crate) fn update_batch_impls(&self) -> Vec<UpdateBatchImpl> {
pub(crate) fn update_batch_impls(&self) -> Vec<Option<UpdateBatchImpl>> {
self.identifiers
.iter()
.map(|identifier| UpdateBatchImpl {
model: self.model.clone(),
table_name: self.table_name(),
table_mod: self.table.clone(),
row: self.row.ident(),
changeset: self.changeset.ident(),
identifier: identifier.clone(),
primary_key_column: self.get_primary_field_column(),
.map(|identifier| {
UpdateBatchImpl {
model: self.model.clone(),
table_name: self.table_name(),
table_mod: self.table.clone(),
row: self.row.ident(),
changeset: self.changeset.ident(),
identifier: identifier.clone(),
primary_key_column: self.get_primary_field_column(),
}
.tokens_if(self.impl_plan.batch_ops.update)
})
.collect()
}

pub(crate) fn delete_batch_impls(&self) -> Vec<DeleteBatchImpl> {
pub(crate) fn delete_batch_impls(&self) -> Vec<Option<DeleteBatchImpl>> {
self.identifiers
.iter()
.map(|identifier| DeleteBatchImpl {
model: self.model.clone(),
table_name: self.table_name(),
table_mod: self.table.clone(),
identifier: identifier.clone(),
.map(|identifier| {
DeleteBatchImpl {
model: self.model.clone(),
table_name: self.table_name(),
table_mod: self.table.clone(),
identifier: identifier.clone(),
}
.tokens_if(self.impl_plan.batch_ops.delete)
})
.collect()
}
}

trait TokensIf: Sized {
fn tokens_if(self, condition: bool) -> Option<Self> {
if condition {
Some(self)
} else {
None
}
}
}

impl<T: ToTokens> TokensIf for T {}
Loading

0 comments on commit 590c43f

Please sign in to comment.