From 97cb1fb0a74de665b2850b3b42d210fbd7236780 Mon Sep 17 00:00:00 2001 From: Anton Parfonov Date: Fri, 26 Apr 2024 09:45:53 +0300 Subject: [PATCH 01/10] DerefMut tests now use the macro --- .../derive_tools/tests/inc/deref_mut_test.rs | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/module/core/derive_tools/tests/inc/deref_mut_test.rs b/module/core/derive_tools/tests/inc/deref_mut_test.rs index 8624d1d43c..3560ca675f 100644 --- a/module/core/derive_tools/tests/inc/deref_mut_test.rs +++ b/module/core/derive_tools/tests/inc/deref_mut_test.rs @@ -3,21 +3,7 @@ use super::*; // use diagnostics_tools::prelude::*; // use derives::*; -#[ derive( Debug, Clone, Copy, PartialEq ) ] +#[ derive( Debug, Clone, Copy, PartialEq, the_module::Deref, the_module::DerefMut ) ] pub struct IsTransparent( bool ); -impl std::ops::Deref for IsTransparent { - type Target = bool; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl std::ops::DerefMut for IsTransparent { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.0 - } -} - include!( "./only_test/deref_mut.rs" ); From 65657e2a583c033c7621698382633ed3af247b9f Mon Sep 17 00:00:00 2001 From: Anton Parfonov Date: Fri, 3 May 2024 18:22:50 +0300 Subject: [PATCH 02/10] Implement Deref/DerefMut for generics --- .../derive_tools_meta/src/derive/deref.rs | 5 ++- .../derive_tools_meta/src/derive/deref_mut.rs | 5 ++- module/core/macro_tools/src/type_struct.rs | 37 ++++++++++++++++++- 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/module/core/derive_tools_meta/src/derive/deref.rs b/module/core/derive_tools_meta/src/derive/deref.rs index cf10b9630c..fbbc78de74 100644 --- a/module/core/derive_tools_meta/src/derive/deref.rs +++ b/module/core/derive_tools_meta/src/derive/deref.rs @@ -6,11 +6,14 @@ pub fn deref( input : proc_macro::TokenStream ) -> Result< proc_macro2::TokenStr { let parsed = syn::parse::< type_struct::TypeStructParsed >( input )?; let field_type = parsed.first_field_type()?; + let generic_arguments = parsed.generic_arguments(); let item_name = parsed.item_name; + let generics = parsed.generics; + let where_clause = &generics.where_clause; let result = qt! { - impl core::ops::Deref for #item_name + impl #generics ::core::ops::Deref for #item_name #generic_arguments #where_clause { type Target = #field_type; #[ inline( always ) ] diff --git a/module/core/derive_tools_meta/src/derive/deref_mut.rs b/module/core/derive_tools_meta/src/derive/deref_mut.rs index 0fd71ca1f6..757db562f9 100644 --- a/module/core/derive_tools_meta/src/derive/deref_mut.rs +++ b/module/core/derive_tools_meta/src/derive/deref_mut.rs @@ -7,11 +7,14 @@ use macro_tools::{ type_struct, Result }; pub fn deref_mut( input : proc_macro::TokenStream ) -> Result< proc_macro2::TokenStream > { let parsed = syn::parse::< type_struct::TypeStructParsed >( input )?; + let generic_arguments = parsed.generic_arguments(); let item_name = parsed.item_name; + let generics = parsed.generics; + let where_clause = &generics.where_clause; let result = qt! { - impl core::ops::DerefMut for #item_name + impl #generics ::core::ops::DerefMut for #item_name #generic_arguments #where_clause { #[ inline( always ) ] fn deref_mut( &mut self ) -> &mut Self::Target diff --git a/module/core/macro_tools/src/type_struct.rs b/module/core/macro_tools/src/type_struct.rs index b3390f5995..8aa21c2d81 100644 --- a/module/core/macro_tools/src/type_struct.rs +++ b/module/core/macro_tools/src/type_struct.rs @@ -6,6 +6,7 @@ pub( crate ) mod private { use super::super::*; + use quote::ToTokens; // use interval_adapter::BoundExt; // xxx : raname to Parsed @@ -22,6 +23,8 @@ pub( crate ) mod private pub item : syn::ItemStruct, /// Identifier of the struct, useful for referencing in generated code. pub item_name : syn::Ident, + /// Generics of the struct, including the where clause + pub generics : syn::Generics, /// Collection of struct's fields, including visibility, attributes, and types. pub fields : syn::Fields, } @@ -29,6 +32,37 @@ pub( crate ) mod private impl TypeStructParsed { + /// Returns a list of generic arguments based on generic parameters of the struct + /// + /// # Example: + /// `<'a, T: Default>` -> `<'a, T>` + pub fn generic_arguments( &self ) -> syn::AngleBracketedGenericArguments + { + let mut generics = &self.generics; + + let mut simplified_generics = Vec::with_capacity( generics.params.len() ); + for generic in &generics.params + { + let ident = match generic + { + syn::GenericParam::Lifetime( p ) => syn::GenericArgument::Lifetime( p.lifetime.to_owned() ), + syn::GenericParam::Type( p ) => syn::GenericArgument::Type( syn::Type::Verbatim( p.ident.to_token_stream() ) ), + syn::GenericParam::Const( p ) => syn::GenericArgument::Const( syn::Expr::Verbatim( p.ident.to_token_stream() ) ), + }; + simplified_generics.push(ident); + } + + let punctuated = syn::punctuated::Punctuated::<_, Token![,]>::from_iter(simplified_generics.into_iter()); + + syn::AngleBracketedGenericArguments + { + colon2_token: None, + lt_token: Default::default(), + args: punctuated, + gt_token: Default::default(), + } + } + /// Returns a vector of the struct's fields for iteration. pub fn fields_many( &self ) -> Vec< &syn::Field > { @@ -121,6 +155,7 @@ pub( crate ) mod private let item_name = item.ident.clone(); let fields = item.fields.clone(); + let generics = item.generics.clone(); // let fields_many : Vec< syn::Field > = match item.fields // { @@ -134,7 +169,7 @@ pub( crate ) mod private // let field_names = field_names( &fields_many )?; // Ok( Self { item, item_name, fields, fields_many, field_types, field_names } ) - Ok( Self { item, item_name, fields } ) + Ok( Self { item, item_name, generics, fields } ) } } From f74721e8d74b6f1036b6f8694f0d2de93c182017 Mon Sep 17 00:00:00 2001 From: Anton Parfonov Date: Fri, 17 May 2024 13:28:27 +0300 Subject: [PATCH 03/10] Tests for derive deref and mut --- .../tests/inc/deref_manual_test.rs | 21 ++++++++++-- .../tests/inc/deref_mut_manual_test.rs | 33 ++++++++++++++++--- .../derive_tools/tests/inc/deref_mut_test.rs | 8 ++++- .../core/derive_tools/tests/inc/deref_test.rs | 8 ++++- .../derive_tools/tests/inc/only_test/deref.rs | 18 ++++++++-- .../tests/inc/only_test/deref_mut.rs | 30 +++++++++++++++-- 6 files changed, 104 insertions(+), 14 deletions(-) diff --git a/module/core/derive_tools/tests/inc/deref_manual_test.rs b/module/core/derive_tools/tests/inc/deref_manual_test.rs index 57c3994eea..3ad2c5c1b4 100644 --- a/module/core/derive_tools/tests/inc/deref_manual_test.rs +++ b/module/core/derive_tools/tests/inc/deref_manual_test.rs @@ -3,12 +3,27 @@ use super::*; // use diagnostics_tools::prelude::*; // use derives::*; -#[ derive( Debug, Clone, Copy, PartialEq ) ] -pub struct IsTransparent( bool ); +#[ derive( Debug, Clone, Copy, PartialEq, ) ] +pub struct IsTransparentSimple( bool ); -impl core::ops::Deref for IsTransparent +impl core::ops::Deref for IsTransparentSimple { type Target = bool; + #[ inline ( always) ] + fn deref( &self ) -> &Self::Target + { + &self.0 + } +} + +#[ derive( Debug, Clone, Copy, PartialEq ) ] +pub struct IsTransparentComplex< 'a, 'b : 'a, T, U : ToString + ?Sized, const N : usize >( &'a T, core::marker::PhantomData< &'b U > ) +where 'a : 'b, T : AsRef< U >; + +impl< 'a, 'b : 'a, T, U : ToString + ?Sized, const N : usize > core::ops::Deref for IsTransparentComplex< 'a, 'b, T, U, N > +where 'a : 'b, T : AsRef< U > +{ + type Target = &'a T; #[ inline( always ) ] fn deref( &self ) -> &Self::Target { diff --git a/module/core/derive_tools/tests/inc/deref_mut_manual_test.rs b/module/core/derive_tools/tests/inc/deref_mut_manual_test.rs index c559375af5..a5541fbc52 100644 --- a/module/core/derive_tools/tests/inc/deref_mut_manual_test.rs +++ b/module/core/derive_tools/tests/inc/deref_mut_manual_test.rs @@ -3,12 +3,36 @@ use super::*; // use diagnostics_tools::prelude::*; // use derives::*; -#[ derive( Debug, Clone, Copy, PartialEq ) ] -pub struct IsTransparent( bool ); +#[ derive( Debug, Clone, Copy, PartialEq, ) ] +pub struct IsTransparentSimple( bool ); -impl core::ops::Deref for IsTransparent +impl core::ops::Deref for IsTransparentSimple { type Target = bool; + #[ inline ( always) ] + fn deref( &self ) -> &Self::Target + { + &self.0 + } +} + +impl core::ops::DerefMut for IsTransparentSimple +{ + #[ inline( always ) ] + fn deref_mut( &mut self ) -> &mut Self::Target + { + &mut self.0 + } +} + +#[ derive( Debug, Clone, Copy, PartialEq ) ] +pub struct IsTransparentComplex< 'a, 'b : 'a, T, U : ToString + ?Sized, const N : usize >( &'a T, core::marker::PhantomData< &'b U > ) +where 'a : 'b, T : AsRef< U >; + +impl< 'a, 'b : 'a, T, U : ToString + ?Sized, const N : usize > core::ops::Deref for IsTransparentComplex< 'a, 'b, T, U, N > +where 'a : 'b, T : AsRef< U > +{ + type Target = &'a T; #[ inline( always ) ] fn deref( &self ) -> &Self::Target { @@ -16,7 +40,8 @@ impl core::ops::Deref for IsTransparent } } -impl core::ops::DerefMut for IsTransparent +impl< 'a, 'b : 'a, T, U : ToString + ?Sized, const N : usize > core::ops::DerefMut for IsTransparentComplex< 'a, 'b, T, U, N > +where 'a : 'b, T : AsRef< U > { #[ inline( always ) ] fn deref_mut( &mut self ) -> &mut Self::Target diff --git a/module/core/derive_tools/tests/inc/deref_mut_test.rs b/module/core/derive_tools/tests/inc/deref_mut_test.rs index 3560ca675f..aae9db0775 100644 --- a/module/core/derive_tools/tests/inc/deref_mut_test.rs +++ b/module/core/derive_tools/tests/inc/deref_mut_test.rs @@ -4,6 +4,12 @@ use super::*; // use derives::*; #[ derive( Debug, Clone, Copy, PartialEq, the_module::Deref, the_module::DerefMut ) ] -pub struct IsTransparent( bool ); +pub struct IsTransparentSimple( bool ); + +#[ derive( Debug, Clone, Copy, PartialEq, the_module::Deref, the_module::DerefMut ) ] +pub struct IsTransparentComplex< 'a, 'b : 'a, T, U : ToString + ?Sized, const N : usize >( &'a T, core::marker::PhantomData< &'b U > ) +where + 'a : 'b, + T : AsRef< U >; include!( "./only_test/deref_mut.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_test.rs b/module/core/derive_tools/tests/inc/deref_test.rs index e7e9fc2772..df445ac9b4 100644 --- a/module/core/derive_tools/tests/inc/deref_test.rs +++ b/module/core/derive_tools/tests/inc/deref_test.rs @@ -4,6 +4,12 @@ use super::*; // use derives::*; #[ derive( Debug, Clone, Copy, PartialEq, the_module::Deref ) ] -pub struct IsTransparent( bool ); +pub struct IsTransparentSimple( bool ); + +#[ derive( Debug, Clone, Copy, PartialEq, the_module::Deref ) ] +pub struct IsTransparentComplex< 'a, 'b : 'a, T, U : ToString + ?Sized, const N : usize >( &'a T, core::marker::PhantomData< &'b U > ) +where + 'a : 'b, + T : AsRef< U >; include!( "./only_test/deref.rs" ); diff --git a/module/core/derive_tools/tests/inc/only_test/deref.rs b/module/core/derive_tools/tests/inc/only_test/deref.rs index 1586fa7430..2c5447dc84 100644 --- a/module/core/derive_tools/tests/inc/only_test/deref.rs +++ b/module/core/derive_tools/tests/inc/only_test/deref.rs @@ -1,12 +1,26 @@ #[ test ] -fn deref_test() +fn simple() { // Deref - let got = IsTransparent( true ); + let got = IsTransparentSimple( true ); let exp = true; a_id!( *got, exp ); } + +#[ test ] +fn complex() +{ + + // Deref + + let got_tmp = "start".to_string(); + let got = IsTransparentComplex::< '_, '_, String, str, 0 >( &got_tmp, core::marker::PhantomData ); + let exp_tmp = "start".to_string(); + let exp = &exp_tmp; + assert_eq!( *got, exp ); + +} diff --git a/module/core/derive_tools/tests/inc/only_test/deref_mut.rs b/module/core/derive_tools/tests/inc/only_test/deref_mut.rs index 357c28a108..ab36833c71 100644 --- a/module/core/derive_tools/tests/inc/only_test/deref_mut.rs +++ b/module/core/derive_tools/tests/inc/only_test/deref_mut.rs @@ -1,19 +1,43 @@ #[ test ] -fn deref_mut_test() +fn simple() { // Deref - let got = IsTransparent( true ); + let got = IsTransparentSimple( true ); let exp = true; a_id!( *got, exp ); // DerefMut - let mut got = IsTransparent( true ); + let mut got = IsTransparentSimple( true ); *got = false; let exp = false; a_id!( *got, exp ); } + +#[ test ] +fn complex() +{ + + // Deref + + let got_tmp = "start".to_string(); + let got = IsTransparentComplex::< '_, '_, String, str, 0 >( &got_tmp, core::marker::PhantomData ); + let exp_tmp = "start".to_string(); + let exp = &exp_tmp; + assert_eq!( *got, exp ); + + // DerefMut + + let got_tmp = "start".to_string(); + let mut got = IsTransparentComplex::< '_, '_, String, str, 0 >( &got_tmp, core::marker::PhantomData ); + let got_tmp = "end".to_string(); + *got = &got_tmp; + let exp_tmp = "end".to_string(); + let exp = &exp_tmp; + assert_eq!( *got, exp ); + +} From 901962787c6e710bd18e9530247645b75d5620d8 Mon Sep 17 00:00:00 2001 From: Anton Parfonov Date: Fri, 17 May 2024 16:40:32 +0300 Subject: [PATCH 04/10] Add documentation for From and InnerFrom helper functions --- .../core/derive_tools_meta/src/derive/from.rs | 199 ++++++++++++++---- .../src/derive/inner_from.rs | 136 ++++++++++-- 2 files changed, 282 insertions(+), 53 deletions(-) diff --git a/module/core/derive_tools_meta/src/derive/from.rs b/module/core/derive_tools_meta/src/derive/from.rs index 1a415eed14..6f8b6ee223 100644 --- a/module/core/derive_tools_meta/src/derive/from.rs +++ b/module/core/derive_tools_meta/src/derive/from.rs @@ -22,56 +22,141 @@ pub fn from( input : proc_macro::TokenStream ) -> Result< proc_macro2::TokenStre Ok( result ) } -// qqq : document, add example of generated code +// qqq : document, add example of generated code -- done +/// Generates `From` implementation for tuple structs with a single field +/// +/// # Example +/// +/// ## Input +/// ```rust +/// # use derive_tools_meta::From; +/// #[ derive( From ) ] +/// pub struct IsTransparent +/// { +/// value : bool, +/// } +/// ``` +/// +/// ## Output +/// ```rust +/// pub struct IsTransparent +/// { +/// value : bool, +/// } +/// #[ automatically_derived ] +/// impl From< bool > for IsTransparent +/// { +/// #[ inline( always ) ] +/// fn from( src : bool ) -> Self +/// { +/// Self { value : src } +/// } +/// } +/// ``` +/// fn generate_from_single_field_named ( - field_type: &syn::Type, - field_name: &syn::Ident, - item_name: syn::Ident, + field_type : &syn::Type, + field_name : &syn::Ident, + item_name : syn::Ident, ) -> proc_macro2::TokenStream { qt! { #[ automatically_derived ] - // impl From < i32 > for MyStruct impl From< #field_type > for #item_name { #[ inline( always ) ] - // fn from( src: i32 ) -> Self - fn from( src: #field_type ) -> Self + fn from( src : #field_type ) -> Self { - // Self { a: src } - Self { #field_name: src } + Self { #field_name : src } } } } } -// qqq : document, add example of generated code +// qqq : document, add example of generated code -- done +/// Generates `From`` implementation for structs with a single named field +/// +/// # Example of generated code +/// +/// ## Input +/// ```rust +/// # use derive_tools_meta::From; +/// #[ derive( From ) ] +/// pub struct IsTransparent( bool ); +/// ``` +/// +/// ## Output +/// ```rust +/// pub struct IsTransparent( bool ); +/// #[ automatically_derived ] +/// impl From< bool > for IsTransparent +/// { +/// #[ inline( always ) ] +/// fn from( src : bool ) -> Self +/// { +/// Self( src ) +/// } +/// } +/// ``` +/// fn generate_from_single_field ( - field_type: &syn::Type, - item_name: syn::Ident, + field_type : &syn::Type, + item_name : syn::Ident, ) -> proc_macro2::TokenStream { qt! { #[automatically_derived] - // impl From< bool > for IsTransparent impl From< #field_type > for #item_name { #[ inline( always ) ] - // fn from( src: bool ) -> Self - fn from( src: #field_type ) -> Self + fn from( src : #field_type ) -> Self { - // Self(src) - Self(src) + Self( src ) } } } } -// qqq : for Petro : document, add example of generated code +// qqq : document, add example of generated code -- done +/// Generates `From` implementation for structs with multiple named fields +/// +/// # Example +/// +/// ## Input +/// ```rust +/// # use derive_tools_meta::From; +/// #[ derive( From ) ] +/// pub struct Struct +/// { +/// value1 : bool, +/// value2 : i32, +/// } +/// ``` +/// +/// ## Output +/// ```rust +/// pub struct Struct +/// { +/// value1 : bool, +/// value2 : i32, +/// } +/// impl From< ( bool, i32 ) > for Struct +/// { +/// #[ inline( always ) ] +/// fn from( src : ( bool, i32 ) ) -> Self +/// { +/// Struct +/// { +/// value1 : src.0, +/// value2 : src.1, +/// } +/// } +/// } +/// ``` fn generate_from_multiple_fields_named ( field_types : &Vec< &syn::Type >, @@ -91,28 +176,48 @@ fn generate_from_multiple_fields_named qt! { - // impl From< (i32, bool) > for StructNamedFields - impl From< (#(#field_types), *) > for #item_name + impl From< ( #( #field_types ), * ) > for #item_name { #[ inline( always ) ] - // fn from( src: (i32, bool) ) -> Self - fn from( src: (#(#field_types), *) ) -> Self + fn from( src : ( #( #field_types ), * ) ) -> Self { - // StructNamedFields{ a: src.0, b: src.1 } - #item_name { #(#params), * } + #item_name { #( #params ), * } } } } } -// qqq : document, add example of generated code +// qqq : document, add example of generated code -- done +/// Generates `From` implementation for tuple structs with multiple fields +/// +/// # Example +/// +/// ## Input +/// ```rust +/// # use derive_tools_meta::From; +/// #[ derive( From ) ] +/// pub struct Struct( bool, i32 ); +/// ``` +/// +/// ## Output +/// ```rust +/// pub struct Struct( bool, i32 ); +/// impl From< ( bool, i32 ) > for Struct +/// { +/// #[ inline( always ) ] +/// fn from( src : ( bool, i32 ) ) -> Self +/// { +/// Struct( src.0, src.1 ) +/// } +/// } +/// ``` fn generate_from_multiple_fields ( field_types : &Vec< &syn::Type >, - item_name: syn::Ident, + item_name : syn::Ident, ) -> proc_macro2::TokenStream { - let params: Vec< proc_macro2::TokenStream > = ( 0..field_types.len() ) + let params : Vec< proc_macro2::TokenStream > = ( 0..field_types.len() ) .map( | index | { let index = index.to_string().parse::< proc_macro2::TokenStream >().unwrap(); @@ -122,30 +227,50 @@ fn generate_from_multiple_fields qt! { - // impl From< (i32, bool) > for StructWithManyFields - impl From< (#(#field_types), *) > for #item_name + impl From< ( #( #field_types ), * ) > for #item_name { #[ inline( always ) ] - // fn from( src: (i32, bool) ) -> Self - fn from( src: (#(#field_types), *) ) -> Self + fn from( src : ( #( #field_types ), * ) ) -> Self { - // StructWithManyFields( src.0, src.1 ) - #item_name( #(#params), *) + #item_name( #( #params ), * ) } } } } -// qqq : document, add example of generated code -fn generate_unit( item_name: syn::Ident ) -> proc_macro2::TokenStream +// qqq : document, add example of generated code -- done +/// Generates `From` implementation for unit structs +/// +/// # Example +/// +/// ## Input +/// ```rust +/// # use derive_tools_meta::From; +/// #[ derive( From ) ] +/// pub struct IsTransparent; +/// ``` +/// +/// ## Output +/// ```rust +/// pub struct IsTransparent; +/// impl From< () > for IsTransparent +/// { +/// #[ inline( always ) ] +/// fn from( src : () ) -> Self +/// { +/// Self +/// } +/// } +/// ``` +/// +fn generate_unit( item_name : syn::Ident ) -> proc_macro2::TokenStream { qt! { - // impl From< () > for UnitStruct impl From< () > for #item_name { #[ inline( always ) ] - fn from( src: () ) -> Self + fn from( src : () ) -> Self { Self } diff --git a/module/core/derive_tools_meta/src/derive/inner_from.rs b/module/core/derive_tools_meta/src/derive/inner_from.rs index bf80c7dd51..b3d8b0392f 100644 --- a/module/core/derive_tools_meta/src/derive/inner_from.rs +++ b/module/core/derive_tools_meta/src/derive/inner_from.rs @@ -48,6 +48,39 @@ pub fn inner_from( input : proc_macro::TokenStream ) -> Result< proc_macro2::Tok } // qqq : document, add example of generated code +/// Generates `From` implementation for the inner type regarding bounded type +/// Works with structs with a single named field +/// +/// # Example +/// +/// ## Input +/// ```rust +/// # use derive_tools_meta::InnerFrom; +/// #[ derive( InnerFrom ) ] +/// pub struct Struct +/// { +/// value : bool, +/// } +/// ``` +/// +/// ## Output +/// ```rust +/// pub struct Struct +/// { +/// value : bool, +/// } +/// #[ allow( non_local_definitions ) ] +/// #[ automatically_derived ] +/// impl From< Struct > for bool +/// { +/// #[ inline( always ) ] +/// fn from( src : Struct ) -> Self +/// { +/// src.value +/// } +/// } +/// ``` +/// fn from_impl_named ( item_name : syn::Ident, @@ -59,21 +92,44 @@ fn from_impl_named { #[ allow( non_local_definitions ) ] #[ automatically_derived ] - // impl From< MyStruct > for i32 impl From< #item_name > for #field_type { #[ inline( always ) ] - // fm from( src: MyStruct ) -> Self fn from( src: #item_name ) -> Self { - // src.a src.#field_name } } } } -// qqq : document, add example of generated code +// qqq : document, add example of generated code -- done +/// Generates `From` implementation for the only contained type regarding the bounded type +/// +/// # Example +/// +/// ## Input +/// ```rust +/// # use derive_tools_meta::InnerFrom; +/// #[ derive( InnerFrom ) ] +/// pub struct Struct( bool ); +/// ``` +/// +/// ## Output +/// ```rust +/// pub struct Struct( bool ); +/// #[ allow( non_local_definitions ) ] +/// #[ automatically_derived ] +/// impl From< Struct > for bool +/// { +/// #[ inline( always ) ] +/// fn from( src : Struct ) -> Self +/// { +/// src.0 +/// } +/// } +/// ``` +/// fn from_impl ( item_name : syn::Ident, @@ -84,11 +140,9 @@ fn from_impl { #[ allow( non_local_definitions ) ] #[ automatically_derived ] - // impl From< IsTransparent> for bool impl From< #item_name > for #field_type { #[ inline( always ) ] - // fn from( src: IsTransparent ) -> Self fn from( src: #item_name ) -> Self { src.0 @@ -97,7 +151,34 @@ fn from_impl } } -// qqq : document, add example of generated code +// qqq : document, add example of generated code -- done +/// Generates `From` implementation for the tuple type containing all the inner types regarding the bounded type +/// Can generate implementations both for structs with named fields and tuple structs. +/// +/// # Example +/// +/// ## Input +/// ```rust +/// # use derive_tools_meta::InnerFrom; +/// #[ derive( InnerFrom ) ] +/// pub struct Struct( bool, i32 ); +/// ``` +/// +/// ## Output +/// ```rust +/// pub struct Struct( bool, i32 ); +/// #[ allow( non_local_definitions ) ] +/// #[ automatically_derived ] +/// impl From< Struct > for ( bool, i32 ) +/// { +/// #[ inline( always ) ] +/// fn from( src : Struct ) -> Self +/// { +/// ( src.0, src.1 ) +/// } +/// } +/// ``` +/// fn from_impl_multiple_fields ( item_name : syn::Ident, @@ -109,32 +190,55 @@ fn from_impl_multiple_fields { #[ allow( non_local_definitions ) ] #[ automatically_derived ] - // impl From< StructWithManyFields > for ( i32, bool ) - impl From< #item_name > for ( #(#field_types), *) + impl From< #item_name > for ( #( #field_types ), *) { #[ inline( always ) ] - // fn from( src: StructWithManyFields ) -> Self - fn from( src: #item_name ) -> Self + fn from( src : #item_name ) -> Self { - //( src.0, src.1 ) - (#(#params), *) + ( #( #params ), * ) } } } } -// qqq : document, add example of generated code +// qqq : document, add example of generated code -- done +/// Generates `From` implementation for the unit type regarding the bound type +/// +/// # Example +/// +/// ## Input +/// ```rust +/// # use derive_tools_meta::InnerFrom; +/// #[ derive( InnerFrom ) ] +/// pub struct Struct; +/// ``` +/// +/// ## Output +/// ```rust +/// pub struct Struct; +/// #[ allow( non_local_definitions ) ] +/// #[ allow( clippy::unused_imports ) ] +/// #[ automatically_derived] +/// impl From< Struct > for () +/// { +/// #[ inline( always ) ] +/// fn from( src : Struct ) -> () +/// { +/// () +/// } +/// } +/// ``` +/// fn unit( item_name : syn::Ident ) -> proc_macro2::TokenStream { qt! { #[ allow( non_local_definitions ) ] + #[ allow( clippy::unused_imports ) ] #[ automatically_derived ] - // impl From< UnitStruct > for () impl From< #item_name > for () { #[ inline( always ) ] - // fn from( src: UnitStruct ) -> () fn from( src: #item_name ) -> () { () From 0c59b3bf2ee8bc0db782982b537606aed0c8561c Mon Sep 17 00:00:00 2001 From: Anton Parfonov Date: Mon, 20 May 2024 09:33:28 +0300 Subject: [PATCH 05/10] Update deref, deref_mut, fix macro_tools::generic_params --- .../derive_tools_meta/src/derive/deref.rs | 141 +++++++++++-- .../derive_tools_meta/src/derive/deref_mut.rs | 191 ++++++++++++++++-- module/core/macro_tools/src/generic_params.rs | 12 +- 3 files changed, 316 insertions(+), 28 deletions(-) diff --git a/module/core/derive_tools_meta/src/derive/deref.rs b/module/core/derive_tools_meta/src/derive/deref.rs index 9de0e2a829..5e4b5eda82 100644 --- a/module/core/derive_tools_meta/src/derive/deref.rs +++ b/module/core/derive_tools_meta/src/derive/deref.rs @@ -1,32 +1,62 @@ use super::*; -use macro_tools::{ attr, diag, item_struct, Result }; +use macro_tools::{ attr, diag, generic_params, item_struct, Result, struct_like::StructLike }; pub fn deref( input : proc_macro::TokenStream ) -> Result< proc_macro2::TokenStream > { let original_input = input.clone(); - let parsed = syn::parse::< type_struct::TypeStructParsed >( input )?; - let has_debug = attr::has_debug( parsed.attrs.iter() )?; + let parsed = syn::parse::< StructLike >( input )?; + let has_debug = attr::has_debug( parsed.attrs().iter() )?; + let item_name = &parsed.ident(); - let field_type = item_struct::first_field_type( &parsed )?; - let generic_arguments = parsed.generic_arguments(); - let item_name = parsed.item_name; - let generics = parsed.generics; - let where_clause = &generics.where_clause; + let ( _generics_with_defaults, generics_impl, generics_ty, generics_where ) + = generic_params::decompose( &parsed.generics() ); - let result = qt! + let result = match parsed { - impl #generics ::core::ops::Deref for #item_name #generic_arguments #where_clause + StructLike::Unit( ref item ) | StructLike::Struct( ref item ) => { - type Target = #field_type; - #[ inline( always ) ] - fn deref( &self ) -> &Self::Target + let mut field_types = item_struct::field_types( &item ); + let field_names = item_struct::field_names( &item ); + + match ( field_types.len(), field_names ) { - &self.0 + ( 0, _ ) => + generate_unit + ( + item_name, + &generics_impl, + &generics_ty, + &generics_where, + ), + ( _, Some( mut field_names ) ) => + generate_named_field + ( + item_name, + &generics_impl, + &generics_ty, + &generics_where, + field_names.next().unwrap(), + &field_types.next().unwrap(), + ), + ( _, None ) => + generate_tuple_field + ( + item_name, + &generics_impl, + &generics_ty, + &generics_where, + &field_types.next().unwrap(), + ), } } + StructLike::Enum( ref item ) => + { + todo!() + } }; + eprintln!("{result}"); if has_debug { let about = format!( "derive : Deref\nstructure : {item_name}" ); @@ -35,3 +65,86 @@ pub fn deref( input : proc_macro::TokenStream ) -> Result< proc_macro2::TokenStr Ok( result ) } + +// qqq : docs +fn generate_unit +( + item_name : &syn::Ident, + generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_where: &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, +) +-> proc_macro2::TokenStream +{ + qt! + { + #[ automatically_derived ] + impl< #generics_impl > ::core::ops::Deref for #item_name< #generics_ty > + where + #generics_where + { + type Target = (); + fn deref( &self ) -> &Self::Target + { + &() + } + } + } +} + +// qqq : docs +fn generate_named_field +( + item_name : &syn::Ident, + generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_where: &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, + field_name : &syn::Ident, + field_type : &syn::Type, +) +-> proc_macro2::TokenStream +{ + qt! + { + #[ automatically_derived ] + impl< #generics_impl > ::core::ops::Deref for #item_name< #generics_ty > + where + #generics_where + { + type Target = #field_type; + #[ inline( always ) ] + fn deref( &self ) -> &Self::Target + { + &self.#field_name + } + } + } +} + +// qqq : docs +fn generate_tuple_field +( + item_name : &syn::Ident, + generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_where: &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, + field_type : &syn::Type, +) +-> proc_macro2::TokenStream +{ + qt! + { + #[ automatically_derived ] + impl< #generics_impl > ::core::ops::Deref for #item_name< #generics_ty > + where + #generics_where + { + type Target = #field_type; + #[ inline( always ) ] + fn deref( &self ) -> &Self::Target + { + &self.0 + } + } + } +} diff --git a/module/core/derive_tools_meta/src/derive/deref_mut.rs b/module/core/derive_tools_meta/src/derive/deref_mut.rs index 8d21ec7b62..63317386b7 100644 --- a/module/core/derive_tools_meta/src/derive/deref_mut.rs +++ b/module/core/derive_tools_meta/src/derive/deref_mut.rs @@ -1,30 +1,59 @@ use super::*; -use macro_tools::{ attr, diag, Result }; +use macro_tools::{ attr, diag, generic_params, item_struct, Result, struct_like::StructLike }; // pub fn deref_mut( input : proc_macro::TokenStream ) -> Result< proc_macro2::TokenStream > { let original_input = input.clone(); - let parsed = syn::parse::< type_struct::TypeStructParsed >( input )?; - let has_debug = attr::has_debug( parsed.attrs.iter() )?; + let parsed = syn::parse::< StructLike >( input )?; + let has_debug = attr::has_debug( parsed.attrs().iter() )?; + let item_name = &parsed.ident(); - let generic_arguments = parsed.generic_arguments(); - let item_name = parsed.item_name; - let generics = parsed.generics; - let where_clause = &generics.where_clause; + let ( _generics_with_defaults, generics_impl, generics_ty, generics_where ) + = generic_params::decompose( &parsed.generics() ); - let result = qt! + let result = match parsed { - impl #generics ::core::ops::DerefMut for #item_name #generic_arguments #where_clause + StructLike::Unit( ref item ) | StructLike::Struct( ref item ) => { - #[ inline( always ) ] - fn deref_mut( &mut self ) -> &mut Self::Target + let field_types = item_struct::field_types( &item ); + let field_names = item_struct::field_names( &item ); + + match ( field_types.len(), field_names ) { - &mut self.0 + ( 0, _ ) => + generate_unit + ( + item_name, + &generics_impl, + &generics_ty, + &generics_where, + ), + ( _, Some( mut field_names ) ) => + generate_named_field + ( + item_name, + &generics_impl, + &generics_ty, + &generics_where, + field_names.next().unwrap(), + ), + ( _, None ) => + generate_tuple_field + ( + item_name, + &generics_impl, + &generics_ty, + &generics_where, + ), } } + StructLike::Enum( ref item ) => + { + todo!() + } }; if has_debug @@ -35,3 +64,141 @@ pub fn deref_mut( input : proc_macro::TokenStream ) -> Result< proc_macro2::Toke Ok( result ) } + +// qqq : docs +fn generate_unit +( + item_name : &syn::Ident, + generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_where: &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, +) +-> proc_macro2::TokenStream +{ + qt! + { + #[ automatically_derived ] + impl< #generics_impl > ::core::ops::DerefMut for #item_name< #generics_ty > + where + #generics_where + { + fn deref_mut( &mut self ) -> &mut Self::Target + { + &mut () + } + } + } +} + +// qqq : docs +fn generate_named_field +( + item_name : &syn::Ident, + generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_where: &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, + field_name : &syn::Ident, +) +-> proc_macro2::TokenStream +{ + qt! + { + #[ automatically_derived ] + impl< #generics_impl > ::core::ops::DerefMut for #item_name< #generics_ty > + where + #generics_where + { + #[ inline( always ) ] + fn deref_mut( &mut self ) -> &mut Self::Target + { + &mut self.#field_name + } + } + } +} + +// qqq : docs +fn generate_tuple_field +( + item_name : &syn::Ident, + generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_where: &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, +) +-> proc_macro2::TokenStream +{ + qt! + { + #[ automatically_derived ] + impl< #generics_impl > ::core::ops::DerefMut for #item_name< #generics_ty > + where + #generics_where + { + #[ inline( always ) ] + fn deref_mut( &mut self ) -> &mut Self::Target + { + &mut self.0 + } + } + } +} + +// qqq : docs +fn generate_variant +( + item_name : &syn::Ident, + generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_where: &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, + variant : &syn::Variant, +) +-> proc_macro2::TokenStream +{ + // TODO + todo!() + // let variant_name = &variant.ident; + // let fields = &variant.fields; + + // if fields.len() <= 0 + // { + // return qt!{}; + // } + + // let ( args, use_src ) = if fields.len() == 1 + // { + // let field = fields.iter().next().unwrap(); + // ( + // qt!{ #field }, + // qt!{ src }, + // ) + // } + // else + // { + // let src_i = ( 0..fields.len() ).map( | e | + // { + // let i = syn::Index::from( e ); + // qt!{ src.#i, } + // }); + // ( + // qt!{ #fields }, + // qt!{ #( #src_i )* }, + // // qt!{ src.0, src.1 }, + // ) + // }; + + // qt! + // { + // #[ automatically_derived ] + // impl< #generics_impl > DerefMut< #args > for #item_name< #generics_ty > + // where + // #generics_where + // { + // #[ inline ] + // fn deref_mut( src : #args ) -> Self + // { + // Self::#variant_name( #use_src ) + // } + // } + // } + +} diff --git a/module/core/macro_tools/src/generic_params.rs b/module/core/macro_tools/src/generic_params.rs index 5af6bdc366..09f4445e5b 100644 --- a/module/core/macro_tools/src/generic_params.rs +++ b/module/core/macro_tools/src/generic_params.rs @@ -462,10 +462,18 @@ pub( crate ) mod private }, syn::GenericParam::Lifetime( lifetime_param ) => { - // Lifetimes are added as-is to both generics_for_impl and generics_for_ty + // Lifetimes are added as-is to generics_for_impl and without bounds to generics_for_ty generics_for_impl.push_value( syn::GenericParam::Lifetime( lifetime_param.clone() ) ); generics_for_impl.push_punct( syn::token::Comma::default() ); - generics_for_ty.push_value( syn::GenericParam::Lifetime( lifetime_param.clone() ) ); + + let ty_param = syn::GenericParam::Lifetime( syn::LifetimeParam + { + attrs : vec![], + lifetime : lifetime_param.lifetime.clone(), + colon_token : None, + bounds : syn::punctuated::Punctuated::new(), + }); + generics_for_ty.push_value( ty_param ); generics_for_ty.push_punct( syn::token::Comma::default() ); } } From 9a993cdc8834fa7af94b491c4bc2b14f5ab1bafc Mon Sep 17 00:00:00 2001 From: Anton Parfonov Date: Fri, 31 May 2024 12:36:36 +0300 Subject: [PATCH 06/10] Implement Deref and DerefMut --- .../derive_tools_meta/src/derive/deref.rs | 547 +++++++++++++--- .../derive_tools_meta/src/derive/deref_mut.rs | 593 ++++++++++++++---- 2 files changed, 938 insertions(+), 202 deletions(-) diff --git a/module/core/derive_tools_meta/src/derive/deref.rs b/module/core/derive_tools_meta/src/derive/deref.rs index 5e4b5eda82..3d35cce3fb 100644 --- a/module/core/derive_tools_meta/src/derive/deref.rs +++ b/module/core/derive_tools_meta/src/derive/deref.rs @@ -1,6 +1,7 @@ - use super::*; -use macro_tools::{ attr, diag, generic_params, item_struct, Result, struct_like::StructLike }; +use macro_tools::{ attr, diag, generic_params, Result, struct_like::StructLike }; + +// pub fn deref( input : proc_macro::TokenStream ) -> Result< proc_macro2::TokenStream > { @@ -14,49 +15,40 @@ pub fn deref( input : proc_macro::TokenStream ) -> Result< proc_macro2::TokenStr let result = match parsed { - StructLike::Unit( ref item ) | StructLike::Struct( ref item ) => + StructLike::Unit( _ ) => { - let mut field_types = item_struct::field_types( &item ); - let field_names = item_struct::field_names( &item ); - - match ( field_types.len(), field_names ) - { - ( 0, _ ) => - generate_unit - ( - item_name, - &generics_impl, - &generics_ty, - &generics_where, - ), - ( _, Some( mut field_names ) ) => - generate_named_field - ( - item_name, - &generics_impl, - &generics_ty, - &generics_where, - field_names.next().unwrap(), - &field_types.next().unwrap(), - ), - ( _, None ) => - generate_tuple_field - ( - item_name, - &generics_impl, - &generics_ty, - &generics_where, - &field_types.next().unwrap(), - ), - } + generate_unit + ( + item_name, + &generics_impl, + &generics_ty, + &generics_where, + ) + } + StructLike::Struct( ref item ) => + { + generate_struct + ( + item_name, + &generics_impl, + &generics_ty, + &generics_where, + &item.fields, + ) } StructLike::Enum( ref item ) => { - todo!() + generate_enum + ( + item_name, + &generics_impl, + &generics_ty, + &generics_where, + &item.variants, + ) } - }; + }?; - eprintln!("{result}"); if has_debug { let about = format!( "derive : Deref\nstructure : {item_name}" ); @@ -66,7 +58,31 @@ pub fn deref( input : proc_macro::TokenStream ) -> Result< proc_macro2::TokenStr Ok( result ) } -// qqq : docs +/// Generates `Deref` implementation for unit structs and enums +/// +/// # Example +/// +/// ## Input +/// ```rust +/// #[ derive( Deref ) ] +/// pub struct Struct; +/// ``` +/// +/// ## Output +/// ```rust +/// pub struct Struct; +/// #[ automatically_derived ] +/// impl ::core::ops::Deref for Struct +/// { +/// type Target = (); +/// #[ inline( always ) ] +/// fn deref( &self ) -> &Self::Target +/// { +/// &() +/// } +/// } +/// ``` +/// fn generate_unit ( item_name : &syn::Ident, @@ -74,77 +90,452 @@ fn generate_unit generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, generics_where: &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, ) --> proc_macro2::TokenStream +-> Result< proc_macro2::TokenStream > { - qt! - { - #[ automatically_derived ] - impl< #generics_impl > ::core::ops::Deref for #item_name< #generics_ty > - where - #generics_where + Ok + ( + qt! { - type Target = (); - fn deref( &self ) -> &Self::Target + #[ automatically_derived ] + impl< #generics_impl > ::core::ops::Deref for #item_name< #generics_ty > + where + #generics_where { - &() + type Target = (); + #[ inline( always ) ] + fn deref( &self ) -> &Self::Target + { + &() + } } } + ) +} + +/// An aggregator function to generate `Deref` implementation for unit, tuple structs and the ones with named fields +fn generate_struct +( + item_name : &syn::Ident, + generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_where: &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, + fields : &syn::Fields, +) +-> Result< proc_macro2::TokenStream > +{ + match fields + { + + syn::Fields::Unit => + generate_unit + ( + item_name, + generics_impl, + generics_ty, + generics_where, + ), + + syn::Fields::Unnamed( fields ) => + generate_struct_tuple_fields + ( + item_name, + generics_impl, + generics_ty, + generics_where, + fields, + ), + + syn::Fields::Named( fields ) => + generate_struct_named_fields + ( + item_name, + generics_impl, + generics_ty, + generics_where, + fields, + ), + } } -// qqq : docs -fn generate_named_field +/// Generates `Deref` implementation for structs with tuple fields +/// +/// # Example +/// +/// ## Input +/// ```rust +/// #[ derive( Deref ) ] +/// pub struct Struct( i32, Vec< String > ); +/// ``` +/// +/// ## Output +/// ```rust +/// pub struct Struct( i32, Vec< String > ); +/// #[ automatically_derived ] +/// impl ::core::ops::Deref for Struct +/// { +/// type Target = i32; +/// #[ inline( always ) ] +/// fn deref( &self ) -> &Self::Target +/// { +/// &self.0 +/// } +/// } +/// ``` +/// +fn generate_struct_tuple_fields ( item_name : &syn::Ident, generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, generics_where: &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, - field_name : &syn::Ident, - field_type : &syn::Type, + fields : &syn::FieldsUnnamed, ) --> proc_macro2::TokenStream +-> Result< proc_macro2::TokenStream > { - qt! + let fields = &fields.unnamed; + let field_type = match fields.first() { - #[ automatically_derived ] - impl< #generics_impl > ::core::ops::Deref for #item_name< #generics_ty > - where - #generics_where + Some( field ) => &field.ty, + None => return generate_unit + ( + item_name, + generics_impl, + generics_ty, + generics_where, + ), + }; + + Ok + ( + qt! { - type Target = #field_type; - #[ inline( always ) ] - fn deref( &self ) -> &Self::Target + #[ automatically_derived ] + impl< #generics_impl > ::core::ops::Deref for #item_name< #generics_ty > + where + #generics_where { - &self.#field_name + type Target = #field_type; + #[ inline( always ) ] + fn deref( &self ) -> &Self::Target + { + &self.0 + } } } - } + ) } -// qqq : docs -fn generate_tuple_field +/// Generates `Deref` implementation for structs with named fields +/// +/// # Example +/// +/// ## Input +/// ```rust +/// #[ derive( Deref ) ] +/// pub struct Struct +/// { +/// a : i32, +/// b : Vec< String >, +/// } +/// ``` +/// +/// ## Output +/// ```rust +/// pub struct Struct +/// { +/// a : i32, +/// b : Vec< String >, +/// } +/// #[ automatically_derived ] +/// impl ::core::ops::Deref for Struct +/// { +/// type Target = i32; +/// #[ inline( always ) ] +/// fn deref( &self ) -> &Self::Target +/// { +/// &self.a +/// } +/// } +/// ``` +/// +fn generate_struct_named_fields ( item_name : &syn::Ident, generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, generics_where: &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, - field_type : &syn::Type, + fields : &syn::FieldsNamed, ) --> proc_macro2::TokenStream +-> Result< proc_macro2::TokenStream > { - qt! + let fields = &fields.named; + let ( field_name, field_type ) = match fields.first() { - #[ automatically_derived ] - impl< #generics_impl > ::core::ops::Deref for #item_name< #generics_ty > - where - #generics_where + Some( field ) => ( field.ident.as_ref().unwrap(), &field.ty ), + None => return generate_unit + ( + item_name, + generics_impl, + generics_ty, + generics_where, + ), + }; + + Ok + ( + qt! { - type Target = #field_type; - #[ inline( always ) ] - fn deref( &self ) -> &Self::Target + #[ automatically_derived ] + impl< #generics_impl > ::core::ops::Deref for #item_name< #generics_ty > + where + #generics_where { - &self.0 + type Target = #field_type; + #[ inline( always ) ] + fn deref( &self ) -> &Self::Target + { + &self.#field_name + } } } + ) +} + +/// An aggregator function to generate `Deref` implementation for unit, tuple enums and the ones with named fields +fn generate_enum +( + item_name : &syn::Ident, + generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_where: &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, + variants : &syn::punctuated::Punctuated, +) +-> Result< proc_macro2::TokenStream > +{ + let fields = match variants.first() + { + Some( variant ) => &variant.fields, + None => return generate_unit + ( + item_name, + &generics_impl, + &generics_ty, + &generics_where, + ), + }; + + // error if fields have different types + if !variants.iter().skip(1).all(|v| &v.fields == fields) + { + return Err( syn::Error::new( variants.span(), "Variants must have the same type" ) ); + } + + let idents = variants.iter().map( | v | v.ident.clone() ).collect::< Vec< _ > >(); + + match fields + { + + syn::Fields::Unit => + generate_unit + ( + item_name, + &generics_impl, + &generics_ty, + &generics_where, + ), + + syn::Fields::Unnamed( ref item ) => + generate_enum_tuple_variants + ( + item_name, + &generics_impl, + &generics_ty, + &generics_where, + &idents, + item, + ), + + syn::Fields::Named( ref item ) => + generate_enum_named_variants + ( + item_name, + &generics_impl, + &generics_ty, + &generics_where, + &idents, + item, + ), + } } + +/// Generates `Deref` implementation for enums with tuple fields +/// +/// # Example +/// +/// ## Input +/// ```rust +/// #[ derive( Deref ) ] +/// pub enum E +/// { +/// A ( i32, Vec< String > ), +/// B ( i32, Vec< String > ), +/// C ( i32, Vec< String > ), +/// } +/// ``` +/// +/// ## Output +/// ```rust +/// pub enum E +/// { +/// A ( i32, Vec< String > ), +/// B ( i32, Vec< String > ), +/// C ( i32, Vec< String > ), +/// } +/// #[ automatically_derived ] +/// impl ::core::ops::Deref for E +/// { +/// type Target = i32; +/// #[ inline( always ) ] +/// fn deref( &self ) -> &Self::Target +/// { +/// match self +/// { +/// E::A( v, .. ) | E::B( v, .. ) | E::C( v, .. ) => v, +/// } +/// } +/// } +/// ``` +/// +fn generate_enum_tuple_variants +( + item_name : &syn::Ident, + generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_where : &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, + variant_idents : &[ syn::Ident ], + fields : &syn::FieldsUnnamed, +) +-> Result< proc_macro2::TokenStream > +{ + let fields = &fields.unnamed; + let field_ty = match fields.first() + { + Some( field ) => &field.ty, + None => return generate_unit + ( + item_name, + generics_impl, + generics_ty, + generics_where, + ), + }; + + Ok + ( + qt! + { + #[ automatically_derived ] + impl< #generics_impl > ::core::ops::Deref for #item_name< #generics_ty > + where + #generics_where + { + type Target = #field_ty; + #[ inline( always ) ] + fn deref( &self ) -> &Self::Target + { + match self + { + #( #item_name::#variant_idents( v, .. ) )|* => v + } + } + } + } + ) +} + +/// Generates `Deref` implementation for enums with named fields +/// +/// # Example +/// +/// ## Input +/// ```rust +/// #[ derive( Deref ) ] +/// pub enum E +/// { +/// A { a : i32, b : Vec< String > }, +/// B { a : i32, b : Vec< String > }, +/// C { a : i32, b : Vec< String > }, +/// } +/// ``` +/// +/// ## Output +/// ```rust +/// pub enum E +/// { +/// A { a : i32, b : Vec< String > }, +/// B { a : i32, b : Vec< String > }, +/// C { a : i32, b : Vec< String > }, +/// } +/// #[ automatically_derived ] +/// impl ::core::ops::Deref for E +/// { +/// type Target = i32; +/// #[ inline( always ) ] +/// fn deref( &self ) -> &Self::Target +/// { +/// match self +/// { +/// E::A { a : v, .. } | E::B { a : v, .. } | E::C { a : v, .. } => v, +/// } +/// } +/// } +/// ``` +/// +fn generate_enum_named_variants +( + item_name : &syn::Ident, + generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_where: &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, + variant_idents : &[ syn::Ident ], + fields : &syn::FieldsNamed, +) +-> Result< proc_macro2::TokenStream > +{ + let fields = &fields.named; + let ( field_name, field_ty ) = match fields.first() + { + Some( field ) => ( field.ident.as_ref().unwrap(), &field.ty ), + None => return generate_unit + ( + item_name, + generics_impl, + generics_ty, + generics_where, + ), + }; + + Ok + ( + qt! + { + #[ automatically_derived ] + impl< #generics_impl > ::core::ops::Deref for #item_name< #generics_ty > + where + #generics_where + { + type Target = #field_ty; + #[ inline( always ) ] + fn deref( &self ) -> &Self::Target + { + match self + { + #( #item_name::#variant_idents{ #field_name : v, ..} )|* => v + } + } + } + } + ) +} diff --git a/module/core/derive_tools_meta/src/derive/deref_mut.rs b/module/core/derive_tools_meta/src/derive/deref_mut.rs index 63317386b7..896590b524 100644 --- a/module/core/derive_tools_meta/src/derive/deref_mut.rs +++ b/module/core/derive_tools_meta/src/derive/deref_mut.rs @@ -1,6 +1,5 @@ - use super::*; -use macro_tools::{ attr, diag, generic_params, item_struct, Result, struct_like::StructLike }; +use macro_tools::{ attr, diag, generic_params, Result, struct_like::StructLike }; // @@ -16,45 +15,37 @@ pub fn deref_mut( input : proc_macro::TokenStream ) -> Result< proc_macro2::Toke let result = match parsed { - StructLike::Unit( ref item ) | StructLike::Struct( ref item ) => - { - let field_types = item_struct::field_types( &item ); - let field_names = item_struct::field_names( &item ); - match ( field_types.len(), field_names ) - { - ( 0, _ ) => - generate_unit - ( - item_name, - &generics_impl, - &generics_ty, - &generics_where, - ), - ( _, Some( mut field_names ) ) => - generate_named_field - ( - item_name, - &generics_impl, - &generics_ty, - &generics_where, - field_names.next().unwrap(), - ), - ( _, None ) => - generate_tuple_field - ( - item_name, - &generics_impl, - &generics_ty, - &generics_where, - ), - } - } + StructLike::Unit( _ ) => + generate_unit + ( + item_name, + &generics_impl, + &generics_ty, + &generics_where, + ), + + StructLike::Struct( ref item ) => + generate_struct + ( + item_name, + &generics_impl, + &generics_ty, + &generics_where, + &item.fields, + ), + StructLike::Enum( ref item ) => - { - todo!() - } - }; + generate_enum + ( + item_name, + &generics_impl, + &generics_ty, + &generics_where, + &item.variants, + ), + + }?; if has_debug { @@ -65,7 +56,40 @@ pub fn deref_mut( input : proc_macro::TokenStream ) -> Result< proc_macro2::Toke Ok( result ) } -// qqq : docs +/// Generates `DerefMut` implementation for unit structs +/// +/// # Example +/// +/// ## Input +/// ```rust +/// #[ derive( Deref, DerefMut ) ] +/// pub struct Struct; +/// ``` +/// +/// ## Output +/// ```rust +/// pub struct Struct; +/// #[ automatically_derived ] +/// impl ::core::ops::Deref for Struct +/// { +/// type Target = (); +/// #[ inline( always ) ] +/// fn deref( &self ) -> &Self::Target +/// { +/// &() +/// } +/// } +/// #[ automatically_derived ] +/// impl ::core::ops::DerefMut for Struct +/// { +/// #[ inline( always ) ] +/// fn deref_mut( &mut self ) -> &mut Self::Target +/// { +/// &mut () +/// } +/// } +/// ``` +/// fn generate_unit ( item_name : &syn::Ident, @@ -73,132 +97,453 @@ fn generate_unit generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, generics_where: &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, ) --> proc_macro2::TokenStream +-> Result< proc_macro2::TokenStream > { - qt! - { - #[ automatically_derived ] - impl< #generics_impl > ::core::ops::DerefMut for #item_name< #generics_ty > - where - #generics_where + Ok + ( + qt! { - fn deref_mut( &mut self ) -> &mut Self::Target + #[ automatically_derived ] + impl< #generics_impl > ::core::ops::DerefMut for #item_name< #generics_ty > + where + #generics_where { - &mut () + #[ inline( always ) ] + fn deref_mut( &mut self ) -> &mut Self::Target + { + &mut () + } } } - } + ) } -// qqq : docs -fn generate_named_field +/// An aggregator function to generate `DerefMut` implementation for unit, tuple structs and the ones with named fields +fn generate_struct ( item_name : &syn::Ident, generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, generics_where: &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, - field_name : &syn::Ident, + fields : &syn::Fields, ) --> proc_macro2::TokenStream +-> Result< proc_macro2::TokenStream > { - qt! + match fields { - #[ automatically_derived ] - impl< #generics_impl > ::core::ops::DerefMut for #item_name< #generics_ty > - where - #generics_where + + syn::Fields::Unit => + generate_unit + ( + item_name, + generics_impl, + generics_ty, + generics_where, + ), + + syn::Fields::Unnamed( _ ) => + generate_struct_tuple_fields + ( + item_name, + generics_impl, + generics_ty, + generics_where, + ), + + syn::Fields::Named( fields ) => + generate_struct_named_fields + ( + item_name, + generics_impl, + generics_ty, + generics_where, + fields, + ), + + } +} + +/// Generates `DerefMut` implementation for structs with tuple fields +/// +/// # Example +/// +/// ## Input +/// ```rust +/// #[ derive( Deref, DerefMut ) ] +/// pub struct Struct( i32, Vec< String > ); +/// ``` +/// +/// ## Output +/// ```rust +/// pub struct Struct( i32, Vec< String > ); +/// #[ automatically_derived ] +/// impl ::core::ops::Deref for Struct +/// { +/// type Target = i32; +/// #[ inline( always ) ] +/// fn deref( &self ) -> &Self::Target +/// { +/// &self.0 +/// } +/// } +/// #[ automatically_derived ] +/// impl ::core::ops::DerefMut for Struct +/// { +/// #[ inline( always ) ] +/// fn deref_mut( &mut self ) -> &mut Self::Target +/// { +/// &mut self.0 +/// } +/// } +/// ``` +/// +fn generate_struct_tuple_fields +( + item_name : &syn::Ident, + generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_where: &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, +) +-> Result< proc_macro2::TokenStream > +{ + Ok + ( + qt! { - #[ inline( always ) ] - fn deref_mut( &mut self ) -> &mut Self::Target + #[ automatically_derived ] + impl< #generics_impl > ::core::ops::Deref for #item_name< #generics_ty > + where + #generics_where { - &mut self.#field_name + #[ inline( always ) ] + fn deref_mut( &mut self ) -> &mut Self::Target + { + &mut self.0 + } } } - } + ) } -// qqq : docs -fn generate_tuple_field +/// Generates `DerefMut` implementation for structs with named fields +/// +/// # Example +/// +/// ## Input +/// ```rust +/// #[ derive( Deref, DerefMut ) ] +/// pub struct Struct +/// { +/// a : i32, +/// b : Vec< String >, +/// } +/// ``` +/// +/// ## Output +/// ```rust +/// pub struct Struct +/// { +/// a : i32, +/// b : Vec< String >, +/// } +/// #[ automatically_derived ] +/// impl ::core::ops::Deref for Struct +/// { +/// type Target = i32; +/// #[ inline( always ) ] +/// fn deref( &self ) -> &Self::Target +/// { +/// &self.a +/// } +/// } +/// #[ automatically_derived ] +/// impl ::core::ops::DerefMut for Struct +/// { +/// #[ inline( always ) ] +/// fn deref_mut( &mut self ) -> &mut Self::Target +/// { +/// &mut self.a +/// } +/// } +/// ``` +/// +fn generate_struct_named_fields ( item_name : &syn::Ident, generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, generics_where: &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, + fields : &syn::FieldsNamed, ) --> proc_macro2::TokenStream +-> Result< proc_macro2::TokenStream > { - qt! + let fields = &fields.named; + let field_name = match fields.first() { - #[ automatically_derived ] - impl< #generics_impl > ::core::ops::DerefMut for #item_name< #generics_ty > - where - #generics_where + Some( field ) => field.ident.as_ref().unwrap(), + None => return generate_unit + ( + item_name, + generics_impl, + generics_ty, + generics_where, + ), + }; + + Ok + ( + qt! { - #[ inline( always ) ] - fn deref_mut( &mut self ) -> &mut Self::Target + #[ automatically_derived ] + impl< #generics_impl > ::core::ops::DerefMut for #item_name< #generics_ty > + where + #generics_where { - &mut self.0 + #[ inline( always ) ] + fn deref_mut( &self ) -> &Self::Target + { + &self.#field_name + } } } + ) +} + +/// An aggregator function to generate `DerefMut` implementation for unit, tuple enums and the ones with named fields +fn generate_enum +( + item_name : &syn::Ident, + generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_where: &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, + variants : &syn::punctuated::Punctuated, +) +-> Result< proc_macro2::TokenStream > +{ + let fields = match variants.first() + { + Some( variant ) => &variant.fields, + None => return generate_unit + ( + item_name, + &generics_impl, + &generics_ty, + &generics_where, + ), + }; + + let idents = variants.iter().map( | v | v.ident.clone() ).collect::< Vec< _ > >(); + + match fields + { + + syn::Fields::Unit => + generate_unit + ( + item_name, + &generics_impl, + &generics_ty, + &generics_where, + ), + + syn::Fields::Unnamed( _ ) => + generate_enum_tuple_variants + ( + item_name, + &generics_impl, + &generics_ty, + &generics_where, + &idents, + ), + + syn::Fields::Named( ref item ) => + generate_enum_named_variants + ( + item_name, + &generics_impl, + &generics_ty, + &generics_where, + &idents, + item, + ), + } } -// qqq : docs -fn generate_variant +/// Generates `DerefMut` implementation for enums with tuple fields +/// +/// # Example +/// +/// ## Input +/// ```rust +/// #[ derive( Deref, DerefMut ) ] +/// pub enum E +/// { +/// A ( i32, Vec< String > ), +/// B ( i32, Vec< String > ), +/// C ( i32, Vec< String > ), +/// } +/// ``` +/// +/// ## Output +/// ```rust +/// pub enum E +/// { +/// A ( i32, Vec< String > ), +/// B ( i32, Vec< String > ), +/// C ( i32, Vec< String > ), +/// } +/// #[ automatically_derived ] +/// impl ::core::ops::Deref for E +/// { +/// type Target = i32; +/// #[ inline( always ) ] +/// fn deref( &self ) -> &Self::Target +/// { +/// match self +/// { +/// E::A( v, .. ) | E::B( v, .. ) | E::C( v, .. ) => v, +/// } +/// } +/// } +/// #[ automatically_derived ] +/// impl ::core::ops::DerefMut for E +/// { +/// #[ inline( always ) ] +/// fn deref_mut( &mut self ) -> &mut Self::Target +/// { +/// match self +/// { +/// E::A( v, .. ) | E::B( v, .. ) | E::C( v, .. ) => v, +/// } +/// } +/// } +/// ``` +/// +fn generate_enum_tuple_variants +( + item_name : &syn::Ident, + generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_where : &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, + variant_idents : &[ syn::Ident ], +) +-> Result< proc_macro2::TokenStream > +{ + Ok + ( + qt! + { + #[ automatically_derived ] + impl< #generics_impl > ::core::ops::DerefMut for #item_name< #generics_ty > + where + #generics_where + { + #[ inline( always ) ] + fn deref_mut( &mut self ) -> &mut Self::Target + { + match self + { + #( #item_name::#variant_idents( v, .. ) )|* => v + } + } + } + } + ) +} + +/// Generates `DerefMut` implementation for enums with named fields +/// +/// # Example +/// +/// ## Input +/// ```rust +/// #[ derive( Deref, DerefMut ) ] +/// pub enum E +/// { +/// A { a : i32, b : Vec< String > }, +/// B { a : i32, b : Vec< String > }, +/// C { a : i32, b : Vec< String > }, +/// } +/// ``` +/// +/// ## Output +/// ```rust +/// pub enum E +/// { +/// A { a : i32, b : Vec< String > }, +/// B { a : i32, b : Vec< String > }, +/// C { a : i32, b : Vec< String > }, +/// } +/// #[ automatically_derived ] +/// impl ::core::ops::Deref for E +/// { +/// type Target = i32; +/// #[ inline( always ) ] +/// fn deref( &self ) -> &Self::Target +/// { +/// match self +/// { +/// E::A { a : v, .. } | E::B { a : v, .. } | E::C { a : v, .. } => v, +/// } +/// } +/// } +/// #[ automatically_derived ] +/// impl ::core::ops::DerefMut for E +/// { +/// #[ inline( always ) ] +/// fn deref_mut( &mut self ) -> &mut Self::Target +/// { +/// match self +/// { +/// E::A { a : v, .. } | E::B { a : v, .. } | E::C { a : v, .. } => v, +/// } +/// } +/// } +/// ``` +/// +fn generate_enum_named_variants ( item_name : &syn::Ident, generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, generics_where: &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, - variant : &syn::Variant, + variant_idents : &[ syn::Ident ], + fields : &syn::FieldsNamed, ) --> proc_macro2::TokenStream +-> Result< proc_macro2::TokenStream > { - // TODO - todo!() - // let variant_name = &variant.ident; - // let fields = &variant.fields; - - // if fields.len() <= 0 - // { - // return qt!{}; - // } - - // let ( args, use_src ) = if fields.len() == 1 - // { - // let field = fields.iter().next().unwrap(); - // ( - // qt!{ #field }, - // qt!{ src }, - // ) - // } - // else - // { - // let src_i = ( 0..fields.len() ).map( | e | - // { - // let i = syn::Index::from( e ); - // qt!{ src.#i, } - // }); - // ( - // qt!{ #fields }, - // qt!{ #( #src_i )* }, - // // qt!{ src.0, src.1 }, - // ) - // }; - - // qt! - // { - // #[ automatically_derived ] - // impl< #generics_impl > DerefMut< #args > for #item_name< #generics_ty > - // where - // #generics_where - // { - // #[ inline ] - // fn deref_mut( src : #args ) -> Self - // { - // Self::#variant_name( #use_src ) - // } - // } - // } + let fields = &fields.named; + let field_name = match fields.first() + { + Some( field ) => field.ident.as_ref().unwrap(), + None => return generate_unit + ( + item_name, + generics_impl, + generics_ty, + generics_where, + ), + }; + Ok + ( + qt! + { + #[ automatically_derived ] + impl< #generics_impl > ::core::ops::DerefMut for #item_name< #generics_ty > + where + #generics_where + { + #[ inline( always ) ] + fn deref_mut( &mut self ) -> &mut Self::Target + { + match self + { + #( #item_name::#variant_idents{ #field_name : v, ..} )|* => v + } + } + } + } + ) } From 73a83ddf0c6197266120827e425b6b57fbf0a2fb Mon Sep 17 00:00:00 2001 From: Anton Parfonov Date: Fri, 31 May 2024 13:05:30 +0300 Subject: [PATCH 07/10] Fix from.rs after git merge --- .../core/derive_tools_meta/src/derive/from.rs | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/module/core/derive_tools_meta/src/derive/from.rs b/module/core/derive_tools_meta/src/derive/from.rs index 0a3da38ec4..69f17b0d25 100644 --- a/module/core/derive_tools_meta/src/derive/from.rs +++ b/module/core/derive_tools_meta/src/derive/from.rs @@ -141,7 +141,31 @@ pub fn from( input : proc_macro::TokenStream ) -> Result< proc_macro2::TokenStre Ok( result ) } -// qqq : document, add example of generated code +// qqq : document, add example of generated code -- done +/// Generates `From` implementation for unit structs +/// +/// # Example +/// +/// ## Input +/// ```rust +/// # use derive_tools_meta::From; +/// #[ derive( From ) ] +/// pub struct IsTransparent; +/// ``` +/// +/// ## Output +/// ```rust +/// pub struct IsTransparent; +/// impl From< () > for IsTransparent +/// { +/// #[ inline( always ) ] +/// fn from( src : () ) -> Self +/// { +/// Self +/// } +/// } +/// ``` +/// fn generate_unit ( item_name : &syn::Ident, @@ -414,32 +438,8 @@ fn generate_from_multiple_fields< 'a > } } -// qqq : document, add example of generated code -- done -/// Generates `From` implementation for unit structs -/// -/// # Example -/// -/// ## Input -/// ```rust -/// # use derive_tools_meta::From; -/// #[ derive( From ) ] -/// pub struct IsTransparent; -/// ``` -/// -/// ## Output -/// ```rust -/// pub struct IsTransparent; -/// impl From< () > for IsTransparent -/// { -/// #[ inline( always ) ] -/// fn from( src : () ) -> Self -/// { -/// Self -/// } -/// } -/// ``` -/// -fn generate_unit +// qqq : document, add example of generated code +fn variant_generate ( item_name : &syn::Ident, item_attrs : &ItemAttributes, @@ -536,4 +536,4 @@ field : {variant_name}"#, } ) -} +} \ No newline at end of file From 8ea98f4072da463633e5d1e98b17decece1018b4 Mon Sep 17 00:00:00 2001 From: Anton Parfonov Date: Fri, 31 May 2024 13:07:21 +0300 Subject: [PATCH 08/10] Fix DerefMut --- module/core/derive_tools_meta/src/derive/deref_mut.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/core/derive_tools_meta/src/derive/deref_mut.rs b/module/core/derive_tools_meta/src/derive/deref_mut.rs index 896590b524..d144a2d274 100644 --- a/module/core/derive_tools_meta/src/derive/deref_mut.rs +++ b/module/core/derive_tools_meta/src/derive/deref_mut.rs @@ -211,7 +211,7 @@ fn generate_struct_tuple_fields qt! { #[ automatically_derived ] - impl< #generics_impl > ::core::ops::Deref for #item_name< #generics_ty > + impl< #generics_impl > ::core::ops::DerefMut for #item_name< #generics_ty > where #generics_where { From 893ccac68d67b50c0f7fc8a6a2c4cc91989b4c69 Mon Sep 17 00:00:00 2001 From: Anton Parfonov Date: Fri, 31 May 2024 13:27:01 +0300 Subject: [PATCH 09/10] Fix Deref(Mut), fix tests --- .../derive_tools_meta/src/derive/deref.rs | 5 + .../derive_tools_meta/src/derive/deref_mut.rs | 121 +++--------------- module/core/derive_tools_meta/src/lib.rs | 2 +- 3 files changed, 21 insertions(+), 107 deletions(-) diff --git a/module/core/derive_tools_meta/src/derive/deref.rs b/module/core/derive_tools_meta/src/derive/deref.rs index 3d35cce3fb..ac2217c1c8 100644 --- a/module/core/derive_tools_meta/src/derive/deref.rs +++ b/module/core/derive_tools_meta/src/derive/deref.rs @@ -64,6 +64,7 @@ pub fn deref( input : proc_macro::TokenStream ) -> Result< proc_macro2::TokenStr /// /// ## Input /// ```rust +/// # use derive_tools_meta::Deref; /// #[ derive( Deref ) ] /// pub struct Struct; /// ``` @@ -164,6 +165,7 @@ fn generate_struct /// /// ## Input /// ```rust +/// # use derive_tools_meta::Deref; /// #[ derive( Deref ) ] /// pub struct Struct( i32, Vec< String > ); /// ``` @@ -232,6 +234,7 @@ fn generate_struct_tuple_fields /// /// ## Input /// ```rust +/// # use derive_tools_meta::Deref; /// #[ derive( Deref ) ] /// pub struct Struct /// { @@ -376,6 +379,7 @@ fn generate_enum /// /// ## Input /// ```rust +/// # use derive_tools_meta::Deref; /// #[ derive( Deref ) ] /// pub enum E /// { @@ -461,6 +465,7 @@ fn generate_enum_tuple_variants /// /// ## Input /// ```rust +/// # use derive_tools_meta::Deref; /// #[ derive( Deref ) ] /// pub enum E /// { diff --git a/module/core/derive_tools_meta/src/derive/deref_mut.rs b/module/core/derive_tools_meta/src/derive/deref_mut.rs index d144a2d274..46d7a273f6 100644 --- a/module/core/derive_tools_meta/src/derive/deref_mut.rs +++ b/module/core/derive_tools_meta/src/derive/deref_mut.rs @@ -16,14 +16,7 @@ pub fn deref_mut( input : proc_macro::TokenStream ) -> Result< proc_macro2::Toke let result = match parsed { - StructLike::Unit( _ ) => - generate_unit - ( - item_name, - &generics_impl, - &generics_ty, - &generics_where, - ), + StructLike::Unit( _ ) => generate_unit(), StructLike::Struct( ref item ) => generate_struct @@ -56,66 +49,10 @@ pub fn deref_mut( input : proc_macro::TokenStream ) -> Result< proc_macro2::Toke Ok( result ) } -/// Generates `DerefMut` implementation for unit structs -/// -/// # Example -/// -/// ## Input -/// ```rust -/// #[ derive( Deref, DerefMut ) ] -/// pub struct Struct; -/// ``` -/// -/// ## Output -/// ```rust -/// pub struct Struct; -/// #[ automatically_derived ] -/// impl ::core::ops::Deref for Struct -/// { -/// type Target = (); -/// #[ inline( always ) ] -/// fn deref( &self ) -> &Self::Target -/// { -/// &() -/// } -/// } -/// #[ automatically_derived ] -/// impl ::core::ops::DerefMut for Struct -/// { -/// #[ inline( always ) ] -/// fn deref_mut( &mut self ) -> &mut Self::Target -/// { -/// &mut () -/// } -/// } -/// ``` -/// -fn generate_unit -( - item_name : &syn::Ident, - generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, - generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, - generics_where: &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, -) --> Result< proc_macro2::TokenStream > +/// Placeholder for unit structs and enums. Does not generate any `DerefMut` implementation +fn generate_unit() -> Result< proc_macro2::TokenStream > { - Ok - ( - qt! - { - #[ automatically_derived ] - impl< #generics_impl > ::core::ops::DerefMut for #item_name< #generics_ty > - where - #generics_where - { - #[ inline( always ) ] - fn deref_mut( &mut self ) -> &mut Self::Target - { - &mut () - } - } - } - ) + Ok( qt!{} ) } /// An aggregator function to generate `DerefMut` implementation for unit, tuple structs and the ones with named fields @@ -132,14 +69,7 @@ fn generate_struct match fields { - syn::Fields::Unit => - generate_unit - ( - item_name, - generics_impl, - generics_ty, - generics_where, - ), + syn::Fields::Unit => generate_unit(), syn::Fields::Unnamed( _ ) => generate_struct_tuple_fields @@ -169,6 +99,7 @@ fn generate_struct /// /// ## Input /// ```rust +/// # use derive_tools_meta::{ Deref, DerefMut }; /// #[ derive( Deref, DerefMut ) ] /// pub struct Struct( i32, Vec< String > ); /// ``` @@ -231,6 +162,7 @@ fn generate_struct_tuple_fields /// /// ## Input /// ```rust +/// # use derive_tools_meta::{ Deref, DerefMut }; /// #[ derive( Deref, DerefMut ) ] /// pub struct Struct /// { @@ -281,13 +213,7 @@ fn generate_struct_named_fields let field_name = match fields.first() { Some( field ) => field.ident.as_ref().unwrap(), - None => return generate_unit - ( - item_name, - generics_impl, - generics_ty, - generics_where, - ), + None => return generate_unit(), }; Ok @@ -300,9 +226,9 @@ fn generate_struct_named_fields #generics_where { #[ inline( always ) ] - fn deref_mut( &self ) -> &Self::Target + fn deref_mut( &mut self ) -> &mut Self::Target { - &self.#field_name + &mut self.#field_name } } } @@ -323,13 +249,7 @@ fn generate_enum let fields = match variants.first() { Some( variant ) => &variant.fields, - None => return generate_unit - ( - item_name, - &generics_impl, - &generics_ty, - &generics_where, - ), + None => return generate_unit(), }; let idents = variants.iter().map( | v | v.ident.clone() ).collect::< Vec< _ > >(); @@ -337,14 +257,7 @@ fn generate_enum match fields { - syn::Fields::Unit => - generate_unit - ( - item_name, - &generics_impl, - &generics_ty, - &generics_where, - ), + syn::Fields::Unit => generate_unit(), syn::Fields::Unnamed( _ ) => generate_enum_tuple_variants @@ -376,6 +289,7 @@ fn generate_enum /// /// ## Input /// ```rust +/// # use derive_tools_meta::{ Deref, DerefMut }; /// #[ derive( Deref, DerefMut ) ] /// pub enum E /// { @@ -458,6 +372,7 @@ fn generate_enum_tuple_variants /// /// ## Input /// ```rust +/// # use derive_tools_meta::{ Deref, DerefMut }; /// #[ derive( Deref, DerefMut ) ] /// pub enum E /// { @@ -517,13 +432,7 @@ fn generate_enum_named_variants let field_name = match fields.first() { Some( field ) => field.ident.as_ref().unwrap(), - None => return generate_unit - ( - item_name, - generics_impl, - generics_ty, - generics_where, - ), + None => return generate_unit(), }; Ok diff --git a/module/core/derive_tools_meta/src/lib.rs b/module/core/derive_tools_meta/src/lib.rs index b2b6f19f6b..faf49a8acb 100644 --- a/module/core/derive_tools_meta/src/lib.rs +++ b/module/core/derive_tools_meta/src/lib.rs @@ -226,7 +226,7 @@ pub fn deref( input : proc_macro::TokenStream ) -> proc_macro::TokenStream /// /// Write this /// -/// ```rust ignore +/// ```rust /// # use derive_tools_meta::*; /// #[ derive( Deref, DerefMut ) ] /// pub struct IsTransparent( bool ); From dc7c9dee7c7f1511da2eaa21d7833f1c719dde00 Mon Sep 17 00:00:00 2001 From: Anton Parfonov Date: Fri, 31 May 2024 18:58:52 +0300 Subject: [PATCH 10/10] Reorganize tests for deref\(_mut\) --- .../tests/inc/deref/bounds_inlined.rs | 10 ++ .../tests/inc/deref/bounds_inlined_manual.rs | 17 +++ .../tests/inc/deref/bounds_mixed.rs | 12 ++ .../tests/inc/deref/bounds_mixed_manual.rs | 21 ++++ .../tests/inc/deref/bounds_where.rs | 14 +++ .../tests/inc/deref/bounds_where_manual.rs | 24 ++++ .../tests/inc/deref/enum_named.rs | 12 ++ .../tests/inc/deref/enum_named_empty.rs | 12 ++ .../inc/deref/enum_named_empty_manual.rs | 19 +++ .../tests/inc/deref/enum_named_manual.rs | 22 ++++ .../tests/inc/deref/enum_tuple.rs | 12 ++ .../tests/inc/deref/enum_tuple_empty.rs | 12 ++ .../inc/deref/enum_tuple_empty_manual.rs | 19 +++ .../tests/inc/deref/enum_tuple_manual.rs | 22 ++++ .../derive_tools/tests/inc/deref/enum_unit.rs | 12 ++ .../tests/inc/deref/enum_unit_manual.rs | 19 +++ .../tests/inc/deref/generics_constants.rs | 8 ++ .../inc/deref/generics_constants_default.rs | 8 ++ .../generics_constants_default_manual.rs | 15 +++ .../inc/deref/generics_constants_manual.rs | 15 +++ .../tests/inc/deref/generics_lifetimes.rs | 8 ++ .../inc/deref/generics_lifetimes_manual.rs | 15 +++ .../tests/inc/deref/generics_types.rs | 8 ++ .../tests/inc/deref/generics_types_default.rs | 8 ++ .../deref/generics_types_default_manual.rs | 15 +++ .../tests/inc/deref/generics_types_manual.rs | 15 +++ .../tests/inc/deref/name_collisions.rs | 23 ++++ .../inc/deref/only_tests/bounds_inlined.rs | 8 ++ .../inc/deref/only_tests/bounds_mixed.rs | 8 ++ .../inc/deref/only_tests/bounds_where.rs | 8 ++ .../tests/inc/deref/only_tests/enum_named.rs | 8 ++ .../inc/deref/only_tests/enum_named_empty.rs | 8 ++ .../tests/inc/deref/only_tests/enum_tuple.rs | 8 ++ .../inc/deref/only_tests/enum_tuple_empty.rs | 8 ++ .../tests/inc/deref/only_tests/enum_unit.rs | 8 ++ .../deref/only_tests/generics_constants.rs | 8 ++ .../only_tests/generics_constants_default.rs | 8 ++ .../deref/only_tests/generics_lifetimes.rs | 8 ++ .../inc/deref/only_tests/generics_types.rs | 8 ++ .../only_tests/generics_types_default.rs | 8 ++ .../inc/deref/only_tests/name_collisions.rs | 8 ++ .../inc/deref/only_tests/struct_named.rs | 8 ++ .../deref/only_tests/struct_named_empty.rs | 8 ++ .../inc/deref/only_tests/struct_tuple.rs | 8 ++ .../deref/only_tests/struct_tuple_empty.rs | 8 ++ .../tests/inc/deref/only_tests/struct_unit.rs | 8 ++ .../tests/inc/deref/struct_named.rs | 12 ++ .../tests/inc/deref/struct_named_empty.rs | 8 ++ .../inc/deref/struct_named_empty_manual.rs | 15 +++ .../tests/inc/deref/struct_named_manual.rs | 19 +++ .../tests/inc/deref/struct_tuple.rs | 8 ++ .../tests/inc/deref/struct_tuple_empty.rs | 8 ++ .../inc/deref/struct_tuple_empty_manual.rs | 15 +++ .../tests/inc/deref/struct_tuple_manual.rs | 15 +++ .../tests/inc/deref/struct_unit.rs | 8 ++ .../tests/inc/deref/struct_unit_manual.rs | 15 +++ .../tests/inc/deref_mut/bounds_inlined.rs | 10 ++ .../inc/deref_mut/bounds_inlined_manual.rs | 24 ++++ .../tests/inc/deref_mut/bounds_mixed.rs | 12 ++ .../inc/deref_mut/bounds_mixed_manual.rs | 31 +++++ .../tests/inc/deref_mut/bounds_where.rs | 14 +++ .../inc/deref_mut/bounds_where_manual.rs | 34 ++++++ .../tests/inc/deref_mut/enum_named.rs | 12 ++ .../tests/inc/deref_mut/enum_named_manual.rs | 32 +++++ .../tests/inc/deref_mut/enum_tuple.rs | 12 ++ .../tests/inc/deref_mut/enum_tuple_manual.rs | 32 +++++ .../tests/inc/deref_mut/generics_constants.rs | 8 ++ .../deref_mut/generics_constants_default.rs | 8 ++ .../generics_constants_default_manual.rs | 22 ++++ .../deref_mut/generics_constants_manual.rs | 22 ++++ .../tests/inc/deref_mut/generics_lifetimes.rs | 8 ++ .../deref_mut/generics_lifetimes_manual.rs | 22 ++++ .../tests/inc/deref_mut/generics_types.rs | 8 ++ .../inc/deref_mut/generics_types_default.rs | 8 ++ .../generics_types_default_manual.rs | 22 ++++ .../inc/deref_mut/generics_types_manual.rs | 22 ++++ .../tests/inc/deref_mut/name_collisions.rs | 23 ++++ .../deref_mut/only_tests/bounds_inlined.rs | 9 ++ .../inc/deref_mut/only_tests/bounds_mixed.rs | 9 ++ .../inc/deref_mut/only_tests/bounds_where.rs | 9 ++ .../inc/deref_mut/only_tests/enum_named.rs | 9 ++ .../inc/deref_mut/only_tests/enum_tuple.rs | 9 ++ .../only_tests/generics_constants.rs | 9 ++ .../only_tests/generics_constants_default.rs | 9 ++ .../only_tests/generics_lifetimes.rs | 9 ++ .../deref_mut/only_tests/generics_types.rs | 9 ++ .../only_tests/generics_types_default.rs | 9 ++ .../deref_mut/only_tests/name_collisions.rs | 9 ++ .../inc/deref_mut/only_tests/struct_named.rs | 9 ++ .../inc/deref_mut/only_tests/struct_tuple.rs | 9 ++ .../tests/inc/deref_mut/struct_named.rs | 12 ++ .../inc/deref_mut/struct_named_manual.rs | 26 +++++ .../tests/inc/deref_mut/struct_tuple.rs | 8 ++ .../inc/deref_mut/struct_tuple_manual.rs | 22 ++++ module/core/derive_tools/tests/inc/mod.rs | 110 +++++++++++++++++- 95 files changed, 1348 insertions(+), 5 deletions(-) create mode 100644 module/core/derive_tools/tests/inc/deref/bounds_inlined.rs create mode 100644 module/core/derive_tools/tests/inc/deref/bounds_inlined_manual.rs create mode 100644 module/core/derive_tools/tests/inc/deref/bounds_mixed.rs create mode 100644 module/core/derive_tools/tests/inc/deref/bounds_mixed_manual.rs create mode 100644 module/core/derive_tools/tests/inc/deref/bounds_where.rs create mode 100644 module/core/derive_tools/tests/inc/deref/bounds_where_manual.rs create mode 100644 module/core/derive_tools/tests/inc/deref/enum_named.rs create mode 100644 module/core/derive_tools/tests/inc/deref/enum_named_empty.rs create mode 100644 module/core/derive_tools/tests/inc/deref/enum_named_empty_manual.rs create mode 100644 module/core/derive_tools/tests/inc/deref/enum_named_manual.rs create mode 100644 module/core/derive_tools/tests/inc/deref/enum_tuple.rs create mode 100644 module/core/derive_tools/tests/inc/deref/enum_tuple_empty.rs create mode 100644 module/core/derive_tools/tests/inc/deref/enum_tuple_empty_manual.rs create mode 100644 module/core/derive_tools/tests/inc/deref/enum_tuple_manual.rs create mode 100644 module/core/derive_tools/tests/inc/deref/enum_unit.rs create mode 100644 module/core/derive_tools/tests/inc/deref/enum_unit_manual.rs create mode 100644 module/core/derive_tools/tests/inc/deref/generics_constants.rs create mode 100644 module/core/derive_tools/tests/inc/deref/generics_constants_default.rs create mode 100644 module/core/derive_tools/tests/inc/deref/generics_constants_default_manual.rs create mode 100644 module/core/derive_tools/tests/inc/deref/generics_constants_manual.rs create mode 100644 module/core/derive_tools/tests/inc/deref/generics_lifetimes.rs create mode 100644 module/core/derive_tools/tests/inc/deref/generics_lifetimes_manual.rs create mode 100644 module/core/derive_tools/tests/inc/deref/generics_types.rs create mode 100644 module/core/derive_tools/tests/inc/deref/generics_types_default.rs create mode 100644 module/core/derive_tools/tests/inc/deref/generics_types_default_manual.rs create mode 100644 module/core/derive_tools/tests/inc/deref/generics_types_manual.rs create mode 100644 module/core/derive_tools/tests/inc/deref/name_collisions.rs create mode 100644 module/core/derive_tools/tests/inc/deref/only_tests/bounds_inlined.rs create mode 100644 module/core/derive_tools/tests/inc/deref/only_tests/bounds_mixed.rs create mode 100644 module/core/derive_tools/tests/inc/deref/only_tests/bounds_where.rs create mode 100644 module/core/derive_tools/tests/inc/deref/only_tests/enum_named.rs create mode 100644 module/core/derive_tools/tests/inc/deref/only_tests/enum_named_empty.rs create mode 100644 module/core/derive_tools/tests/inc/deref/only_tests/enum_tuple.rs create mode 100644 module/core/derive_tools/tests/inc/deref/only_tests/enum_tuple_empty.rs create mode 100644 module/core/derive_tools/tests/inc/deref/only_tests/enum_unit.rs create mode 100644 module/core/derive_tools/tests/inc/deref/only_tests/generics_constants.rs create mode 100644 module/core/derive_tools/tests/inc/deref/only_tests/generics_constants_default.rs create mode 100644 module/core/derive_tools/tests/inc/deref/only_tests/generics_lifetimes.rs create mode 100644 module/core/derive_tools/tests/inc/deref/only_tests/generics_types.rs create mode 100644 module/core/derive_tools/tests/inc/deref/only_tests/generics_types_default.rs create mode 100644 module/core/derive_tools/tests/inc/deref/only_tests/name_collisions.rs create mode 100644 module/core/derive_tools/tests/inc/deref/only_tests/struct_named.rs create mode 100644 module/core/derive_tools/tests/inc/deref/only_tests/struct_named_empty.rs create mode 100644 module/core/derive_tools/tests/inc/deref/only_tests/struct_tuple.rs create mode 100644 module/core/derive_tools/tests/inc/deref/only_tests/struct_tuple_empty.rs create mode 100644 module/core/derive_tools/tests/inc/deref/only_tests/struct_unit.rs create mode 100644 module/core/derive_tools/tests/inc/deref/struct_named.rs create mode 100644 module/core/derive_tools/tests/inc/deref/struct_named_empty.rs create mode 100644 module/core/derive_tools/tests/inc/deref/struct_named_empty_manual.rs create mode 100644 module/core/derive_tools/tests/inc/deref/struct_named_manual.rs create mode 100644 module/core/derive_tools/tests/inc/deref/struct_tuple.rs create mode 100644 module/core/derive_tools/tests/inc/deref/struct_tuple_empty.rs create mode 100644 module/core/derive_tools/tests/inc/deref/struct_tuple_empty_manual.rs create mode 100644 module/core/derive_tools/tests/inc/deref/struct_tuple_manual.rs create mode 100644 module/core/derive_tools/tests/inc/deref/struct_unit.rs create mode 100644 module/core/derive_tools/tests/inc/deref/struct_unit_manual.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/bounds_inlined.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/bounds_inlined_manual.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/bounds_mixed.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/bounds_mixed_manual.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/bounds_where.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/bounds_where_manual.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/enum_named.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/enum_named_manual.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/enum_tuple.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/enum_tuple_manual.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/generics_constants.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/generics_constants_default.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/generics_constants_default_manual.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/generics_constants_manual.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/generics_lifetimes.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/generics_lifetimes_manual.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/generics_types.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/generics_types_default.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/generics_types_default_manual.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/generics_types_manual.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/name_collisions.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/only_tests/bounds_inlined.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/only_tests/bounds_mixed.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/only_tests/bounds_where.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/only_tests/enum_named.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/only_tests/enum_tuple.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/only_tests/generics_constants.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/only_tests/generics_constants_default.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/only_tests/generics_lifetimes.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/only_tests/generics_types.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/only_tests/generics_types_default.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/only_tests/name_collisions.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/only_tests/struct_named.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/only_tests/struct_tuple.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/struct_named.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/struct_named_manual.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/struct_tuple.rs create mode 100644 module/core/derive_tools/tests/inc/deref_mut/struct_tuple_manual.rs diff --git a/module/core/derive_tools/tests/inc/deref/bounds_inlined.rs b/module/core/derive_tools/tests/inc/deref/bounds_inlined.rs new file mode 100644 index 0000000000..8d31b2d56d --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/bounds_inlined.rs @@ -0,0 +1,10 @@ +use core::fmt::Debug; + +use core::ops::Deref; +use derive_tools::Deref; + +#[ allow( dead_code ) ] +#[ derive( Deref ) ] +struct BoundsInlined< T : ToString, U : Debug >( T, U ); + +include!( "./only_tests/bounds_inlined.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/bounds_inlined_manual.rs b/module/core/derive_tools/tests/inc/deref/bounds_inlined_manual.rs new file mode 100644 index 0000000000..a6e4306512 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/bounds_inlined_manual.rs @@ -0,0 +1,17 @@ +use core::fmt::Debug; + +use core::ops::Deref; + +#[ allow( dead_code ) ] +struct BoundsInlined< T : ToString, U : Debug >( T, U ); + +impl< T : ToString, U : Debug > Deref for BoundsInlined< T, U > +{ + type Target = T; + fn deref( &self ) -> &Self::Target + { + &self.0 + } +} + +include!( "./only_tests/bounds_inlined.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/bounds_mixed.rs b/module/core/derive_tools/tests/inc/deref/bounds_mixed.rs new file mode 100644 index 0000000000..b539d8a862 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/bounds_mixed.rs @@ -0,0 +1,12 @@ +use core::fmt::Debug; + +use core::ops::Deref; +use derive_tools::Deref; + +#[ allow( dead_code ) ] +#[ derive( Deref ) ] +struct BoundsMixed< T : ToString, U >( T, U ) +where + U : Debug; + +include!( "./only_tests/bounds_mixed.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/bounds_mixed_manual.rs b/module/core/derive_tools/tests/inc/deref/bounds_mixed_manual.rs new file mode 100644 index 0000000000..fbd3ae91e5 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/bounds_mixed_manual.rs @@ -0,0 +1,21 @@ +use core::fmt::Debug; + +use core::ops::Deref; + +#[ allow( dead_code ) ] +struct BoundsMixed< T : ToString, U >( T, U ) +where + U : Debug; + +impl< T : ToString, U > Deref for BoundsMixed< T, U > +where + U : Debug, +{ + type Target = T; + fn deref( &self ) -> &Self::Target + { + &self.0 + } +} + +include!( "./only_tests/bounds_mixed.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/bounds_where.rs b/module/core/derive_tools/tests/inc/deref/bounds_where.rs new file mode 100644 index 0000000000..9fb1a3f08a --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/bounds_where.rs @@ -0,0 +1,14 @@ +trait Trait<'a> {} +impl<'a> Trait<'a> for i32 {} + +use core::ops::Deref; +use derive_tools::Deref; + +#[ allow( dead_code ) ] +#[ derive( Deref ) ] +struct BoundsWhere< T, U >( T, U ) +where + T : ToString, + for< 'a > U : Trait< 'a >; + +include!( "./only_tests/bounds_where.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/bounds_where_manual.rs b/module/core/derive_tools/tests/inc/deref/bounds_where_manual.rs new file mode 100644 index 0000000000..0b440a2c94 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/bounds_where_manual.rs @@ -0,0 +1,24 @@ +trait Trait<'a> {} +impl<'a> Trait<'a> for i32 {} + +use core::ops::Deref; + +#[ allow( dead_code ) ] +struct BoundsWhere< T, U >( T, U ) +where + T : ToString, + for< 'a > U : Trait< 'a >; + +impl< T, U > Deref for BoundsWhere< T, U > +where + T : ToString, + for< 'a > U : Trait< 'a > +{ + type Target = T; + fn deref( &self ) -> &Self::Target + { + &self.0 + } +} + +include!( "./only_tests/bounds_where.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/enum_named.rs b/module/core/derive_tools/tests/inc/deref/enum_named.rs new file mode 100644 index 0000000000..98f87a8797 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/enum_named.rs @@ -0,0 +1,12 @@ +use core::ops::Deref; +use derive_tools::Deref; + +#[ allow( dead_code) ] +#[ derive( Deref ) ] +enum EnumNamed +{ + A { a : String, b : i32 }, + B { a : String, b : i32 }, +} + +include!( "./only_tests/enum_named.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/enum_named_empty.rs b/module/core/derive_tools/tests/inc/deref/enum_named_empty.rs new file mode 100644 index 0000000000..22a7c2f8ad --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/enum_named_empty.rs @@ -0,0 +1,12 @@ +use core::ops::Deref; +use derive_tools::Deref; + +#[ allow( dead_code) ] +#[ derive( Deref ) ] +enum EnumNamedEmpty +{ + A {}, + B {}, +} + +include!( "./only_tests/enum_named_empty.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/enum_named_empty_manual.rs b/module/core/derive_tools/tests/inc/deref/enum_named_empty_manual.rs new file mode 100644 index 0000000000..533dc78b0e --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/enum_named_empty_manual.rs @@ -0,0 +1,19 @@ +use core::ops::Deref; + +#[ allow( dead_code) ] +enum EnumNamedEmpty +{ + A {}, + B {}, +} + +impl Deref for EnumNamedEmpty +{ + type Target = (); + fn deref( &self ) -> &Self::Target + { + &() + } +} + +include!( "./only_tests/enum_named_empty.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/enum_named_manual.rs b/module/core/derive_tools/tests/inc/deref/enum_named_manual.rs new file mode 100644 index 0000000000..238192d0b3 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/enum_named_manual.rs @@ -0,0 +1,22 @@ +use core::ops::Deref; + +#[ allow( dead_code) ] +enum EnumNamed +{ + A { a : String, b : i32 }, + B { a : String, b : i32 }, +} + +impl Deref for EnumNamed +{ + type Target = String; + fn deref( &self ) -> &Self::Target + { + match self + { + Self::A { a : v, ..} | Self::B { a : v, .. } => v + } + } +} + +include!( "./only_tests/enum_named.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/enum_tuple.rs b/module/core/derive_tools/tests/inc/deref/enum_tuple.rs new file mode 100644 index 0000000000..2c6701331b --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/enum_tuple.rs @@ -0,0 +1,12 @@ +use core::ops::Deref; +use derive_tools::Deref; + +#[ allow( dead_code) ] +#[ derive( Deref ) ] +enum EnumTuple +{ + A( String, i32 ), + B( String, i32 ), +} + +include!( "./only_tests/enum_tuple.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/enum_tuple_empty.rs b/module/core/derive_tools/tests/inc/deref/enum_tuple_empty.rs new file mode 100644 index 0000000000..df423d9893 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/enum_tuple_empty.rs @@ -0,0 +1,12 @@ +use core::ops::Deref; +use derive_tools::Deref; + +#[ allow( dead_code) ] +#[ derive( Deref ) ] +enum EnumTupleEmpty +{ + A(), + B(), +} + +include!( "./only_tests/enum_tuple_empty.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/enum_tuple_empty_manual.rs b/module/core/derive_tools/tests/inc/deref/enum_tuple_empty_manual.rs new file mode 100644 index 0000000000..df54d3101e --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/enum_tuple_empty_manual.rs @@ -0,0 +1,19 @@ +use core::ops::Deref; + +#[ allow( dead_code) ] +enum EnumTupleEmpty +{ + A(), + B(), +} + +impl Deref for EnumTupleEmpty +{ + type Target = (); + fn deref( &self ) -> &Self::Target + { + &() + } +} + +include!( "./only_tests/enum_tuple_empty.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/enum_tuple_manual.rs b/module/core/derive_tools/tests/inc/deref/enum_tuple_manual.rs new file mode 100644 index 0000000000..efd16f833a --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/enum_tuple_manual.rs @@ -0,0 +1,22 @@ +use core::ops::Deref; + +#[ allow( dead_code) ] +enum EnumTuple +{ + A( String, i32 ), + B( String, i32 ), +} + +impl Deref for EnumTuple +{ + type Target = String; + fn deref( &self ) -> &Self::Target + { + match self + { + Self::A( v, .. ) | Self::B( v, .. ) => v + } + } +} + +include!( "./only_tests/enum_tuple.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/enum_unit.rs b/module/core/derive_tools/tests/inc/deref/enum_unit.rs new file mode 100644 index 0000000000..3ef2b204ce --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/enum_unit.rs @@ -0,0 +1,12 @@ +use core::ops::Deref; +use derive_tools::Deref; + +#[ allow( dead_code) ] +#[ derive( Deref ) ] +enum EnumUnit +{ + A, + B, +} + +include!( "./only_tests/enum_unit.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/enum_unit_manual.rs b/module/core/derive_tools/tests/inc/deref/enum_unit_manual.rs new file mode 100644 index 0000000000..1cc6fdc94b --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/enum_unit_manual.rs @@ -0,0 +1,19 @@ +use core::ops::Deref; + +#[ allow( dead_code) ] +enum EnumUnit +{ + A, + B, +} + +impl Deref for EnumUnit +{ + type Target = (); + fn deref( &self ) -> &Self::Target + { + &() + } +} + +include!( "./only_tests/enum_unit.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/generics_constants.rs b/module/core/derive_tools/tests/inc/deref/generics_constants.rs new file mode 100644 index 0000000000..f4198931f3 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/generics_constants.rs @@ -0,0 +1,8 @@ +use core::ops::Deref; +use derive_tools::Deref; + +#[ allow( dead_code ) ] +#[ derive( Deref ) ] +struct GenericsConstants< const N : usize >( i32 ); + +include!( "./only_tests/generics_constants.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/generics_constants_default.rs b/module/core/derive_tools/tests/inc/deref/generics_constants_default.rs new file mode 100644 index 0000000000..b5b03688dc --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/generics_constants_default.rs @@ -0,0 +1,8 @@ +use core::ops::Deref; +use derive_tools::Deref; + +#[ allow( dead_code ) ] +#[ derive( Deref ) ] +struct GenericsConstantsDefault< const N : usize = 0 >( i32 ); + +include!( "./only_tests/generics_constants_default.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/generics_constants_default_manual.rs b/module/core/derive_tools/tests/inc/deref/generics_constants_default_manual.rs new file mode 100644 index 0000000000..b56469fe34 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/generics_constants_default_manual.rs @@ -0,0 +1,15 @@ +use core::ops::Deref; + +#[ allow( dead_code ) ] +struct GenericsConstantsDefault< const N : usize = 0 >( i32 ); + +impl< const N : usize > Deref for GenericsConstantsDefault< N > +{ + type Target = i32; + fn deref( &self ) -> &Self::Target + { + &self.0 + } +} + +include!( "./only_tests/generics_constants_default.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/generics_constants_manual.rs b/module/core/derive_tools/tests/inc/deref/generics_constants_manual.rs new file mode 100644 index 0000000000..fcc6b6da76 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/generics_constants_manual.rs @@ -0,0 +1,15 @@ +use core::ops::Deref; + +#[ allow( dead_code ) ] +struct GenericsConstants< const N : usize >( i32 ); + +impl< const N : usize > Deref for GenericsConstants< N > +{ + type Target = i32; + fn deref( &self ) -> &Self::Target + { + &self.0 + } +} + +include!( "./only_tests/generics_constants.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/generics_lifetimes.rs b/module/core/derive_tools/tests/inc/deref/generics_lifetimes.rs new file mode 100644 index 0000000000..a308db8fee --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/generics_lifetimes.rs @@ -0,0 +1,8 @@ +use core::ops::Deref; +use derive_tools::Deref; + +#[ allow( dead_code ) ] +#[ derive( Deref ) ] +struct GenericsLifetimes< 'a >( &'a i32 ); + +include!( "./only_tests/generics_lifetimes.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/generics_lifetimes_manual.rs b/module/core/derive_tools/tests/inc/deref/generics_lifetimes_manual.rs new file mode 100644 index 0000000000..57f647c9ff --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/generics_lifetimes_manual.rs @@ -0,0 +1,15 @@ +use core::ops::Deref; + +#[ allow( dead_code ) ] +struct GenericsLifetimes< 'a >( &'a i32 ); + +impl< 'a > Deref for GenericsLifetimes< 'a > +{ + type Target = &'a i32; + fn deref( &self ) -> &Self::Target + { + &self.0 + } +} + +include!( "./only_tests/generics_lifetimes.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/generics_types.rs b/module/core/derive_tools/tests/inc/deref/generics_types.rs new file mode 100644 index 0000000000..d6acb22702 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/generics_types.rs @@ -0,0 +1,8 @@ +use core::ops::Deref; +use derive_tools::Deref; + +#[ allow( dead_code ) ] +#[ derive( Deref ) ] +struct GenericsTypes< T >( T ); + +include!( "./only_tests/generics_types.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/generics_types_default.rs b/module/core/derive_tools/tests/inc/deref/generics_types_default.rs new file mode 100644 index 0000000000..f89f5d9430 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/generics_types_default.rs @@ -0,0 +1,8 @@ +use core::ops::Deref; +use derive_tools::Deref; + +#[ allow( dead_code ) ] +#[ derive ( Deref ) ] +struct GenericsTypesDefault< T = i32 >( T ); + +include!( "./only_tests/generics_types_default.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/generics_types_default_manual.rs b/module/core/derive_tools/tests/inc/deref/generics_types_default_manual.rs new file mode 100644 index 0000000000..773061023c --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/generics_types_default_manual.rs @@ -0,0 +1,15 @@ +use core::ops::Deref; + +#[ allow( dead_code ) ] +struct GenericsTypesDefault< T = i32 >( T ); + +impl< T > Deref for GenericsTypesDefault< T > +{ + type Target = T; + fn deref( &self ) -> &Self::Target + { + &self.0 + } +} + +include!( "./only_tests/generics_types_default.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/generics_types_manual.rs b/module/core/derive_tools/tests/inc/deref/generics_types_manual.rs new file mode 100644 index 0000000000..8b9ab74909 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/generics_types_manual.rs @@ -0,0 +1,15 @@ +use core::ops::Deref; + +#[ allow( dead_code ) ] +struct GenericsTypes< T >( T ); + +impl< T > Deref for GenericsTypes< T > +{ + type Target = T; + fn deref( &self ) -> &Self::Target + { + &self.0 + } +} + +include!( "./only_tests/generics_types.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/name_collisions.rs b/module/core/derive_tools/tests/inc/deref/name_collisions.rs new file mode 100644 index 0000000000..3a0fe2a74f --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/name_collisions.rs @@ -0,0 +1,23 @@ +#![ allow( non_snake_case ) ] +#![ allow( unused_imports ) ] + +use ::core::ops::Deref; +use derive_tools::Deref; + +pub mod core {} +pub mod std {} +pub mod marker {} + +pub mod FromString {} +pub mod FromPair {} +pub mod FromBin {} + +#[ allow( dead_code ) ] +#[ derive( Deref ) ] +struct NameCollisions +{ + a : i32, + b : String, +} + +include!( "./only_tests/name_collisions.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/bounds_inlined.rs b/module/core/derive_tools/tests/inc/deref/only_tests/bounds_inlined.rs new file mode 100644 index 0000000000..5fa47b683b --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/only_tests/bounds_inlined.rs @@ -0,0 +1,8 @@ +#[ test ] +fn deref() +{ + let a = BoundsInlined::< String, i32 >( "boo".into(), 3 ); + let exp = "boo"; + let got = a.deref(); + assert_eq!(got, exp); +} diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/bounds_mixed.rs b/module/core/derive_tools/tests/inc/deref/only_tests/bounds_mixed.rs new file mode 100644 index 0000000000..198ddd7019 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/only_tests/bounds_mixed.rs @@ -0,0 +1,8 @@ +#[ test ] +fn deref() +{ + let a = BoundsMixed::< String, i32 >( "boo".into(), 3 ); + let exp = "boo"; + let got = a.deref(); + assert_eq!(got, exp); +} diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/bounds_where.rs b/module/core/derive_tools/tests/inc/deref/only_tests/bounds_where.rs new file mode 100644 index 0000000000..a7733a9b5b --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/only_tests/bounds_where.rs @@ -0,0 +1,8 @@ +#[ test ] +fn deref() +{ + let a = BoundsWhere::< String, i32 >( "boo".into(), 3 ); + let exp = "boo"; + let got = a.deref(); + assert_eq!(got, exp); +} diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/enum_named.rs b/module/core/derive_tools/tests/inc/deref/only_tests/enum_named.rs new file mode 100644 index 0000000000..fc6072f1cd --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/only_tests/enum_named.rs @@ -0,0 +1,8 @@ +#[ test ] +fn deref() +{ + let a = EnumNamed::A { a : "boo".into(), b : 3 }; + let exp = "boo"; + let got = a.deref(); + assert_eq!(got, exp); +} diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/enum_named_empty.rs b/module/core/derive_tools/tests/inc/deref/only_tests/enum_named_empty.rs new file mode 100644 index 0000000000..d0062ce381 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/only_tests/enum_named_empty.rs @@ -0,0 +1,8 @@ +#[ test ] +fn deref() +{ + let a = EnumNamedEmpty::A {}; + let exp = &(); + let got = a.deref(); + assert_eq!(got, exp); +} diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/enum_tuple.rs b/module/core/derive_tools/tests/inc/deref/only_tests/enum_tuple.rs new file mode 100644 index 0000000000..b5a71cc2e1 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/only_tests/enum_tuple.rs @@ -0,0 +1,8 @@ +#[ test ] +fn deref() +{ + let a = EnumTuple::A( "boo".into(), 3 ); + let exp = "boo"; + let got = a.deref(); + assert_eq!(got, exp); +} diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/enum_tuple_empty.rs b/module/core/derive_tools/tests/inc/deref/only_tests/enum_tuple_empty.rs new file mode 100644 index 0000000000..897c714aff --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/only_tests/enum_tuple_empty.rs @@ -0,0 +1,8 @@ +#[ test ] +fn deref() +{ + let a = EnumTupleEmpty::A(); + let exp = &(); + let got = a.deref(); + assert_eq!(got, exp); +} diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/enum_unit.rs b/module/core/derive_tools/tests/inc/deref/only_tests/enum_unit.rs new file mode 100644 index 0000000000..c6af5da907 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/only_tests/enum_unit.rs @@ -0,0 +1,8 @@ +#[ test ] +fn deref() +{ + let a = EnumUnit::A; + let exp = &(); + let got = a.deref(); + assert_eq!(got, exp); +} diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/generics_constants.rs b/module/core/derive_tools/tests/inc/deref/only_tests/generics_constants.rs new file mode 100644 index 0000000000..5a8c8f023e --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/only_tests/generics_constants.rs @@ -0,0 +1,8 @@ +#[ test ] +fn deref() +{ + let a = GenericsConstants::< 0 >( 5 ); + let exp = &5; + let got = a.deref(); + assert_eq!(got, exp); +} diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/generics_constants_default.rs b/module/core/derive_tools/tests/inc/deref/only_tests/generics_constants_default.rs new file mode 100644 index 0000000000..c0cee0bd67 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/only_tests/generics_constants_default.rs @@ -0,0 +1,8 @@ +#[ test ] +fn deref() +{ + let a = GenericsConstantsDefault::< 0 >( 5 ); + let exp = &5; + let got = a.deref(); + assert_eq!(got, exp); +} diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/generics_lifetimes.rs b/module/core/derive_tools/tests/inc/deref/only_tests/generics_lifetimes.rs new file mode 100644 index 0000000000..cdb4089835 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/only_tests/generics_lifetimes.rs @@ -0,0 +1,8 @@ +#[ test ] +fn deref() +{ + let a = GenericsLifetimes( &3 ); + let exp = &&3; + let got = a.deref(); + assert_eq!(got, exp); +} diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/generics_types.rs b/module/core/derive_tools/tests/inc/deref/only_tests/generics_types.rs new file mode 100644 index 0000000000..da3b2c39f6 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/only_tests/generics_types.rs @@ -0,0 +1,8 @@ +#[ test ] +fn deref() +{ + let a = GenericsTypes::< &str >( "boo" ); + let got = &"boo"; + let exp = a.deref(); + assert_eq!(got, exp); +} diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/generics_types_default.rs b/module/core/derive_tools/tests/inc/deref/only_tests/generics_types_default.rs new file mode 100644 index 0000000000..07e25da195 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/only_tests/generics_types_default.rs @@ -0,0 +1,8 @@ +#[ test ] +fn deref() +{ + let a = GenericsTypesDefault( 2 ); + let got = &2; + let exp = a.deref(); + assert_eq!(got, exp); +} diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/name_collisions.rs b/module/core/derive_tools/tests/inc/deref/only_tests/name_collisions.rs new file mode 100644 index 0000000000..862e034763 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/only_tests/name_collisions.rs @@ -0,0 +1,8 @@ +#[ test ] +fn deref() +{ + let a = NameCollisions { a : 5, b : "boo".into() }; + let exp = &5; + let got = a.deref(); + assert_eq!(got, exp); +} diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/struct_named.rs b/module/core/derive_tools/tests/inc/deref/only_tests/struct_named.rs new file mode 100644 index 0000000000..48675ce5f0 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/only_tests/struct_named.rs @@ -0,0 +1,8 @@ +#[ test ] +fn deref() +{ + let a = StructNamed{ a : "boo".into(), b : 3 }; + let exp = "boo"; + let got = a.deref(); + assert_eq!(got, exp); +} diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/struct_named_empty.rs b/module/core/derive_tools/tests/inc/deref/only_tests/struct_named_empty.rs new file mode 100644 index 0000000000..9692ed2716 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/only_tests/struct_named_empty.rs @@ -0,0 +1,8 @@ +#[ test ] +fn deref() +{ + let a = StructNamedEmpty{}; + let exp = &(); + let got = a.deref(); + assert_eq!(got, exp); +} diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/struct_tuple.rs b/module/core/derive_tools/tests/inc/deref/only_tests/struct_tuple.rs new file mode 100644 index 0000000000..60bb72d77e --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/only_tests/struct_tuple.rs @@ -0,0 +1,8 @@ +#[ test ] +fn deref() +{ + let a = StructTuple( "boo".into(), 3 ); + let exp = "boo"; + let got = a.deref(); + assert_eq!(got, exp); +} diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/struct_tuple_empty.rs b/module/core/derive_tools/tests/inc/deref/only_tests/struct_tuple_empty.rs new file mode 100644 index 0000000000..e2cc30db26 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/only_tests/struct_tuple_empty.rs @@ -0,0 +1,8 @@ +#[ test ] +fn deref() +{ + let a = StructTupleEmpty(); + let exp = &(); + let got = a.deref(); + assert_eq!(got, exp); +} diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/struct_unit.rs b/module/core/derive_tools/tests/inc/deref/only_tests/struct_unit.rs new file mode 100644 index 0000000000..fdb39247cc --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/only_tests/struct_unit.rs @@ -0,0 +1,8 @@ +#[ test ] +fn deref() +{ + let a = StructUnit; + let exp = &(); + let got = a.deref(); + assert_eq!(got, exp); +} diff --git a/module/core/derive_tools/tests/inc/deref/struct_named.rs b/module/core/derive_tools/tests/inc/deref/struct_named.rs new file mode 100644 index 0000000000..470670a206 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/struct_named.rs @@ -0,0 +1,12 @@ +use core::ops::Deref; +use derive_tools::Deref; + +#[ allow( dead_code ) ] +#[ derive( Deref) ] +struct StructNamed +{ + a : String, + b : i32, +} + +include!( "./only_tests/struct_named.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/struct_named_empty.rs b/module/core/derive_tools/tests/inc/deref/struct_named_empty.rs new file mode 100644 index 0000000000..ebe217835d --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/struct_named_empty.rs @@ -0,0 +1,8 @@ +use core::ops::Deref; +use derive_tools::Deref; + +#[ allow( dead_code ) ] +#[ derive( Deref ) ] +struct StructNamedEmpty{} + +include!( "./only_tests/struct_named_empty.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/struct_named_empty_manual.rs b/module/core/derive_tools/tests/inc/deref/struct_named_empty_manual.rs new file mode 100644 index 0000000000..efd92be335 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/struct_named_empty_manual.rs @@ -0,0 +1,15 @@ +use core::ops::Deref; + +#[ allow( dead_code ) ] +struct StructNamedEmpty{} + +impl Deref for StructNamedEmpty +{ + type Target = (); + fn deref( &self ) -> &Self::Target + { + &() + } +} + +include!( "./only_tests/struct_named_empty.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/struct_named_manual.rs b/module/core/derive_tools/tests/inc/deref/struct_named_manual.rs new file mode 100644 index 0000000000..88e31246e6 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/struct_named_manual.rs @@ -0,0 +1,19 @@ +use core::ops::Deref; + +#[ allow( dead_code ) ] +struct StructNamed +{ + a : String, + b : i32, +} + +impl Deref for StructNamed +{ + type Target = String; + fn deref( &self ) -> &Self::Target + { + &self.a + } +} + +include!( "./only_tests/struct_named.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/struct_tuple.rs b/module/core/derive_tools/tests/inc/deref/struct_tuple.rs new file mode 100644 index 0000000000..29c4b3c4ff --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/struct_tuple.rs @@ -0,0 +1,8 @@ +use core::ops::Deref; +use derive_tools::Deref; + +#[ allow( dead_code ) ] +#[ derive ( Deref ) ] +struct StructTuple( String, i32 ); + +include!( "./only_tests/struct_tuple.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/struct_tuple_empty.rs b/module/core/derive_tools/tests/inc/deref/struct_tuple_empty.rs new file mode 100644 index 0000000000..57e2ea7257 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/struct_tuple_empty.rs @@ -0,0 +1,8 @@ +use core::ops::Deref; +use derive_tools::Deref; + +#[ allow( dead_code ) ] +#[ derive ( Deref ) ] +struct StructTupleEmpty(); + +include!( "./only_tests/struct_tuple_empty.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/struct_tuple_empty_manual.rs b/module/core/derive_tools/tests/inc/deref/struct_tuple_empty_manual.rs new file mode 100644 index 0000000000..b239eccd44 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/struct_tuple_empty_manual.rs @@ -0,0 +1,15 @@ +use core::ops::Deref; + +#[ allow( dead_code ) ] +struct StructTupleEmpty(); + +impl Deref for StructTupleEmpty +{ + type Target = (); + fn deref( &self ) -> &Self::Target + { + &() + } +} + +include!( "./only_tests/struct_tuple_empty.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/struct_tuple_manual.rs b/module/core/derive_tools/tests/inc/deref/struct_tuple_manual.rs new file mode 100644 index 0000000000..7a97225d3b --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/struct_tuple_manual.rs @@ -0,0 +1,15 @@ +use core::ops::Deref; + +#[ allow( dead_code ) ] +struct StructTuple( String, i32 ); + +impl Deref for StructTuple +{ + type Target = String; + fn deref( &self ) -> &Self::Target + { + &self.0 + } +} + +include!( "./only_tests/struct_tuple.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/struct_unit.rs b/module/core/derive_tools/tests/inc/deref/struct_unit.rs new file mode 100644 index 0000000000..30c742a68e --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/struct_unit.rs @@ -0,0 +1,8 @@ +use core::ops::Deref; +use derive_tools::Deref; + +#[ allow( dead_code ) ] +#[ derive ( Deref ) ] +struct StructUnit; + +include!( "./only_tests/struct_unit.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/struct_unit_manual.rs b/module/core/derive_tools/tests/inc/deref/struct_unit_manual.rs new file mode 100644 index 0000000000..c43a711d50 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref/struct_unit_manual.rs @@ -0,0 +1,15 @@ +use core::ops::Deref; + +#[ allow( dead_code ) ] +struct StructUnit; + +impl Deref for StructUnit +{ + type Target = (); + fn deref( &self ) -> &Self::Target + { + &() + } +} + +include!( "./only_tests/struct_unit.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/bounds_inlined.rs b/module/core/derive_tools/tests/inc/deref_mut/bounds_inlined.rs new file mode 100644 index 0000000000..ebb9fe65b6 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/bounds_inlined.rs @@ -0,0 +1,10 @@ +use core::fmt::Debug; + +use core::ops::{ Deref }; +use derive_tools::{ Deref, DerefMut }; + +#[ allow( dead_code ) ] +#[ derive( Deref, DerefMut ) ] +struct BoundsInlined< T : ToString, U : Debug >( T, U ); + +include!( "./only_tests/bounds_inlined.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/bounds_inlined_manual.rs b/module/core/derive_tools/tests/inc/deref_mut/bounds_inlined_manual.rs new file mode 100644 index 0000000000..84051196bf --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/bounds_inlined_manual.rs @@ -0,0 +1,24 @@ +use core::fmt::Debug; + +use core::ops::{ Deref, DerefMut }; + +#[ allow( dead_code ) ] +struct BoundsInlined< T : ToString, U : Debug >( T, U ); + +impl< T : ToString, U : Debug > Deref for BoundsInlined< T, U > +{ + type Target = T; + fn deref( &self ) -> &Self::Target + { + &self.0 + } +} +impl< T : ToString, U : Debug > DerefMut for BoundsInlined< T, U > +{ + fn deref_mut( &mut self ) -> &mut Self::Target + { + &mut self.0 + } +} + +include!( "./only_tests/bounds_inlined.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/bounds_mixed.rs b/module/core/derive_tools/tests/inc/deref_mut/bounds_mixed.rs new file mode 100644 index 0000000000..5b8d13196f --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/bounds_mixed.rs @@ -0,0 +1,12 @@ +use core::fmt::Debug; + +use core::ops::{ Deref }; +use derive_tools::{ Deref, DerefMut }; + +#[ allow( dead_code ) ] +#[ derive( Deref, DerefMut ) ] +struct BoundsMixed< T : ToString, U >( T, U ) +where + U : Debug; + +include!( "./only_tests/bounds_mixed.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/bounds_mixed_manual.rs b/module/core/derive_tools/tests/inc/deref_mut/bounds_mixed_manual.rs new file mode 100644 index 0000000000..4bbfa33c21 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/bounds_mixed_manual.rs @@ -0,0 +1,31 @@ +use core::fmt::Debug; + +use core::ops::{ Deref, DerefMut }; + +#[ allow( dead_code ) ] +struct BoundsMixed< T : ToString, U >( T, U ) +where + U : Debug; + +impl< T : ToString, U > Deref for BoundsMixed< T, U > +where + U : Debug, +{ + type Target = T; + fn deref( &self ) -> &Self::Target + { + &self.0 + } +} +impl< T : ToString, U > DerefMut for BoundsMixed< T, U > +where + U : Debug, +{ + fn deref_mut( &mut self ) -> &mut Self::Target + { + &mut self.0 + } +} + + +include!( "./only_tests/bounds_mixed.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/bounds_where.rs b/module/core/derive_tools/tests/inc/deref_mut/bounds_where.rs new file mode 100644 index 0000000000..25a61c35d1 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/bounds_where.rs @@ -0,0 +1,14 @@ +trait Trait<'a> {} +impl<'a> Trait<'a> for i32 {} + +use core::ops::{ Deref }; +use derive_tools::{ Deref, DerefMut }; + +#[ allow( dead_code ) ] +#[ derive( Deref, DerefMut ) ] +struct BoundsWhere< T, U >( T, U ) +where + T : ToString, + for< 'a > U : Trait< 'a >; + +include!( "./only_tests/bounds_where.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/bounds_where_manual.rs b/module/core/derive_tools/tests/inc/deref_mut/bounds_where_manual.rs new file mode 100644 index 0000000000..3a61604a87 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/bounds_where_manual.rs @@ -0,0 +1,34 @@ +trait Trait<'a> {} +impl<'a> Trait<'a> for i32 {} + +use core::ops::{ Deref, DerefMut }; + +#[ allow( dead_code ) ] +struct BoundsWhere< T, U >( T, U ) +where + T : ToString, + for< 'a > U : Trait< 'a >; + +impl< T, U > Deref for BoundsWhere< T, U > +where + T : ToString, + for< 'a > U : Trait< 'a > +{ + type Target = T; + fn deref( &self ) -> &Self::Target + { + &self.0 + } +} +impl< T, U > DerefMut for BoundsWhere< T, U > +where + T : ToString, + for< 'a > U : Trait< 'a > +{ + fn deref_mut( &mut self ) -> &mut Self::Target + { + &mut self.0 + } +} + +include!( "./only_tests/bounds_where.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/enum_named.rs b/module/core/derive_tools/tests/inc/deref_mut/enum_named.rs new file mode 100644 index 0000000000..f6ced02179 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/enum_named.rs @@ -0,0 +1,12 @@ +use core::ops::{ Deref }; +use derive_tools::{ Deref, DerefMut }; + +#[ allow( dead_code) ] +#[ derive( Deref, DerefMut ) ] +enum EnumNamed +{ + A { a : String, b : i32 }, + B { a : String, b : i32 }, +} + +include!( "./only_tests/enum_named.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/enum_named_manual.rs b/module/core/derive_tools/tests/inc/deref_mut/enum_named_manual.rs new file mode 100644 index 0000000000..096c52cf20 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/enum_named_manual.rs @@ -0,0 +1,32 @@ +use core::ops::{ Deref, DerefMut }; + +#[ allow( dead_code) ] +enum EnumNamed +{ + A { a : String, b : i32 }, + B { a : String, b : i32 }, +} + +impl Deref for EnumNamed +{ + type Target = String; + fn deref( &self ) -> &Self::Target + { + match self + { + Self::A { a : v, ..} | Self::B { a : v, .. } => v + } + } +} +impl DerefMut for EnumNamed +{ + fn deref_mut( &mut self ) -> &mut Self::Target + { + match self + { + Self::A { a : v, ..} | Self::B { a : v, .. } => v + } + } +} + +include!( "./only_tests/enum_named.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/enum_tuple.rs b/module/core/derive_tools/tests/inc/deref_mut/enum_tuple.rs new file mode 100644 index 0000000000..8957e47e25 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/enum_tuple.rs @@ -0,0 +1,12 @@ +use core::ops::{ Deref }; +use derive_tools::{ Deref, DerefMut }; + +#[ allow( dead_code) ] +#[ derive( Deref, DerefMut ) ] +enum EnumTuple +{ + A( String, i32 ), + B( String, i32 ), +} + +include!( "./only_tests/enum_tuple.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/enum_tuple_manual.rs b/module/core/derive_tools/tests/inc/deref_mut/enum_tuple_manual.rs new file mode 100644 index 0000000000..c04408ef45 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/enum_tuple_manual.rs @@ -0,0 +1,32 @@ +use core::ops::{ Deref, DerefMut }; + +#[ allow( dead_code) ] +enum EnumTuple +{ + A( String, i32 ), + B( String, i32 ), +} + +impl Deref for EnumTuple +{ + type Target = String; + fn deref( &self ) -> &Self::Target + { + match self + { + Self::A( v, .. ) | Self::B( v, .. ) => v + } + } +} +impl DerefMut for EnumTuple +{ + fn deref_mut( &mut self ) -> &mut Self::Target + { + match self + { + Self::A( v, .. ) | Self::B( v, .. ) => v + } + } +} + +include!( "./only_tests/enum_tuple.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/generics_constants.rs b/module/core/derive_tools/tests/inc/deref_mut/generics_constants.rs new file mode 100644 index 0000000000..33ff0ff89f --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/generics_constants.rs @@ -0,0 +1,8 @@ +use core::ops::{ Deref }; +use derive_tools::{ Deref, DerefMut }; + +#[ allow( dead_code ) ] +#[ derive( Deref, DerefMut ) ] +struct GenericsConstants< const N : usize >( i32 ); + +include!( "./only_tests/generics_constants.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/generics_constants_default.rs b/module/core/derive_tools/tests/inc/deref_mut/generics_constants_default.rs new file mode 100644 index 0000000000..a5591f7569 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/generics_constants_default.rs @@ -0,0 +1,8 @@ +use core::ops::{ Deref }; +use derive_tools::{ Deref, DerefMut }; + +#[ allow( dead_code ) ] +#[ derive( Deref, DerefMut ) ] +struct GenericsConstantsDefault< const N : usize = 0 >( i32 ); + +include!( "./only_tests/generics_constants_default.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/generics_constants_default_manual.rs b/module/core/derive_tools/tests/inc/deref_mut/generics_constants_default_manual.rs new file mode 100644 index 0000000000..6348347253 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/generics_constants_default_manual.rs @@ -0,0 +1,22 @@ +use core::ops::{ Deref, DerefMut }; + +#[ allow( dead_code ) ] +struct GenericsConstantsDefault< const N : usize = 0 >( i32 ); + +impl< const N : usize > Deref for GenericsConstantsDefault< N > +{ + type Target = i32; + fn deref( &self ) -> &Self::Target + { + &self.0 + } +} +impl< const N : usize > DerefMut for GenericsConstantsDefault< N > +{ + fn deref_mut( &mut self ) -> &mut Self::Target + { + &mut self.0 + } +} + +include!( "./only_tests/generics_constants_default.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/generics_constants_manual.rs b/module/core/derive_tools/tests/inc/deref_mut/generics_constants_manual.rs new file mode 100644 index 0000000000..efe320d565 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/generics_constants_manual.rs @@ -0,0 +1,22 @@ +use core::ops::{ Deref, DerefMut }; + +#[ allow( dead_code ) ] +struct GenericsConstants< const N : usize >( i32 ); + +impl< const N : usize > Deref for GenericsConstants< N > +{ + type Target = i32; + fn deref( &self ) -> &Self::Target + { + &self.0 + } +} +impl< const N : usize > DerefMut for GenericsConstants< N > +{ + fn deref_mut( &mut self ) -> &mut Self::Target + { + &mut self.0 + } +} + +include!( "./only_tests/generics_constants.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/generics_lifetimes.rs b/module/core/derive_tools/tests/inc/deref_mut/generics_lifetimes.rs new file mode 100644 index 0000000000..3a3ff17bdd --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/generics_lifetimes.rs @@ -0,0 +1,8 @@ +use core::ops::{ Deref }; +use derive_tools::{ Deref, DerefMut }; + +#[ allow( dead_code ) ] +#[ derive( Deref, DerefMut ) ] +struct GenericsLifetimes< 'a >( &'a i32 ); + +include!( "./only_tests/generics_lifetimes.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/generics_lifetimes_manual.rs b/module/core/derive_tools/tests/inc/deref_mut/generics_lifetimes_manual.rs new file mode 100644 index 0000000000..7d16d699c9 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/generics_lifetimes_manual.rs @@ -0,0 +1,22 @@ +use core::ops::{ Deref, DerefMut }; + +#[ allow( dead_code ) ] +struct GenericsLifetimes< 'a >( &'a i32 ); + +impl< 'a > Deref for GenericsLifetimes< 'a > +{ + type Target = &'a i32; + fn deref( &self ) -> &Self::Target + { + &self.0 + } +} +impl< 'a > DerefMut for GenericsLifetimes< 'a > +{ + fn deref_mut( &mut self ) -> &mut Self::Target + { + &mut self.0 + } +} + +include!( "./only_tests/generics_lifetimes.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/generics_types.rs b/module/core/derive_tools/tests/inc/deref_mut/generics_types.rs new file mode 100644 index 0000000000..dc64f4ec43 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/generics_types.rs @@ -0,0 +1,8 @@ +use core::ops::{ Deref }; +use derive_tools::{ Deref, DerefMut }; + +#[ allow( dead_code ) ] +#[ derive( Deref, DerefMut ) ] +struct GenericsTypes< T >( T ); + +include!( "./only_tests/generics_types.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/generics_types_default.rs b/module/core/derive_tools/tests/inc/deref_mut/generics_types_default.rs new file mode 100644 index 0000000000..8680954981 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/generics_types_default.rs @@ -0,0 +1,8 @@ +use core::ops::{ Deref }; +use derive_tools::{ Deref, DerefMut }; + +#[ allow( dead_code ) ] +#[ derive ( Deref, DerefMut ) ] +struct GenericsTypesDefault< T = i32 >( T ); + +include!( "./only_tests/generics_types_default.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/generics_types_default_manual.rs b/module/core/derive_tools/tests/inc/deref_mut/generics_types_default_manual.rs new file mode 100644 index 0000000000..00b41e2ece --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/generics_types_default_manual.rs @@ -0,0 +1,22 @@ +use core::ops::{ Deref, DerefMut }; + +#[ allow( dead_code ) ] +struct GenericsTypesDefault< T = i32 >( T ); + +impl< T > Deref for GenericsTypesDefault< T > +{ + type Target = T; + fn deref( &self ) -> &Self::Target + { + &self.0 + } +} +impl< T > DerefMut for GenericsTypesDefault< T > +{ + fn deref_mut( &mut self ) -> &mut Self::Target + { + &mut self.0 + } +} + +include!( "./only_tests/generics_types_default.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/generics_types_manual.rs b/module/core/derive_tools/tests/inc/deref_mut/generics_types_manual.rs new file mode 100644 index 0000000000..2bdeb3183f --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/generics_types_manual.rs @@ -0,0 +1,22 @@ +use core::ops::{ Deref, DerefMut }; + +#[ allow( dead_code ) ] +struct GenericsTypes< T >( T ); + +impl< T > Deref for GenericsTypes< T > +{ + type Target = T; + fn deref( &self ) -> &Self::Target + { + &self.0 + } +} +impl< T > DerefMut for GenericsTypes< T > +{ + fn deref_mut( &mut self ) -> &mut Self::Target + { + &mut self.0 + } +} + +include!( "./only_tests/generics_types.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/name_collisions.rs b/module/core/derive_tools/tests/inc/deref_mut/name_collisions.rs new file mode 100644 index 0000000000..66f82b0fb1 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/name_collisions.rs @@ -0,0 +1,23 @@ +#![ allow( non_snake_case ) ] +#![ allow( unused_imports ) ] + +use ::core::ops::Deref; +use derive_tools::{ Deref, DerefMut }; + +pub mod core {} +pub mod std {} +pub mod marker {} + +pub mod FromString {} +pub mod FromPair {} +pub mod FromBin {} + +#[ allow( dead_code ) ] +#[ derive( Deref, DerefMut ) ] +struct NameCollisions +{ + a : i32, + b : String, +} + +include!( "./only_tests/name_collisions.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/only_tests/bounds_inlined.rs b/module/core/derive_tools/tests/inc/deref_mut/only_tests/bounds_inlined.rs new file mode 100644 index 0000000000..c70dca1ce0 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/only_tests/bounds_inlined.rs @@ -0,0 +1,9 @@ +#[ test ] +fn deref_mut() +{ + let mut a = BoundsInlined::< String, i32 >( "boo".into(), 3 ); + *a = "foo".into(); + let exp = "foo"; + let got = a.deref(); + assert_eq!(got, exp); +} diff --git a/module/core/derive_tools/tests/inc/deref_mut/only_tests/bounds_mixed.rs b/module/core/derive_tools/tests/inc/deref_mut/only_tests/bounds_mixed.rs new file mode 100644 index 0000000000..d511bc31cf --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/only_tests/bounds_mixed.rs @@ -0,0 +1,9 @@ +#[ test ] +fn deref_mut() +{ + let mut a = BoundsMixed::< String, i32 >( "boo".into(), 3 ); + *a = "foo".into(); + let exp = "foo"; + let got = a.deref(); + assert_eq!(got, exp); +} diff --git a/module/core/derive_tools/tests/inc/deref_mut/only_tests/bounds_where.rs b/module/core/derive_tools/tests/inc/deref_mut/only_tests/bounds_where.rs new file mode 100644 index 0000000000..4606689250 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/only_tests/bounds_where.rs @@ -0,0 +1,9 @@ +#[ test ] +fn deref_mut() +{ + let mut a = BoundsWhere::< String, i32 >( "boo".into(), 3 ); + *a = "foo".into(); + let exp = "foo"; + let got = a.deref(); + assert_eq!(got, exp); +} diff --git a/module/core/derive_tools/tests/inc/deref_mut/only_tests/enum_named.rs b/module/core/derive_tools/tests/inc/deref_mut/only_tests/enum_named.rs new file mode 100644 index 0000000000..a659c7aaeb --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/only_tests/enum_named.rs @@ -0,0 +1,9 @@ +#[ test ] +fn deref_mut() +{ + let mut a = EnumNamed::A { a : "boo".into(), b : 3 }; + *a = "foo".into(); + let exp = "foo"; + let got = a.deref(); + assert_eq!(got, exp); +} diff --git a/module/core/derive_tools/tests/inc/deref_mut/only_tests/enum_tuple.rs b/module/core/derive_tools/tests/inc/deref_mut/only_tests/enum_tuple.rs new file mode 100644 index 0000000000..5228288f0a --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/only_tests/enum_tuple.rs @@ -0,0 +1,9 @@ +#[ test ] +fn deref_mut() +{ + let mut a = EnumTuple::A( "boo".into(), 3 ); + *a = "foo".into(); + let exp = "foo"; + let got = a.deref(); + assert_eq!(got, exp); +} diff --git a/module/core/derive_tools/tests/inc/deref_mut/only_tests/generics_constants.rs b/module/core/derive_tools/tests/inc/deref_mut/only_tests/generics_constants.rs new file mode 100644 index 0000000000..54b9f97fd0 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/only_tests/generics_constants.rs @@ -0,0 +1,9 @@ +#[ test ] +fn deref_mut() +{ + let mut a = GenericsConstants::< 0 >( 5 ); + *a = -5; + let exp = &-5; + let got = a.deref(); + assert_eq!(got, exp); +} diff --git a/module/core/derive_tools/tests/inc/deref_mut/only_tests/generics_constants_default.rs b/module/core/derive_tools/tests/inc/deref_mut/only_tests/generics_constants_default.rs new file mode 100644 index 0000000000..3430c4e252 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/only_tests/generics_constants_default.rs @@ -0,0 +1,9 @@ +#[ test ] +fn deref_mut() +{ + let mut a = GenericsConstantsDefault::< 0 >( 5 ); + *a = -5; + let exp = &-5; + let got = a.deref(); + assert_eq!(got, exp); +} diff --git a/module/core/derive_tools/tests/inc/deref_mut/only_tests/generics_lifetimes.rs b/module/core/derive_tools/tests/inc/deref_mut/only_tests/generics_lifetimes.rs new file mode 100644 index 0000000000..9428644f06 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/only_tests/generics_lifetimes.rs @@ -0,0 +1,9 @@ +#[ test ] +fn deref_mut() +{ + let mut a = GenericsLifetimes( &3 ); + *a = &-3; + let exp = &&-3; + let got = a.deref(); + assert_eq!(got, exp); +} diff --git a/module/core/derive_tools/tests/inc/deref_mut/only_tests/generics_types.rs b/module/core/derive_tools/tests/inc/deref_mut/only_tests/generics_types.rs new file mode 100644 index 0000000000..336a59148a --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/only_tests/generics_types.rs @@ -0,0 +1,9 @@ +#[ test ] +fn deref_mut() +{ + let mut a = GenericsTypes::< &str >( "boo" ); + *a = "foo"; + let got = &"foo"; + let exp = a.deref(); + assert_eq!(got, exp); +} diff --git a/module/core/derive_tools/tests/inc/deref_mut/only_tests/generics_types_default.rs b/module/core/derive_tools/tests/inc/deref_mut/only_tests/generics_types_default.rs new file mode 100644 index 0000000000..efc09bda56 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/only_tests/generics_types_default.rs @@ -0,0 +1,9 @@ +#[ test ] +fn deref_mut() +{ + let mut a = GenericsTypesDefault( 2 ); + *a = -2; + let got = &-2; + let exp = a.deref(); + assert_eq!(got, exp); +} diff --git a/module/core/derive_tools/tests/inc/deref_mut/only_tests/name_collisions.rs b/module/core/derive_tools/tests/inc/deref_mut/only_tests/name_collisions.rs new file mode 100644 index 0000000000..f2a24e90a7 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/only_tests/name_collisions.rs @@ -0,0 +1,9 @@ +#[ test ] +fn deref_mut() +{ + let mut a = NameCollisions { a : 5, b : "boo".into() }; + *a = -5; + let exp = &-5; + let got = a.deref(); + assert_eq!(got, exp); +} diff --git a/module/core/derive_tools/tests/inc/deref_mut/only_tests/struct_named.rs b/module/core/derive_tools/tests/inc/deref_mut/only_tests/struct_named.rs new file mode 100644 index 0000000000..edcacf11f1 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/only_tests/struct_named.rs @@ -0,0 +1,9 @@ +#[ test ] +fn deref_mut() +{ + let mut a = StructNamed{ a : "boo".into(), b : 3 }; + *a = "foo".into(); + let exp = "foo"; + let got = a.deref(); + assert_eq!(got, exp); +} diff --git a/module/core/derive_tools/tests/inc/deref_mut/only_tests/struct_tuple.rs b/module/core/derive_tools/tests/inc/deref_mut/only_tests/struct_tuple.rs new file mode 100644 index 0000000000..a36de0ea6f --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/only_tests/struct_tuple.rs @@ -0,0 +1,9 @@ +#[ test ] +fn deref_mut() +{ + let mut a = StructTuple( "boo".into(), 3 ); + *a = "foo".into(); + let exp = "foo"; + let got = a.deref(); + assert_eq!(got, exp); +} diff --git a/module/core/derive_tools/tests/inc/deref_mut/struct_named.rs b/module/core/derive_tools/tests/inc/deref_mut/struct_named.rs new file mode 100644 index 0000000000..4cf35f59df --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/struct_named.rs @@ -0,0 +1,12 @@ +use core::ops::{ Deref }; +use derive_tools::{ Deref, DerefMut }; + +#[ allow( dead_code ) ] +#[ derive( Deref, DerefMut ) ] +struct StructNamed +{ + a : String, + b : i32, +} + +include!( "./only_tests/struct_named.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/struct_named_manual.rs b/module/core/derive_tools/tests/inc/deref_mut/struct_named_manual.rs new file mode 100644 index 0000000000..24cff7f14a --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/struct_named_manual.rs @@ -0,0 +1,26 @@ +use core::ops::{ Deref, DerefMut }; + +#[ allow( dead_code ) ] +struct StructNamed +{ + a : String, + b : i32, +} + +impl Deref for StructNamed +{ + type Target = String; + fn deref( &self ) -> &Self::Target + { + &self.a + } +} +impl DerefMut for StructNamed +{ + fn deref_mut( &mut self ) -> &mut Self::Target + { + &mut self.a + } +} + +include!( "./only_tests/struct_named.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/struct_tuple.rs b/module/core/derive_tools/tests/inc/deref_mut/struct_tuple.rs new file mode 100644 index 0000000000..5d5d439859 --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/struct_tuple.rs @@ -0,0 +1,8 @@ +use core::ops::{ Deref }; +use derive_tools::{ Deref, DerefMut }; + +#[ allow( dead_code ) ] +#[ derive ( Deref, DerefMut ) ] +struct StructTuple( String, i32 ); + +include!( "./only_tests/struct_tuple.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/struct_tuple_manual.rs b/module/core/derive_tools/tests/inc/deref_mut/struct_tuple_manual.rs new file mode 100644 index 0000000000..de82ac329c --- /dev/null +++ b/module/core/derive_tools/tests/inc/deref_mut/struct_tuple_manual.rs @@ -0,0 +1,22 @@ +use core::ops::{ Deref, DerefMut }; + +#[ allow( dead_code ) ] +struct StructTuple( String, i32 ); + +impl Deref for StructTuple +{ + type Target = String; + fn deref( &self ) -> &Self::Target + { + &self.0 + } +} +impl DerefMut for StructTuple +{ + fn deref_mut( &mut self ) -> &mut Self::Target + { + &mut self.0 + } +} + +include!( "./only_tests/struct_tuple.rs" ); diff --git a/module/core/derive_tools/tests/inc/mod.rs b/module/core/derive_tools/tests/inc/mod.rs index f100189dbf..518d8757d4 100644 --- a/module/core/derive_tools/tests/inc/mod.rs +++ b/module/core/derive_tools/tests/inc/mod.rs @@ -39,17 +39,117 @@ mod as_ref_manual_test; #[ cfg( feature = "derive_as_ref" ) ] mod as_ref_test; -mod deref_manual_test; #[ cfg( feature = "derive_deref" ) ] -mod deref_test; +#[ path = "deref" ] +mod deref_tests +{ + #[ allow( unused_imports ) ] + use super::*; + + // + + mod struct_unit; + mod struct_unit_manual; + mod struct_tuple; + mod struct_tuple_manual; + mod struct_tuple_empty; + mod struct_tuple_empty_manual; + mod struct_named; + mod struct_named_manual; + mod struct_named_empty; + mod struct_named_empty_manual; + + mod enum_unit; + mod enum_unit_manual; + mod enum_tuple; + mod enum_tuple_manual; + mod enum_tuple_empty; + mod enum_tuple_empty_manual; + mod enum_named; + mod enum_named_manual; + mod enum_named_empty; + mod enum_named_empty_manual; + + // + + mod generics_lifetimes; + mod generics_lifetimes_manual; + + mod generics_types; + mod generics_types_manual; + mod generics_types_default; + mod generics_types_default_manual; + + mod generics_constants; + mod generics_constants_manual; + mod generics_constants_default; + mod generics_constants_default_manual; + + // + + mod bounds_inlined; + mod bounds_inlined_manual; + mod bounds_where; + mod bounds_where_manual; + mod bounds_mixed; + mod bounds_mixed_manual; + + // + + mod name_collisions; +} -mod deref_mut_manual_test; #[ cfg( feature = "derive_deref_mut" ) ] -mod deref_mut_test; +#[ path = "deref_mut" ] +mod deref_mut_tests +{ + #[ allow( unused_imports ) ] + use super::*; + + // + + mod struct_tuple; + mod struct_tuple_manual; + mod struct_named; + mod struct_named_manual; + + mod enum_tuple; + mod enum_tuple_manual; + mod enum_named; + mod enum_named_manual; + + // + + mod generics_lifetimes; + mod generics_lifetimes_manual; + + mod generics_types; + mod generics_types_manual; + mod generics_types_default; + mod generics_types_default_manual; + + mod generics_constants; + mod generics_constants_manual; + mod generics_constants_default; + mod generics_constants_default_manual; + + // + + mod bounds_inlined; + mod bounds_inlined_manual; + mod bounds_where; + mod bounds_where_manual; + mod bounds_mixed; + mod bounds_mixed_manual; + + // + + mod name_collisions; +} #[ cfg( feature = "derive_from" ) ] #[ path = "from" ] -mod tests +mod from { #[ allow( unused_imports ) ] use super::*;