Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions crates/cgp-core/src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub use cgp_field::types::{
pub use cgp_macro::{
cgp_auto_getter, cgp_component, cgp_context, cgp_getter, cgp_new_provider, cgp_preset,
cgp_provider, cgp_type, check_components, delegate_and_check_components, delegate_components,
product, re_export_imports, replace_with, BuildField, CgpVariant, ExtractField, FromVariant,
HasField, HasFields, Product, Sum, Symbol, Symbol as symbol,
product, re_export_imports, replace_with, BuildField, CgpData, CgpRecord, CgpVariant,
ExtractField, FromVariant, HasField, HasFields, Product, Sum, Symbol, Symbol as symbol,
};
pub use cgp_type::{HasType, ProvideType, UseType};
17 changes: 17 additions & 0 deletions crates/cgp-macro-lib/src/entrypoints/cgp_data.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use proc_macro2::TokenStream;
use syn::{parse2, Error, Item};

use crate::{derive_cgp_record_from_struct, derive_cgp_variant_from_enum};

pub fn derive_cgp_data(body: TokenStream) -> syn::Result<TokenStream> {
let item: Item = parse2(body)?;

match item {
Item::Struct(item_struct) => derive_cgp_record_from_struct(&item_struct),
Item::Enum(item_enum) => derive_cgp_variant_from_enum(&item_enum),
_ => Err(Error::new_spanned(
item,
"expect body to be either a struct or enum",
)),
}
}
24 changes: 24 additions & 0 deletions crates/cgp-macro-lib/src/entrypoints/cgp_record.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use proc_macro2::TokenStream;
use quote::quote;
use syn::{parse2, ItemStruct};

use crate::derive_build_field_from_struct;
use crate::derive_has_fields::derive_has_fields_impls_from_struct;
use crate::field::derive_has_field_impls_from_struct;

pub fn derive_cgp_record(body: TokenStream) -> syn::Result<TokenStream> {
let item_struct = parse2(body)?;
derive_cgp_record_from_struct(&item_struct)
}

pub fn derive_cgp_record_from_struct(item_struct: &ItemStruct) -> syn::Result<TokenStream> {
let has_field_impls = derive_has_field_impls_from_struct(item_struct);
let has_fields_impls = derive_has_fields_impls_from_struct(item_struct)?;
let build_field_impls = derive_build_field_from_struct(item_struct)?;

Ok(quote! {
#( #has_field_impls )*
#( #has_fields_impls )*
#build_field_impls
})
}
19 changes: 13 additions & 6 deletions crates/cgp-macro-lib/src/entrypoints/cgp_variant.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
use proc_macro2::TokenStream;
use quote::quote;
use syn::{parse2, ItemEnum};

use crate::entrypoints::{derive_extract_field, derive_from_variant, derive_has_fields};
use crate::derive_has_fields::derive_has_fields_impls_from_enum;
use crate::{derive_extract_field_from_enum, derive_from_variant_from_enum};

pub fn cgp_variant(body: TokenStream) -> syn::Result<TokenStream> {
let has_fields = derive_has_fields(body.clone())?;
let extract_field = derive_extract_field(body.clone())?;
let from_variant = derive_from_variant(body)?;
pub fn derive_cgp_variant(body: TokenStream) -> syn::Result<TokenStream> {
let item_enum = parse2(body)?;
derive_cgp_variant_from_enum(&item_enum)
}

pub fn derive_cgp_variant_from_enum(item_enum: &ItemEnum) -> syn::Result<TokenStream> {
let has_fields = derive_has_fields_impls_from_enum(item_enum)?;
let extract_field = derive_extract_field_from_enum(item_enum)?;
let from_variant = derive_from_variant_from_enum(item_enum)?;

Ok(quote! {
#has_fields
#( #has_fields )*
#extract_field
#from_variant
})
Expand Down
17 changes: 10 additions & 7 deletions crates/cgp-macro-lib/src/entrypoints/derive_build_field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,26 @@ use crate::derive_builder::{

pub fn derive_build_field(body: TokenStream) -> syn::Result<TokenStream> {
let context_struct: ItemStruct = parse2(body)?;
derive_build_field_from_struct(&context_struct)
}

pub fn derive_build_field_from_struct(context_struct: &ItemStruct) -> syn::Result<TokenStream> {
let context_ident = &context_struct.ident;
let builder_ident = Ident::new(&format!("Partial{context_ident}"), context_ident.span());

let builder_struct = derive_builder_struct(&context_struct, &builder_ident)?;
let builder_struct = derive_builder_struct(context_struct, &builder_ident)?;

let has_builder_impl = derive_has_builder_impl(&context_struct, &builder_ident)?;
let has_builder_impl = derive_has_builder_impl(context_struct, &builder_ident)?;

let into_builder_impl = derive_into_builder_impl(&context_struct, &builder_ident)?;
let into_builder_impl = derive_into_builder_impl(context_struct, &builder_ident)?;

let partial_data_impl = derive_partial_data_impl(&context_struct, &builder_ident)?;
let partial_data_impl = derive_partial_data_impl(context_struct, &builder_ident)?;

let update_field_impls = derive_update_field_impls(&context_struct, &builder_ident)?;
let update_field_impls = derive_update_field_impls(context_struct, &builder_ident)?;

let has_field_impls = derive_has_field_impls(&context_struct, &builder_ident)?;
let has_field_impls = derive_has_field_impls(context_struct, &builder_ident)?;

let finalize_build_impl = derive_finalize_build_impl(&context_struct, &builder_ident)?;
let finalize_build_impl = derive_finalize_build_impl(context_struct, &builder_ident)?;

let out = quote! {
#builder_struct
Expand Down
29 changes: 14 additions & 15 deletions crates/cgp-macro-lib/src/entrypoints/derive_extract_field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,37 +10,36 @@ use crate::derive_extractor::{

pub fn derive_extract_field(body: TokenStream) -> syn::Result<TokenStream> {
let context_enum: ItemEnum = parse2(body)?;
derive_extract_field_from_enum(&context_enum)
}

pub fn derive_extract_field_from_enum(context_enum: &ItemEnum) -> syn::Result<TokenStream> {
let context_ident = &context_enum.ident;

let extractor_ident = Ident::new(&format!("Partial{context_ident}"), context_ident.span());
let extractor_enum = derive_extractor_enum(&context_enum, &extractor_ident)?;
let extractor_enum = derive_extractor_enum(context_enum, &extractor_ident)?;

let extractor_ref_ident =
Ident::new(&format!("PartialRef{context_ident}"), context_ident.span());
let extractor_ref_enum = derive_extractor_enum_ref(&context_enum, &extractor_ref_ident)?;
let extractor_ref_enum = derive_extractor_enum_ref(context_enum, &extractor_ref_ident)?;

let has_extractor_impl = derive_has_extractor_impl(&context_enum, &extractor_ident)?;
let has_extractor_impl = derive_has_extractor_impl(context_enum, &extractor_ident)?;

let has_extractor_ref_impl =
derive_has_extractor_ref_impl(&context_enum, &extractor_ref_ident)?;
let has_extractor_ref_impl = derive_has_extractor_ref_impl(context_enum, &extractor_ref_ident)?;

let has_extractor_mut_impl =
derive_has_extractor_mut_impl(&context_enum, &extractor_ref_ident)?;
let has_extractor_mut_impl = derive_has_extractor_mut_impl(context_enum, &extractor_ref_ident)?;

let finalize_extract_impl =
derive_finalize_extract_impl(&context_enum, &extractor_ident, false)?;
derive_finalize_extract_impl(context_enum, &extractor_ident, false)?;

let finalize_extract_ref_impl =
derive_finalize_extract_impl(&context_enum, &extractor_ref_ident, true)?;
derive_finalize_extract_impl(context_enum, &extractor_ref_ident, true)?;

let partial_data_impl = derive_partial_data_impl(&context_enum, &extractor_ident, false)?;
let partial_ref_data_impl =
derive_partial_data_impl(&context_enum, &extractor_ref_ident, true)?;
let partial_data_impl = derive_partial_data_impl(context_enum, &extractor_ident, false)?;
let partial_ref_data_impl = derive_partial_data_impl(context_enum, &extractor_ref_ident, true)?;

let extractor_impls = derive_extract_field_impls(&context_enum, &extractor_ident, false)?;
let extractor_ref_impls =
derive_extract_field_impls(&context_enum, &extractor_ref_ident, true)?;
let extractor_impls = derive_extract_field_impls(context_enum, &extractor_ident, false)?;
let extractor_ref_impls = derive_extract_field_impls(context_enum, &extractor_ref_ident, true)?;

let out = quote! {
#extractor_enum
Expand Down
9 changes: 7 additions & 2 deletions crates/cgp-macro-lib/src/entrypoints/derive_from_variant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,21 @@ use crate::symbol::symbol_from_string;

pub fn derive_from_variant(body: TokenStream) -> syn::Result<TokenStream> {
let item_enum: ItemEnum = parse2(body)?;

derive_from_variant_from_enum(&item_enum)
}

pub fn derive_from_variant_from_enum(item_enum: &ItemEnum) -> syn::Result<TokenStream> {
let enum_ident = &item_enum.ident;

let (impl_generics, ty_generics, where_clause) = item_enum.generics.split_for_impl();

let mut item_impls: Vec<ItemImpl> = Vec::new();

for variant in item_enum.variants {
for variant in item_enum.variants.iter() {
let variant_ident = &variant.ident;
let variant_tag = symbol_from_string(&variant_ident.to_string());
let variant_type = get_variant_type(&variant)?;
let variant_type = get_variant_type(variant)?;

let item_impl: ItemImpl = parse2(quote! {
impl #impl_generics FromVariant<#variant_tag> for #enum_ident #ty_generics
Expand Down
10 changes: 4 additions & 6 deletions crates/cgp-macro-lib/src/entrypoints/derive_has_fields.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use proc_macro2::TokenStream;
use quote::TokenStreamExt;
use quote::quote;
use syn::{parse2, Error, Item};

use crate::derive_has_fields::{
Expand All @@ -20,9 +20,7 @@ pub fn derive_has_fields(body: TokenStream) -> syn::Result<TokenStream> {
}
};

let mut out = TokenStream::new();

out.append_all(impls);

Ok(out)
Ok(quote! {
#( #impls )*
})
}
4 changes: 4 additions & 0 deletions crates/cgp-macro-lib/src/entrypoints/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ mod blanket_trait;
mod cgp_auto_getter;
mod cgp_component;
mod cgp_context;
mod cgp_data;
mod cgp_getter;
mod cgp_new_provider;
mod cgp_preset;
mod cgp_provider;
mod cgp_record;
mod cgp_type;
mod cgp_variant;
mod check_components;
Expand All @@ -22,10 +24,12 @@ pub use blanket_trait::*;
pub use cgp_auto_getter::*;
pub use cgp_component::*;
pub use cgp_context::*;
pub use cgp_data::*;
pub use cgp_getter::*;
pub use cgp_new_provider::*;
pub use cgp_preset::*;
pub use cgp_provider::*;
pub use cgp_record::*;
pub use cgp_type::*;
pub use cgp_variant::*;
pub use check_components::*;
Expand Down
16 changes: 6 additions & 10 deletions crates/cgp-macro-lib/src/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ use alloc::string::ToString;
use alloc::vec::Vec;

use proc_macro2::TokenStream;
use quote::{quote, ToTokens};
use quote::quote;
use syn::spanned::Spanned;
use syn::{parse_quote, Fields, ItemImpl, ItemStruct, LitInt};

use crate::symbol::symbol_from_string;

pub fn derive_has_field_impls(item_struct: &ItemStruct) -> Vec<ItemImpl> {
pub fn derive_has_field_impls_from_struct(item_struct: &ItemStruct) -> Vec<ItemImpl> {
let struct_ident = &item_struct.ident;

let (impl_generics, ty_generics, where_clause) = item_struct.generics.split_for_impl();
Expand Down Expand Up @@ -109,16 +109,12 @@ pub fn derive_has_field_impls(item_struct: &ItemStruct) -> Vec<ItemImpl> {
item_impls
}

pub fn derive_fields(input: TokenStream) -> TokenStream {
pub fn derive_has_field(input: TokenStream) -> TokenStream {
let item_struct: ItemStruct = syn::parse2(input).unwrap();

let item_impls = derive_has_field_impls(&item_struct);
let item_impls = derive_has_field_impls_from_struct(&item_struct);

let mut output = TokenStream::new();

for item_impl in item_impls {
output.extend(item_impl.to_token_stream());
quote! {
#( #item_impls )*
}

output
}
2 changes: 1 addition & 1 deletion crates/cgp-macro-lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub(crate) mod product;
pub(crate) mod symbol;
pub(crate) mod type_component;

pub use field::derive_fields;
pub use field::derive_has_field;
pub use product::{make_product_expr, make_product_type, make_sum_type};
pub use symbol::make_symbol;

Expand Down
6 changes: 3 additions & 3 deletions crates/cgp-macro-lib/src/tests/field.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use quote::quote;

use crate::field::derive_fields;
use crate::field::derive_has_field;
use crate::tests::helper::equal::equal_token_stream;

#[test]
fn test_basic_derive_fields() {
let derived = derive_fields(quote! {
let derived = derive_has_field(quote! {
pub struct Foo {
pub bar: Bar,
pub baz: Baz,
Expand Down Expand Up @@ -59,7 +59,7 @@ fn test_basic_derive_fields() {

#[test]
fn test_generic_derive_fields() {
let derived = derive_fields(quote! {
let derived = derive_has_field(quote! {
pub struct Foo<FooParamA, FooParamB: Clone>
where
FooParamA: Eq,
Expand Down
18 changes: 16 additions & 2 deletions crates/cgp-macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -940,7 +940,7 @@ pub fn product(body: TokenStream) -> TokenStream {

#[proc_macro_derive(HasField)]
pub fn derive_fields(item: TokenStream) -> TokenStream {
cgp_macro_lib::derive_fields(item.into()).into()
cgp_macro_lib::derive_has_field(item.into()).into()
}

#[proc_macro_derive(HasFields)]
Expand Down Expand Up @@ -973,7 +973,21 @@ pub fn derive_from_variant(item: TokenStream) -> TokenStream {

#[proc_macro_derive(CgpVariant)]
pub fn derive_cgp_variant(item: TokenStream) -> TokenStream {
cgp_macro_lib::cgp_variant(item.into())
cgp_macro_lib::derive_cgp_variant(item.into())
.unwrap_or_else(syn::Error::into_compile_error)
.into()
}

#[proc_macro_derive(CgpRecord)]
pub fn derive_cgp_record(item: TokenStream) -> TokenStream {
cgp_macro_lib::derive_cgp_record(item.into())
.unwrap_or_else(syn::Error::into_compile_error)
.into()
}

#[proc_macro_derive(CgpData)]
pub fn derive_cgp_data(item: TokenStream) -> TokenStream {
cgp_macro_lib::derive_cgp_data(item.into())
.unwrap_or_else(syn::Error::into_compile_error)
.into()
}
6 changes: 3 additions & 3 deletions crates/cgp-tests/tests/extensible_data_tests/records/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,20 @@ use cgp::extra::dispatch::{BuildAndMerge, BuildAndSetField, BuildWithHandlers};
use cgp::extra::handler::{Computer, Producer, ProducerComponent};
use cgp::prelude::*;

#[derive(Debug, Eq, PartialEq, HasFields, BuildField)]
#[derive(Debug, Eq, PartialEq, CgpData)]
pub struct FooBarBaz {
pub foo: u64,
pub bar: String,
pub baz: bool,
}

#[derive(Debug, Eq, PartialEq, HasFields, BuildField)]
#[derive(Debug, Eq, PartialEq, CgpData)]
pub struct FooBar {
pub foo: u64,
pub bar: String,
}

#[derive(Debug, Eq, PartialEq, HasFields, BuildField)]
#[derive(Debug, Eq, PartialEq, CgpData)]
pub struct Baz {
pub baz: bool,
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use cgp::prelude::*;

#[derive(BuildField)]
#[derive(CgpData)]
pub struct Context<Foo, Bar, Baz>
where
Foo: Clone,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use cgp::prelude::*;

#[derive(BuildField)]
#[derive(CgpData)]
pub struct Context(pub u64, pub String, pub bool);
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use cgp::extra::field::impls::{
};
use cgp::prelude::*;

#[derive(HasFields, BuildField)]
#[derive(CgpData)]
pub struct Context {
pub foo: String,
pub bar: u64,
Expand Down
Loading
Loading