Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

READY: Attribute macros phantom implementation #1375

Merged
merged 8 commits into from
Jun 11, 2024
Merged
Show file tree
Hide file tree
Changes from 5 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
6 changes: 6 additions & 0 deletions module/core/derive_tools/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ default = [
"derive_inner_from",
"derive_new",

"derive_phantom_data"

# "use_std",
]

Expand Down Expand Up @@ -114,6 +116,8 @@ full = [
"derive_inner_from",
"derive_new",

"derive_phantom_data"

# "use_std",
]
no_std = []
Expand Down Expand Up @@ -174,6 +178,8 @@ derive_from = [ "derive_tools_meta/derive_from" ]
derive_inner_from = [ "derive_tools_meta/derive_inner_from" ]
derive_new = [ "derive_tools_meta/derive_new" ]

derive_phantom_data = [ "derive_tools_meta/derive_phantom_data" ]

parse_display = [ "parse-display" ]

[dependencies]
Expand Down
13 changes: 13 additions & 0 deletions module/core/derive_tools/tests/inc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ mod all_manual_test;
feature = "derive_deref_mut",
feature = "derive_from",
feature = "derive_inner_from",
feature = "derive_phantom_data"
)
)]
mod all_test;
Expand Down Expand Up @@ -245,3 +246,15 @@ mod inner_from_tests
mod multiple_unnamed_test;

}

#[ cfg( feature = "derive_phantom_data" ) ]
#[ path = "phantom_data" ]
mod phantom_data_tests {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code style

#[ allow( unused_imports ) ]
use super::*;

mod struct_named;
mod struct_named_manual;
mod struct_tuple;
mod struct_tuple_manual;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#[ test ]
fn phantom_data()
{
let _ = StructNamed::< bool >{ a : "boo".into(), b : 3, _phantom: Default::default() };
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#[ test ]
fn phantom_data()
{
let _ = StructTuple::< bool >( "boo".into(), 3, Default::default() );
}
11 changes: 11 additions & 0 deletions module/core/derive_tools/tests/inc/phantom_data/struct_named.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use super::*;

#[ allow( dead_code ) ]
#[ the_module::phantom_data ]
struct StructNamed<T>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

codestyle

{
a : String,
b : i32,
}

include!("./only_test/struct_named.rs");
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

codestyle

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use super::*;
use std::marker::PhantomData;

#[ allow( dead_code ) ]
struct StructNamed<T>
{
a : String,
b : i32,
_phantom : PhantomData<T>,
}

include!("./only_test/struct_named.rs");
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
use super::*;

#[ allow( dead_code ) ]
#[ the_module::phantom_data ]
struct StructTuple< T >( String, i32 );

include!( "./only_test/struct_tuple.rs" );
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
use std::marker::PhantomData;
use super::*;

#[ allow( dead_code ) ]
struct StructTuple< T >( String, i32, PhantomData< T > );

include!( "./only_test/struct_tuple.rs" );
3 changes: 3 additions & 0 deletions module/core/derive_tools_meta/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ default = [
"derive_as_ref",
"derive_as_mut",
"derive_variadic_from",
"derive_phantom_data"
]
full = [
"enabled",
Expand All @@ -51,6 +52,7 @@ full = [
"derive_as_ref",
"derive_as_mut",
"derive_variadic_from",
"derive_phantom_data"
]
enabled = [ "macro_tools/enabled", "iter_tools/enabled", "former_types/enabled" ]

Expand All @@ -62,6 +64,7 @@ derive_from = []
derive_new = []
derive_inner_from = []
derive_variadic_from = []
derive_phantom_data = []

[dependencies]
# xxx : qqq : optimize features set
Expand Down
2 changes: 2 additions & 0 deletions module/core/derive_tools_meta/src/derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,5 @@ pub mod new;
pub mod variadic_from;
#[ cfg( feature = "derive_reflect" ) ]
pub mod reflect;
#[ cfg( feature = "derive_phantom_data" ) ]
pub mod phantom_data;
27 changes: 27 additions & 0 deletions module/core/derive_tools_meta/src/derive/phantom_data.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use super::*;
use macro_tools::{
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code style

attr,
diag,
Result,
phantom::add_to_item,
quote::ToTokens,
syn::ItemStruct,
};

pub fn phantom_data( input : proc_macro::TokenStream ) -> Result<proc_macro2::TokenStream>
{
let original_input = input.clone();
let parsed = syn::parse::< ItemStruct >( input )?;
let has_debug = attr::has_debug( parsed.attrs.iter() )?;
let item_name = &parsed.ident;

let result = add_to_item( &parsed ).to_token_stream();

if has_debug
{
let about = format!( "derive : PhantomData\nstructure : {item_name}" );
diag::report_print( about, &original_input, &result );
}

Ok( result )
}
51 changes: 51 additions & 0 deletions module/core/derive_tools_meta/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
feature = "derive_from",
feature = "derive_inner_from",
feature = "derive_variadic_from",
feature = "derive_phantom_data"
)
)]
#[ cfg( feature = "enabled" ) ]
Expand All @@ -30,6 +31,7 @@ mod derive;
// feature = "derive_from",
// feature = "derive_inner_from",
// feature = "derive_variadic_from",
// feature = "derive_phantom_data"
// )
// )]
// #[ cfg( feature = "enabled" ) ]
Expand Down Expand Up @@ -517,3 +519,52 @@ pub fn derive_variadic_from( input : proc_macro::TokenStream ) -> proc_macro::To
Err( err ) => err.to_compile_error().into(),
}
}

///
/// Provides an automatic `PhantomData` field for a struct based on its generic types.
///
/// This macro simplifies the addition of a `PhantomData` field to a struct
/// to indicate that the struct logically owns instances of the generic types,
/// even though it does not store them.
///
/// ## Example Usage
///
/// Instead of manually adding `PhantomData<T>` to `MyStruct`:
///
/// ```rust
/// use std::marker::PhantomData;
///
/// pub struct MyStruct<T>
/// {
/// data: i32,
/// _phantom: PhantomData<T>,
/// }
/// ```
///
/// Use `#[ phantom_data ]` to automatically generate the `PhantomData` field:
///
/// ```rust
/// use derive_tools_meta::*;
///
/// #[ phantom_data ]
/// pub struct MyStruct< T >
/// {
/// data: i32,
/// }
/// ```
///
/// The macro facilitates the addition of the `PhantomData` field without additional boilerplate code.
///

#[ cfg( feature = "enabled" ) ]
#[ cfg ( feature = "derive_phantom_data" ) ]
#[ proc_macro_attribute ]
pub fn phantom_data( _attr: proc_macro::TokenStream, input : proc_macro::TokenStream ) -> proc_macro::TokenStream
{
let result = derive::phantom_data::phantom_data( input );
match result
{
Ok( stream ) => stream.into(),
Err( err ) => err.to_compile_error().into(),
}
}