Skip to content

Commit

Permalink
macro_tools : introduce GenericsWithWhere
Browse files Browse the repository at this point in the history
  • Loading branch information
Wandalen committed Apr 15, 2024
1 parent 7b719c7 commit a1c42b4
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 12 deletions.
2 changes: 2 additions & 0 deletions module/core/former/tests/inc/former_tests/a_basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ pub struct Struct1

// = begin of generated



// = end of generated

include!( "./only_test/basic.rs" );
10 changes: 7 additions & 3 deletions module/core/former/tests/inc/former_tests/string_slice.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
use super::*;

// #[ derive( Debug, PartialEq, the_module::Former ) ]
#[ derive( Debug, PartialEq, the_module::Former ) ] #[ debug ]
// #[ derive( Debug, PartialEq, former::Former ) ]
#[ derive( Debug, PartialEq, former::Former ) ] #[ debug ]
pub struct Struct1< 'a >
{
pub string_slice_1 : &'a str,
}

//
// === begin of generated



// === end of generated

// include!( "./only_test/string_slice.rs" );
// xxx : uncomment
Original file line number Diff line number Diff line change
Expand Up @@ -261,4 +261,3 @@ where
// === end of generated

include!( "./only_test/string_slice.rs" );
// xxx : uncomment
2 changes: 1 addition & 1 deletion module/core/former/tests/inc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ mod former_tests

// xxx
mod string_slice_manual;
// mod string_slice;
mod string_slice;
mod unsigned_primitive_types;
mod default_user_type;
mod user_type_no_default;
Expand Down
16 changes: 15 additions & 1 deletion module/core/former_meta/src/derive/former.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1059,7 +1059,6 @@ pub fn former( input : proc_macro::TokenStream ) -> Result< TokenStream >
let has_debug = attr::has_debug( ast.attrs.iter() )?;
let example_of_custom_setter = false;


/* names */

let struct_name = &ast.ident;
Expand Down Expand Up @@ -1089,22 +1088,37 @@ pub fn former( input : proc_macro::TokenStream ) -> Result< TokenStream >
qt!{ #_generics_params, }
};

// xxx
// if has_debug
// {
// let q = qt!
// {
// < Definition = #former_definition < #generics_ty > >;
// };
// println!( "= a =" );
// // diag::debug_report_print( "derive : Former", original_input, &result );
// macro_tools::code_print!( q );
// }

// add embedded generic parameters
let mut extra_generics : syn::Generics = parse_quote!
{
< Definition = #former_definition < #generics_ty (), #struct_name, former::ReturnPreformed > >
// Definition = Struct1FormerDefinition< (), Struct1, former::ReturnPreformed >,
// xxx
};

extra_generics.where_clause = parse_quote!
{
where
Definition : former::FormerDefinition,
Definition::Types : former::FormerDefinitionTypes< Storage = #former_storage #generics_ty >,
// < Definition::Types as former::FormerDefinitionTypes >::Storage : former::StoragePreform,
};

// zzz : write helper to fix bug with where
let generics_of_former = generics::merge( &generics, &extra_generics );

let ( generics_of_former_impl, generics_of_former_ty, generics_of_former_where ) = generics_of_former.split_for_impl();
let generics_of_former_with_defaults = generics_of_former.params.clone();
// macro_tools::code_print!( generics_of_former_with_defaults );
Expand Down
92 changes: 92 additions & 0 deletions module/core/macro_tools/src/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,73 @@
pub( crate ) mod private
{

/// A `GenericsWithWhere` struct to handle the parsing of Rust generics with an explicit `where` clause.
///
/// This wrapper addresses the limitation in the `syn` crate where parsing `Generics` directly from a `ParseStream`
/// does not automatically handle associated `where` clauses. By integrating `where` clause parsing into the
/// `GenericsWithWhere`, this struct provides a seamless way to capture both the generics and their constraints
/// in scenarios where the `where` clause is crucial for type constraints and bounds in Rust macros and code generation.
///
/// Usage:
/// ```
/// let parsed_generics : macro_tools::GenericsWithWhere = syn::parse_str( "< T : Clone, U : Default = Default1 > where T : Default").unwrap();
/// assert!( parsed_generics.generics.params.len() == 2 );
/// assert!( parsed_generics.generics.where_clause.is_some() );
/// ```
///
#[ derive( Debug ) ]
pub struct GenericsWithWhere
{
/// Syn's generics parameters.
pub generics : syn::Generics,
}

impl GenericsWithWhere
{
/// Unwraps the `GenericsWithWhere` to retrieve the inner `syn::Generics`.
pub fn unwrap( self ) -> syn::Generics
{
self.generics
}

/// Parses a string to a `GenericsWithWhere`, specifically designed to handle generics syntax with where clauses effectively.
pub fn parse_from_str( s : &str ) -> syn::Result< GenericsWithWhere >
{
syn::parse_str::< GenericsWithWhere >( s )
}
}

impl syn::parse::Parse for GenericsWithWhere
{
fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self >
{
let generics : syn::Generics = input.parse()?;
let where_clause : Option< syn::WhereClause > = input.parse()?;

let mut generics_clone = generics.clone();
generics_clone.where_clause = where_clause;

Ok( GenericsWithWhere
{
generics : generics_clone,
})
}
}

impl quote::ToTokens for GenericsWithWhere
{
fn to_tokens( &self, tokens : &mut proc_macro2::TokenStream )
{
self.generics.to_tokens( tokens );
}
}

// pub fn make< IntoTokens : Into< proc_macro2::TokenStream > >( input : IntoTokens )
// {
//
// }

/// Merges two `syn::Generics` instances into a new one.
///
/// This function takes two references to `syn::Generics` and combines their
Expand Down Expand Up @@ -110,6 +177,25 @@ pub( crate ) mod private
result
}

// // add embedded generic parameters
// let mut extra_generics : syn::Generics = parse_quote!
// {
// < Definition = #former_definition < #generics_ty (), #struct_name, former::ReturnPreformed > >
// // Definition = Struct1FormerDefinition< (), Struct1, former::ReturnPreformed >,
// // xxx
// };
//
// extra_generics.where_clause = parse_quote!
// {
// where
// Definition : former::FormerDefinition,
// Definition::Types : former::FormerDefinitionTypes< Storage = #former_storage #generics_ty >,
// // < Definition::Types as former::FormerDefinitionTypes >::Storage : former::StoragePreform,
// };
//
// // zzz : write helper to fix bug with where
// let generics_of_former = generics::merge( &generics, &extra_generics );

/// Extracts parameter names from the given `Generics`,
/// dropping bounds, defaults, and the where clause.
///
Expand Down Expand Up @@ -210,6 +296,12 @@ pub mod orphan
#[ doc( inline ) ]
#[ allow( unused_imports ) ]
pub use super::exposed::*;
#[ doc( inline ) ]
#[ allow( unused_imports ) ]
pub use super::private::
{
GenericsWithWhere,
};
}

/// Exposed namespace of the module.
Expand Down
38 changes: 37 additions & 1 deletion module/core/macro_tools/tests/inc/generics_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use super::*;
//

#[ test ]
fn basic()
fn assumptions()
{

let mut generics_a : syn::Generics = parse_quote!{ < T : Clone, U : Default > };
Expand Down Expand Up @@ -38,6 +38,42 @@ fn basic()

//

#[ test ]
fn where_assumptions()
{

let got : the_module::GenericsWithWhere = parse_quote!
{
< 'a, T : Clone, U : Default >
where
Definition : former::FormerDefinition,
};
let got = got.unwrap();

let mut exp : syn::Generics = parse_quote!
{
< 'a, T : Clone, U : Default, V : std::fmt::Debug >
};
exp.where_clause = parse_quote!
{
where
Definition : former::FormerDefinition,
};

// a_id!( tree_print!( got ), tree_print!( exp ) );
// code_print!( got );
// code_print!( exp );
// code_print!( got.where_clause );
// code_print!( exp.where_clause );

assert_eq!( got.params, exp.params );
assert_eq!( got.where_clause, exp.where_clause );
assert_eq!( got, exp );

}

//

#[ test ]
fn merge_defaults()
{
Expand Down
5 changes: 0 additions & 5 deletions module/core/meta_tools/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@
#![ doc( html_logo_url = "https://raw.githubusercontent.com/Wandalen/wTools/master/asset/img/logo_v3_trans_square.png" ) ]
#![ doc( html_favicon_url = "https://raw.githubusercontent.com/Wandalen/wTools/alpha/asset/img/logo_v3_trans_square_icon_small_v2.ico" ) ]
#![ doc( html_root_url = "https://docs.rs/meta_tools/latest/meta_tools/" ) ]

//!
//! Collection of general purpose meta tools.
//!
#![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/", "Readme.md" ) ) ]

/// Namespace with dependencies.
Expand Down

0 comments on commit a1c42b4

Please sign in to comment.