Skip to content

Commit

Permalink
NOT READY: Attribute macros phantom implementation (#1375)
Browse files Browse the repository at this point in the history
derive_tools : first implementation of derive_phantom
  • Loading branch information
BigglesworthCat authored Jun 11, 2024
1 parent 6a1ee3c commit 5f8ea59
Show file tree
Hide file tree
Showing 12 changed files with 151 additions and 0 deletions.
6 changes: 6 additions & 0 deletions module/core/derive_tools/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ default = [
"derive_inner_from",
"derive_new",

"derive_phantom"

# "use_std",
]

Expand Down Expand Up @@ -117,6 +119,8 @@ full = [
"derive_inner_from",
"derive_new",

"derive_phantom"

# "use_std",
]
no_std = []
Expand Down Expand Up @@ -177,6 +181,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 = [ "derive_tools_meta/derive_phantom" ]

parse_display = [ "parse-display" ]


Expand Down
14 changes: 14 additions & 0 deletions module/core/derive_tools/tests/inc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ mod all_manual_test;
feature = "derive_deref_mut",
feature = "derive_from",
feature = "derive_inner_from",
feature = "derive_phantom"
)
)]
mod all_test;
Expand Down Expand Up @@ -252,3 +253,16 @@ mod inner_from_tests
mod multiple_unnamed_test;

}

#[ cfg( feature = "derive_phantom" ) ]
#[ path = "phantom" ]
mod phantom_tests
{
#[ 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()
{
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()
{
let _ = StructTuple::< bool >( "boo".into(), 3, Default::default() );
}
11 changes: 11 additions & 0 deletions module/core/derive_tools/tests/inc/phantom/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 ]
struct StructNamed< T >
{
a : String,
b : i32,
}

include!( "./only_test/struct_named.rs" );
12 changes: 12 additions & 0 deletions module/core/derive_tools/tests/inc/phantom/struct_named_manual.rs
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" );
7 changes: 7 additions & 0 deletions module/core/derive_tools/tests/inc/phantom/struct_tuple.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
use super::*;

#[ allow( dead_code ) ]
#[ the_module::phantom ]
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"
]
full = [
"enabled",
Expand All @@ -51,6 +52,7 @@ full = [
"derive_as_ref",
"derive_as_mut",
"derive_variadic_from",
"derive_phantom"
]
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 = []

[dependencies]
# zzz : 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" ) ]
pub mod phantom;
28 changes: 28 additions & 0 deletions module/core/derive_tools_meta/src/derive/phantom.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use super::*;
use macro_tools::
{
attr,
diag,
Result,
phantom::add_to_item,
quote::ToTokens,
syn::ItemStruct,
};

pub fn phantom( 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"
)
)]
#[ 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"
// )
// )]
// #[ 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 ]` to automatically generate the `PhantomData` field:
///
/// ```rust
/// use derive_tools_meta::*;
///
/// #[ phantom ]
/// 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" ) ]
#[ proc_macro_attribute ]
pub fn phantom( _attr: proc_macro::TokenStream, input : proc_macro::TokenStream ) -> proc_macro::TokenStream
{
let result = derive::phantom::phantom( input );
match result
{
Ok( stream ) => stream.into(),
Err( err ) => err.to_compile_error().into(),
}
}

0 comments on commit 5f8ea59

Please sign in to comment.