diff --git a/crates/generator-macros/src/select_include/definitions.rs b/crates/generator-macros/src/select_include/definitions.rs index 65421d83..5eabeaf7 100644 --- a/crates/generator-macros/src/select_include/definitions.rs +++ b/crates/generator-macros/src/select_include/definitions.rs @@ -1,5 +1,5 @@ use convert_case::Casing; -use prisma_client_rust_generator_shared::Arity; +use prisma_client_rust_generator_shared::{Arity, RelationArity}; use proc_macro2::TokenStream; use quote::quote; use syn::Field; @@ -59,15 +59,10 @@ pub fn definitions(input: &Input) -> TokenStream { return None; } - let field = quote! { - #(#attrs)* - pub #ident: #dollar::#model_path::#ty - }; - - let field_module = field_in_selectables + let (field_type, field_module) = field_in_selectables .zip(field_in_selection.and_then(|f| f.sub_selection.as_ref())) .and_then(|(field_in_selectables, (variant, sub_selection))| { - let Arity::Relation(relation_model_path, _) = &field_in_selectables.arity else { + let Arity::Relation(relation_model_path, arity) = &field_in_selectables.arity else { return None; }; @@ -79,8 +74,22 @@ pub fn definitions(input: &Input) -> TokenStream { } }; - Some(value) - }); + let base = quote!(#ident::Data); + + let typ = match arity { + RelationArity::One => base, + RelationArity::Many => quote!(Vec<#base>), + RelationArity::Optional => quote!(Option<#base>), + }; + + Some((typ, Some(value))) + }) + .unwrap_or_else(|| (quote!(#dollar::#model_path::#ty), None)); + + let field = quote! { + #(#attrs)* + pub #ident: #field_type + }; Some((field, field_module)) }) diff --git a/crates/generator-macros/src/select_include/selection/mod.rs b/crates/generator-macros/src/select_include/selection/mod.rs index 1e671c40..145aecc7 100644 --- a/crates/generator-macros/src/select_include/selection/mod.rs +++ b/crates/generator-macros/src/select_include/selection/mod.rs @@ -82,18 +82,6 @@ pub fn selection_to_params(input: &Input, variant: Variant) -> Vec }, Arity::Relation(relation_model_path, relation_arity) => { match (relation_arity, sub_selection) { - (RelationArity::One, None) => quote! { - #into(#variant_type_path::Fetch) - }, - (RelationArity::One, Some((selection_variant, selection))) => quote! { - #into( - #variant_type_path::#selection_variant( - #dollar::#relation_model_path::#selection_variant! { - selection_to_params @ #selection - }.into_iter().collect() - ) - ) - }, (RelationArity::Many, None) => quote! { #into( #variant_type_path::Fetch( @@ -115,6 +103,21 @@ pub fn selection_to_params(input: &Input, variant: Variant) -> Vec ) ) }, + (RelationArity::One | RelationArity::Optional, None) => quote! { + #into(#variant_type_path::Fetch) + }, + ( + RelationArity::One | RelationArity::Optional, + Some((selection_variant, selection)), + ) => quote! { + #into( + #variant_type_path::#selection_variant( + #dollar::#relation_model_path::#selection_variant! { + selection_to_params @ #selection + }.into_iter().collect() + ) + ) + }, } } } diff --git a/crates/generator-shared/src/lib.rs b/crates/generator-shared/src/lib.rs index d8a527da..714349b5 100644 --- a/crates/generator-shared/src/lib.rs +++ b/crates/generator-shared/src/lib.rs @@ -19,6 +19,7 @@ pub mod select_include; pub enum RelationArity { One, Many, + Optional, } impl Parse for RelationArity { @@ -28,7 +29,13 @@ impl Parse for RelationArity { Ok(match ident.to_string().as_str() { "One" => Self::One, "Many" => Self::Many, - _ => return Err(syn::Error::new_spanned(ident, "expected `One` or `Many`")), + "Optional" => Self::Optional, + _ => { + return Err(syn::Error::new_spanned( + ident, + "expected `One`, `Many`, or `Optional`", + )) + } }) } } @@ -38,6 +45,7 @@ impl ToTokens for RelationArity { tokens.extend(match self { Self::One => quote!(One), Self::Many => quote!(Many), + Self::Optional => quote!(Optional), }) } } @@ -99,7 +107,8 @@ impl FieldTuple { let relation_arity = match &field.ast_field().arity { FieldArity::List => RelationArity::Many, - _ => RelationArity::One, + FieldArity::Optional => RelationArity::Optional, + FieldArity::Required => RelationArity::One, }; Arity::Relation( diff --git a/integration-tests/tests/lib.rs b/integration-tests/tests/lib.rs index 0040ea9e..31b49cbf 100644 --- a/integration-tests/tests/lib.rs +++ b/integration-tests/tests/lib.rs @@ -8,7 +8,7 @@ mod utils; #[tokio::test] async fn aaaa_run_migrations() -> TestResult { - let client = db::new_client().await.unwrap(); + let client = db::PrismaClient::_builder().build().await.unwrap(); client._db_push().accept_data_loss().await.unwrap();