From 37117bc12846a3f6d4b29c4ee69007b44913f073 Mon Sep 17 00:00:00 2001 From: wandalen Date: Sat, 17 Feb 2024 00:37:43 +0200 Subject: [PATCH 01/19] unitore: refactoring --- Cargo.toml | 2 +- .../src/problems/traveling_salesman.rs | 46 +++++++++---------- .../{test_feed_list.toml => feeds.toml} | 0 module/move/unitore/src/executor.rs | 19 ++++++++ module/move/unitore/src/feed_config.rs | 8 ++-- module/move/unitore/src/lib.rs | 5 +- module/move/unitore/src/main.rs | 20 +++----- .../unitore/src/{client.rs => retriever.rs} | 25 ++++++---- 8 files changed, 72 insertions(+), 53 deletions(-) rename module/move/unitore/{test_feed_list.toml => feeds.toml} (100%) create mode 100644 module/move/unitore/src/executor.rs rename module/move/unitore/src/{client.rs => retriever.rs} (57%) diff --git a/Cargo.toml b/Cargo.toml index 37563b72e3..e40589fa6d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ resolver = "2" members = [ "module/alias/*", - "module/blank/*", + # "module/blank/*", "module/core/*", "module/move/*", # "module/step/*", diff --git a/module/move/optimization_tools/src/problems/traveling_salesman.rs b/module/move/optimization_tools/src/problems/traveling_salesman.rs index fba1ec1336..b0bd3fb0a4 100644 --- a/module/move/optimization_tools/src/problems/traveling_salesman.rs +++ b/module/move/optimization_tools/src/problems/traveling_salesman.rs @@ -1,18 +1,18 @@ //! Solving Traveling Salesman Problem using HybridOptiomizer. -//! +//! //! Initial population generated as random routes where each node appears exactly once( except for starting node, which apperars at the beginning and at the end ). -//! +//! //! Selection operator performes tourmanent selection: randomly selecting a group of individuals from the population( the number of individuals selected is equal to the tournament_size value). //! Likelihood of win of the fittest participant is determined by tournament_selection_pressure. -//! -//! Crossover operator performs ordered crossover to preserve uniqueness of each node in route: a subroute from the first parent is selected and the remainder of the route is filled +//! +//! Crossover operator performs ordered crossover to preserve uniqueness of each node in route: a subroute from the first parent is selected and the remainder of the route is filled //! with the nodes from the second parent in the order in which they appear, without duplicating any nodes in the selected subroute from the first parent. -//! -//! Mutation operator alters solution in one of three different ways, determined randomly: -//! - by swapping two nodes within the route( start and end nodes excluded ), -//! - by reversing subroute, +//! +//! Mutation operator alters solution in one of three different ways, determined randomly: +//! - by swapping two nodes within the route( start and end nodes excluded ), +//! - by reversing subroute, //! - by changing position of subroute. -//! +//! use std::collections::HashMap; use crate::hybrid_optimizer::*; @@ -22,7 +22,7 @@ use deterministic_rand::{ Hrng, seq::{ SliceRandom, IteratorRandom } }; use iter_tools::Itertools; /// Functionality for symmetrical traveling salesman problem undirected graph representation. -pub trait Graph +pub trait Graph { /// Graph node type. type N; @@ -32,7 +32,7 @@ pub trait Graph /// Checks if edge connecting two nodes exists. fn has_edge( &self, node1 : &Self::N, node2 : &Self::N ) -> bool; - /// Adds edge to graph, connecting two nodes. + /// Adds edge to graph, connecting two nodes. fn add_edge( &mut self, node1 : Self::N, node2 : Self::N, weight : f64 ); /// Return list of graph nodes. @@ -61,7 +61,7 @@ impl TSPGraph impl Default for TSPGraph { - fn default() -> Self + fn default() -> Self { let mut graph = TSPGraph::new(); graph.add_edge( NodeIndex( 1 ), NodeIndex( 2 ), 10.0 ); @@ -133,7 +133,7 @@ impl Graph for TSPGraph None } - fn add_edge( &mut self, node1 : Self::N, node2 : Self::N, weight : f64 ) + fn add_edge( &mut self, node1 : Self::N, node2 : Self::N, weight : f64 ) { self.adjacency_list.entry( node1 ).or_default().push( ( node2, weight.into() ) ); self.adjacency_list.entry( node2 ).or_default().push( ( node1, weight.into() ) ); @@ -166,7 +166,7 @@ impl TSProblem /// Possible solution of traveling salesman problem, contains route and its distance. #[ derive( Debug, PartialEq, Clone ) ] -pub struct TSPerson +pub struct TSPerson { /// Route which contains starting node at first and last position and every other node exactly once. pub route : Vec< NodeIndex >, @@ -191,12 +191,12 @@ impl Individual for TSPerson self.distance as usize } - fn is_optimal( &self ) -> bool + fn is_optimal( &self ) -> bool { false } - fn update_fitness( &mut self, value : f64 ) + fn update_fitness( &mut self, value : f64 ) { self.distance = value; } @@ -206,7 +206,7 @@ impl InitialProblem for TSProblem { type Person = TSPerson; - fn get_random_person( &self, hrng : Hrng ) -> TSPerson + fn get_random_person( &self, hrng : Hrng ) -> TSPerson { let mut list = Vec::new(); list.push( self.starting_node ); @@ -227,7 +227,7 @@ impl InitialProblem for TSProblem person } - fn evaluate( &self, person : &TSPerson ) -> f64 + fn evaluate( &self, person : &TSPerson ) -> f64 { let mut dist = 0.0; for ( node1, node2 ) in person.route.iter().tuple_windows() @@ -236,7 +236,7 @@ impl InitialProblem for TSProblem { dist += f64::from( edge.weight() ) } - else + else { dist += f64::from( f64::INFINITY ); } @@ -253,7 +253,7 @@ pub struct OrderedRouteCrossover {} impl CrossoverOperator for OrderedRouteCrossover { type Person = TSPerson; - fn crossover( &self, hrng : Hrng, parent1 : &Self::Person, parent2 : &Self::Person ) -> Self::Person + fn crossover( &self, hrng : Hrng, parent1 : &Self::Person, parent2 : &Self::Person ) -> Self::Person { let rng_ref = hrng.rng_ref(); let mut rng = rng_ref.lock().unwrap(); @@ -311,7 +311,7 @@ impl TSRouteMutation new_route.extend( person.route.iter().skip( start ).take( end - start - 1 ).rev() ); new_route.extend( person.route.iter().skip( end - 1 ) ); let new_route = new_route.into_iter().map( | n | *n ).collect_vec(); - + person.route = new_route; } @@ -355,7 +355,7 @@ impl MutationOperator for TSRouteMutation type Person = TSPerson; type Problem = TSProblem; - fn mutate( &self, hrng : Hrng, person : &mut Self::Person, _context : &Self::Problem ) + fn mutate( &self, hrng : Hrng, person : &mut Self::Person, _context : &Self::Problem ) { let rng_ref = hrng.rng_ref(); let mut rng = rng_ref.lock().unwrap(); @@ -371,4 +371,4 @@ impl MutationOperator for TSRouteMutation _ => unreachable!() } } -} \ No newline at end of file +} diff --git a/module/move/unitore/test_feed_list.toml b/module/move/unitore/feeds.toml similarity index 100% rename from module/move/unitore/test_feed_list.toml rename to module/move/unitore/feeds.toml diff --git a/module/move/unitore/src/executor.rs b/module/move/unitore/src/executor.rs new file mode 100644 index 0000000000..0e65f3eda1 --- /dev/null +++ b/module/move/unitore/src/executor.rs @@ -0,0 +1,19 @@ +//! Execute plan. + +use super::*; +use retriever::FeedClient; +use feed_config::read_feed_config; + +pub async fn execute() -> Result< (), Box< dyn std::error::Error + Send + Sync > > +{ + let client = FeedClient; + //let _f = client.fetch( String::from( "https://feeds.bbci.co.uk/news/world/rss.xml" ) ).await?; + + let feed_configs = read_feed_config().unwrap(); + + for config in feed_configs + { + client.fetch( config.link ).await?; + } + Ok( () ) +} diff --git a/module/move/unitore/src/feed_config.rs b/module/move/unitore/src/feed_config.rs index 9bc314aa0f..acb97d809c 100644 --- a/module/move/unitore/src/feed_config.rs +++ b/module/move/unitore/src/feed_config.rs @@ -1,5 +1,5 @@ -use std::{ fs::OpenOptions, io::{BufReader, Read} }; - +// use super::*; +use std::{ fs::OpenOptions, io::{ BufReader, Read } }; use serde::Deserialize; #[ derive( Debug, Deserialize ) ] @@ -19,7 +19,7 @@ pub struct Feeds pub fn read_feed_config() -> Result< Vec< FeedConfig >, Box< dyn std::error::Error > > { - let path = format!( "./test_feed_list.toml" ); + let path = format!( "./feeds.toml" ); let read_file = OpenOptions::new().read( true ).open( &path )?; let mut reader = BufReader::new( read_file ); @@ -28,7 +28,7 @@ pub fn read_feed_config() -> Result< Vec< FeedConfig >, Box< dyn std::error::Err let feeds : Feeds = toml::from_str( &String::from_utf8( buffer )? )?; - println!( "{:#?}", feeds ); + // println!( "{:#?}", feeds ); Ok( feeds.config ) } diff --git a/module/move/unitore/src/lib.rs b/module/move/unitore/src/lib.rs index 353abab4fd..5a5acf2918 100644 --- a/module/move/unitore/src/lib.rs +++ b/module/move/unitore/src/lib.rs @@ -1,3 +1,4 @@ //! Feed client -pub mod client; -pub mod feed_config; \ No newline at end of file +pub mod retriever; +pub mod feed_config; +pub mod executor; diff --git a/module/move/unitore/src/main.rs b/module/move/unitore/src/main.rs index 47242eb2b8..db221ff31e 100644 --- a/module/move/unitore/src/main.rs +++ b/module/move/unitore/src/main.rs @@ -1,18 +1,10 @@ //! -use unitore::client::FeedClient; -use unitore::feed_config::read_feed_config; +// use unitore::retriever::FeedClient; +// use unitore::feed_config::read_feed_config; +pub use unitore::executor; #[ tokio::main ] -async fn main() -> Result< (), Box< dyn std::error::Error + Send + Sync > > +async fn main() -> Result< (), Box< dyn std::error::Error + Send + Sync > > { - let client = FeedClient; - //let _f = client.fetch( String::from( "https://feeds.bbci.co.uk/news/world/rss.xml" ) ).await?; - - let feed_configs = read_feed_config().unwrap(); - - for config in feed_configs - { - client.fetch( config.link ).await?; - } - Ok( () ) -} \ No newline at end of file + executor::execute().await +} diff --git a/module/move/unitore/src/client.rs b/module/move/unitore/src/retriever.rs similarity index 57% rename from module/move/unitore/src/client.rs rename to module/move/unitore/src/retriever.rs index 155f1d127e..389400690f 100644 --- a/module/move/unitore/src/client.rs +++ b/module/move/unitore/src/retriever.rs @@ -1,19 +1,21 @@ //! Feed client + +// use super::*; use hyper_tls::HttpsConnector; -use hyper_util::{ +use hyper_util:: +{ client::legacy::Client, rt::TokioExecutor, }; use http_body_util::{ Empty, BodyExt }; use hyper::body::Bytes; - use feed_rs::parser as feed_parser; /// Feed client #[ derive( Debug ) ] pub struct FeedClient; -impl FeedClient +impl FeedClient { /// Fetch feed. pub async fn fetch( &self, source: String ) -> Result< (), Box< dyn std::error::Error + Send + Sync > > @@ -21,18 +23,23 @@ impl FeedClient let https = HttpsConnector::new(); let client = Client::builder( TokioExecutor::new() ).build::< _, Empty< Bytes > >( https ); let mut res = client.get( source.parse()? ).await?; - println!( "Response status: {:?}", res.status() ); - println!( "Response headers: {:?}", res.headers() ); + + // println!( "Response status: {:?}", res.status() ); + // println!( "Response headers: {:?}", res.headers() ); + let mut feed = Vec::new(); - while let Some( next ) = res.frame().await + while let Some( next ) = res.frame().await { let frame = next?; - if let Some( chunk ) = frame.data_ref() + if let Some( chunk ) = frame.data_ref() { feed.extend( chunk.to_vec() ); } } - println!("{:#?}", feed_parser::parse( feed.as_slice() ) ); + let feed = feed_parser::parse( feed.as_slice() )?; + println!("New feed | id::{:?} | published::{:?} | ttl::{:?} | entries::{:?}", feed.id, feed.published, feed.ttl, feed.entries.len() ); + // println!("title::{:?}", feed.title ); + // println!("{:#?}", feed ); Ok( () ) } -} \ No newline at end of file +} From 2e6d80527197cb44b261577455542bca785b76ad Mon Sep 17 00:00:00 2001 From: wandalen Date: Sat, 17 Feb 2024 13:48:44 +0200 Subject: [PATCH 02/19] unitore : list entries --- module/move/unitore/{ => config}/feeds.toml | 0 module/move/unitore/src/feed_config.rs | 3 ++- module/move/unitore/src/retriever.rs | 9 ++++++++- 3 files changed, 10 insertions(+), 2 deletions(-) rename module/move/unitore/{ => config}/feeds.toml (100%) diff --git a/module/move/unitore/feeds.toml b/module/move/unitore/config/feeds.toml similarity index 100% rename from module/move/unitore/feeds.toml rename to module/move/unitore/config/feeds.toml diff --git a/module/move/unitore/src/feed_config.rs b/module/move/unitore/src/feed_config.rs index acb97d809c..1e78339d5e 100644 --- a/module/move/unitore/src/feed_config.rs +++ b/module/move/unitore/src/feed_config.rs @@ -19,7 +19,8 @@ pub struct Feeds pub fn read_feed_config() -> Result< Vec< FeedConfig >, Box< dyn std::error::Error > > { - let path = format!( "./feeds.toml" ); + let path = format!( "./config/feeds.toml" ); + // qqq : parametrize let read_file = OpenOptions::new().read( true ).open( &path )?; let mut reader = BufReader::new( read_file ); diff --git a/module/move/unitore/src/retriever.rs b/module/move/unitore/src/retriever.rs index 389400690f..fe4a42a4b7 100644 --- a/module/move/unitore/src/retriever.rs +++ b/module/move/unitore/src/retriever.rs @@ -37,7 +37,14 @@ impl FeedClient } } let feed = feed_parser::parse( feed.as_slice() )?; - println!("New feed | id::{:?} | published::{:?} | ttl::{:?} | entries::{:?}", feed.id, feed.published, feed.ttl, feed.entries.len() ); + println!("Feed | id::{:?} | published::{:?} | ttl::{:?} | entries::{:?}", feed.id, feed.published, feed.ttl, feed.entries.len() ); + + for e in feed.entries + { + println!(" Entry | id::{:?} | updated::{:?}", e.id, e.updated ); + println!(" summary::{:20?}", e.summary ); + } + // println!("title::{:?}", feed.title ); // println!("{:#?}", feed ); Ok( () ) From 2f266d555481da2b11e10dc642118c0e629267d0 Mon Sep 17 00:00:00 2001 From: wandalen Date: Sat, 17 Feb 2024 18:20:47 +0200 Subject: [PATCH 03/19] derive_tools : reflect prototype --- Readme.md | 102 +++---- module/core/derive_tools/Cargo.toml | 6 + module/core/derive_tools/build.rs | 7 +- module/core/derive_tools/src/lib.rs | 37 ++- module/core/derive_tools/src/reflect.rs | 283 ++++++++++++++++++ module/core/derive_tools/src/wtools.rs | 6 +- module/core/derive_tools/tests/inc/mod.rs | 7 + .../tests/inc/only_test/inner_from.rs | 1 - .../tests/inc/only_test/reflect_struct.rs | 28 ++ .../inc/only_test/reflect_struct_in_struct.rs | 31 ++ .../tests/inc/reflect_common_test.rs | 51 ++++ .../reflect_struct_in_struct_manual_test.rs | 70 +++++ .../tests/inc/reflect_struct_manual_test.rs | 37 +++ module/core/derive_tools_meta/Cargo.toml | 3 + .../src/implementation/mod.rs | 2 + .../src/implementation/reflect.rs | 19 ++ module/core/derive_tools_meta/src/lib.rs | 25 ++ module/move/unitore/src/feed_config.rs | 1 - 18 files changed, 637 insertions(+), 79 deletions(-) create mode 100644 module/core/derive_tools/src/reflect.rs create mode 100644 module/core/derive_tools/tests/inc/only_test/reflect_struct.rs create mode 100644 module/core/derive_tools/tests/inc/only_test/reflect_struct_in_struct.rs create mode 100644 module/core/derive_tools/tests/inc/reflect_common_test.rs create mode 100644 module/core/derive_tools/tests/inc/reflect_struct_in_struct_manual_test.rs create mode 100644 module/core/derive_tools/tests/inc/reflect_struct_manual_test.rs create mode 100644 module/core/derive_tools_meta/src/implementation/reflect.rs diff --git a/Readme.md b/Readme.md index d187977466..8824321474 100644 --- a/Readme.md +++ b/Readme.md @@ -2,9 +2,7 @@ ![wTools](./asset/img/logo_v3_trans_wide.png) - - - + [![alpha](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/StandardRustScheduled.yml?branch=master&label=alpha&logo=github)](https://github.com/Wandalen/wTools/actions/workflows/StandardRustStatus.yml) [![discord](https://img.shields.io/discord/872391416519737405?color=eee&logo=discord&logoColor=eee&label=ask)](https://discord.gg/m3YfbXpUUY) @@ -13,43 +11,41 @@ Collection of general purpose tools for solving problems. Fundamentally extend the language without spoiling, so may be used solely or in conjunction with another module of such kind. - - ### Rust tools | Module | Stability | master | alpha | Docs | Sample | |--------|-----------|--------|--------|:----:|:------:| -| [iter_tools](module/core/iter_tools) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleIterToolsPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleIterToolsPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleIterToolsPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleIterToolsPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/iter_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fiter_tools_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20iter_tools_trivial_sample/https://github.com/Wandalen/wTools) | -| [interval_adapter](module/core/interval_adapter) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleIntervalAdapterPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleIntervalAdapterPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleIntervalAdapterPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleIntervalAdapterPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/interval_adapter) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Finterval_adapter_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20interval_adapter_trivial_sample/https://github.com/Wandalen/wTools) | -| [macro_tools](module/core/macro_tools) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleMacroToolsPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleMacroToolsPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleMacroToolsPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleMacroToolsPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/macro_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fmacro_tools_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20macro_tools_trivial_sample/https://github.com/Wandalen/wTools) | -| [former_meta](module/core/former_meta) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleFormerMetaPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleFormerMetaPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleFormerMetaPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleFormerMetaPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/former_meta) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fformer_meta_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20former_meta_trivial_sample/https://github.com/Wandalen/wTools) | -| [former](module/core/former) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleFormerPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleFormerPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleFormerPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleFormerPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/former) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fformer_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20former_trivial_sample/https://github.com/Wandalen/wTools) | -| [strs_tools](module/core/strs_tools) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleStrsToolsPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleStrsToolsPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleStrsToolsPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleStrsToolsPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/strs_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fstrs_tools_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20strs_tools_trivial_sample/https://github.com/Wandalen/wTools) | -| [impls_index_meta](module/core/impls_index_meta) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleImplsIndexMetaPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleImplsIndexMetaPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleImplsIndexMetaPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleImplsIndexMetaPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/impls_index_meta) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fimpls_index_meta_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20impls_index_meta_trivial_sample/https://github.com/Wandalen/wTools) | -| [impls_index](module/core/impls_index) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleImplsIndexPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleImplsIndexPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleImplsIndexPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleImplsIndexPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/impls_index) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fimpls_index_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20impls_index_trivial_sample/https://github.com/Wandalen/wTools) | -| [clone_dyn_meta](module/core/clone_dyn_meta) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleCloneDynMetaPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleCloneDynMetaPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleCloneDynMetaPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleCloneDynMetaPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/clone_dyn_meta) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fclone_dyn_meta_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20clone_dyn_meta_trivial_sample/https://github.com/Wandalen/wTools) | -| [clone_dyn](module/core/clone_dyn) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleCloneDynPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleCloneDynPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleCloneDynPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleCloneDynPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/clone_dyn) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fclone_dyn_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20clone_dyn_trivial_sample/https://github.com/Wandalen/wTools) | -| [derive_tools_meta](module/core/derive_tools_meta) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleDeriveToolsMetaPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleDeriveToolsMetaPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleDeriveToolsMetaPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleDeriveToolsMetaPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/derive_tools_meta) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fderive_tools_meta_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20derive_tools_meta_trivial_sample/https://github.com/Wandalen/wTools) | -| [variadic_from](module/core/variadic_from) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleVariadicFromPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleVariadicFromPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleVariadicFromPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleVariadicFromPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/variadic_from) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fvariadic_from_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20variadic_from_trivial_sample/https://github.com/Wandalen/wTools) | -| [derive_tools](module/core/derive_tools) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleDeriveToolsPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleDeriveToolsPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleDeriveToolsPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleDeriveToolsPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/derive_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fderive_tools_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20derive_tools_trivial_sample/https://github.com/Wandalen/wTools) | -| [mod_interface_meta](module/core/mod_interface_meta) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleModInterfaceMetaPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleModInterfaceMetaPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleModInterfaceMetaPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleModInterfaceMetaPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/mod_interface_meta) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fmod_interface_meta_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20mod_interface_meta_trivial_sample/https://github.com/Wandalen/wTools) | -| [type_constructor](module/core/type_constructor) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleTypeConstructorPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleTypeConstructorPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleTypeConstructorPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleTypeConstructorPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/type_constructor) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Ftype_constructor_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20type_constructor_trivial_sample/https://github.com/Wandalen/wTools) | -| [inspect_type](module/core/inspect_type) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleInspectTypePush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleInspectTypePush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleInspectTypePush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleInspectTypePush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/inspect_type) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Finspect_type_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20inspect_type_trivial_sample/https://github.com/Wandalen/wTools) | -| [time_tools](module/core/time_tools) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleTimeToolsPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleTimeToolsPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleTimeToolsPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleTimeToolsPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/time_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Ftime_tools_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20time_tools_trivial_sample/https://github.com/Wandalen/wTools) | -| [error_tools](module/core/error_tools) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleErrorToolsPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleErrorToolsPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleErrorToolsPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleErrorToolsPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/error_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Ferror_tools_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20error_tools_trivial_sample/https://github.com/Wandalen/wTools) | -| [include_md](module/core/include_md) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleIncludeMdPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleIncludeMdPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleIncludeMdPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleIncludeMdPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/include_md) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Finclude_md_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20include_md_trivial_sample/https://github.com/Wandalen/wTools) | -| [mod_interface](module/core/mod_interface) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleModInterfacePush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleModInterfacePush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleModInterfacePush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleModInterfacePush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/mod_interface) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fmod_interface_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20mod_interface_trivial_sample/https://github.com/Wandalen/wTools) | -| [for_each](module/core/for_each) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleForEachPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleForEachPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleForEachPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleForEachPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/for_each) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Ffor_each_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20for_each_trivial_sample/https://github.com/Wandalen/wTools) | -| [meta_tools](module/core/meta_tools) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleMetaToolsPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleMetaToolsPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleMetaToolsPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleMetaToolsPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/meta_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fmeta_tools_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20meta_tools_trivial_sample/https://github.com/Wandalen/wTools) | -| [data_type](module/core/data_type) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleDataTypePush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleDataTypePush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleDataTypePush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleDataTypePush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/data_type) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fdata_type_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20data_type_trivial_sample/https://github.com/Wandalen/wTools) | -| [diagnostics_tools](module/core/diagnostics_tools) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleDiagnosticsToolsPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleDiagnosticsToolsPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleDiagnosticsToolsPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleDiagnosticsToolsPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/diagnostics_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fdiagnostics_tools_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20diagnostics_tools_trivial_sample/https://github.com/Wandalen/wTools) | -| [is_slice](module/core/is_slice) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleIsSlicePush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleIsSlicePush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleIsSlicePush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleIsSlicePush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/is_slice) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fis_slice_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20is_slice_trivial_sample/https://github.com/Wandalen/wTools) | -| [implements](module/core/implements) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleImplementsPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleImplementsPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleImplementsPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleImplementsPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/implements) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fimplements_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20implements_trivial_sample/https://github.com/Wandalen/wTools) | -| [typing_tools](module/core/typing_tools) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleTypingToolsPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleTypingToolsPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleTypingToolsPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleTypingToolsPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/typing_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Ftyping_tools_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20typing_tools_trivial_sample/https://github.com/Wandalen/wTools) | -| [mem_tools](module/core/mem_tools) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleMemToolsPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleMemToolsPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleMemToolsPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleMemToolsPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/mem_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fmem_tools_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20mem_tools_trivial_sample/https://github.com/Wandalen/wTools) | -| [test_tools](module/core/test_tools) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleTestToolsPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleTestToolsPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleTestToolsPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleTestToolsPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/test_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Ftest_tools_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20test_tools_trivial_sample/https://github.com/Wandalen/wTools) | -| [wtools](module/core/wtools) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleWtoolsPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleWtoolsPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleWtoolsPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleWtoolsPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/wtools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fwtools_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20wtools_trivial_sample/https://github.com/Wandalen/wTools) | +| [iter_tools](module/core/iter_tools) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleIterToolsPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleIterToolsPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleIterToolsPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleIterToolsPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/iter_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fiter_tools_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20iter_tools_trivial_sample/https://github.com/Wandalen/wTools) | +| [interval_adapter](module/core/interval_adapter) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleIntervalAdapterPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleIntervalAdapterPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleIntervalAdapterPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleIntervalAdapterPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/interval_adapter) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Finterval_adapter_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20interval_adapter_trivial_sample/https://github.com/Wandalen/wTools) | +| [macro_tools](module/core/macro_tools) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleMacroToolsPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleMacroToolsPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleMacroToolsPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleMacroToolsPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/macro_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fmacro_tools_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20macro_tools_trivial_sample/https://github.com/Wandalen/wTools) | +| [former_meta](module/core/former_meta) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleFormerMetaPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleFormerMetaPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleFormerMetaPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleFormerMetaPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/former_meta) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fformer_meta_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20former_meta_trivial_sample/https://github.com/Wandalen/wTools) | +| [former](module/core/former) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleFormerPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleFormerPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleFormerPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleFormerPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/former) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fformer_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20former_trivial_sample/https://github.com/Wandalen/wTools) | +| [strs_tools](module/core/strs_tools) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleStrsToolsPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleStrsToolsPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleStrsToolsPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleStrsToolsPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/strs_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fstrs_tools_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20strs_tools_trivial_sample/https://github.com/Wandalen/wTools) | +| [impls_index_meta](module/core/impls_index_meta) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleImplsIndexMetaPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleImplsIndexMetaPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleImplsIndexMetaPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleImplsIndexMetaPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/impls_index_meta) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fimpls_index_meta_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20impls_index_meta_trivial_sample/https://github.com/Wandalen/wTools) | +| [impls_index](module/core/impls_index) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleImplsIndexPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleImplsIndexPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleImplsIndexPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleImplsIndexPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/impls_index) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fimpls_index_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20impls_index_trivial_sample/https://github.com/Wandalen/wTools) | +| [clone_dyn_meta](module/core/clone_dyn_meta) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleCloneDynMetaPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleCloneDynMetaPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleCloneDynMetaPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleCloneDynMetaPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/clone_dyn_meta) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fclone_dyn_meta_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20clone_dyn_meta_trivial_sample/https://github.com/Wandalen/wTools) | +| [clone_dyn](module/core/clone_dyn) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleCloneDynPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleCloneDynPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleCloneDynPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleCloneDynPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/clone_dyn) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fclone_dyn_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20clone_dyn_trivial_sample/https://github.com/Wandalen/wTools) | +| [derive_tools_meta](module/core/derive_tools_meta) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleDeriveToolsMetaPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleDeriveToolsMetaPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleDeriveToolsMetaPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleDeriveToolsMetaPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/derive_tools_meta) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fderive_tools_meta_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20derive_tools_meta_trivial_sample/https://github.com/Wandalen/wTools) | +| [variadic_from](module/core/variadic_from) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleVariadicFromPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleVariadicFromPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleVariadicFromPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleVariadicFromPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/variadic_from) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fvariadic_from_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20variadic_from_trivial_sample/https://github.com/Wandalen/wTools) | +| [derive_tools](module/core/derive_tools) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleDeriveToolsPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleDeriveToolsPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleDeriveToolsPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleDeriveToolsPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/derive_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fderive_tools_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20derive_tools_trivial_sample/https://github.com/Wandalen/wTools) | +| [mod_interface_meta](module/core/mod_interface_meta) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleModInterfaceMetaPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleModInterfaceMetaPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleModInterfaceMetaPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleModInterfaceMetaPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/mod_interface_meta) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fmod_interface_meta_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20mod_interface_meta_trivial_sample/https://github.com/Wandalen/wTools) | +| [type_constructor](module/core/type_constructor) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleTypeConstructorPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleTypeConstructorPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleTypeConstructorPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleTypeConstructorPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/type_constructor) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Ftype_constructor_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20type_constructor_trivial_sample/https://github.com/Wandalen/wTools) | +| [inspect_type](module/core/inspect_type) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleInspectTypePush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleInspectTypePush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleInspectTypePush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleInspectTypePush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/inspect_type) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Finspect_type_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20inspect_type_trivial_sample/https://github.com/Wandalen/wTools) | +| [time_tools](module/core/time_tools) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleTimeToolsPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleTimeToolsPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleTimeToolsPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleTimeToolsPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/time_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Ftime_tools_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20time_tools_trivial_sample/https://github.com/Wandalen/wTools) | +| [error_tools](module/core/error_tools) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleErrorToolsPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleErrorToolsPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleErrorToolsPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleErrorToolsPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/error_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Ferror_tools_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20error_tools_trivial_sample/https://github.com/Wandalen/wTools) | +| [include_md](module/core/include_md) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleIncludeMdPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleIncludeMdPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleIncludeMdPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleIncludeMdPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/include_md) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Finclude_md_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20include_md_trivial_sample/https://github.com/Wandalen/wTools) | +| [mod_interface](module/core/mod_interface) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleModInterfacePush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleModInterfacePush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleModInterfacePush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleModInterfacePush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/mod_interface) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fmod_interface_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20mod_interface_trivial_sample/https://github.com/Wandalen/wTools) | +| [for_each](module/core/for_each) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleForEachPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleForEachPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleForEachPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleForEachPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/for_each) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Ffor_each_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20for_each_trivial_sample/https://github.com/Wandalen/wTools) | +| [meta_tools](module/core/meta_tools) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleMetaToolsPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleMetaToolsPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleMetaToolsPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleMetaToolsPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/meta_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fmeta_tools_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20meta_tools_trivial_sample/https://github.com/Wandalen/wTools) | +| [data_type](module/core/data_type) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleDataTypePush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleDataTypePush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleDataTypePush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleDataTypePush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/data_type) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fdata_type_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20data_type_trivial_sample/https://github.com/Wandalen/wTools) | +| [diagnostics_tools](module/core/diagnostics_tools) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleDiagnosticsToolsPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleDiagnosticsToolsPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleDiagnosticsToolsPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleDiagnosticsToolsPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/diagnostics_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fdiagnostics_tools_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20diagnostics_tools_trivial_sample/https://github.com/Wandalen/wTools) | +| [is_slice](module/core/is_slice) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleIsSlicePush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleIsSlicePush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleIsSlicePush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleIsSlicePush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/is_slice) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fis_slice_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20is_slice_trivial_sample/https://github.com/Wandalen/wTools) | +| [implements](module/core/implements) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleImplementsPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleImplementsPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleImplementsPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleImplementsPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/implements) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fimplements_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20implements_trivial_sample/https://github.com/Wandalen/wTools) | +| [typing_tools](module/core/typing_tools) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleTypingToolsPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleTypingToolsPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleTypingToolsPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleTypingToolsPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/typing_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Ftyping_tools_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20typing_tools_trivial_sample/https://github.com/Wandalen/wTools) | +| [mem_tools](module/core/mem_tools) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleMemToolsPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleMemToolsPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleMemToolsPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleMemToolsPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/mem_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fmem_tools_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20mem_tools_trivial_sample/https://github.com/Wandalen/wTools) | +| [test_tools](module/core/test_tools) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleTestToolsPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleTestToolsPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleTestToolsPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleTestToolsPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/test_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Ftest_tools_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20test_tools_trivial_sample/https://github.com/Wandalen/wTools) | +| [wtools](module/core/wtools) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleWtoolsPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleWtoolsPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleWtoolsPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleWtoolsPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/wtools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fwtools_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20wtools_trivial_sample/https://github.com/Wandalen/wTools) | ### Rust modules to be moved out to other repositories @@ -57,28 +53,20 @@ Collection of general purpose tools for solving problems. Fundamentally extend t | Module | Stability | master | alpha | Docs | Sample | |--------|-----------|--------|--------|:----:|:------:| -| [crates_tools](module/move/crates_tools) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleCratesToolsPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleCratesToolsPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleCratesToolsPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleCratesToolsPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/crates_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fcrates_tools_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20crates_tools_trivial_sample/https://github.com/Wandalen/wTools) | -| [deterministic_rand](module/move/deterministic_rand) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleDeterministicRandPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleDeterministicRandPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleDeterministicRandPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleDeterministicRandPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/deterministic_rand) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fdeterministic_rand_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20deterministic_rand_trivial_sample/https://github.com/Wandalen/wTools) | -| [optimization_tools](module/move/optimization_tools) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleOptimizationToolsPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleOptimizationToolsPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleOptimizationToolsPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleOptimizationToolsPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/optimization_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Foptimization_tools_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20optimization_tools_trivial_sample/https://github.com/Wandalen/wTools) | -| [graphs_tools](module/move/graphs_tools) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleGraphsToolsPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleGraphsToolsPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleGraphsToolsPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleGraphsToolsPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/graphs_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fgraphs_tools_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20graphs_tools_trivial_sample/https://github.com/Wandalen/wTools) | -| [wca](module/move/wca) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleWcaPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleWcaPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleWcaPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleWcaPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/wca) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fwca_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20wca_trivial_sample/https://github.com/Wandalen/wTools) | -| [willbe](module/move/willbe) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleWillbePush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleWillbePush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleWillbePush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleWillbePush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/willbe) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fwillbe_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20willbe_trivial_sample/https://github.com/Wandalen/wTools) | -| [wplot](module/move/wplot) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleWplotPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleWplotPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleWplotPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleWplotPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/wplot) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fwplot_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20wplot_trivial_sample/https://github.com/Wandalen/wTools) | -| [wpublisher](module/move/wpublisher) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleWpublisherPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleWpublisherPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleWpublisherPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleWpublisherPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/wpublisher) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fwpublisher_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20wpublisher_trivial_sample/https://github.com/Wandalen/wTools) | -| [fs_tools](module/move/fs_tools) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleFsToolsPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleFsToolsPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleFsToolsPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleFsToolsPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/fs_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Ffs_tools_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20fs_tools_trivial_sample/https://github.com/Wandalen/wTools) | -| [sqlx_query](module/move/sqlx_query) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleSqlxQueryPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleSqlxQueryPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleSqlxQueryPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleSqlxQueryPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/sqlx_query) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fsqlx_query_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20sqlx_query_trivial_sample/https://github.com/Wandalen/wTools) | -| [automata_tools](module/move/automata_tools) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleAutomataToolsPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleAutomataToolsPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleAutomataToolsPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleAutomataToolsPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/automata_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fautomata_tools_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20automata_tools_trivial_sample/https://github.com/Wandalen/wTools) | -| [plot_interface](module/move/plot_interface) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModulePlotInterfacePush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModulePlotInterfacePush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModulePlotInterfacePush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModulePlotInterfacePush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/plot_interface) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fplot_interface_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20plot_interface_trivial_sample/https://github.com/Wandalen/wTools) | -| [wcensor](module/move/wcensor) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleWcensorPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleWcensorPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleWcensorPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleWcensorPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/wcensor) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fwcensor_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20wcensor_trivial_sample/https://github.com/Wandalen/wTools) | -| [wlang](module/move/wlang) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleWlangPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleWlangPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleWlangPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleWlangPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/wlang) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fwlang_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20wlang_trivial_sample/https://github.com/Wandalen/wTools) | +| [crates_tools](module/move/crates_tools) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleCratesToolsPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleCratesToolsPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleCratesToolsPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleCratesToolsPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/crates_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fcrates_tools_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20crates_tools_trivial_sample/https://github.com/Wandalen/wTools) | +| [deterministic_rand](module/move/deterministic_rand) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleDeterministicRandPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleDeterministicRandPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleDeterministicRandPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleDeterministicRandPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/deterministic_rand) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fdeterministic_rand_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20deterministic_rand_trivial_sample/https://github.com/Wandalen/wTools) | +| [optimization_tools](module/move/optimization_tools) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleOptimizationToolsPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleOptimizationToolsPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleOptimizationToolsPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleOptimizationToolsPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/optimization_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Foptimization_tools_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20optimization_tools_trivial_sample/https://github.com/Wandalen/wTools) | +| [graphs_tools](module/move/graphs_tools) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleGraphsToolsPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleGraphsToolsPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleGraphsToolsPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleGraphsToolsPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/graphs_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fgraphs_tools_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20graphs_tools_trivial_sample/https://github.com/Wandalen/wTools) | +| [wca](module/move/wca) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleWcaPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleWcaPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleWcaPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleWcaPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/wca) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fwca_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20wca_trivial_sample/https://github.com/Wandalen/wTools) | +| [willbe](module/move/willbe) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleWillbePush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleWillbePush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleWillbePush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleWillbePush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/willbe) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fwillbe_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20willbe_trivial_sample/https://github.com/Wandalen/wTools) | +| [wplot](module/move/wplot) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleWplotPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleWplotPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleWplotPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleWplotPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/wplot) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fwplot_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20wplot_trivial_sample/https://github.com/Wandalen/wTools) | +| [wpublisher](module/move/wpublisher) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleWpublisherPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleWpublisherPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleWpublisherPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleWpublisherPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/wpublisher) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fwpublisher_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20wpublisher_trivial_sample/https://github.com/Wandalen/wTools) | +| [fs_tools](module/move/fs_tools) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleFsToolsPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleFsToolsPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleFsToolsPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleFsToolsPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/fs_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Ffs_tools_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20fs_tools_trivial_sample/https://github.com/Wandalen/wTools) | +| [sqlx_query](module/move/sqlx_query) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleSqlxQueryPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleSqlxQueryPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleSqlxQueryPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleSqlxQueryPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/sqlx_query) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fsqlx_query_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20sqlx_query_trivial_sample/https://github.com/Wandalen/wTools) | +| [automata_tools](module/move/automata_tools) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleAutomataToolsPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleAutomataToolsPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleAutomataToolsPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleAutomataToolsPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/automata_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fautomata_tools_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20automata_tools_trivial_sample/https://github.com/Wandalen/wTools) | +| [plot_interface](module/move/plot_interface) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModulePlotInterfacePush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModulePlotInterfacePush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModulePlotInterfacePush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModulePlotInterfacePush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/plot_interface) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fplot_interface_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20plot_interface_trivial_sample/https://github.com/Wandalen/wTools) | +| [wcensor](module/move/wcensor) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleWcensorPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleWcensorPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleWcensorPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleWcensorPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/wcensor) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fwcensor_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20wcensor_trivial_sample/https://github.com/Wandalen/wTools) | +| [wlang](module/move/wlang) |[![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleWlangPush.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/ModuleWlangPush.yml) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/ModuleWlangPush.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/ModuleWlangPush.yml) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/wlang) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2Fwlang_trivial_sample%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20wlang_trivial_sample/https://github.com/Wandalen/wTools) | Collection of general purpose tools for solving problems. Fundamentally extend the language without spoiling, so may be used solely or in conjunction with another module of such kind. - - - -### JavaScript tools - -| Module | Stability | Master | -|--------|-----------|--------| -| [wTools](https://github.com/Wandalen/wToolsJs/tree/master/module/wTools) | [![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![js-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wToolsJs/StandardJsPublish.yml?label=&branch=master)](https://github.com/Wandalen/wToolsJs/actions/workflows/StandardJsPublish.yml) | diff --git a/module/core/derive_tools/Cargo.toml b/module/core/derive_tools/Cargo.toml index 3ddecf0422..5f7c3af2cf 100644 --- a/module/core/derive_tools/Cargo.toml +++ b/module/core/derive_tools/Cargo.toml @@ -44,6 +44,8 @@ default = [ "derive_error", "derive_from", "derive_inner_from", + "derive_reflect", + "derive_index", "derive_index_mut", "derive_into", @@ -85,6 +87,9 @@ full = [ "derive_deref_mut", "derive_error", "derive_from", + "derive_inner_from", + "derive_reflect", + "derive_index", "derive_index_mut", "derive_into", @@ -137,6 +142,7 @@ derive_error = [ "derive_more", "derive_more/error" ] # derive_from = [ "derive_tools_meta/derive_from" ] derive_from = [ "derive_tools_meta/derive_from" ] derive_inner_from = [ "derive_tools_meta/derive_inner_from" ] +derive_reflect = [ "derive_tools_meta/derive_reflect" ] derive_index = [ "derive_more", "derive_more/index" ] derive_index_mut = [ "derive_more", "derive_more/index_mut" ] diff --git a/module/core/derive_tools/build.rs b/module/core/derive_tools/build.rs index 10968615bb..c3ad64ebc6 100644 --- a/module/core/derive_tools/build.rs +++ b/module/core/derive_tools/build.rs @@ -22,7 +22,8 @@ fn main() feature = "derive_deref_mut", feature = "derive_from", feature = "derive_inner_from", - feature = "derive_variadic_from" + feature = "derive_variadic_from", + feature = "derive_reflect" ) }, any_derive : @@ -35,9 +36,9 @@ fn main() feature = "derive_deref_mut", feature = "derive_from", feature = "derive_inner_from", - feature = "derive_variadic_from" + feature = "derive_variadic_from", + feature = "derive_reflect" ) }, } } - diff --git a/module/core/derive_tools/src/lib.rs b/module/core/derive_tools/src/lib.rs index dd2ed4527a..43a898efab 100644 --- a/module/core/derive_tools/src/lib.rs +++ b/module/core/derive_tools/src/lib.rs @@ -2,9 +2,6 @@ #![ doc( html_logo_url = "https://raw.githubusercontent.com/Wandalen/wTools/master/asset/img/logo_v3_trans_square.png" ) ] #![ doc( html_favicon_url = "https://raw.githubusercontent.com/Wandalen/wTools/alpha/asset/img/logo_v3_trans_square_icon_small_v2.ico" ) ] #![ doc( html_root_url = "https://docs.rs/derive_tools/latest/derive_tools/" ) ] -// #![ deny( rust_2018_idioms ) ] -// #![ deny( missing_debug_implementations ) ] -// #![ deny( missing_docs ) ] // #![ feature( trait_alias ) ] // #![ feature( type_name_of_val ) ] @@ -18,6 +15,9 @@ #[ cfg( feature = "enabled" ) ] pub mod wtools; +#[ cfg( feature = "derive_reflect" ) ] +pub mod reflect; + // use derive_tools_meta::Deref; // use derive_tools_meta::VariadicFrom; @@ -37,9 +37,13 @@ pub mod dependency pub use ::clone_dyn::dependency::*; #[ cfg( any_derive ) ] pub use ::derive_tools_meta; - } +#[ cfg( feature = "enabled" ) ] +#[ doc( inline ) ] +#[ allow( unused_imports ) ] +pub use protected::*; + /// Protected namespace of the module. #[ cfg( feature = "enabled" ) ] pub mod protected @@ -54,18 +58,12 @@ pub mod protected #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::wtools::orphan::*; + #[ cfg( feature = "derive_reflect" ) ] + #[ doc( inline ) ] + #[ allow( unused_imports ) ] + pub use super::reflect::orphan::*; } -#[ cfg( feature = "enabled" ) ] -#[ doc( inline ) ] -#[ allow( unused_imports ) ] -pub use protected::*; - -#[ cfg( feature = "enabled" ) ] -// #[ doc( inline ) ] -#[ allow( unused_imports ) ] -// pub use exposed::*; - /// Orphan namespace of the module. #[ cfg( feature = "enabled" ) ] pub mod orphan @@ -73,7 +71,6 @@ pub mod orphan #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::exposed::*; - } /// Exposed namespace of the module. @@ -114,6 +111,11 @@ pub mod exposed #[ allow( unused_imports ) ] pub use super::wtools::exposed::*; + #[ cfg( feature = "derive_reflect" ) ] + #[ doc( inline ) ] + #[ allow( unused_imports ) ] + pub use super::reflect::exposed::*; + // #[ cfg( any_derive ) ] #[ doc( inline ) ] #[ allow( unused_imports ) ] @@ -138,6 +140,11 @@ pub mod prelude #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use ::clone_dyn::clone_dyn; + #[ cfg( feature = "derive_reflect" ) ] + #[ doc( inline ) ] + #[ allow( unused_imports ) ] + pub use super::reflect::prelude::*; + #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::wtools::prelude::*; diff --git a/module/core/derive_tools/src/reflect.rs b/module/core/derive_tools/src/reflect.rs new file mode 100644 index 0000000000..4af21a5648 --- /dev/null +++ b/module/core/derive_tools/src/reflect.rs @@ -0,0 +1,283 @@ +//! +//! Types, which are extension of std. +//! + +/// Internal namespace. +pub( crate ) mod private +{ + + /// + /// Trait indicating that an entity is a container. + /// + /// Implementors of `IsContainer` are considered to be container types, + /// which can hold zero or more elements. This trait is typically used in + /// conjunction with reflection mechanisms to dynamically inspect, access, + /// or modify the contents of a container at runtime. + pub trait IsContainer + { + } + + /// + /// Trait indicating that an entity is a scalar value. + /// + /// Implementors of `IsScalar` are considered to be scalar types, + /// representing single, indivisible values as opposed to composite entities + /// like arrays or structs. This distinction can be useful in reflection-based + /// APIs or generic programming to treat scalar values differently from containers + /// or other complex types. + pub trait IsScalar + { + } + + // /// + // /// Represents a trait for entity reflection. + // /// + // /// This trait is designed to provide reflection capabilities to the implementing struct, + // /// allowing runtime inspection of its properties, type name, and contained elements if any. + // pub trait Instance : core::any::Any + // { + // fn entity -> + // } + + /// + /// Represents a trait for entity reflection. + /// + /// This trait is designed to provide reflection capabilities to the implementing struct, + /// allowing runtime inspection of its properties, type name, and contained elements if any. + pub trait Entity : core::any::Any + { + + /// Determines if the entity acts as a container for other entities. + /// + /// # Returns + /// + /// Returns `true` if the entity can contain other entities (like a struct, vector, etc.), + /// otherwise `false`. + /// + /// By default, this method returns `false`, assuming that the entity does not act as a container. + #[ inline( always ) ] + fn reflect_is_container( &self ) -> bool + { + false + } + + /// Returns the number of elements contained in the entity. + /// + /// # Returns + /// + /// Returns the count of elements if the entity is a container, otherwise `0`. + /// + /// This method is particularly useful for collections or composite entities. + /// By default, this method returns `0`, assuming the entity contains no elements. + #[ inline( always ) ] + fn reflect_len( &self ) -> usize + { + 0 + } + + /// Retrieves the type name of the entity. + /// + /// # Returns + /// + /// Returns the type name of the implementing entity as a static string slice. + /// + /// This method leverages Rust's `type_name` function to provide the name at runtime, + /// aiding in debugging and logging purposes. + #[ inline( always ) ] + fn reflect_type_name( &self ) -> &'static str + { + core::any::type_name::< Self >() + } + + /// Provides an iterator over the elements contained within the entity, if any. + /// + /// # Returns + /// + /// Returns a boxed iterator over `KeyVal` pairs representing the key-value mappings + /// of the entity's elements. For non-container entities, an empty iterator is returned. + /// + /// This method is crucial for traversing composite entities or collections at runtime, + /// allowing for dynamic inspection and manipulation. + #[ inline( always ) ] + fn reflect_elements( &self ) -> Box< dyn Iterator< Item = KeyVal > + '_ > + { + // std::iter::empty() + Box::new( [].into_iter() ) + } + + } + + /// A trait for entities that support dynamic type inspection and reflection. + /// + /// This trait extends both `core::any::Any` for type checking and downcasting capabilities, + /// and `Entity` for reflection-based operations, enabling runtime inspection of + /// entity properties and structures. + pub trait AnyEntity : core::any::Any + Entity {} + impl< T : core::any::Any + Entity > AnyEntity for T {} + + /// Represents a key-value pair where the key is a static string slice + /// and the value is a boxed entity that implements the `AnyEntity` trait. + /// + /// This struct is typically used in the context of reflecting over the properties + /// or members of a container entity, allowing for dynamic access and inspection + /// of its contents. + /// + /// # Examples + /// + /// ``` + /// # use derive_tools::reflect::{ KeyVal, AnyEntity, Entity }; + /// # struct MyEntity; + /// # impl Entity for MyEntity {} + /// // Assuming `MyEntity` implements `AnyEntity` + /// let my_entity = MyEntity; + /// let reflect_kv = KeyVal + /// { + /// key : "my_entity", + /// val : Box::new( my_entity ), + /// }; + /// + /// assert_eq!(reflect_kv.key, "my_entity"); + /// // Further operations can be performed on `reflect_kv.val` after downcasting it + /// // to its concrete type. + /// ``` + // #[ derive( PartialEq, Debug ) ] + pub struct KeyVal + { + /// The key associated with the value in the key-value pair. + /// + /// This is a static string slice, implying that the key is known at compile time + /// and does not change at runtime. + pub key : &'static str, + /// The value associated with the key in the key-value pair. + /// + /// It is boxed to allow for dynamic typing, enabling the storage of any entity + /// that implements the `AnyEntity` trait. This facilitates runtime reflection + /// and type inspection of the contained entity. + pub val : Box< dyn AnyEntity >, + } + + impl std::fmt::Debug for KeyVal + { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result + { + f + .debug_struct( "KeyVal" ) + .field( "key", &self.key ) + .field( "val", &format_args!( "{}", core::any::type_name::< dyn AnyEntity >() ) ) + .finish() + } + } + + impl PartialEq for KeyVal + { + fn eq( &self, other : &Self ) -> bool + { + self.key == other.key + // qqq : compare also by val + } + } + + impl Entity for i8 {} + impl Entity for i16 {} + impl Entity for i32 {} + impl Entity for i64 {} + impl Entity for u8 {} + impl Entity for u16 {} + impl Entity for u32 {} + impl Entity for u64 {} + impl Entity for f32 {} + impl Entity for f64 {} + impl Entity for String {} + impl Entity for &'static str {} + + impl IsScalar for i8 {} + impl IsScalar for i16 {} + impl IsScalar for i32 {} + impl IsScalar for i64 {} + impl IsScalar for u8 {} + impl IsScalar for u16 {} + impl IsScalar for u32 {} + impl IsScalar for u64 {} + impl IsScalar for f32 {} + impl IsScalar for f64 {} + impl IsScalar for String {} + impl IsScalar for &'static str {} + + impl< T, const N : usize > IsContainer for [ T ; N ] {} + +// impl< T : Entity, const N : usize > Entity for [ T ; N ] +// { +// +// #[ inline( always ) ] +// fn reflect_is_container( &self ) -> bool +// { +// true +// } +// +// #[ inline( always ) ] +// fn reflect_len( &self ) -> usize +// { +// N +// } +// +// #[ inline( always ) ] +// fn reflect_elements( &self ) -> Box< dyn Iterator< Item = KeyVal > + '_ > +// { +// +// let result : [ KeyVal ; N ]; +// for ( k, e ) in self.iter().enumerate() +// { +// result[ k ] = KeyVal { key : "x", val : Box::new( (*e).clone() ) } +// } +// +// Box::new( result.into_iter() ) +// } +// +// } + +} + +#[ doc( inline ) ] +#[ allow( unused_imports ) ] +pub use protected::*; + +/// Protected namespace of the module. +pub mod protected +{ + #[ doc( inline ) ] + #[ allow( unused_imports ) ] + pub use super::orphan::*; +} + +/// Orphan namespace of the module. +pub mod orphan +{ + #[ doc( inline ) ] + #[ allow( unused_imports ) ] + pub use super::exposed::*; + pub use super::private:: + { + IsContainer, + IsScalar, + Entity, + KeyVal, + AnyEntity, + }; +} + +/// Exposed namespace of the module. +pub mod exposed +{ + #[ doc( inline ) ] + #[ allow( unused_imports ) ] + pub use super::prelude::*; +} + +#[ doc( inline ) ] +#[ allow( unused_imports ) ] +pub use exposed::*; + +/// Prelude to use essentials: `use my_module::prelude::*`. +pub mod prelude +{ +} diff --git a/module/core/derive_tools/src/wtools.rs b/module/core/derive_tools/src/wtools.rs index 6a22ce0b97..76c2097948 100644 --- a/module/core/derive_tools/src/wtools.rs +++ b/module/core/derive_tools/src/wtools.rs @@ -38,12 +38,14 @@ pub mod exposed #[ allow( unused_imports ) ] pub use super::prelude::*; #[ cfg( feature = "type_variadic_from" ) ] + #[ doc( inline ) ] + #[ allow( unused_imports ) ] pub use super::from::orphan::*; } -// #[ doc( inline ) ] +#[ doc( inline ) ] #[ allow( unused_imports ) ] -// pub use exposed::*; +pub use exposed::*; /// Prelude to use essentials: `use my_module::prelude::*`. pub mod prelude diff --git a/module/core/derive_tools/tests/inc/mod.rs b/module/core/derive_tools/tests/inc/mod.rs index 5c1c5d8079..a560fec6c3 100644 --- a/module/core/derive_tools/tests/inc/mod.rs +++ b/module/core/derive_tools/tests/inc/mod.rs @@ -68,6 +68,13 @@ mod inner_from_unit_test; #[ cfg( feature = "derive_inner_from" ) ] mod inner_from_multiple_test; +#[ cfg( feature = "derive_reflect" ) ] +mod reflect_common_test; +#[ cfg( feature = "derive_reflect" ) ] +mod reflect_struct_manual_test; +#[ cfg( feature = "derive_reflect" ) ] +mod reflect_struct_in_struct_manual_test; + // #[ cfg( all( feature = "type_variadic_from" ) ) ] // mod variadic_from_manual_test; // diff --git a/module/core/derive_tools/tests/inc/only_test/inner_from.rs b/module/core/derive_tools/tests/inc/only_test/inner_from.rs index 4b10f8b3d0..d0ce048568 100644 --- a/module/core/derive_tools/tests/inc/only_test/inner_from.rs +++ b/module/core/derive_tools/tests/inc/only_test/inner_from.rs @@ -1,4 +1,3 @@ -// qqq2 : move top 2 lines into test.rs file for each file in the dir #[ test ] fn from_outer_test() { diff --git a/module/core/derive_tools/tests/inc/only_test/reflect_struct.rs b/module/core/derive_tools/tests/inc/only_test/reflect_struct.rs new file mode 100644 index 0000000000..5972cdd1dc --- /dev/null +++ b/module/core/derive_tools/tests/inc/only_test/reflect_struct.rs @@ -0,0 +1,28 @@ +#[ test ] +fn reflect_basic_test() +{ + use reflect::Entity; + + let ins = Struct1 + { + f1 : 1, + f2 : "2".into(), + f3 : "3", + }; + + a_id!( ins.reflect_is_container(), true ); + a_id!( ins.reflect_len(), 3 ); + a_id!( ins.reflect_type_name(), "derive_tests::inc::reflect_struct_manual_test::Struct1" ); + let names = ins.reflect_elements().map( | e | e.key ).collect::< Vec< _ > >(); + a_id!( names, vec![ "f1", "f2", "f3" ] ); + let types = ins.reflect_elements().map( | e | e.val.reflect_type_name() ).collect::< Vec< _ > >(); + a_id!( types, vec![ "i32", "alloc::string::String", "&str" ] ); + + let f1 = ins.reflect_elements().next().unwrap(); + a_id!( f1.key, "f1" ); + a_id!( f1.val.reflect_is_container(), false ); + a_id!( f1.val.reflect_len(), 0 ); + a_id!( f1.val.reflect_type_name(), "i32" ); + a_id!( f1.val.reflect_elements().collect::< Vec< _ > >(), vec![] ); + +} diff --git a/module/core/derive_tools/tests/inc/only_test/reflect_struct_in_struct.rs b/module/core/derive_tools/tests/inc/only_test/reflect_struct_in_struct.rs new file mode 100644 index 0000000000..5abc4a4f7e --- /dev/null +++ b/module/core/derive_tools/tests/inc/only_test/reflect_struct_in_struct.rs @@ -0,0 +1,31 @@ +#[ test ] +fn reflect_struct_in_struct() +{ + use reflect::Entity; + + let ins = Struct1 + { + f1 : 1, + f2 : "2".into(), + f3 : Struct2 { s1 : 10, s2 : "20".into(), s3 : "30" }, + }; + + a_id!( ins.reflect_is_container(), true ); + a_id!( ins.reflect_len(), 3 ); + a_id!( ins.reflect_type_name(), "derive_tests::inc::reflect_struct_in_struct_manual_test::Struct1" ); + let names = ins.reflect_elements().map( | e | e.key ).collect::< Vec< _ > >(); + a_id!( names, vec![ "f1", "f2", "f3" ] ); + let types = ins.reflect_elements().map( | e | e.val.reflect_type_name() ).collect::< Vec< _ > >(); + a_id!( types, vec![ "i32", "alloc::string::String", "derive_tests::inc::reflect_struct_in_struct_manual_test::Struct2" ] ); + + let f3 = ins.reflect_elements().skip( 2 ).next().unwrap(); + a_id!( f3.key, "f3" ); + a_id!( f3.val.reflect_is_container(), true ); + a_id!( f3.val.reflect_len(), 3 ); + a_id!( f3.val.reflect_type_name(), "derive_tests::inc::reflect_struct_in_struct_manual_test::Struct2" ); + let names = f3.val.reflect_elements().map( | e | e.key ).collect::< Vec< _ > >(); + a_id!( names, vec![ "s1", "s2", "s3" ] ); + let types = f3.val.reflect_elements().map( | e | e.val.reflect_type_name() ).collect::< Vec< _ > >(); + a_id!( types, vec![ "i32", "alloc::string::String", "&str" ] ); + +} diff --git a/module/core/derive_tools/tests/inc/reflect_common_test.rs b/module/core/derive_tools/tests/inc/reflect_common_test.rs new file mode 100644 index 0000000000..cbafdcb3c1 --- /dev/null +++ b/module/core/derive_tools/tests/inc/reflect_common_test.rs @@ -0,0 +1,51 @@ +use super::*; +pub use TheModule::reflect; + +#[ test ] +fn reflect_basic_test() +{ + use reflect::Entity; + + a_id!( 0i8.reflect_is_container(), false ); + a_id!( 0i8.reflect_len(), 0 ); + a_id!( 0i8.reflect_type_name(), "i8" ); + a_id!( 0i8.reflect_elements().collect::< Vec< _ > >(), Vec::< reflect::KeyVal >::new() ); + + a_id!( 0i16.reflect_is_container(), false ); + a_id!( 0i16.reflect_len(), 0 ); + a_id!( 0i16.reflect_type_name(), "i16" ); + a_id!( 0i16.reflect_elements().collect::< Vec< _ > >(), Vec::< reflect::KeyVal >::new() ); + + a_id!( 0i32.reflect_is_container(), false ); + a_id!( 0i32.reflect_len(), 0 ); + a_id!( 0i32.reflect_type_name(), "i32" ); + a_id!( 0i32.reflect_elements().collect::< Vec< _ > >(), Vec::< reflect::KeyVal >::new() ); + + a_id!( 0i64.reflect_is_container(), false ); + a_id!( 0i64.reflect_len(), 0 ); + a_id!( 0i64.reflect_type_name(), "i64" ); + a_id!( 0i64.reflect_elements().collect::< Vec< _ > >(), Vec::< reflect::KeyVal >::new() ); + + // + + a_id!( 0u8.reflect_is_container(), false ); + a_id!( 0u8.reflect_len(), 0 ); + a_id!( 0u8.reflect_type_name(), "u8" ); + a_id!( 0u8.reflect_elements().collect::< Vec< _ > >(), Vec::< reflect::KeyVal >::new() ); + + a_id!( 0u16.reflect_is_container(), false ); + a_id!( 0u16.reflect_len(), 0 ); + a_id!( 0u16.reflect_type_name(), "u16" ); + a_id!( 0u16.reflect_elements().collect::< Vec< _ > >(), Vec::< reflect::KeyVal >::new() ); + + a_id!( 0u32.reflect_is_container(), false ); + a_id!( 0u32.reflect_len(), 0 ); + a_id!( 0u32.reflect_type_name(), "u32" ); + a_id!( 0u32.reflect_elements().collect::< Vec< _ > >(), Vec::< reflect::KeyVal >::new() ); + + a_id!( 0u64.reflect_is_container(), false ); + a_id!( 0u64.reflect_len(), 0 ); + a_id!( 0u64.reflect_type_name(), "u64" ); + a_id!( 0u64.reflect_elements().collect::< Vec< _ > >(), Vec::< reflect::KeyVal >::new() ); + +} diff --git a/module/core/derive_tools/tests/inc/reflect_struct_in_struct_manual_test.rs b/module/core/derive_tools/tests/inc/reflect_struct_in_struct_manual_test.rs new file mode 100644 index 0000000000..eb3d628042 --- /dev/null +++ b/module/core/derive_tools/tests/inc/reflect_struct_in_struct_manual_test.rs @@ -0,0 +1,70 @@ +use super::*; +pub use TheModule::reflect; + +#[ derive( Debug, Clone, PartialEq ) ] +pub struct Struct1 +{ + pub f1 : i32, + pub f2 : String, + pub f3 : Struct2, +} + +#[ derive( Debug, Clone, PartialEq ) ] +pub struct Struct2 +{ + pub s1 : i32, + pub s2 : String, + pub s3 : &'static str, +} + +impl reflect::Entity for Struct1 +{ + #[ inline( always ) ] + fn reflect_is_container( &self ) -> bool + { + true + } + #[ inline( always ) ] + fn reflect_len( &self ) -> usize + { + 3 + } + #[ inline( always ) ] + fn reflect_elements( &self ) -> Box< dyn Iterator< Item = reflect::KeyVal > + '_ > + { + let result = vec! + [ + reflect::KeyVal { key : "f1", val : Box::new( self.f1 ) }, + reflect::KeyVal { key : "f2", val : Box::new( self.f2.clone() ) }, + reflect::KeyVal { key : "f3", val : Box::new( self.f3.clone() ) }, + ]; + Box::new( result.into_iter() ) + } +} + +impl reflect::Entity for Struct2 +{ + #[ inline( always ) ] + fn reflect_is_container( &self ) -> bool + { + true + } + #[ inline( always ) ] + fn reflect_len( &self ) -> usize + { + 3 + } + #[ inline( always ) ] + fn reflect_elements( &self ) -> Box< dyn Iterator< Item = reflect::KeyVal > + '_ > + { + let result = vec! + [ + reflect::KeyVal { key : "s1", val : Box::new( self.s1 ) }, + reflect::KeyVal { key : "s2", val : Box::new( self.s2.clone() ) }, + reflect::KeyVal { key : "s3", val : Box::new( self.s3 ) }, + ]; + Box::new( result.into_iter() ) + } +} + +include!( "./only_test/reflect_struct_in_struct.rs" ); diff --git a/module/core/derive_tools/tests/inc/reflect_struct_manual_test.rs b/module/core/derive_tools/tests/inc/reflect_struct_manual_test.rs new file mode 100644 index 0000000000..7b37b0a535 --- /dev/null +++ b/module/core/derive_tools/tests/inc/reflect_struct_manual_test.rs @@ -0,0 +1,37 @@ +use super::*; +pub use TheModule::reflect; + +#[ derive( Debug, Clone, PartialEq ) ] +pub struct Struct1 +{ + pub f1 : i32, + pub f2 : String, + pub f3 : &'static str, +} + +impl reflect::Entity for Struct1 +{ + #[ inline( always ) ] + fn reflect_is_container( &self ) -> bool + { + true + } + #[ inline( always ) ] + fn reflect_len( &self ) -> usize + { + 3 + } + #[ inline( always ) ] + fn reflect_elements( &self ) -> Box< dyn Iterator< Item = reflect::KeyVal > + '_ > + { + let result = vec! + [ + reflect::KeyVal { key : "f1", val : Box::new( self.f1 ) }, + reflect::KeyVal { key : "f2", val : Box::new( self.f2.clone() ) }, + reflect::KeyVal { key : "f3", val : Box::new( self.f3 ) }, + ]; + Box::new( result.into_iter() ) + } +} + +include!( "./only_test/reflect_struct.rs" ); diff --git a/module/core/derive_tools_meta/Cargo.toml b/module/core/derive_tools_meta/Cargo.toml index fa41daa13d..bd2dd17958 100644 --- a/module/core/derive_tools_meta/Cargo.toml +++ b/module/core/derive_tools_meta/Cargo.toml @@ -39,6 +39,7 @@ default = [ "derive_as_ref", "derive_as_mut", "derive_variadic_from", + "derive_reflect", ] full = [ "enabled", @@ -49,6 +50,7 @@ full = [ "derive_as_ref", "derive_as_mut", "derive_variadic_from", + "derive_reflect", ] enabled = [] @@ -59,6 +61,7 @@ derive_deref_mut = [] derive_from = [] derive_inner_from = [] derive_variadic_from = [] +derive_reflect = [] [dependencies] macro_tools = { workspace = true, features = [ "full" ] } diff --git a/module/core/derive_tools_meta/src/implementation/mod.rs b/module/core/derive_tools_meta/src/implementation/mod.rs index 3521cd27d4..ec9ed0b65a 100644 --- a/module/core/derive_tools_meta/src/implementation/mod.rs +++ b/module/core/derive_tools_meta/src/implementation/mod.rs @@ -25,3 +25,5 @@ pub mod from_inner; pub mod inner_from; #[ cfg( feature = "derive_variadic_from" ) ] pub mod variadic_from; +#[ cfg( feature = "derive_reflect" ) ] +pub mod reflect; diff --git a/module/core/derive_tools_meta/src/implementation/reflect.rs b/module/core/derive_tools_meta/src/implementation/reflect.rs new file mode 100644 index 0000000000..e4187fbf80 --- /dev/null +++ b/module/core/derive_tools_meta/src/implementation/reflect.rs @@ -0,0 +1,19 @@ + +// use macro_tools::proc_macro2::TokenStream; +use super::*; + +// + +pub fn reflect( input : proc_macro::TokenStream ) -> Result< proc_macro2::TokenStream > +{ + let parsed = syn::parse::< InputParsed >( input )?; + // let field_types = parsed.field_types; + // let field_names = parsed.field_names; + // let item_name = parsed.item_name; + + let result = qt! + { + }; + + Ok( result ) +} diff --git a/module/core/derive_tools_meta/src/lib.rs b/module/core/derive_tools_meta/src/lib.rs index 2e08399e01..df84539e14 100644 --- a/module/core/derive_tools_meta/src/lib.rs +++ b/module/core/derive_tools_meta/src/lib.rs @@ -32,6 +32,7 @@ feature = "derive_from", feature = "derive_inner_from", feature = "derive_variadic_from", + feature = "derive_reflect", ) )] #[ cfg( feature = "enabled" ) ] @@ -47,6 +48,7 @@ mod implementation; feature = "derive_from", feature = "derive_inner_from", feature = "derive_variadic_from", + feature = "derive_reflect", ) )] #[ cfg( feature = "enabled" ) ] @@ -376,6 +378,8 @@ pub fn as_mut( input : proc_macro::TokenStream ) -> proc_macro::TokenStream /// /// ``` +// qqq : xxx : why no run? + #[ cfg( feature = "enabled" ) ] #[ cfg( feature = "derive_variadic_from" ) ] #[ proc_macro_derive( VariadicFrom ) ] @@ -388,3 +392,24 @@ pub fn derive_variadic_from( input : proc_macro::TokenStream ) -> proc_macro::To Err( err ) => err.to_compile_error().into(), } } + +/// +/// Reflect structure of any kind. +/// +/// ### Sample :: trivial. +/// +/// qqq : write, please +/// + +#[ cfg( feature = "enabled" ) ] +#[ cfg( feature = "derive_reflect" ) ] +#[ proc_macro_derive( Reflect ) ] +pub fn derive_reflect( input : proc_macro::TokenStream ) -> proc_macro::TokenStream +{ + let result = reflect::reflect( input ); + match result + { + Ok( stream ) => stream.into(), + Err( err ) => err.to_compile_error().into(), + } +} diff --git a/module/move/unitore/src/feed_config.rs b/module/move/unitore/src/feed_config.rs index 1e78339d5e..570c1fec9b 100644 --- a/module/move/unitore/src/feed_config.rs +++ b/module/move/unitore/src/feed_config.rs @@ -33,4 +33,3 @@ pub fn read_feed_config() -> Result< Vec< FeedConfig >, Box< dyn std::error::Err Ok( feeds.config ) } - From ef2d7faa1835bc3ed678edb5208fc152882a9de6 Mon Sep 17 00:00:00 2001 From: wandalen Date: Sat, 17 Feb 2024 20:37:23 +0200 Subject: [PATCH 04/19] experimenting --- module/core/derive_tools/src/reflect.rs | 165 ++++++++++++------ module/core/derive_tools/tests/inc/mod.rs | 12 +- .../tests/inc/reflect_common_test.rs | 72 ++++---- .../tests/inc/reflect_struct_manual_test.rs | 40 ++++- 4 files changed, 186 insertions(+), 103 deletions(-) diff --git a/module/core/derive_tools/src/reflect.rs b/module/core/derive_tools/src/reflect.rs index 4af21a5648..ff8faa1bcd 100644 --- a/module/core/derive_tools/src/reflect.rs +++ b/module/core/derive_tools/src/reflect.rs @@ -29,23 +29,56 @@ pub( crate ) mod private { } - // /// - // /// Represents a trait for entity reflection. - // /// - // /// This trait is designed to provide reflection capabilities to the implementing struct, - // /// allowing runtime inspection of its properties, type name, and contained elements if any. - // pub trait Instance : core::any::Any - // { - // fn entity -> - // } - /// /// Represents a trait for entity reflection. /// /// This trait is designed to provide reflection capabilities to the implementing struct, /// allowing runtime inspection of its properties, type name, and contained elements if any. - pub trait Entity : core::any::Any + // pub trait Instance : core::any::Any + pub trait Instance + { + /// Return a descriptor of type of current instance of the type. + fn reflect( &self ) -> impl EntityInterface< I = Self > + where + Self : Sized, + EntityDescriptor< Self > : EntityInterface< I = Self >, + { + EntityDescriptor::< Self >::new() + } + } + + /// xxx + pub trait AnyInstance : core::any::Any + Instance {} + impl< T : core::any::Any + Instance > AnyInstance for T {} + + /// + /// Type descriptor + /// + #[ derive( PartialEq, Debug ) ] + pub struct EntityDescriptor< I : Instance > + { + _phantom : core::marker::PhantomData< I >, + } + + impl< I : Instance > EntityDescriptor< I > + { + /// Constructor of the descriptor. + #[ inline( always ) ] + pub fn new() -> Self + { + let _phantom = core::marker::PhantomData::< I >; + Self { _phantom } + } + } + + /// + /// Type descriptor + /// + // pub trait EntityInterface< I : Instance > : core::any::Any + pub trait EntityInterface { + /// Type of the instance the descriptor describe. + type I : Instance; /// Determines if the entity acts as a container for other entities. /// @@ -86,7 +119,7 @@ pub( crate ) mod private #[ inline( always ) ] fn reflect_type_name( &self ) -> &'static str { - core::any::type_name::< Self >() + core::any::type_name::< Self::I >() } /// Provides an iterator over the elements contained within the entity, if any. @@ -98,22 +131,46 @@ pub( crate ) mod private /// /// This method is crucial for traversing composite entities or collections at runtime, /// allowing for dynamic inspection and manipulation. + + // fn reflect_elements(&self) -> Box> + '_>; + + // #[ inline( always ) ] + // fn reflect_elements<'a>( &'a self ) -> Box< dyn Iterator< Item = KeyVal< dyn AnyEntity > > + 'a > + // { + // // std::iter::empty() + // Box::new( [].into_iter() ) + // } + #[ inline( always ) ] - fn reflect_elements( &self ) -> Box< dyn Iterator< Item = KeyVal > + '_ > + // fn reflect_elements( &self ) -> Box< dyn Iterator< Item = KeyVal< Box< dyn Instance > > > > + fn reflect_elements( &self ) -> Box< dyn Iterator< Item = KeyVal< Box< dyn EntityInterface< I = dyn AnyInstance > > > > > { - // std::iter::empty() Box::new( [].into_iter() ) } } +// /// +// pub trait Reflectable +// { +// } +// +// // Assuming all instances that can be reflected upon implement Reflectable. +// impl< T : 'static + Reflectable > EntityInterface for T +// { +// fn reflect_elements(&self) -> Box> + '_> +// { +// Box::new( [].into_iter() ) +// } +// } + /// A trait for entities that support dynamic type inspection and reflection. /// /// This trait extends both `core::any::Any` for type checking and downcasting capabilities, - /// and `Entity` for reflection-based operations, enabling runtime inspection of + /// and `EntityInterface` for reflection-based operations, enabling runtime inspection of /// entity properties and structures. - pub trait AnyEntity : core::any::Any + Entity {} - impl< T : core::any::Any + Entity > AnyEntity for T {} + pub trait AnyEntity : core::any::Any + EntityInterface {} + impl< T : core::any::Any + EntityInterface > AnyEntity for T {} /// Represents a key-value pair where the key is a static string slice /// and the value is a boxed entity that implements the `AnyEntity` trait. @@ -122,26 +179,8 @@ pub( crate ) mod private /// or members of a container entity, allowing for dynamic access and inspection /// of its contents. /// - /// # Examples - /// - /// ``` - /// # use derive_tools::reflect::{ KeyVal, AnyEntity, Entity }; - /// # struct MyEntity; - /// # impl Entity for MyEntity {} - /// // Assuming `MyEntity` implements `AnyEntity` - /// let my_entity = MyEntity; - /// let reflect_kv = KeyVal - /// { - /// key : "my_entity", - /// val : Box::new( my_entity ), - /// }; - /// - /// assert_eq!(reflect_kv.key, "my_entity"); - /// // Further operations can be performed on `reflect_kv.val` after downcasting it - /// // to its concrete type. - /// ``` // #[ derive( PartialEq, Debug ) ] - pub struct KeyVal + pub struct KeyVal< I > { /// The key associated with the value in the key-value pair. /// @@ -153,22 +192,22 @@ pub( crate ) mod private /// It is boxed to allow for dynamic typing, enabling the storage of any entity /// that implements the `AnyEntity` trait. This facilitates runtime reflection /// and type inspection of the contained entity. - pub val : Box< dyn AnyEntity >, + pub val : Box< dyn AnyEntity< I = I > >, } - impl std::fmt::Debug for KeyVal + impl< I > std::fmt::Debug for KeyVal< I > { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result + fn fmt( &self, f: &mut std::fmt::Formatter< '_ > ) -> std::fmt::Result { f .debug_struct( "KeyVal" ) .field( "key", &self.key ) - .field( "val", &format_args!( "{}", core::any::type_name::< dyn AnyEntity >() ) ) + .field( "val", &format_args!( "{}", core::any::type_name::< dyn AnyEntity< I = I > >() ) ) .finish() } } - impl PartialEq for KeyVal + impl< I > PartialEq for KeyVal< I > { fn eq( &self, other : &Self ) -> bool { @@ -177,18 +216,31 @@ pub( crate ) mod private } } - impl Entity for i8 {} - impl Entity for i16 {} - impl Entity for i32 {} - impl Entity for i64 {} - impl Entity for u8 {} - impl Entity for u16 {} - impl Entity for u32 {} - impl Entity for u64 {} - impl Entity for f32 {} - impl Entity for f64 {} - impl Entity for String {} - impl Entity for &'static str {} + impl Instance for i8 {} + impl Instance for i16 {} + impl Instance for i32 {} + impl Instance for i64 {} + impl Instance for u8 {} + impl Instance for u16 {} + impl Instance for u32 {} + impl Instance for u64 {} + impl Instance for f32 {} + impl Instance for f64 {} + impl Instance for String {} + impl Instance for &'static str {} + + impl EntityInterface for EntityDescriptor< i8 > { type I = i8; } + impl EntityInterface for EntityDescriptor< i16 > { type I = i16; } + impl EntityInterface for EntityDescriptor< i32 > { type I = i32; } + impl EntityInterface for EntityDescriptor< i64 > { type I = i64; } + impl EntityInterface for EntityDescriptor< u8 > { type I = u8; } + impl EntityInterface for EntityDescriptor< u16 > { type I = u16; } + impl EntityInterface for EntityDescriptor< u32 > { type I = u32; } + impl EntityInterface for EntityDescriptor< u64 > { type I = u64; } + impl EntityInterface for EntityDescriptor< f32 > { type I = f32; } + impl EntityInterface for EntityDescriptor< f64 > { type I = f64; } + impl EntityInterface for EntityDescriptor< String > { type I = String; } + impl EntityInterface for EntityDescriptor< &'static str > { type I = &'static str; } impl IsScalar for i8 {} impl IsScalar for i16 {} @@ -205,7 +257,7 @@ pub( crate ) mod private impl< T, const N : usize > IsContainer for [ T ; N ] {} -// impl< T : Entity, const N : usize > Entity for [ T ; N ] +// impl< T : EntityInterface, const N : usize > EntityInterface for [ T ; N ] // { // // #[ inline( always ) ] @@ -259,7 +311,10 @@ pub mod orphan { IsContainer, IsScalar, - Entity, + Instance, + AnyInstance, + EntityDescriptor, + EntityInterface, KeyVal, AnyEntity, }; diff --git a/module/core/derive_tools/tests/inc/mod.rs b/module/core/derive_tools/tests/inc/mod.rs index a560fec6c3..87ae9a9404 100644 --- a/module/core/derive_tools/tests/inc/mod.rs +++ b/module/core/derive_tools/tests/inc/mod.rs @@ -68,12 +68,12 @@ mod inner_from_unit_test; #[ cfg( feature = "derive_inner_from" ) ] mod inner_from_multiple_test; -#[ cfg( feature = "derive_reflect" ) ] -mod reflect_common_test; -#[ cfg( feature = "derive_reflect" ) ] -mod reflect_struct_manual_test; -#[ cfg( feature = "derive_reflect" ) ] -mod reflect_struct_in_struct_manual_test; +// #[ cfg( feature = "derive_reflect" ) ] +// mod reflect_common_test; +// #[ cfg( feature = "derive_reflect" ) ] +// mod reflect_struct_manual_test; +// #[ cfg( feature = "derive_reflect" ) ] +// mod reflect_struct_in_struct_manual_test; // #[ cfg( all( feature = "type_variadic_from" ) ) ] // mod variadic_from_manual_test; diff --git a/module/core/derive_tools/tests/inc/reflect_common_test.rs b/module/core/derive_tools/tests/inc/reflect_common_test.rs index cbafdcb3c1..81f0741e35 100644 --- a/module/core/derive_tools/tests/inc/reflect_common_test.rs +++ b/module/core/derive_tools/tests/inc/reflect_common_test.rs @@ -4,48 +4,48 @@ pub use TheModule::reflect; #[ test ] fn reflect_basic_test() { - use reflect::Entity; + use reflect::{ EntityInterface, Instance }; - a_id!( 0i8.reflect_is_container(), false ); - a_id!( 0i8.reflect_len(), 0 ); - a_id!( 0i8.reflect_type_name(), "i8" ); - a_id!( 0i8.reflect_elements().collect::< Vec< _ > >(), Vec::< reflect::KeyVal >::new() ); + a_id!( 0i8.reflect().reflect_is_container(), false ); + a_id!( 0i8.reflect().reflect_len(), 0 ); + a_id!( 0i8.reflect().reflect_type_name(), "i8" ); + a_id!( 0i8.reflect().reflect_elements().collect::< Vec< _ > >(), Vec::< _ >::new() ); - a_id!( 0i16.reflect_is_container(), false ); - a_id!( 0i16.reflect_len(), 0 ); - a_id!( 0i16.reflect_type_name(), "i16" ); - a_id!( 0i16.reflect_elements().collect::< Vec< _ > >(), Vec::< reflect::KeyVal >::new() ); + a_id!( 0i16.reflect().reflect_is_container(), false ); + a_id!( 0i16.reflect().reflect_len(), 0 ); + a_id!( 0i16.reflect().reflect_type_name(), "i16" ); + a_id!( 0i16.reflect().reflect_elements().collect::< Vec< _ > >(), Vec::< _ >::new() ); - a_id!( 0i32.reflect_is_container(), false ); - a_id!( 0i32.reflect_len(), 0 ); - a_id!( 0i32.reflect_type_name(), "i32" ); - a_id!( 0i32.reflect_elements().collect::< Vec< _ > >(), Vec::< reflect::KeyVal >::new() ); + a_id!( 0i32.reflect().reflect_is_container(), false ); + a_id!( 0i32.reflect().reflect_len(), 0 ); + a_id!( 0i32.reflect().reflect_type_name(), "i32" ); + a_id!( 0i32.reflect().reflect_elements().collect::< Vec< _ > >(), Vec::< _ >::new() ); - a_id!( 0i64.reflect_is_container(), false ); - a_id!( 0i64.reflect_len(), 0 ); - a_id!( 0i64.reflect_type_name(), "i64" ); - a_id!( 0i64.reflect_elements().collect::< Vec< _ > >(), Vec::< reflect::KeyVal >::new() ); + a_id!( 0i64.reflect().reflect_is_container(), false ); + a_id!( 0i64.reflect().reflect_len(), 0 ); + a_id!( 0i64.reflect().reflect_type_name(), "i64" ); + a_id!( 0i64.reflect().reflect_elements().collect::< Vec< _ > >(), Vec::< _ >::new() ); // - a_id!( 0u8.reflect_is_container(), false ); - a_id!( 0u8.reflect_len(), 0 ); - a_id!( 0u8.reflect_type_name(), "u8" ); - a_id!( 0u8.reflect_elements().collect::< Vec< _ > >(), Vec::< reflect::KeyVal >::new() ); - - a_id!( 0u16.reflect_is_container(), false ); - a_id!( 0u16.reflect_len(), 0 ); - a_id!( 0u16.reflect_type_name(), "u16" ); - a_id!( 0u16.reflect_elements().collect::< Vec< _ > >(), Vec::< reflect::KeyVal >::new() ); - - a_id!( 0u32.reflect_is_container(), false ); - a_id!( 0u32.reflect_len(), 0 ); - a_id!( 0u32.reflect_type_name(), "u32" ); - a_id!( 0u32.reflect_elements().collect::< Vec< _ > >(), Vec::< reflect::KeyVal >::new() ); - - a_id!( 0u64.reflect_is_container(), false ); - a_id!( 0u64.reflect_len(), 0 ); - a_id!( 0u64.reflect_type_name(), "u64" ); - a_id!( 0u64.reflect_elements().collect::< Vec< _ > >(), Vec::< reflect::KeyVal >::new() ); + a_id!( 0u8.reflect().reflect_is_container(), false ); + a_id!( 0u8.reflect().reflect_len(), 0 ); + a_id!( 0u8.reflect().reflect_type_name(), "u8" ); + a_id!( 0u8.reflect().reflect_elements().collect::< Vec< _ > >(), Vec::< _ >::new() ); + + a_id!( 0u16.reflect().reflect_is_container(), false ); + a_id!( 0u16.reflect().reflect_len(), 0 ); + a_id!( 0u16.reflect().reflect_type_name(), "u16" ); + a_id!( 0u16.reflect().reflect_elements().collect::< Vec< _ > >(), Vec::< _ >::new() ); + + a_id!( 0u32.reflect().reflect_is_container(), false ); + a_id!( 0u32.reflect().reflect_len(), 0 ); + a_id!( 0u32.reflect().reflect_type_name(), "u32" ); + a_id!( 0u32.reflect().reflect_elements().collect::< Vec< _ > >(), Vec::< _ >::new() ); + + a_id!( 0u64.reflect().reflect_is_container(), false ); + a_id!( 0u64.reflect().reflect_len(), 0 ); + a_id!( 0u64.reflect().reflect_type_name(), "u64" ); + a_id!( 0u64.reflect().reflect_elements().collect::< Vec< _ > >(), Vec::< _ >::new() ); } diff --git a/module/core/derive_tools/tests/inc/reflect_struct_manual_test.rs b/module/core/derive_tools/tests/inc/reflect_struct_manual_test.rs index 7b37b0a535..17b43bbb97 100644 --- a/module/core/derive_tools/tests/inc/reflect_struct_manual_test.rs +++ b/module/core/derive_tools/tests/inc/reflect_struct_manual_test.rs @@ -9,8 +9,27 @@ pub struct Struct1 pub f3 : &'static str, } -impl reflect::Entity for Struct1 +#[ derive( PartialEq, Debug ) ] +pub struct EntityDescriptor< I : reflect::Instance > { + _phantom : core::marker::PhantomData< I >, +} + +impl< I : reflect::Instance > EntityDescriptor< I > +{ + /// Constructor of the descriptor. + #[ inline( always ) ] + pub fn new() -> Self + { + let _phantom = core::marker::PhantomData::< I >; + Self { _phantom } + } +} + +impl reflect::Instance for Struct1 {} +impl reflect::EntityInterface for EntityDescriptor< Struct1 > +{ + type I = Struct1; #[ inline( always ) ] fn reflect_is_container( &self ) -> bool { @@ -22,16 +41,25 @@ impl reflect::Entity for Struct1 3 } #[ inline( always ) ] - fn reflect_elements( &self ) -> Box< dyn Iterator< Item = reflect::KeyVal > + '_ > + // fn reflect_elements( &self ) -> Box< dyn Iterator< Item = reflect::KeyVal< Box< dyn reflect::Instance > > > > + fn reflect_elements( &self ) -> Box< dyn Iterator< Item = reflect::KeyVal< Box< dyn reflect::EntityInterface< I = dyn reflect::AnyInstance > > > > > { + // let x = Box::new( reflect::EntityDescriptor::< i32 >::new() ); + let boxed_descriptor_as_trait : Box< dyn reflect::EntityInterface< I = dyn reflect::AnyInstance > > + = Box::new( reflect::EntityDescriptor::< i32 >::new() ); let result = vec! [ - reflect::KeyVal { key : "f1", val : Box::new( self.f1 ) }, - reflect::KeyVal { key : "f2", val : Box::new( self.f2.clone() ) }, - reflect::KeyVal { key : "f3", val : Box::new( self.f3 ) }, + // reflect::KeyVal { key: "f1", val: boxed_descriptor_as_trait }, + // Other KeyVal instances ]; + // let result = vec! + // [ + // reflect::KeyVal { key : "f1", val: Box::new( reflect::EntityDescriptor::< i32 >::new() ) }, + // // reflect::KeyVal { key : "f2", val : Box::new( self.f2.clone() ) }, + // // reflect::KeyVal { key : "f3", val : Box::new( self.f3 ) }, + // ]; Box::new( result.into_iter() ) } } -include!( "./only_test/reflect_struct.rs" ); +// include!( "./only_test/reflect_struct.rs" ); From 6551a279c3c500c7dc1635ecb840e511faa306af Mon Sep 17 00:00:00 2001 From: wandalen Date: Sat, 17 Feb 2024 20:39:18 +0200 Subject: [PATCH 05/19] experimenting --- module/core/derive_tools/src/reflect.rs | 44 ++++++++++++------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/module/core/derive_tools/src/reflect.rs b/module/core/derive_tools/src/reflect.rs index ff8faa1bcd..7e555091f9 100644 --- a/module/core/derive_tools/src/reflect.rs +++ b/module/core/derive_tools/src/reflect.rs @@ -38,10 +38,10 @@ pub( crate ) mod private pub trait Instance { /// Return a descriptor of type of current instance of the type. - fn reflect( &self ) -> impl EntityInterface< I = Self > + fn reflect( &self ) -> impl EntityInterface where Self : Sized, - EntityDescriptor< Self > : EntityInterface< I = Self >, + EntityDescriptor< Self > : EntityInterface, { EntityDescriptor::< Self >::new() } @@ -77,8 +77,8 @@ pub( crate ) mod private // pub trait EntityInterface< I : Instance > : core::any::Any pub trait EntityInterface { - /// Type of the instance the descriptor describe. - type I : Instance; + // /// Type of the instance the descriptor describe. + // type I : Instance; /// Determines if the entity acts as a container for other entities. /// @@ -143,7 +143,7 @@ pub( crate ) mod private #[ inline( always ) ] // fn reflect_elements( &self ) -> Box< dyn Iterator< Item = KeyVal< Box< dyn Instance > > > > - fn reflect_elements( &self ) -> Box< dyn Iterator< Item = KeyVal< Box< dyn EntityInterface< I = dyn AnyInstance > > > > > + fn reflect_elements( &self ) -> Box< dyn Iterator< Item = KeyVal > > { Box::new( [].into_iter() ) } @@ -180,7 +180,7 @@ pub( crate ) mod private /// of its contents. /// // #[ derive( PartialEq, Debug ) ] - pub struct KeyVal< I > + pub struct KeyVal { /// The key associated with the value in the key-value pair. /// @@ -192,22 +192,22 @@ pub( crate ) mod private /// It is boxed to allow for dynamic typing, enabling the storage of any entity /// that implements the `AnyEntity` trait. This facilitates runtime reflection /// and type inspection of the contained entity. - pub val : Box< dyn AnyEntity< I = I > >, + pub val : Box< dyn AnyEntity >, } - impl< I > std::fmt::Debug for KeyVal< I > + impl std::fmt::Debug for KeyVal { fn fmt( &self, f: &mut std::fmt::Formatter< '_ > ) -> std::fmt::Result { f .debug_struct( "KeyVal" ) .field( "key", &self.key ) - .field( "val", &format_args!( "{}", core::any::type_name::< dyn AnyEntity< I = I > >() ) ) + .field( "val", &format_args!( "{}", core::any::type_name::< dyn AnyEntity >() ) ) .finish() } } - impl< I > PartialEq for KeyVal< I > + impl PartialEq for KeyVal { fn eq( &self, other : &Self ) -> bool { @@ -229,18 +229,18 @@ pub( crate ) mod private impl Instance for String {} impl Instance for &'static str {} - impl EntityInterface for EntityDescriptor< i8 > { type I = i8; } - impl EntityInterface for EntityDescriptor< i16 > { type I = i16; } - impl EntityInterface for EntityDescriptor< i32 > { type I = i32; } - impl EntityInterface for EntityDescriptor< i64 > { type I = i64; } - impl EntityInterface for EntityDescriptor< u8 > { type I = u8; } - impl EntityInterface for EntityDescriptor< u16 > { type I = u16; } - impl EntityInterface for EntityDescriptor< u32 > { type I = u32; } - impl EntityInterface for EntityDescriptor< u64 > { type I = u64; } - impl EntityInterface for EntityDescriptor< f32 > { type I = f32; } - impl EntityInterface for EntityDescriptor< f64 > { type I = f64; } - impl EntityInterface for EntityDescriptor< String > { type I = String; } - impl EntityInterface for EntityDescriptor< &'static str > { type I = &'static str; } + impl EntityInterface for EntityDescriptor< i8 > { } + impl EntityInterface for EntityDescriptor< i16 > { } + impl EntityInterface for EntityDescriptor< i32 > { } + impl EntityInterface for EntityDescriptor< i64 > { } + impl EntityInterface for EntityDescriptor< u8 > { } + impl EntityInterface for EntityDescriptor< u16 > { } + impl EntityInterface for EntityDescriptor< u32 > { } + impl EntityInterface for EntityDescriptor< u64 > { } + impl EntityInterface for EntityDescriptor< f32 > { } + impl EntityInterface for EntityDescriptor< f64 > { } + impl EntityInterface for EntityDescriptor< String > { } + impl EntityInterface for EntityDescriptor< &'static str > { } impl IsScalar for i8 {} impl IsScalar for i16 {} From 1b2bdd4c0a8532f20e5a5089c7f6ec1511233b32 Mon Sep 17 00:00:00 2001 From: wandalen Date: Sat, 17 Feb 2024 22:25:00 +0200 Subject: [PATCH 06/19] experimenting --- module/core/derive_tools/src/reflect.rs | 214 ++++++++++-------- module/core/derive_tools/tests/inc/mod.rs | 12 +- .../tests/inc/only_test/reflect_struct.rs | 22 +- .../inc/only_test/reflect_struct_in_struct.rs | 24 +- .../tests/inc/reflect_common_test.rs | 72 +++--- .../reflect_struct_in_struct_manual_test.rs | 81 +++++-- .../tests/inc/reflect_struct_manual_test.rs | 51 +++-- 7 files changed, 286 insertions(+), 190 deletions(-) diff --git a/module/core/derive_tools/src/reflect.rs b/module/core/derive_tools/src/reflect.rs index 7e555091f9..8410da9b3e 100644 --- a/module/core/derive_tools/src/reflect.rs +++ b/module/core/derive_tools/src/reflect.rs @@ -38,18 +38,24 @@ pub( crate ) mod private pub trait Instance { /// Return a descriptor of type of current instance of the type. - fn reflect( &self ) -> impl EntityInterface - where - Self : Sized, - EntityDescriptor< Self > : EntityInterface, + fn reflect( &self ) -> impl Entity; + } + + impl< T > Instance for T + where + EntityDescriptor< T > : Entity, + T : AutoInstance, + { + #[ inline( always ) ] + fn reflect( &self ) -> impl Entity { EntityDescriptor::< Self >::new() } } - /// xxx - pub trait AnyInstance : core::any::Any + Instance {} - impl< T : core::any::Any + Instance > AnyInstance for T {} + // /// xxx + // pub trait AnyInstance : core::any::Any + Instance {} + // impl< T : core::any::Any + Instance > AnyInstance for T {} /// /// Type descriptor @@ -60,6 +66,10 @@ pub( crate ) mod private _phantom : core::marker::PhantomData< I >, } + // xxx : qqq : qqq for Yulia : implement derive Phantom + // #[ derive( PartialEq, Debug, Phantom ) ] + // pub struct EntityDescriptor< I : Instance >; + impl< I : Instance > EntityDescriptor< I > { /// Constructor of the descriptor. @@ -71,14 +81,25 @@ pub( crate ) mod private } } + /// Auto-implement descriptor for this type. + pub trait AutoInstance {} + + impl< T > Entity for EntityDescriptor< T > + where + T : AutoInstance, + { + fn type_name( &self ) -> &'static str + { + core::any::type_name::< T >() + } + } + /// /// Type descriptor /// - // pub trait EntityInterface< I : Instance > : core::any::Any - pub trait EntityInterface + // pub trait Entity< I : Instance > : core::any::Any + pub trait Entity { - // /// Type of the instance the descriptor describe. - // type I : Instance; /// Determines if the entity acts as a container for other entities. /// @@ -89,7 +110,7 @@ pub( crate ) mod private /// /// By default, this method returns `false`, assuming that the entity does not act as a container. #[ inline( always ) ] - fn reflect_is_container( &self ) -> bool + fn is_container( &self ) -> bool { false } @@ -103,7 +124,7 @@ pub( crate ) mod private /// This method is particularly useful for collections or composite entities. /// By default, this method returns `0`, assuming the entity contains no elements. #[ inline( always ) ] - fn reflect_len( &self ) -> usize + fn len( &self ) -> usize { 0 } @@ -116,11 +137,7 @@ pub( crate ) mod private /// /// This method leverages Rust's `type_name` function to provide the name at runtime, /// aiding in debugging and logging purposes. - #[ inline( always ) ] - fn reflect_type_name( &self ) -> &'static str - { - core::any::type_name::< Self::I >() - } + fn type_name( &self ) -> &'static str; /// Provides an iterator over the elements contained within the entity, if any. /// @@ -131,46 +148,21 @@ pub( crate ) mod private /// /// This method is crucial for traversing composite entities or collections at runtime, /// allowing for dynamic inspection and manipulation. - - // fn reflect_elements(&self) -> Box> + '_>; - - // #[ inline( always ) ] - // fn reflect_elements<'a>( &'a self ) -> Box< dyn Iterator< Item = KeyVal< dyn AnyEntity > > + 'a > - // { - // // std::iter::empty() - // Box::new( [].into_iter() ) - // } - #[ inline( always ) ] - // fn reflect_elements( &self ) -> Box< dyn Iterator< Item = KeyVal< Box< dyn Instance > > > > - fn reflect_elements( &self ) -> Box< dyn Iterator< Item = KeyVal > > + fn elements( &self ) -> Box< dyn Iterator< Item = KeyVal > > { Box::new( [].into_iter() ) } } -// /// -// pub trait Reflectable -// { -// } -// -// // Assuming all instances that can be reflected upon implement Reflectable. -// impl< T : 'static + Reflectable > EntityInterface for T -// { -// fn reflect_elements(&self) -> Box> + '_> -// { -// Box::new( [].into_iter() ) -// } -// } - - /// A trait for entities that support dynamic type inspection and reflection. - /// - /// This trait extends both `core::any::Any` for type checking and downcasting capabilities, - /// and `EntityInterface` for reflection-based operations, enabling runtime inspection of - /// entity properties and structures. - pub trait AnyEntity : core::any::Any + EntityInterface {} - impl< T : core::any::Any + EntityInterface > AnyEntity for T {} + // /// A trait for entities that support dynamic type inspection and reflection. + // /// + // /// This trait extends both `core::any::Any` for type checking and downcasting capabilities, + // /// and `Entity` for reflection-based operations, enabling runtime inspection of + // /// entity properties and structures. + // pub trait AnyEntity : core::any::Any + Entity {} + // impl< T : core::any::Any + Entity > AnyEntity for T {} /// Represents a key-value pair where the key is a static string slice /// and the value is a boxed entity that implements the `AnyEntity` trait. @@ -183,16 +175,9 @@ pub( crate ) mod private pub struct KeyVal { /// The key associated with the value in the key-value pair. - /// - /// This is a static string slice, implying that the key is known at compile time - /// and does not change at runtime. pub key : &'static str, /// The value associated with the key in the key-value pair. - /// - /// It is boxed to allow for dynamic typing, enabling the storage of any entity - /// that implements the `AnyEntity` trait. This facilitates runtime reflection - /// and type inspection of the contained entity. - pub val : Box< dyn AnyEntity >, + pub val : Box< dyn Entity >, } impl std::fmt::Debug for KeyVal @@ -202,7 +187,8 @@ pub( crate ) mod private f .debug_struct( "KeyVal" ) .field( "key", &self.key ) - .field( "val", &format_args!( "{}", core::any::type_name::< dyn AnyEntity >() ) ) + // .field( "val", &format_args!( "{}", core::any::type_name::< dyn AnyEntity< I = I > >() ) ) + // xxx .finish() } } @@ -216,31 +202,74 @@ pub( crate ) mod private } } - impl Instance for i8 {} - impl Instance for i16 {} - impl Instance for i32 {} - impl Instance for i64 {} - impl Instance for u8 {} - impl Instance for u16 {} - impl Instance for u32 {} - impl Instance for u64 {} - impl Instance for f32 {} - impl Instance for f64 {} - impl Instance for String {} - impl Instance for &'static str {} - - impl EntityInterface for EntityDescriptor< i8 > { } - impl EntityInterface for EntityDescriptor< i16 > { } - impl EntityInterface for EntityDescriptor< i32 > { } - impl EntityInterface for EntityDescriptor< i64 > { } - impl EntityInterface for EntityDescriptor< u8 > { } - impl EntityInterface for EntityDescriptor< u16 > { } - impl EntityInterface for EntityDescriptor< u32 > { } - impl EntityInterface for EntityDescriptor< u64 > { } - impl EntityInterface for EntityDescriptor< f32 > { } - impl EntityInterface for EntityDescriptor< f64 > { } - impl EntityInterface for EntityDescriptor< String > { } - impl EntityInterface for EntityDescriptor< &'static str > { } + // impl Instance for i8 {} + // impl Instance for i16 {} + // impl Instance for i32 {} + // impl Instance for i64 {} + // impl Instance for u8 {} + // impl Instance for u16 {} + // impl Instance for u32 {} + // impl Instance for u64 {} + // impl Instance for f32 {} + // impl Instance for f64 {} + // impl Instance for String {} + // impl Instance for &'static str {} + + /// Implements Entity for a types. + #[ macro_export ] + macro_rules! impl_entity_for + { + + ( + $( $Path : tt )* + ) + => + { + impl crate::reflect::Entity for crate::reflect::EntityDescriptor< $( $Path )* > + { + #[ inline( always ) ] + fn type_name( &self ) -> &'static str + { + core::any::type_name::< $( $Path )* >() + } + } + }; + + } + + // impl Entity for EntityDescriptor< i8 > + // { + // fn type_name( &self ) -> &'static str + // { + // core::any::type_name::< i8 >() + // } + // } + + // impl_entity_for!( i8 ); + // impl_entity_for!( i16 ); + // impl_entity_for!( i32 ); + // impl_entity_for!( i64 ); + // impl_entity_for!( u8 ); + // impl_entity_for!( u16 ); + // impl_entity_for!( u32 ); + // impl_entity_for!( u64 ); + // impl_entity_for!( f32 ); + // impl_entity_for!( f64 ); + // impl_entity_for!( String ); + // impl_entity_for!( &'static str ); + + impl AutoInstance for i8 {} + impl AutoInstance for i16 {} + impl AutoInstance for i32 {} + impl AutoInstance for i64 {} + impl AutoInstance for u8 {} + impl AutoInstance for u16 {} + impl AutoInstance for u32 {} + impl AutoInstance for u64 {} + impl AutoInstance for f32 {} + impl AutoInstance for f64 {} + impl AutoInstance for String {} + impl AutoInstance for &'static str {} impl IsScalar for i8 {} impl IsScalar for i16 {} @@ -257,23 +286,23 @@ pub( crate ) mod private impl< T, const N : usize > IsContainer for [ T ; N ] {} -// impl< T : EntityInterface, const N : usize > EntityInterface for [ T ; N ] +// impl< T : Entity, const N : usize > Entity for [ T ; N ] // { // // #[ inline( always ) ] -// fn reflect_is_container( &self ) -> bool +// fn is_container( &self ) -> bool // { // true // } // // #[ inline( always ) ] -// fn reflect_len( &self ) -> usize +// fn len( &self ) -> usize // { // N // } // // #[ inline( always ) ] -// fn reflect_elements( &self ) -> Box< dyn Iterator< Item = KeyVal > + '_ > +// fn elements( &self ) -> Box< dyn Iterator< Item = KeyVal > + '_ > // { // // let result : [ KeyVal ; N ]; @@ -312,11 +341,12 @@ pub mod orphan IsContainer, IsScalar, Instance, - AnyInstance, + AutoInstance, + // AnyInstance, EntityDescriptor, - EntityInterface, + Entity, KeyVal, - AnyEntity, + // AnyEntity, }; } diff --git a/module/core/derive_tools/tests/inc/mod.rs b/module/core/derive_tools/tests/inc/mod.rs index 87ae9a9404..a560fec6c3 100644 --- a/module/core/derive_tools/tests/inc/mod.rs +++ b/module/core/derive_tools/tests/inc/mod.rs @@ -68,12 +68,12 @@ mod inner_from_unit_test; #[ cfg( feature = "derive_inner_from" ) ] mod inner_from_multiple_test; -// #[ cfg( feature = "derive_reflect" ) ] -// mod reflect_common_test; -// #[ cfg( feature = "derive_reflect" ) ] -// mod reflect_struct_manual_test; -// #[ cfg( feature = "derive_reflect" ) ] -// mod reflect_struct_in_struct_manual_test; +#[ cfg( feature = "derive_reflect" ) ] +mod reflect_common_test; +#[ cfg( feature = "derive_reflect" ) ] +mod reflect_struct_manual_test; +#[ cfg( feature = "derive_reflect" ) ] +mod reflect_struct_in_struct_manual_test; // #[ cfg( all( feature = "type_variadic_from" ) ) ] // mod variadic_from_manual_test; diff --git a/module/core/derive_tools/tests/inc/only_test/reflect_struct.rs b/module/core/derive_tools/tests/inc/only_test/reflect_struct.rs index 5972cdd1dc..bcfa4b9827 100644 --- a/module/core/derive_tools/tests/inc/only_test/reflect_struct.rs +++ b/module/core/derive_tools/tests/inc/only_test/reflect_struct.rs @@ -1,7 +1,7 @@ #[ test ] fn reflect_basic_test() { - use reflect::Entity; + use reflect::{ Instance, Entity }; let ins = Struct1 { @@ -10,19 +10,19 @@ fn reflect_basic_test() f3 : "3", }; - a_id!( ins.reflect_is_container(), true ); - a_id!( ins.reflect_len(), 3 ); - a_id!( ins.reflect_type_name(), "derive_tests::inc::reflect_struct_manual_test::Struct1" ); - let names = ins.reflect_elements().map( | e | e.key ).collect::< Vec< _ > >(); + a_id!( ins.reflect().is_container(), true ); + a_id!( ins.reflect().len(), 3 ); + a_id!( ins.reflect().type_name(), "derive_tests::inc::reflect_struct_manual_test::Struct1" ); + let names = ins.reflect().elements().map( | e | e.key ).collect::< Vec< _ > >(); a_id!( names, vec![ "f1", "f2", "f3" ] ); - let types = ins.reflect_elements().map( | e | e.val.reflect_type_name() ).collect::< Vec< _ > >(); + let types = ins.reflect().elements().map( | e | e.val.type_name() ).collect::< Vec< _ > >(); a_id!( types, vec![ "i32", "alloc::string::String", "&str" ] ); - let f1 = ins.reflect_elements().next().unwrap(); + let f1 = ins.reflect().elements().next().unwrap(); a_id!( f1.key, "f1" ); - a_id!( f1.val.reflect_is_container(), false ); - a_id!( f1.val.reflect_len(), 0 ); - a_id!( f1.val.reflect_type_name(), "i32" ); - a_id!( f1.val.reflect_elements().collect::< Vec< _ > >(), vec![] ); + a_id!( f1.val.is_container(), false ); + a_id!( f1.val.len(), 0 ); + a_id!( f1.val.type_name(), "i32" ); + a_id!( f1.val.elements().collect::< Vec< _ > >(), vec![] ); } diff --git a/module/core/derive_tools/tests/inc/only_test/reflect_struct_in_struct.rs b/module/core/derive_tools/tests/inc/only_test/reflect_struct_in_struct.rs index 5abc4a4f7e..679f885b75 100644 --- a/module/core/derive_tools/tests/inc/only_test/reflect_struct_in_struct.rs +++ b/module/core/derive_tools/tests/inc/only_test/reflect_struct_in_struct.rs @@ -1,7 +1,7 @@ #[ test ] fn reflect_struct_in_struct() { - use reflect::Entity; + use reflect::{ Instance, Entity }; let ins = Struct1 { @@ -10,22 +10,22 @@ fn reflect_struct_in_struct() f3 : Struct2 { s1 : 10, s2 : "20".into(), s3 : "30" }, }; - a_id!( ins.reflect_is_container(), true ); - a_id!( ins.reflect_len(), 3 ); - a_id!( ins.reflect_type_name(), "derive_tests::inc::reflect_struct_in_struct_manual_test::Struct1" ); - let names = ins.reflect_elements().map( | e | e.key ).collect::< Vec< _ > >(); + a_id!( ins.reflect().is_container(), true ); + a_id!( ins.reflect().len(), 3 ); + a_id!( ins.reflect().type_name(), "derive_tests::inc::reflect_struct_in_struct_manual_test::Struct1" ); + let names = ins.reflect().elements().map( | e | e.key ).collect::< Vec< _ > >(); a_id!( names, vec![ "f1", "f2", "f3" ] ); - let types = ins.reflect_elements().map( | e | e.val.reflect_type_name() ).collect::< Vec< _ > >(); + let types = ins.reflect().elements().map( | e | e.val.type_name() ).collect::< Vec< _ > >(); a_id!( types, vec![ "i32", "alloc::string::String", "derive_tests::inc::reflect_struct_in_struct_manual_test::Struct2" ] ); - let f3 = ins.reflect_elements().skip( 2 ).next().unwrap(); + let f3 = ins.reflect().elements().skip( 2 ).next().unwrap(); a_id!( f3.key, "f3" ); - a_id!( f3.val.reflect_is_container(), true ); - a_id!( f3.val.reflect_len(), 3 ); - a_id!( f3.val.reflect_type_name(), "derive_tests::inc::reflect_struct_in_struct_manual_test::Struct2" ); - let names = f3.val.reflect_elements().map( | e | e.key ).collect::< Vec< _ > >(); + a_id!( f3.val.is_container(), true ); + a_id!( f3.val.len(), 3 ); + a_id!( f3.val.type_name(), "derive_tests::inc::reflect_struct_in_struct_manual_test::Struct2" ); + let names = f3.val.elements().map( | e | e.key ).collect::< Vec< _ > >(); a_id!( names, vec![ "s1", "s2", "s3" ] ); - let types = f3.val.reflect_elements().map( | e | e.val.reflect_type_name() ).collect::< Vec< _ > >(); + let types = f3.val.elements().map( | e | e.val.type_name() ).collect::< Vec< _ > >(); a_id!( types, vec![ "i32", "alloc::string::String", "&str" ] ); } diff --git a/module/core/derive_tools/tests/inc/reflect_common_test.rs b/module/core/derive_tools/tests/inc/reflect_common_test.rs index 81f0741e35..bad399dfe9 100644 --- a/module/core/derive_tools/tests/inc/reflect_common_test.rs +++ b/module/core/derive_tools/tests/inc/reflect_common_test.rs @@ -4,48 +4,48 @@ pub use TheModule::reflect; #[ test ] fn reflect_basic_test() { - use reflect::{ EntityInterface, Instance }; + use reflect::{ Entity, Instance }; - a_id!( 0i8.reflect().reflect_is_container(), false ); - a_id!( 0i8.reflect().reflect_len(), 0 ); - a_id!( 0i8.reflect().reflect_type_name(), "i8" ); - a_id!( 0i8.reflect().reflect_elements().collect::< Vec< _ > >(), Vec::< _ >::new() ); + a_id!( 0i8.reflect().is_container(), false ); + a_id!( 0i8.reflect().len(), 0 ); + a_id!( 0i8.reflect().type_name(), "i8" ); + a_id!( 0i8.reflect().elements().collect::< Vec< _ > >(), Vec::< _ >::new() ); - a_id!( 0i16.reflect().reflect_is_container(), false ); - a_id!( 0i16.reflect().reflect_len(), 0 ); - a_id!( 0i16.reflect().reflect_type_name(), "i16" ); - a_id!( 0i16.reflect().reflect_elements().collect::< Vec< _ > >(), Vec::< _ >::new() ); + a_id!( 0i16.reflect().is_container(), false ); + a_id!( 0i16.reflect().len(), 0 ); + a_id!( 0i16.reflect().type_name(), "i16" ); + a_id!( 0i16.reflect().elements().collect::< Vec< _ > >(), Vec::< _ >::new() ); - a_id!( 0i32.reflect().reflect_is_container(), false ); - a_id!( 0i32.reflect().reflect_len(), 0 ); - a_id!( 0i32.reflect().reflect_type_name(), "i32" ); - a_id!( 0i32.reflect().reflect_elements().collect::< Vec< _ > >(), Vec::< _ >::new() ); + a_id!( 0i32.reflect().is_container(), false ); + a_id!( 0i32.reflect().len(), 0 ); + a_id!( 0i32.reflect().type_name(), "i32" ); + a_id!( 0i32.reflect().elements().collect::< Vec< _ > >(), Vec::< _ >::new() ); - a_id!( 0i64.reflect().reflect_is_container(), false ); - a_id!( 0i64.reflect().reflect_len(), 0 ); - a_id!( 0i64.reflect().reflect_type_name(), "i64" ); - a_id!( 0i64.reflect().reflect_elements().collect::< Vec< _ > >(), Vec::< _ >::new() ); + a_id!( 0i64.reflect().is_container(), false ); + a_id!( 0i64.reflect().len(), 0 ); + a_id!( 0i64.reflect().type_name(), "i64" ); + a_id!( 0i64.reflect().elements().collect::< Vec< _ > >(), Vec::< _ >::new() ); // - a_id!( 0u8.reflect().reflect_is_container(), false ); - a_id!( 0u8.reflect().reflect_len(), 0 ); - a_id!( 0u8.reflect().reflect_type_name(), "u8" ); - a_id!( 0u8.reflect().reflect_elements().collect::< Vec< _ > >(), Vec::< _ >::new() ); - - a_id!( 0u16.reflect().reflect_is_container(), false ); - a_id!( 0u16.reflect().reflect_len(), 0 ); - a_id!( 0u16.reflect().reflect_type_name(), "u16" ); - a_id!( 0u16.reflect().reflect_elements().collect::< Vec< _ > >(), Vec::< _ >::new() ); - - a_id!( 0u32.reflect().reflect_is_container(), false ); - a_id!( 0u32.reflect().reflect_len(), 0 ); - a_id!( 0u32.reflect().reflect_type_name(), "u32" ); - a_id!( 0u32.reflect().reflect_elements().collect::< Vec< _ > >(), Vec::< _ >::new() ); - - a_id!( 0u64.reflect().reflect_is_container(), false ); - a_id!( 0u64.reflect().reflect_len(), 0 ); - a_id!( 0u64.reflect().reflect_type_name(), "u64" ); - a_id!( 0u64.reflect().reflect_elements().collect::< Vec< _ > >(), Vec::< _ >::new() ); + a_id!( 0u8.reflect().is_container(), false ); + a_id!( 0u8.reflect().len(), 0 ); + a_id!( 0u8.reflect().type_name(), "u8" ); + a_id!( 0u8.reflect().elements().collect::< Vec< _ > >(), Vec::< _ >::new() ); + + a_id!( 0u16.reflect().is_container(), false ); + a_id!( 0u16.reflect().len(), 0 ); + a_id!( 0u16.reflect().type_name(), "u16" ); + a_id!( 0u16.reflect().elements().collect::< Vec< _ > >(), Vec::< _ >::new() ); + + a_id!( 0u32.reflect().is_container(), false ); + a_id!( 0u32.reflect().len(), 0 ); + a_id!( 0u32.reflect().type_name(), "u32" ); + a_id!( 0u32.reflect().elements().collect::< Vec< _ > >(), Vec::< _ >::new() ); + + a_id!( 0u64.reflect().is_container(), false ); + a_id!( 0u64.reflect().len(), 0 ); + a_id!( 0u64.reflect().type_name(), "u64" ); + a_id!( 0u64.reflect().elements().collect::< Vec< _ > >(), Vec::< _ >::new() ); } diff --git a/module/core/derive_tools/tests/inc/reflect_struct_in_struct_manual_test.rs b/module/core/derive_tools/tests/inc/reflect_struct_in_struct_manual_test.rs index eb3d628042..64bf75c743 100644 --- a/module/core/derive_tools/tests/inc/reflect_struct_in_struct_manual_test.rs +++ b/module/core/derive_tools/tests/inc/reflect_struct_in_struct_manual_test.rs @@ -17,54 +17,107 @@ pub struct Struct2 pub s3 : &'static str, } -impl reflect::Entity for Struct1 +// -- + +#[ derive( PartialEq, Debug ) ] +pub struct EntityDescriptor< I : reflect::Instance > +{ + _phantom : core::marker::PhantomData< I >, +} + +impl< I : reflect::Instance > EntityDescriptor< I > +{ + /// Constructor of the descriptor. + #[ inline( always ) ] + pub fn new() -> Self + { + let _phantom = core::marker::PhantomData::< I >; + Self { _phantom } + } +} + +// -- + +impl reflect::Instance for Struct1 +{ + #[ inline( always ) ] + fn reflect( &self ) -> impl reflect::Entity + { + EntityDescriptor::< Self >::new() + } +} + +impl reflect::Instance for Struct2 { #[ inline( always ) ] - fn reflect_is_container( &self ) -> bool + fn reflect( &self ) -> impl reflect::Entity + { + EntityDescriptor::< Self >::new() + } +} + +impl reflect::Entity for EntityDescriptor< Struct1 > +{ + #[ inline( always ) ] + fn is_container( &self ) -> bool { true } #[ inline( always ) ] - fn reflect_len( &self ) -> usize + fn len( &self ) -> usize { 3 } #[ inline( always ) ] - fn reflect_elements( &self ) -> Box< dyn Iterator< Item = reflect::KeyVal > + '_ > + fn type_name( &self ) -> &'static str + { + core::any::type_name::< Struct1 >() + } + + #[ inline( always ) ] + fn elements(&self) -> Box< dyn Iterator< Item = reflect::KeyVal > > { let result = vec! [ - reflect::KeyVal { key : "f1", val : Box::new( self.f1 ) }, - reflect::KeyVal { key : "f2", val : Box::new( self.f2.clone() ) }, - reflect::KeyVal { key : "f3", val : Box::new( self.f3.clone() ) }, + reflect::KeyVal { key: "f1", val: Box::new( reflect::EntityDescriptor::::new() ) }, + reflect::KeyVal { key: "f2", val: Box::new( reflect::EntityDescriptor::::new() ) }, + reflect::KeyVal { key: "f3", val: Box::new( EntityDescriptor::::new() ) }, ]; Box::new( result.into_iter() ) } + } -impl reflect::Entity for Struct2 +impl reflect::Entity for EntityDescriptor< Struct2 > { #[ inline( always ) ] - fn reflect_is_container( &self ) -> bool + fn is_container( &self ) -> bool { true } #[ inline( always ) ] - fn reflect_len( &self ) -> usize + fn len( &self ) -> usize { 3 } #[ inline( always ) ] - fn reflect_elements( &self ) -> Box< dyn Iterator< Item = reflect::KeyVal > + '_ > + fn type_name( &self ) -> &'static str + { + core::any::type_name::< Struct2 >() + } + + #[ inline( always ) ] + fn elements(&self) -> Box< dyn Iterator< Item = reflect::KeyVal > > { let result = vec! [ - reflect::KeyVal { key : "s1", val : Box::new( self.s1 ) }, - reflect::KeyVal { key : "s2", val : Box::new( self.s2.clone() ) }, - reflect::KeyVal { key : "s3", val : Box::new( self.s3 ) }, + reflect::KeyVal { key: "s1", val: Box::new( reflect::EntityDescriptor::::new() ) }, + reflect::KeyVal { key: "s2", val: Box::new( reflect::EntityDescriptor::::new() ) }, + reflect::KeyVal { key: "s3", val: Box::new( reflect::EntityDescriptor::<&'static str>::new() ) }, ]; Box::new( result.into_iter() ) } + } include!( "./only_test/reflect_struct_in_struct.rs" ); diff --git a/module/core/derive_tools/tests/inc/reflect_struct_manual_test.rs b/module/core/derive_tools/tests/inc/reflect_struct_manual_test.rs index 17b43bbb97..b1c0f0b4d0 100644 --- a/module/core/derive_tools/tests/inc/reflect_struct_manual_test.rs +++ b/module/core/derive_tools/tests/inc/reflect_struct_manual_test.rs @@ -9,6 +9,8 @@ pub struct Struct1 pub f3 : &'static str, } +// -- + #[ derive( PartialEq, Debug ) ] pub struct EntityDescriptor< I : reflect::Instance > { @@ -26,40 +28,51 @@ impl< I : reflect::Instance > EntityDescriptor< I > } } -impl reflect::Instance for Struct1 {} -impl reflect::EntityInterface for EntityDescriptor< Struct1 > +// qqq : qqq for Yulia : implement derive ReflectInstance +impl reflect::Instance for Struct1 +{ + #[ inline( always ) ] + fn reflect( &self ) -> impl reflect::Entity + { + EntityDescriptor::< Self >::new() + } +} + +// -- + +impl reflect::Entity for EntityDescriptor< Struct1 > { - type I = Struct1; + #[ inline( always ) ] - fn reflect_is_container( &self ) -> bool + fn is_container( &self ) -> bool { true } + #[ inline( always ) ] - fn reflect_len( &self ) -> usize + fn len( &self ) -> usize { 3 } + + #[ inline( always ) ] + fn type_name( &self ) -> &'static str + { + core::any::type_name::< Struct1 >() + } + #[ inline( always ) ] - // fn reflect_elements( &self ) -> Box< dyn Iterator< Item = reflect::KeyVal< Box< dyn reflect::Instance > > > > - fn reflect_elements( &self ) -> Box< dyn Iterator< Item = reflect::KeyVal< Box< dyn reflect::EntityInterface< I = dyn reflect::AnyInstance > > > > > + fn elements(&self) -> Box< dyn Iterator< Item = reflect::KeyVal > > { - // let x = Box::new( reflect::EntityDescriptor::< i32 >::new() ); - let boxed_descriptor_as_trait : Box< dyn reflect::EntityInterface< I = dyn reflect::AnyInstance > > - = Box::new( reflect::EntityDescriptor::< i32 >::new() ); let result = vec! [ - // reflect::KeyVal { key: "f1", val: boxed_descriptor_as_trait }, - // Other KeyVal instances + reflect::KeyVal { key: "f1", val: Box::new( reflect::EntityDescriptor::::new() ) }, + reflect::KeyVal { key: "f2", val: Box::new( reflect::EntityDescriptor::::new() ) }, + reflect::KeyVal { key: "f3", val: Box::new( reflect::EntityDescriptor::<&'static str>::new() ) }, ]; - // let result = vec! - // [ - // reflect::KeyVal { key : "f1", val: Box::new( reflect::EntityDescriptor::< i32 >::new() ) }, - // // reflect::KeyVal { key : "f2", val : Box::new( self.f2.clone() ) }, - // // reflect::KeyVal { key : "f3", val : Box::new( self.f3 ) }, - // ]; Box::new( result.into_iter() ) } + } -// include!( "./only_test/reflect_struct.rs" ); +include!( "./only_test/reflect_struct.rs" ); From ff0be7903b3c810c04daf1a70814e60e240a46fd Mon Sep 17 00:00:00 2001 From: wandalen Date: Sat, 17 Feb 2024 23:55:48 +0200 Subject: [PATCH 07/19] experimenting --- module/core/derive_tools/src/reflect.rs | 16 +++++++++----- module/core/derive_tools/tests/inc/mod.rs | 10 ++++----- .../reflect_struct_in_struct_manual_test.rs | 22 +++++++++---------- .../tests/inc/reflect_struct_manual_test.rs | 9 ++++---- 4 files changed, 32 insertions(+), 25 deletions(-) diff --git a/module/core/derive_tools/src/reflect.rs b/module/core/derive_tools/src/reflect.rs index 8410da9b3e..21106a7793 100644 --- a/module/core/derive_tools/src/reflect.rs +++ b/module/core/derive_tools/src/reflect.rs @@ -37,8 +37,15 @@ pub( crate ) mod private // pub trait Instance : core::any::Any pub trait Instance { - /// Return a descriptor of type of current instance of the type. - fn reflect( &self ) -> impl Entity; + /// Entity descriptor. + type Entity : Entity; + /// Return a descriptor of type with current instance. + fn reflect( &self ) -> Self::Entity + { + Self::Reflect() + } + /// Return a descriptor of type with type of instance. + fn Reflect() -> Self::Entity; } impl< T > Instance for T @@ -46,8 +53,9 @@ pub( crate ) mod private EntityDescriptor< T > : Entity, T : AutoInstance, { + type Entity = EntityDescriptor::< Self >; #[ inline( always ) ] - fn reflect( &self ) -> impl Entity + fn Reflect() -> Self::Entity { EntityDescriptor::< Self >::new() } @@ -342,11 +350,9 @@ pub mod orphan IsScalar, Instance, AutoInstance, - // AnyInstance, EntityDescriptor, Entity, KeyVal, - // AnyEntity, }; } diff --git a/module/core/derive_tools/tests/inc/mod.rs b/module/core/derive_tools/tests/inc/mod.rs index a560fec6c3..3fb5c980f8 100644 --- a/module/core/derive_tools/tests/inc/mod.rs +++ b/module/core/derive_tools/tests/inc/mod.rs @@ -72,8 +72,8 @@ mod inner_from_multiple_test; mod reflect_common_test; #[ cfg( feature = "derive_reflect" ) ] mod reflect_struct_manual_test; -#[ cfg( feature = "derive_reflect" ) ] -mod reflect_struct_in_struct_manual_test; +// #[ cfg( feature = "derive_reflect" ) ] +// mod reflect_struct_in_struct_manual_test; // #[ cfg( all( feature = "type_variadic_from" ) ) ] // mod variadic_from_manual_test; @@ -87,6 +87,6 @@ mod reflect_struct_in_struct_manual_test; // #[ cfg( all( feature = "derive_variadic_from", feature = "type_variadic_from" ) ) ] // mod variadic_from2_derive; -#[ cfg( any( feature = "derive_variadic_from", feature = "type_variadic_from" ) ) ] -#[ path = "../../../../../module/core/variadic_from/tests/inc/mod.rs" ] -mod variadic_tests; +// #[ cfg( any( feature = "derive_variadic_from", feature = "type_variadic_from" ) ) ] +// #[ path = "../../../../../module/core/variadic_from/tests/inc/mod.rs" ] +// mod variadic_tests; diff --git a/module/core/derive_tools/tests/inc/reflect_struct_in_struct_manual_test.rs b/module/core/derive_tools/tests/inc/reflect_struct_in_struct_manual_test.rs index 64bf75c743..901fa8445e 100644 --- a/module/core/derive_tools/tests/inc/reflect_struct_in_struct_manual_test.rs +++ b/module/core/derive_tools/tests/inc/reflect_struct_in_struct_manual_test.rs @@ -27,13 +27,14 @@ pub struct EntityDescriptor< I : reflect::Instance > impl< I : reflect::Instance > EntityDescriptor< I > { - /// Constructor of the descriptor. + /// Constructor of the descriptor of type. #[ inline( always ) ] pub fn new() -> Self { let _phantom = core::marker::PhantomData::< I >; Self { _phantom } } + /// Constructor of the descriptor of type. } // -- @@ -41,16 +42,16 @@ impl< I : reflect::Instance > EntityDescriptor< I > impl reflect::Instance for Struct1 { #[ inline( always ) ] - fn reflect( &self ) -> impl reflect::Entity + fn Reflect() -> impl reflect::Entity { EntityDescriptor::< Self >::new() } } -impl reflect::Instance for Struct2 +impl Reflect::Instance for Struct2 { #[ inline( always ) ] - fn reflect( &self ) -> impl reflect::Entity + fn Reflect() -> impl reflect::Entity { EntityDescriptor::< Self >::new() } @@ -73,15 +74,14 @@ impl reflect::Entity for EntityDescriptor< Struct1 > { core::any::type_name::< Struct1 >() } - #[ inline( always ) ] fn elements(&self) -> Box< dyn Iterator< Item = reflect::KeyVal > > { let result = vec! [ - reflect::KeyVal { key: "f1", val: Box::new( reflect::EntityDescriptor::::new() ) }, - reflect::KeyVal { key: "f2", val: Box::new( reflect::EntityDescriptor::::new() ) }, - reflect::KeyVal { key: "f3", val: Box::new( EntityDescriptor::::new() ) }, + reflect::KeyVal { key: "f1", val: Box::new( < i32 as reflect::Instance >::Reflect() ) }, + reflect::KeyVal { key: "f2", val: Box::new( < String as reflect::Instance >::Reflect() ) }, + reflect::KeyVal { key: "f3", val: Box::new( < Struct2 as reflect::Instance >::Reflect() ) }, ]; Box::new( result.into_iter() ) } @@ -111,9 +111,9 @@ impl reflect::Entity for EntityDescriptor< Struct2 > { let result = vec! [ - reflect::KeyVal { key: "s1", val: Box::new( reflect::EntityDescriptor::::new() ) }, - reflect::KeyVal { key: "s2", val: Box::new( reflect::EntityDescriptor::::new() ) }, - reflect::KeyVal { key: "s3", val: Box::new( reflect::EntityDescriptor::<&'static str>::new() ) }, + reflect::KeyVal { key: "s1", val: Box::new( < i32 as reflect::Instance >::Reflect() ) }, + reflect::KeyVal { key: "s2", val: Box::new( < String as reflect::Instance >::Reflect() ) }, + reflect::KeyVal { key: "s3", val: Box::new( < &'static str as reflect::Instance >::Reflect() ) }, ]; Box::new( result.into_iter() ) } diff --git a/module/core/derive_tools/tests/inc/reflect_struct_manual_test.rs b/module/core/derive_tools/tests/inc/reflect_struct_manual_test.rs index b1c0f0b4d0..b9e6852dde 100644 --- a/module/core/derive_tools/tests/inc/reflect_struct_manual_test.rs +++ b/module/core/derive_tools/tests/inc/reflect_struct_manual_test.rs @@ -31,8 +31,9 @@ impl< I : reflect::Instance > EntityDescriptor< I > // qqq : qqq for Yulia : implement derive ReflectInstance impl reflect::Instance for Struct1 { + type Entity = EntityDescriptor::< Self >; #[ inline( always ) ] - fn reflect( &self ) -> impl reflect::Entity + fn Reflect() -> Self::Entity { EntityDescriptor::< Self >::new() } @@ -66,9 +67,9 @@ impl reflect::Entity for EntityDescriptor< Struct1 > { let result = vec! [ - reflect::KeyVal { key: "f1", val: Box::new( reflect::EntityDescriptor::::new() ) }, - reflect::KeyVal { key: "f2", val: Box::new( reflect::EntityDescriptor::::new() ) }, - reflect::KeyVal { key: "f3", val: Box::new( reflect::EntityDescriptor::<&'static str>::new() ) }, + reflect::KeyVal { key: "f1", val: Box::new( < i32 as reflect::Instance >::Reflect() ) }, + reflect::KeyVal { key: "f2", val: Box::new( < String as reflect::Instance >::Reflect() ) }, + reflect::KeyVal { key: "f3", val: Box::new( < &'static str as reflect::Instance >::Reflect() ) }, ]; Box::new( result.into_iter() ) } From 0145c232acac626567fd1ef04e91b3c863f598cf Mon Sep 17 00:00:00 2001 From: wandalen Date: Sun, 18 Feb 2024 00:08:46 +0200 Subject: [PATCH 08/19] experimenting --- module/core/derive_tools/src/reflect.rs | 48 ++++++++++++++----------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/module/core/derive_tools/src/reflect.rs b/module/core/derive_tools/src/reflect.rs index 21106a7793..5631d2df02 100644 --- a/module/core/derive_tools/src/reflect.rs +++ b/module/core/derive_tools/src/reflect.rs @@ -51,7 +51,7 @@ pub( crate ) mod private impl< T > Instance for T where EntityDescriptor< T > : Entity, - T : AutoInstance, + T : InstanceMarker, { type Entity = EntityDescriptor::< Self >; #[ inline( always ) ] @@ -68,7 +68,7 @@ pub( crate ) mod private /// /// Type descriptor /// - #[ derive( PartialEq, Debug ) ] + #[ derive( PartialEq ) ] pub struct EntityDescriptor< I : Instance > { _phantom : core::marker::PhantomData< I >, @@ -90,11 +90,11 @@ pub( crate ) mod private } /// Auto-implement descriptor for this type. - pub trait AutoInstance {} + pub trait InstanceMarker {} impl< T > Entity for EntityDescriptor< T > where - T : AutoInstance, + T : InstanceMarker, { fn type_name( &self ) -> &'static str { @@ -102,11 +102,20 @@ pub( crate ) mod private } } + impl< T : InstanceMarker > std::fmt::Debug for EntityDescriptor< T > + { + fn fmt( &self, f: &mut std::fmt::Formatter< '_ > ) -> std::fmt::Result + { + f + .write_str( format!( "{}#{}", self.type_name(), self.type_id() ) ) + } + } + /// /// Type descriptor /// // pub trait Entity< I : Instance > : core::any::Any - pub trait Entity + pub trait Entity : core::fmt::Debug { /// Determines if the entity acts as a container for other entities. @@ -195,8 +204,7 @@ pub( crate ) mod private f .debug_struct( "KeyVal" ) .field( "key", &self.key ) - // .field( "val", &format_args!( "{}", core::any::type_name::< dyn AnyEntity< I = I > >() ) ) - // xxx + .field( "val", &format_args!( "{:?}", &self.val ) ) .finish() } } @@ -266,18 +274,18 @@ pub( crate ) mod private // impl_entity_for!( String ); // impl_entity_for!( &'static str ); - impl AutoInstance for i8 {} - impl AutoInstance for i16 {} - impl AutoInstance for i32 {} - impl AutoInstance for i64 {} - impl AutoInstance for u8 {} - impl AutoInstance for u16 {} - impl AutoInstance for u32 {} - impl AutoInstance for u64 {} - impl AutoInstance for f32 {} - impl AutoInstance for f64 {} - impl AutoInstance for String {} - impl AutoInstance for &'static str {} + impl InstanceMarker for i8 {} + impl InstanceMarker for i16 {} + impl InstanceMarker for i32 {} + impl InstanceMarker for i64 {} + impl InstanceMarker for u8 {} + impl InstanceMarker for u16 {} + impl InstanceMarker for u32 {} + impl InstanceMarker for u64 {} + impl InstanceMarker for f32 {} + impl InstanceMarker for f64 {} + impl InstanceMarker for String {} + impl InstanceMarker for &'static str {} impl IsScalar for i8 {} impl IsScalar for i16 {} @@ -349,7 +357,7 @@ pub mod orphan IsContainer, IsScalar, Instance, - AutoInstance, + InstanceMarker, EntityDescriptor, Entity, KeyVal, From ffc2b4386bbf53377454ae7905cebe214dc97369 Mon Sep 17 00:00:00 2001 From: wandalen Date: Sun, 18 Feb 2024 00:15:04 +0200 Subject: [PATCH 09/19] experimenting --- module/core/derive_tools/src/reflect.rs | 13 +++++++++++-- .../inc/reflect_struct_in_struct_manual_test.rs | 11 ++++++++++- .../tests/inc/reflect_struct_manual_test.rs | 6 ++++++ 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/module/core/derive_tools/src/reflect.rs b/module/core/derive_tools/src/reflect.rs index 5631d2df02..21af3c0613 100644 --- a/module/core/derive_tools/src/reflect.rs +++ b/module/core/derive_tools/src/reflect.rs @@ -96,10 +96,16 @@ pub( crate ) mod private where T : InstanceMarker, { + #[ inline( always ) ] fn type_name( &self ) -> &'static str { core::any::type_name::< T >() } + #[ inline( always ) ] + fn type_id( &self ) -> core::any::TypeId + { + core::any::TypeId::of::() + } } impl< T : InstanceMarker > std::fmt::Debug for EntityDescriptor< T > @@ -107,7 +113,7 @@ pub( crate ) mod private fn fmt( &self, f: &mut std::fmt::Formatter< '_ > ) -> std::fmt::Result { f - .write_str( format!( "{}#{}", self.type_name(), self.type_id() ) ) + .write_str( &format!( "{}#{:?}", self.type_name(), self.type_id() ) ) } } @@ -146,7 +152,7 @@ pub( crate ) mod private 0 } - /// Retrieves the type name of the entity. + /// Retrieves the type name. /// /// # Returns /// @@ -156,6 +162,9 @@ pub( crate ) mod private /// aiding in debugging and logging purposes. fn type_name( &self ) -> &'static str; + /// Retrives the typ id. + fn type_id( &self ) -> core::any::TypeId; + /// Provides an iterator over the elements contained within the entity, if any. /// /// # Returns diff --git a/module/core/derive_tools/tests/inc/reflect_struct_in_struct_manual_test.rs b/module/core/derive_tools/tests/inc/reflect_struct_in_struct_manual_test.rs index 901fa8445e..cf3c08dcec 100644 --- a/module/core/derive_tools/tests/inc/reflect_struct_in_struct_manual_test.rs +++ b/module/core/derive_tools/tests/inc/reflect_struct_in_struct_manual_test.rs @@ -75,6 +75,11 @@ impl reflect::Entity for EntityDescriptor< Struct1 > core::any::type_name::< Struct1 >() } #[ inline( always ) ] + fn type_id( &self ) -> core::any::TypeId + { + core::any::TypeId::of::< Struct1 >() + } + #[ inline( always ) ] fn elements(&self) -> Box< dyn Iterator< Item = reflect::KeyVal > > { let result = vec! @@ -105,7 +110,11 @@ impl reflect::Entity for EntityDescriptor< Struct2 > { core::any::type_name::< Struct2 >() } - + #[ inline( always ) ] + fn type_id( &self ) -> core::any::TypeId + { + core::any::TypeId::of::< Struct2 >() + } #[ inline( always ) ] fn elements(&self) -> Box< dyn Iterator< Item = reflect::KeyVal > > { diff --git a/module/core/derive_tools/tests/inc/reflect_struct_manual_test.rs b/module/core/derive_tools/tests/inc/reflect_struct_manual_test.rs index b9e6852dde..ac25c0946a 100644 --- a/module/core/derive_tools/tests/inc/reflect_struct_manual_test.rs +++ b/module/core/derive_tools/tests/inc/reflect_struct_manual_test.rs @@ -62,6 +62,12 @@ impl reflect::Entity for EntityDescriptor< Struct1 > core::any::type_name::< Struct1 >() } + #[ inline( always ) ] + fn type_id( &self ) -> core::any::TypeId + { + core::any::TypeId::of::< Struct1 >() + } + #[ inline( always ) ] fn elements(&self) -> Box< dyn Iterator< Item = reflect::KeyVal > > { From db216ae6ab5cefab7f63d2f86b05a7e1eae4ee63 Mon Sep 17 00:00:00 2001 From: wandalen Date: Sun, 18 Feb 2024 00:21:10 +0200 Subject: [PATCH 10/19] experimenting --- module/core/derive_tools/src/reflect.rs | 80 ++++++++++++++----------- 1 file changed, 46 insertions(+), 34 deletions(-) diff --git a/module/core/derive_tools/src/reflect.rs b/module/core/derive_tools/src/reflect.rs index 21af3c0613..6e04a4966e 100644 --- a/module/core/derive_tools/src/reflect.rs +++ b/module/core/derive_tools/src/reflect.rs @@ -13,7 +13,7 @@ pub( crate ) mod private /// which can hold zero or more elements. This trait is typically used in /// conjunction with reflection mechanisms to dynamically inspect, access, /// or modify the contents of a container at runtime. - pub trait IsContainer + pub trait IsContainer : Instance { } @@ -25,7 +25,7 @@ pub( crate ) mod private /// like arrays or structs. This distinction can be useful in reflection-based /// APIs or generic programming to treat scalar values differently from containers /// or other complex types. - pub trait IsScalar + pub trait IsScalar : Instance { } @@ -104,7 +104,7 @@ pub( crate ) mod private #[ inline( always ) ] fn type_id( &self ) -> core::any::TypeId { - core::any::TypeId::of::() + core::any::TypeId::of::< T >() } } @@ -309,37 +309,49 @@ pub( crate ) mod private impl IsScalar for String {} impl IsScalar for &'static str {} - impl< T, const N : usize > IsContainer for [ T ; N ] {} - -// impl< T : Entity, const N : usize > Entity for [ T ; N ] -// { -// -// #[ inline( always ) ] -// fn is_container( &self ) -> bool -// { -// true -// } -// -// #[ inline( always ) ] -// fn len( &self ) -> usize -// { -// N -// } -// -// #[ inline( always ) ] -// fn elements( &self ) -> Box< dyn Iterator< Item = KeyVal > + '_ > -// { -// -// let result : [ KeyVal ; N ]; -// for ( k, e ) in self.iter().enumerate() -// { -// result[ k ] = KeyVal { key : "x", val : Box::new( (*e).clone() ) } -// } -// -// Box::new( result.into_iter() ) -// } -// -// } + // impl< T, const N : usize > IsContainer for [ T ; N ] {} + + impl< T : Entity, const N : usize > Entity for EntityDescriptor< [ T ; N ] > + { + + #[ inline( always ) ] + fn is_container( &self ) -> bool + { + true + } + + #[ inline( always ) ] + fn len( &self ) -> usize + { + N + } + + #[ inline( always ) ] + fn type_name( &self ) -> &'static str + { + core::any::type_name::< [ T ; N ] >() + } + + #[ inline( always ) ] + fn type_id( &self ) -> core::any::TypeId + { + core::any::TypeId::of::< [ T ; N ] >() + } + + #[ inline( always ) ] + fn elements( &self ) -> Box< dyn Iterator< Item = KeyVal > + '_ > + { + + let result : [ KeyVal ; N ]; + for ( k, e ) in self.iter().enumerate() + { + result[ k ] = KeyVal { key : "x", val : Box::new( (*e).clone() ) } + } + + Box::new( result.into_iter() ) + } + + } } From 21f3c9850158289918d5e451d7363078366470b3 Mon Sep 17 00:00:00 2001 From: wandalen Date: Sun, 18 Feb 2024 00:28:32 +0200 Subject: [PATCH 11/19] experimenting --- module/core/derive_tools/src/reflect.rs | 90 +++++++++++++------------ 1 file changed, 47 insertions(+), 43 deletions(-) diff --git a/module/core/derive_tools/src/reflect.rs b/module/core/derive_tools/src/reflect.rs index 6e04a4966e..20281320a0 100644 --- a/module/core/derive_tools/src/reflect.rs +++ b/module/core/derive_tools/src/reflect.rs @@ -94,7 +94,7 @@ pub( crate ) mod private impl< T > Entity for EntityDescriptor< T > where - T : InstanceMarker, + T : InstanceMarker + 'static, { #[ inline( always ) ] fn type_name( &self ) -> &'static str @@ -108,7 +108,9 @@ pub( crate ) mod private } } - impl< T : InstanceMarker > std::fmt::Debug for EntityDescriptor< T > + impl< T > std::fmt::Debug for EntityDescriptor< T > + where + T : InstanceMarker + 'static, { fn fmt( &self, f: &mut std::fmt::Formatter< '_ > ) -> std::fmt::Result { @@ -311,47 +313,49 @@ pub( crate ) mod private // impl< T, const N : usize > IsContainer for [ T ; N ] {} - impl< T : Entity, const N : usize > Entity for EntityDescriptor< [ T ; N ] > - { - - #[ inline( always ) ] - fn is_container( &self ) -> bool - { - true - } - - #[ inline( always ) ] - fn len( &self ) -> usize - { - N - } - - #[ inline( always ) ] - fn type_name( &self ) -> &'static str - { - core::any::type_name::< [ T ; N ] >() - } - - #[ inline( always ) ] - fn type_id( &self ) -> core::any::TypeId - { - core::any::TypeId::of::< [ T ; N ] >() - } - - #[ inline( always ) ] - fn elements( &self ) -> Box< dyn Iterator< Item = KeyVal > + '_ > - { - - let result : [ KeyVal ; N ]; - for ( k, e ) in self.iter().enumerate() - { - result[ k ] = KeyVal { key : "x", val : Box::new( (*e).clone() ) } - } - - Box::new( result.into_iter() ) - } - - } + // impl< T, const N : usize > InstanceMarker for [ T ; N ] {} +// impl< T, const N : usize > Entity for EntityDescriptor< [ T ; N ] > +// { +// +// #[ inline( always ) ] +// fn is_container( &self ) -> bool +// { +// true +// } +// +// #[ inline( always ) ] +// fn len( &self ) -> usize +// { +// N +// } +// +// #[ inline( always ) ] +// fn type_name( &self ) -> &'static str +// { +// core::any::type_name::< [ T ; N ] >() +// } +// +// #[ inline( always ) ] +// fn type_id( &self ) -> core::any::TypeId +// { +// core::any::TypeId::of::< [ T ; N ] >() +// } +// +// #[ inline( always ) ] +// // fn elements( &self ) -> Box< dyn Iterator< Item = KeyVal > + '_ > +// fn elements( &self ) -> Box< dyn Iterator< Item = KeyVal > > +// { +// +// let result : [ KeyVal ; N ]; +// for ( k, e ) in self.iter().enumerate() +// { +// result[ k ] = KeyVal { key : "x", val : Box::new( (*e).clone() ) } +// } +// +// Box::new( result.into_iter() ) +// } +// +// } } From 430793d2bba2e393028f52d68e9405e7aec8272d Mon Sep 17 00:00:00 2001 From: wandalen Date: Sun, 18 Feb 2024 00:36:43 +0200 Subject: [PATCH 12/19] experimenting --- module/core/derive_tools/src/reflect.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/module/core/derive_tools/src/reflect.rs b/module/core/derive_tools/src/reflect.rs index 20281320a0..01bb12a9ba 100644 --- a/module/core/derive_tools/src/reflect.rs +++ b/module/core/derive_tools/src/reflect.rs @@ -45,6 +45,7 @@ pub( crate ) mod private Self::Reflect() } /// Return a descriptor of type with type of instance. + #[ allow( non_snake_case ) ] fn Reflect() -> Self::Entity; } @@ -110,7 +111,8 @@ pub( crate ) mod private impl< T > std::fmt::Debug for EntityDescriptor< T > where - T : InstanceMarker + 'static, + T : Instance + 'static, + EntityDescriptor< T > : Entity, { fn fmt( &self, f: &mut std::fmt::Formatter< '_ > ) -> std::fmt::Result { @@ -122,7 +124,6 @@ pub( crate ) mod private /// /// Type descriptor /// - // pub trait Entity< I : Instance > : core::any::Any pub trait Entity : core::fmt::Debug { @@ -314,6 +315,18 @@ pub( crate ) mod private // impl< T, const N : usize > IsContainer for [ T ; N ] {} // impl< T, const N : usize > InstanceMarker for [ T ; N ] {} + impl< T, const N : usize > Instance for [ T ; N ] + where + EntityDescriptor< [ T ; N ] > : Entity, + { + type Entity = EntityDescriptor::< Self >; + #[ inline( always ) ] + fn Reflect() -> Self::Entity + { + EntityDescriptor::< Self >::new() + } + } + // impl< T, const N : usize > Entity for EntityDescriptor< [ T ; N ] > // { // From c4d793aec957b24859d35cce18676994ebc1ff31 Mon Sep 17 00:00:00 2001 From: wandalen Date: Sun, 18 Feb 2024 00:37:11 +0200 Subject: [PATCH 13/19] experimenting --- module/core/derive_tools/src/reflect.rs | 84 ++++++++++++------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/module/core/derive_tools/src/reflect.rs b/module/core/derive_tools/src/reflect.rs index 01bb12a9ba..67430908ab 100644 --- a/module/core/derive_tools/src/reflect.rs +++ b/module/core/derive_tools/src/reflect.rs @@ -327,48 +327,48 @@ pub( crate ) mod private } } -// impl< T, const N : usize > Entity for EntityDescriptor< [ T ; N ] > -// { -// -// #[ inline( always ) ] -// fn is_container( &self ) -> bool -// { -// true -// } -// -// #[ inline( always ) ] -// fn len( &self ) -> usize -// { -// N -// } -// -// #[ inline( always ) ] -// fn type_name( &self ) -> &'static str -// { -// core::any::type_name::< [ T ; N ] >() -// } -// -// #[ inline( always ) ] -// fn type_id( &self ) -> core::any::TypeId -// { -// core::any::TypeId::of::< [ T ; N ] >() -// } -// -// #[ inline( always ) ] -// // fn elements( &self ) -> Box< dyn Iterator< Item = KeyVal > + '_ > -// fn elements( &self ) -> Box< dyn Iterator< Item = KeyVal > > -// { -// -// let result : [ KeyVal ; N ]; -// for ( k, e ) in self.iter().enumerate() -// { -// result[ k ] = KeyVal { key : "x", val : Box::new( (*e).clone() ) } -// } -// -// Box::new( result.into_iter() ) -// } -// -// } + impl< T, const N : usize > Entity for EntityDescriptor< [ T ; N ] > + { + + #[ inline( always ) ] + fn is_container( &self ) -> bool + { + true + } + + #[ inline( always ) ] + fn len( &self ) -> usize + { + N + } + + #[ inline( always ) ] + fn type_name( &self ) -> &'static str + { + core::any::type_name::< [ T ; N ] >() + } + + #[ inline( always ) ] + fn type_id( &self ) -> core::any::TypeId + { + core::any::TypeId::of::< [ T ; N ] >() + } + + #[ inline( always ) ] + // fn elements( &self ) -> Box< dyn Iterator< Item = KeyVal > + '_ > + fn elements( &self ) -> Box< dyn Iterator< Item = KeyVal > > + { + + let result : [ KeyVal ; N ]; + for ( k, e ) in self.iter().enumerate() + { + result[ k ] = KeyVal { key : "x", val : Box::new( (*e).clone() ) } + } + + Box::new( result.into_iter() ) + } + + } } From 54b346a38d372de1679f5c5ecd92de9696073031 Mon Sep 17 00:00:00 2001 From: wandalen Date: Sun, 18 Feb 2024 02:02:32 +0200 Subject: [PATCH 14/19] experimenting --- module/core/derive_tools/src/reflect.rs | 99 +++++++++++++++++-- module/core/derive_tools/tests/inc/mod.rs | 6 +- .../tests/inc/reflect_data_test.rs | 12 +++ .../reflect_struct_in_struct_manual_test.rs | 10 +- .../tests/inc/reflect_struct_manual_test.rs | 6 +- 5 files changed, 115 insertions(+), 18 deletions(-) create mode 100644 module/core/derive_tools/tests/inc/reflect_data_test.rs diff --git a/module/core/derive_tools/src/reflect.rs b/module/core/derive_tools/src/reflect.rs index 67430908ab..a9c5971a41 100644 --- a/module/core/derive_tools/src/reflect.rs +++ b/module/core/derive_tools/src/reflect.rs @@ -29,6 +29,80 @@ pub( crate ) mod private { } + /// Represents a general-purpose data container that can hold various primitive types + /// and strings. This enum is designed to encapsulate common data types in a unified + /// format, simplifying the handling of different types of data in generic contexts. + /// + /// # Variants + /// + /// - `i8`, `i16`, `i32`, `i64`, `isize`: Signed integer types. + /// - `u8`, `u16`, `u32`, `u64`, `usize`: Unsigned integer types. + /// - `f32`, `f64`: Floating-point types. + /// - `String`: A heap-allocated string (`String`). + /// - `str`: A borrowed string slice (`&'static str`), typically used for string literals. + /// - `binary`: A borrowed slice of bytes (`&'static [u8]`), useful for binary data. + /// + /// # Examples + /// + /// Creating a `Data` instance with an integer: + /// + /// ``` + /// # use derive_tools::Data; + /// let num = Data::i32(42); + /// ``` + /// + /// Creating a `Data` instance with a string: + /// + /// ``` + /// # use derive_tools::Data; + /// let greeting = Data::String( "Hello, world!".to_string() ); + /// ``` + /// + /// Creating a `Data` instance with a binary slice: + /// + /// ``` + /// # use derive_tools::Data; + /// let bytes = Data::binary(&[0xde, 0xad, 0xbe, 0xef]); + /// ``` + #[ allow( non_camel_case_types ) ] + #[ derive( Debug, PartialEq, Default ) ] + pub enum Data + { + /// None + #[ default ] + none, + /// Represents a signed 8-bit integer. + i8( i8 ), + /// Represents a signed 16-bit integer. + i16( i16 ), + /// Represents a signed 32-bit integer. + i32( i32 ), + /// Represents a signed 64-bit integer. + i64( i64 ), + /// Represents a machine-sized signed integer. + isize( isize ), + /// Represents an unsigned 8-bit integer. + u8( u8 ), + /// Represents an unsigned 16-bit integer. + u16( u16 ), + /// Represents an unsigned 32-bit integer. + u32( u32 ), + /// Represents an unsigned 64-bit integer. + u64( u64 ), + /// Represents a machine-sized unsigned integer. + usize( usize ), + /// Represents a 32-bit floating-point number. + f32( f32 ), + /// Represents a 64-bit floating-point number. + f64( f64 ), + /// Represents a dynamically allocated string. + String( String ), + /// Represents a statically allocated string slice. + str( &'static str ), + /// Represents a statically allocated slice of bytes. + binary( &'static [ u8 ] ), + } + /// /// Represents a trait for entity reflection. /// @@ -69,7 +143,7 @@ pub( crate ) mod private /// /// Type descriptor /// - #[ derive( PartialEq ) ] + #[ derive( PartialEq, Default ) ] pub struct EntityDescriptor< I : Instance > { _phantom : core::marker::PhantomData< I >, @@ -95,7 +169,7 @@ pub( crate ) mod private impl< T > Entity for EntityDescriptor< T > where - T : InstanceMarker + 'static, + T : InstanceMarker + Default + 'static, { #[ inline( always ) ] fn type_name( &self ) -> &'static str @@ -201,6 +275,7 @@ pub( crate ) mod private /// of its contents. /// // #[ derive( PartialEq, Debug ) ] + // #[ derive( Default ) ] pub struct KeyVal { /// The key associated with the value in the key-value pair. @@ -328,6 +403,8 @@ pub( crate ) mod private } impl< T, const N : usize > Entity for EntityDescriptor< [ T ; N ] > + where + T : 'static + Instance, { #[ inline( always ) ] @@ -355,15 +432,20 @@ pub( crate ) mod private } #[ inline( always ) ] - // fn elements( &self ) -> Box< dyn Iterator< Item = KeyVal > + '_ > fn elements( &self ) -> Box< dyn Iterator< Item = KeyVal > > { - let result : [ KeyVal ; N ]; - for ( k, e ) in self.iter().enumerate() - { - result[ k ] = KeyVal { key : "x", val : Box::new( (*e).clone() ) } - } + // qqq : write optimal implementation +// let mut result : [ KeyVal ; N ] = Default::default(); +// +// for i in 0..N +// { +// result[ i ] = KeyVal { key : "x", val : Box::new( < T as Instance >::Reflect() ) } +// } + + let result: Vec = (0..N) + .map(|_| KeyVal { key: "x", val: Box::new( < T as Instance >::Reflect() ) } ) + .collect(); Box::new( result.into_iter() ) } @@ -392,6 +474,7 @@ pub mod orphan pub use super::exposed::*; pub use super::private:: { + Data, IsContainer, IsScalar, Instance, diff --git a/module/core/derive_tools/tests/inc/mod.rs b/module/core/derive_tools/tests/inc/mod.rs index 3fb5c980f8..05aac3028a 100644 --- a/module/core/derive_tools/tests/inc/mod.rs +++ b/module/core/derive_tools/tests/inc/mod.rs @@ -71,9 +71,11 @@ mod inner_from_multiple_test; #[ cfg( feature = "derive_reflect" ) ] mod reflect_common_test; #[ cfg( feature = "derive_reflect" ) ] +mod reflect_data_test; +#[ cfg( feature = "derive_reflect" ) ] mod reflect_struct_manual_test; -// #[ cfg( feature = "derive_reflect" ) ] -// mod reflect_struct_in_struct_manual_test; +#[ cfg( feature = "derive_reflect" ) ] +mod reflect_struct_in_struct_manual_test; // #[ cfg( all( feature = "type_variadic_from" ) ) ] // mod variadic_from_manual_test; diff --git a/module/core/derive_tools/tests/inc/reflect_data_test.rs b/module/core/derive_tools/tests/inc/reflect_data_test.rs new file mode 100644 index 0000000000..3305475eb9 --- /dev/null +++ b/module/core/derive_tools/tests/inc/reflect_data_test.rs @@ -0,0 +1,12 @@ +use super::*; +pub use TheModule::reflect; + +#[ test ] +fn data_basic() +{ + use reflect::Data; + + let got = Data::i32( 13i32 ); + a_id!( got, Data::i32( 13i32 ) ); + +} diff --git a/module/core/derive_tools/tests/inc/reflect_struct_in_struct_manual_test.rs b/module/core/derive_tools/tests/inc/reflect_struct_in_struct_manual_test.rs index cf3c08dcec..97b272219e 100644 --- a/module/core/derive_tools/tests/inc/reflect_struct_in_struct_manual_test.rs +++ b/module/core/derive_tools/tests/inc/reflect_struct_in_struct_manual_test.rs @@ -27,31 +27,31 @@ pub struct EntityDescriptor< I : reflect::Instance > impl< I : reflect::Instance > EntityDescriptor< I > { - /// Constructor of the descriptor of type. #[ inline( always ) ] pub fn new() -> Self { let _phantom = core::marker::PhantomData::< I >; Self { _phantom } } - /// Constructor of the descriptor of type. } // -- impl reflect::Instance for Struct1 { + type Entity = EntityDescriptor< Struct1 >; #[ inline( always ) ] - fn Reflect() -> impl reflect::Entity + fn Reflect() -> Self::Entity { EntityDescriptor::< Self >::new() } } -impl Reflect::Instance for Struct2 +impl reflect::Instance for Struct2 { + type Entity = EntityDescriptor< Struct2 >; #[ inline( always ) ] - fn Reflect() -> impl reflect::Entity + fn Reflect() -> Self::Entity { EntityDescriptor::< Self >::new() } diff --git a/module/core/derive_tools/tests/inc/reflect_struct_manual_test.rs b/module/core/derive_tools/tests/inc/reflect_struct_manual_test.rs index ac25c0946a..c959a70898 100644 --- a/module/core/derive_tools/tests/inc/reflect_struct_manual_test.rs +++ b/module/core/derive_tools/tests/inc/reflect_struct_manual_test.rs @@ -73,9 +73,9 @@ impl reflect::Entity for EntityDescriptor< Struct1 > { let result = vec! [ - reflect::KeyVal { key: "f1", val: Box::new( < i32 as reflect::Instance >::Reflect() ) }, - reflect::KeyVal { key: "f2", val: Box::new( < String as reflect::Instance >::Reflect() ) }, - reflect::KeyVal { key: "f3", val: Box::new( < &'static str as reflect::Instance >::Reflect() ) }, + reflect::KeyVal { key : "f1", val : Box::new( < i32 as reflect::Instance >::Reflect() ) }, + reflect::KeyVal { key : "f2", val : Box::new( < String as reflect::Instance >::Reflect() ) }, + reflect::KeyVal { key : "f3", val : Box::new( < &'static str as reflect::Instance >::Reflect() ) }, ]; Box::new( result.into_iter() ) } From 80d1d94f10345415057f7bfd55a5a7e161cd8359 Mon Sep 17 00:00:00 2001 From: wandalen Date: Sun, 18 Feb 2024 02:17:58 +0200 Subject: [PATCH 15/19] experimenting --- module/core/derive_tools/src/reflect.rs | 42 +++++++++++++------ module/core/derive_tools/tests/inc/mod.rs | 2 +- .../tests/inc/reflect_data_test.rs | 12 ------ .../tests/inc/reflect_primitive_test.rs | 12 ++++++ 4 files changed, 43 insertions(+), 25 deletions(-) delete mode 100644 module/core/derive_tools/tests/inc/reflect_data_test.rs create mode 100644 module/core/derive_tools/tests/inc/reflect_primitive_test.rs diff --git a/module/core/derive_tools/src/reflect.rs b/module/core/derive_tools/src/reflect.rs index a9c5971a41..a0d933f3ec 100644 --- a/module/core/derive_tools/src/reflect.rs +++ b/module/core/derive_tools/src/reflect.rs @@ -44,33 +44,33 @@ pub( crate ) mod private /// /// # Examples /// - /// Creating a `Data` instance with an integer: + /// Creating a `Primitive` instance with an integer: /// /// ``` - /// # use derive_tools::Data; - /// let num = Data::i32(42); + /// # use derive_tools::Primitive; + /// let num = Primitive::i32(42); /// ``` /// - /// Creating a `Data` instance with a string: + /// Creating a `Primitive` instance with a string: /// /// ``` - /// # use derive_tools::Data; - /// let greeting = Data::String( "Hello, world!".to_string() ); + /// # use derive_tools::Primitive; + /// let greeting = Primitive::String( "Hello, world!".to_string() ); /// ``` /// - /// Creating a `Data` instance with a binary slice: + /// Creating a `Primitive` instance with a binary slice: /// /// ``` - /// # use derive_tools::Data; - /// let bytes = Data::binary(&[0xde, 0xad, 0xbe, 0xef]); + /// # use derive_tools::Primitive; + /// let bytes = Primitive::binary(&[0xde, 0xad, 0xbe, 0xef]); /// ``` #[ allow( non_camel_case_types ) ] #[ derive( Debug, PartialEq, Default ) ] - pub enum Data + pub enum Primitive { /// None #[ default ] - none, + None, /// Represents a signed 8-bit integer. i8( i8 ), /// Represents a signed 16-bit integer. @@ -103,6 +103,24 @@ pub( crate ) mod private binary( &'static [ u8 ] ), } + #[ allow( non_camel_case_types ) ] + #[ derive( Debug, PartialEq ) ] + pub enum Data< const N : usize = 0 > + { + /// None + Primitive( Primitive ), + // 2/// Array + // array( &'a [ Data ; N ] ), + } + + impl< const N : usize > Default for Data< N > + { + fn default() -> Self + { + Data::Primitive( Primitive::None ) + } + } + /// /// Represents a trait for entity reflection. /// @@ -474,7 +492,7 @@ pub mod orphan pub use super::exposed::*; pub use super::private:: { - Data, + Primitive, IsContainer, IsScalar, Instance, diff --git a/module/core/derive_tools/tests/inc/mod.rs b/module/core/derive_tools/tests/inc/mod.rs index 05aac3028a..c18d3cdca7 100644 --- a/module/core/derive_tools/tests/inc/mod.rs +++ b/module/core/derive_tools/tests/inc/mod.rs @@ -71,7 +71,7 @@ mod inner_from_multiple_test; #[ cfg( feature = "derive_reflect" ) ] mod reflect_common_test; #[ cfg( feature = "derive_reflect" ) ] -mod reflect_data_test; +mod reflect_primitive_test; #[ cfg( feature = "derive_reflect" ) ] mod reflect_struct_manual_test; #[ cfg( feature = "derive_reflect" ) ] diff --git a/module/core/derive_tools/tests/inc/reflect_data_test.rs b/module/core/derive_tools/tests/inc/reflect_data_test.rs deleted file mode 100644 index 3305475eb9..0000000000 --- a/module/core/derive_tools/tests/inc/reflect_data_test.rs +++ /dev/null @@ -1,12 +0,0 @@ -use super::*; -pub use TheModule::reflect; - -#[ test ] -fn data_basic() -{ - use reflect::Data; - - let got = Data::i32( 13i32 ); - a_id!( got, Data::i32( 13i32 ) ); - -} diff --git a/module/core/derive_tools/tests/inc/reflect_primitive_test.rs b/module/core/derive_tools/tests/inc/reflect_primitive_test.rs new file mode 100644 index 0000000000..d6ce5df3e9 --- /dev/null +++ b/module/core/derive_tools/tests/inc/reflect_primitive_test.rs @@ -0,0 +1,12 @@ +use super::*; +pub use TheModule::reflect; + +#[ test ] +fn data_basic() +{ + use reflect::Primitive; + + let got = Primitive::i32( 13i32 ); + a_id!( got, Primitive::i32( 13i32 ) ); + +} From 881441b24e530471e0b3c9fee3204eacf13a6e50 Mon Sep 17 00:00:00 2001 From: wandalen Date: Sun, 18 Feb 2024 02:22:05 +0200 Subject: [PATCH 16/19] experimenting --- module/core/derive_tools/src/reflect.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/module/core/derive_tools/src/reflect.rs b/module/core/derive_tools/src/reflect.rs index a0d933f3ec..5e39bf89d4 100644 --- a/module/core/derive_tools/src/reflect.rs +++ b/module/core/derive_tools/src/reflect.rs @@ -109,7 +109,7 @@ pub( crate ) mod private { /// None Primitive( Primitive ), - // 2/// Array + // /// Array // array( &'a [ Data ; N ] ), } @@ -297,7 +297,8 @@ pub( crate ) mod private pub struct KeyVal { /// The key associated with the value in the key-value pair. - pub key : &'static str, + pub key : Primitive, + // pub key : &'static str, /// The value associated with the key in the key-value pair. pub val : Box< dyn Entity >, } @@ -405,9 +406,6 @@ pub( crate ) mod private impl IsScalar for String {} impl IsScalar for &'static str {} - // impl< T, const N : usize > IsContainer for [ T ; N ] {} - - // impl< T, const N : usize > InstanceMarker for [ T ; N ] {} impl< T, const N : usize > Instance for [ T ; N ] where EntityDescriptor< [ T ; N ] > : Entity, @@ -462,7 +460,7 @@ pub( crate ) mod private // } let result: Vec = (0..N) - .map(|_| KeyVal { key: "x", val: Box::new( < T as Instance >::Reflect() ) } ) + .map(|_| KeyVal { key : "x", val : Box::new( < T as Instance >::Reflect() ) } ) .collect(); Box::new( result.into_iter() ) From 627028b03187d66de1e38a329aeaa685325f6aa2 Mon Sep 17 00:00:00 2001 From: wandalen Date: Sun, 18 Feb 2024 02:27:58 +0200 Subject: [PATCH 17/19] experimenting --- module/core/derive_tools/src/reflect.rs | 4 ++-- .../tests/inc/only_test/reflect_struct.rs | 4 ++-- .../tests/inc/only_test/reflect_struct_in_struct.rs | 6 +++--- .../inc/reflect_struct_in_struct_manual_test.rs | 12 ++++++------ .../tests/inc/reflect_struct_manual_test.rs | 6 +++--- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/module/core/derive_tools/src/reflect.rs b/module/core/derive_tools/src/reflect.rs index 5e39bf89d4..c9e4635374 100644 --- a/module/core/derive_tools/src/reflect.rs +++ b/module/core/derive_tools/src/reflect.rs @@ -459,8 +459,8 @@ pub( crate ) mod private // result[ i ] = KeyVal { key : "x", val : Box::new( < T as Instance >::Reflect() ) } // } - let result: Vec = (0..N) - .map(|_| KeyVal { key : "x", val : Box::new( < T as Instance >::Reflect() ) } ) + let result : Vec< KeyVal > = ( 0 .. N ) + .map( | k | KeyVal { key : Primitive::usize( k ), val : Box::new( < T as Instance >::Reflect() ) } ) .collect(); Box::new( result.into_iter() ) diff --git a/module/core/derive_tools/tests/inc/only_test/reflect_struct.rs b/module/core/derive_tools/tests/inc/only_test/reflect_struct.rs index bcfa4b9827..88e85be0c8 100644 --- a/module/core/derive_tools/tests/inc/only_test/reflect_struct.rs +++ b/module/core/derive_tools/tests/inc/only_test/reflect_struct.rs @@ -14,12 +14,12 @@ fn reflect_basic_test() a_id!( ins.reflect().len(), 3 ); a_id!( ins.reflect().type_name(), "derive_tests::inc::reflect_struct_manual_test::Struct1" ); let names = ins.reflect().elements().map( | e | e.key ).collect::< Vec< _ > >(); - a_id!( names, vec![ "f1", "f2", "f3" ] ); + a_id!( names, vec![ reflect::Primitive::str( "f1" ), reflect::Primitive::str( "f2" ), reflect::Primitive::str( "f3" ) ] ); let types = ins.reflect().elements().map( | e | e.val.type_name() ).collect::< Vec< _ > >(); a_id!( types, vec![ "i32", "alloc::string::String", "&str" ] ); let f1 = ins.reflect().elements().next().unwrap(); - a_id!( f1.key, "f1" ); + a_id!( f1.key, reflect::Primitive::str( "f1" ) ); a_id!( f1.val.is_container(), false ); a_id!( f1.val.len(), 0 ); a_id!( f1.val.type_name(), "i32" ); diff --git a/module/core/derive_tools/tests/inc/only_test/reflect_struct_in_struct.rs b/module/core/derive_tools/tests/inc/only_test/reflect_struct_in_struct.rs index 679f885b75..99d890fcc1 100644 --- a/module/core/derive_tools/tests/inc/only_test/reflect_struct_in_struct.rs +++ b/module/core/derive_tools/tests/inc/only_test/reflect_struct_in_struct.rs @@ -14,17 +14,17 @@ fn reflect_struct_in_struct() a_id!( ins.reflect().len(), 3 ); a_id!( ins.reflect().type_name(), "derive_tests::inc::reflect_struct_in_struct_manual_test::Struct1" ); let names = ins.reflect().elements().map( | e | e.key ).collect::< Vec< _ > >(); - a_id!( names, vec![ "f1", "f2", "f3" ] ); + a_id!( names, vec![ reflect::Primitive::str( "f1" ), reflect::Primitive::str( "f2" ), reflect::Primitive::str( "f3" ) ] ); let types = ins.reflect().elements().map( | e | e.val.type_name() ).collect::< Vec< _ > >(); a_id!( types, vec![ "i32", "alloc::string::String", "derive_tests::inc::reflect_struct_in_struct_manual_test::Struct2" ] ); let f3 = ins.reflect().elements().skip( 2 ).next().unwrap(); - a_id!( f3.key, "f3" ); + a_id!( f3.key, reflect::Primitive::str( "f3" ) ); a_id!( f3.val.is_container(), true ); a_id!( f3.val.len(), 3 ); a_id!( f3.val.type_name(), "derive_tests::inc::reflect_struct_in_struct_manual_test::Struct2" ); let names = f3.val.elements().map( | e | e.key ).collect::< Vec< _ > >(); - a_id!( names, vec![ "s1", "s2", "s3" ] ); + a_id!( names, vec![ reflect::Primitive::str( "s1" ), reflect::Primitive::str( "s2" ), reflect::Primitive::str( "s3" ) ] ); let types = f3.val.elements().map( | e | e.val.type_name() ).collect::< Vec< _ > >(); a_id!( types, vec![ "i32", "alloc::string::String", "&str" ] ); diff --git a/module/core/derive_tools/tests/inc/reflect_struct_in_struct_manual_test.rs b/module/core/derive_tools/tests/inc/reflect_struct_in_struct_manual_test.rs index 97b272219e..93971ebc3b 100644 --- a/module/core/derive_tools/tests/inc/reflect_struct_in_struct_manual_test.rs +++ b/module/core/derive_tools/tests/inc/reflect_struct_in_struct_manual_test.rs @@ -84,9 +84,9 @@ impl reflect::Entity for EntityDescriptor< Struct1 > { let result = vec! [ - reflect::KeyVal { key: "f1", val: Box::new( < i32 as reflect::Instance >::Reflect() ) }, - reflect::KeyVal { key: "f2", val: Box::new( < String as reflect::Instance >::Reflect() ) }, - reflect::KeyVal { key: "f3", val: Box::new( < Struct2 as reflect::Instance >::Reflect() ) }, + reflect::KeyVal { key: reflect::Primitive::str( "f1" ), val: Box::new( < i32 as reflect::Instance >::Reflect() ) }, + reflect::KeyVal { key: reflect::Primitive::str( "f2" ), val: Box::new( < String as reflect::Instance >::Reflect() ) }, + reflect::KeyVal { key: reflect::Primitive::str( "f3" ), val: Box::new( < Struct2 as reflect::Instance >::Reflect() ) }, ]; Box::new( result.into_iter() ) } @@ -120,9 +120,9 @@ impl reflect::Entity for EntityDescriptor< Struct2 > { let result = vec! [ - reflect::KeyVal { key: "s1", val: Box::new( < i32 as reflect::Instance >::Reflect() ) }, - reflect::KeyVal { key: "s2", val: Box::new( < String as reflect::Instance >::Reflect() ) }, - reflect::KeyVal { key: "s3", val: Box::new( < &'static str as reflect::Instance >::Reflect() ) }, + reflect::KeyVal { key: reflect::Primitive::str( "s1" ), val: Box::new( < i32 as reflect::Instance >::Reflect() ) }, + reflect::KeyVal { key: reflect::Primitive::str( "s2" ), val: Box::new( < String as reflect::Instance >::Reflect() ) }, + reflect::KeyVal { key: reflect::Primitive::str( "s3" ), val: Box::new( < &'static str as reflect::Instance >::Reflect() ) }, ]; Box::new( result.into_iter() ) } diff --git a/module/core/derive_tools/tests/inc/reflect_struct_manual_test.rs b/module/core/derive_tools/tests/inc/reflect_struct_manual_test.rs index c959a70898..cec40a4835 100644 --- a/module/core/derive_tools/tests/inc/reflect_struct_manual_test.rs +++ b/module/core/derive_tools/tests/inc/reflect_struct_manual_test.rs @@ -73,9 +73,9 @@ impl reflect::Entity for EntityDescriptor< Struct1 > { let result = vec! [ - reflect::KeyVal { key : "f1", val : Box::new( < i32 as reflect::Instance >::Reflect() ) }, - reflect::KeyVal { key : "f2", val : Box::new( < String as reflect::Instance >::Reflect() ) }, - reflect::KeyVal { key : "f3", val : Box::new( < &'static str as reflect::Instance >::Reflect() ) }, + reflect::KeyVal { key : reflect::Primitive::str( "f1" ), val : Box::new( < i32 as reflect::Instance >::Reflect() ) }, + reflect::KeyVal { key : reflect::Primitive::str( "f2" ), val : Box::new( < String as reflect::Instance >::Reflect() ) }, + reflect::KeyVal { key : reflect::Primitive::str( "f3" ), val : Box::new( < &'static str as reflect::Instance >::Reflect() ) }, ]; Box::new( result.into_iter() ) } From 71cc8b35d1bf8ce418a155b2b0cd3550c2faaf9e Mon Sep 17 00:00:00 2001 From: wandalen Date: Sun, 18 Feb 2024 14:06:33 +0200 Subject: [PATCH 18/19] experimenting --- module/core/derive_tools/src/reflect.rs | 4 - module/core/derive_tools/tests/inc/mod.rs | 2 + .../only_test/reflect_struct_with_lifetime.rs | 50 +++++++++++ .../tests/inc/reflect_struct_manual_test.rs | 22 +++++ ...eflect_struct_with_lifetime_manual_test.rs | 85 +++++++++++++++++++ 5 files changed, 159 insertions(+), 4 deletions(-) create mode 100644 module/core/derive_tools/tests/inc/only_test/reflect_struct_with_lifetime.rs create mode 100644 module/core/derive_tools/tests/inc/reflect_struct_with_lifetime_manual_test.rs diff --git a/module/core/derive_tools/src/reflect.rs b/module/core/derive_tools/src/reflect.rs index c9e4635374..0d86558595 100644 --- a/module/core/derive_tools/src/reflect.rs +++ b/module/core/derive_tools/src/reflect.rs @@ -167,10 +167,6 @@ pub( crate ) mod private _phantom : core::marker::PhantomData< I >, } - // xxx : qqq : qqq for Yulia : implement derive Phantom - // #[ derive( PartialEq, Debug, Phantom ) ] - // pub struct EntityDescriptor< I : Instance >; - impl< I : Instance > EntityDescriptor< I > { /// Constructor of the descriptor. diff --git a/module/core/derive_tools/tests/inc/mod.rs b/module/core/derive_tools/tests/inc/mod.rs index c18d3cdca7..bfa2df482c 100644 --- a/module/core/derive_tools/tests/inc/mod.rs +++ b/module/core/derive_tools/tests/inc/mod.rs @@ -76,6 +76,8 @@ mod reflect_primitive_test; mod reflect_struct_manual_test; #[ cfg( feature = "derive_reflect" ) ] mod reflect_struct_in_struct_manual_test; +#[ cfg( feature = "derive_reflect" ) ] +mod reflect_struct_with_lifetime_manual_test; // #[ cfg( all( feature = "type_variadic_from" ) ) ] // mod variadic_from_manual_test; diff --git a/module/core/derive_tools/tests/inc/only_test/reflect_struct_with_lifetime.rs b/module/core/derive_tools/tests/inc/only_test/reflect_struct_with_lifetime.rs new file mode 100644 index 0000000000..4186b6a3f3 --- /dev/null +++ b/module/core/derive_tools/tests/inc/only_test/reflect_struct_with_lifetime.rs @@ -0,0 +1,50 @@ +#[ test ] +fn reflect_struct_with_lifetime() +{ + use reflect::{ Instance, Entity }; + + // assumptions + a_id!( core::any::TypeId::of::< &'static str >(), core::any::TypeId::of::< &str >() ); + + // structure + let x = 1; + let z = "3"; + let ins = Struct1 + { + f1 : &x, + f2 : "2".into(), + f3 : &z, + }; + + println!( "i32 : {:?}", 1i32.reflect().type_id() ); + println!( "&i32 : {:?}", ( &1i32 ).reflect().type_id() ); + println!( "String : {:?}", "abc".to_string().reflect().type_id() ); + println!( "&String : {:?}", ( &"abc".to_string() ).reflect().type_id() ); + println!( "str : {:?}", "abc".reflect().type_id() ); + println!( "&str : {:?}", ( &"abc" ).reflect().type_id() ); + + println!( "Struct1 : {:?}", ins.reflect().type_id() ); + println!( "Struct1.f1 : {:?}", ins.reflect().elements().next().unwrap().val.type_id() ); + println!( "Struct1.f2 : {:?}", ins.reflect().elements().skip( 1 ).next().unwrap().val.type_id() ); + println!( "Struct1.f3 : {:?}", ins.reflect().elements().skip( 2 ).next().unwrap().val.type_id() ); + + // inspection of structure + a_id!( ins.reflect().is_container(), true ); + a_id!( ins.reflect().len(), 3 ); + a_id!( ins.reflect().type_name(), "derive_tests::inc::reflect_struct_with_lifetime_manual_test::Struct1" ); + a_id!( ins.reflect().type_id(), core::any::TypeId::of::< Struct1< 'static, 'static > >() ); + let names = ins.reflect().elements().map( | e | e.key ).collect::< Vec< _ > >(); + a_id!( names, vec![ reflect::Primitive::str( "f1" ), reflect::Primitive::str( "f2" ), reflect::Primitive::str( "f3" ) ] ); + let types = ins.reflect().elements().map( | e | e.val.type_name() ).collect::< Vec< _ > >(); + a_id!( types, vec![ "i32", "alloc::string::String", "&str" ] ); + + // inspection of a field + let f1 = ins.reflect().elements().next().unwrap(); + a_id!( f1.key, reflect::Primitive::str( "f1" ) ); + a_id!( f1.val.is_container(), false ); + a_id!( f1.val.len(), 0 ); + a_id!( f1.val.type_name(), "i32" ); + a_id!( f1.val.type_id(), core::any::TypeId::of::< &'static str >() ); + a_id!( f1.val.elements().collect::< Vec< _ > >(), vec![] ); + +} diff --git a/module/core/derive_tools/tests/inc/reflect_struct_manual_test.rs b/module/core/derive_tools/tests/inc/reflect_struct_manual_test.rs index cec40a4835..6c0319b0f4 100644 --- a/module/core/derive_tools/tests/inc/reflect_struct_manual_test.rs +++ b/module/core/derive_tools/tests/inc/reflect_struct_manual_test.rs @@ -17,6 +17,28 @@ pub struct EntityDescriptor< I : reflect::Instance > _phantom : core::marker::PhantomData< I >, } +// +// xxx : qqq : qqq for Yulia : implement derive Phantom +// +// #[ derive( PartialEq, Debug ) ] +// pub struct EntityDescriptor< I : reflect::Instance > +// { +// _phantom : core::marker::PhantomData< I >, +// } +// +// #[ derive( PartialEq, Debug, Phantom ) ] +// pub struct EntityDescriptor< I : Instance >; +// +// #[ derive( PartialEq, Debug, Phantom ) ] +// pub struct EntityDescriptor< I : Instance > {}; +// +// #[ derive( PartialEq, Debug ) ] +// pub struct EntityDescriptor< 'a, 'b, I : reflect::Instance > +// { +// _phantom : core::marker::PhantomData< ( &'a (), &'b (), I ) >, +// } +// + impl< I : reflect::Instance > EntityDescriptor< I > { /// Constructor of the descriptor. diff --git a/module/core/derive_tools/tests/inc/reflect_struct_with_lifetime_manual_test.rs b/module/core/derive_tools/tests/inc/reflect_struct_with_lifetime_manual_test.rs new file mode 100644 index 0000000000..a490b39e3e --- /dev/null +++ b/module/core/derive_tools/tests/inc/reflect_struct_with_lifetime_manual_test.rs @@ -0,0 +1,85 @@ +use super::*; +pub use TheModule::reflect; + +#[ derive( Debug, Clone, PartialEq ) ] +pub struct Struct1< 'a, 'b > +{ + pub f1 : &'a i32, + pub f2 : String, + pub f3 : &'b str, +} + +// -- + +#[ derive( PartialEq, Debug ) ] +pub struct EntityDescriptor< 'a, 'b, I : reflect::Instance > +{ + _phantom : core::marker::PhantomData< ( &'a (), &'b (), I ) >, +} + +impl< 'a, 'b, I : reflect::Instance > EntityDescriptor< 'a, 'b, I > +{ + /// Constructor of the descriptor. + #[ inline( always ) ] + pub fn new() -> Self + { + let _phantom = core::marker::PhantomData::< ( &'a (), &'b (), I ) >; + Self { _phantom } + } +} + +// qqq : qqq for Yulia : implement derive ReflectInstance +impl< 'a, 'b > reflect::Instance for Struct1< 'a, 'b > +{ + type Entity = EntityDescriptor::< 'a, 'b, Self >; + #[ inline( always ) ] + fn Reflect() -> Self::Entity + { + EntityDescriptor::< Self >::new() + } +} + +// -- + +impl< 'a, 'b > reflect::Entity for EntityDescriptor< 'a, 'b, Struct1< 'a, 'b > > +{ + + #[ inline( always ) ] + fn is_container( &self ) -> bool + { + true + } + + #[ inline( always ) ] + fn len( &self ) -> usize + { + 3 + } + + #[ inline( always ) ] + fn type_name( &self ) -> &'static str + { + core::any::type_name::< Struct1< 'a, 'b > >() + } + + #[ inline( always ) ] + fn type_id( &self ) -> core::any::TypeId + { + core::any::TypeId::of::< Struct1< 'static, 'static > >() + } + + #[ inline( always ) ] + fn elements(&self) -> Box< dyn Iterator< Item = reflect::KeyVal > > + { + let result = vec! + [ + reflect::KeyVal { key : reflect::Primitive::str( "f1" ), val : Box::new( < i32 as reflect::Instance >::Reflect() ) }, + reflect::KeyVal { key : reflect::Primitive::str( "f2" ), val : Box::new( < String as reflect::Instance >::Reflect() ) }, + reflect::KeyVal { key : reflect::Primitive::str( "f3" ), val : Box::new( < &'static str as reflect::Instance >::Reflect() ) }, + ]; + Box::new( result.into_iter() ) + } + +} + +include!( "./only_test/reflect_struct_with_lifetime.rs" ); From 52a5e23aa13e095889d079d1cd689c02c56cc6fa Mon Sep 17 00:00:00 2001 From: wandalen Date: Mon, 19 Feb 2024 00:05:08 +0200 Subject: [PATCH 19/19] logical milestone --- module/core/derive_tools/src/reflect.rs | 62 ++----------------- .../only_test/reflect_struct_with_lifetime.rs | 24 +++++-- ...eflect_struct_with_lifetime_manual_test.rs | 6 +- 3 files changed, 27 insertions(+), 65 deletions(-) diff --git a/module/core/derive_tools/src/reflect.rs b/module/core/derive_tools/src/reflect.rs index 0d86558595..5c264bc7b0 100644 --- a/module/core/derive_tools/src/reflect.rs +++ b/module/core/derive_tools/src/reflect.rs @@ -183,7 +183,7 @@ pub( crate ) mod private impl< T > Entity for EntityDescriptor< T > where - T : InstanceMarker + Default + 'static, + T : InstanceMarker + 'static, { #[ inline( always ) ] fn type_name( &self ) -> &'static str @@ -320,62 +320,6 @@ pub( crate ) mod private } } - // impl Instance for i8 {} - // impl Instance for i16 {} - // impl Instance for i32 {} - // impl Instance for i64 {} - // impl Instance for u8 {} - // impl Instance for u16 {} - // impl Instance for u32 {} - // impl Instance for u64 {} - // impl Instance for f32 {} - // impl Instance for f64 {} - // impl Instance for String {} - // impl Instance for &'static str {} - - /// Implements Entity for a types. - #[ macro_export ] - macro_rules! impl_entity_for - { - - ( - $( $Path : tt )* - ) - => - { - impl crate::reflect::Entity for crate::reflect::EntityDescriptor< $( $Path )* > - { - #[ inline( always ) ] - fn type_name( &self ) -> &'static str - { - core::any::type_name::< $( $Path )* >() - } - } - }; - - } - - // impl Entity for EntityDescriptor< i8 > - // { - // fn type_name( &self ) -> &'static str - // { - // core::any::type_name::< i8 >() - // } - // } - - // impl_entity_for!( i8 ); - // impl_entity_for!( i16 ); - // impl_entity_for!( i32 ); - // impl_entity_for!( i64 ); - // impl_entity_for!( u8 ); - // impl_entity_for!( u16 ); - // impl_entity_for!( u32 ); - // impl_entity_for!( u64 ); - // impl_entity_for!( f32 ); - // impl_entity_for!( f64 ); - // impl_entity_for!( String ); - // impl_entity_for!( &'static str ); - impl InstanceMarker for i8 {} impl InstanceMarker for i16 {} impl InstanceMarker for i32 {} @@ -389,6 +333,10 @@ pub( crate ) mod private impl InstanceMarker for String {} impl InstanceMarker for &'static str {} + impl< T > InstanceMarker for &T + where T : InstanceMarker + {} + impl IsScalar for i8 {} impl IsScalar for i16 {} impl IsScalar for i32 {} diff --git a/module/core/derive_tools/tests/inc/only_test/reflect_struct_with_lifetime.rs b/module/core/derive_tools/tests/inc/only_test/reflect_struct_with_lifetime.rs index 4186b6a3f3..d4814182f2 100644 --- a/module/core/derive_tools/tests/inc/only_test/reflect_struct_with_lifetime.rs +++ b/module/core/derive_tools/tests/inc/only_test/reflect_struct_with_lifetime.rs @@ -12,22 +12,36 @@ fn reflect_struct_with_lifetime() let ins = Struct1 { f1 : &x, - f2 : "2".into(), + f2 : 2, f3 : &z, }; + // for understanding + println!( "TypeId< i32 > : {:?}", core::any::TypeId::of::< i32 >() ); + println!( "TypeId< &i32 > : {:?}", core::any::TypeId::of::< & i32 >() ); // qqq : qqq fro Yuliia : problem. should be distinct id + println!( "TypeId< String > : {:?}", core::any::TypeId::of::< String >() ); + println!( "TypeId< &String > : {:?}", core::any::TypeId::of::< & String >() ); + println!( "TypeId< str > : {:?}", core::any::TypeId::of::< str >() ); + println!( "TypeId< &str > : {:?}", core::any::TypeId::of::< & str >() ); + println!( "i32 : {:?}", 1i32.reflect().type_id() ); println!( "&i32 : {:?}", ( &1i32 ).reflect().type_id() ); println!( "String : {:?}", "abc".to_string().reflect().type_id() ); println!( "&String : {:?}", ( &"abc".to_string() ).reflect().type_id() ); println!( "str : {:?}", "abc".reflect().type_id() ); println!( "&str : {:?}", ( &"abc" ).reflect().type_id() ); - println!( "Struct1 : {:?}", ins.reflect().type_id() ); println!( "Struct1.f1 : {:?}", ins.reflect().elements().next().unwrap().val.type_id() ); println!( "Struct1.f2 : {:?}", ins.reflect().elements().skip( 1 ).next().unwrap().val.type_id() ); println!( "Struct1.f3 : {:?}", ins.reflect().elements().skip( 2 ).next().unwrap().val.type_id() ); + println!( "i32.type_id : {:?}", 1i32.reflect().type_id() ); + println!( "i32.type_name : {:?}", 1i32.reflect().type_name() ); + println!( "&i32.type_id : {:?}", ( &1i32 ).reflect().type_id() ); + println!( "&i32.type_name : {:?}", ( &1i32 ).reflect().type_name() ); + println!( "&i32.type_id : {:?}", reflect::Instance::reflect( &1i32 ).type_id() ); + println!( "&i32.type_name : {:?}", reflect::Instance::reflect( &1i32 ).type_name() ); + // inspection of structure a_id!( ins.reflect().is_container(), true ); a_id!( ins.reflect().len(), 3 ); @@ -36,15 +50,15 @@ fn reflect_struct_with_lifetime() let names = ins.reflect().elements().map( | e | e.key ).collect::< Vec< _ > >(); a_id!( names, vec![ reflect::Primitive::str( "f1" ), reflect::Primitive::str( "f2" ), reflect::Primitive::str( "f3" ) ] ); let types = ins.reflect().elements().map( | e | e.val.type_name() ).collect::< Vec< _ > >(); - a_id!( types, vec![ "i32", "alloc::string::String", "&str" ] ); + a_id!( types, vec![ "&i32", "i32", "&str" ] ); // inspection of a field let f1 = ins.reflect().elements().next().unwrap(); a_id!( f1.key, reflect::Primitive::str( "f1" ) ); a_id!( f1.val.is_container(), false ); a_id!( f1.val.len(), 0 ); - a_id!( f1.val.type_name(), "i32" ); - a_id!( f1.val.type_id(), core::any::TypeId::of::< &'static str >() ); + a_id!( f1.val.type_name(), "&i32" ); + a_id!( f1.val.type_id(), core::any::TypeId::of::< &'static i32 >() ); a_id!( f1.val.elements().collect::< Vec< _ > >(), vec![] ); } diff --git a/module/core/derive_tools/tests/inc/reflect_struct_with_lifetime_manual_test.rs b/module/core/derive_tools/tests/inc/reflect_struct_with_lifetime_manual_test.rs index a490b39e3e..220bdf0b26 100644 --- a/module/core/derive_tools/tests/inc/reflect_struct_with_lifetime_manual_test.rs +++ b/module/core/derive_tools/tests/inc/reflect_struct_with_lifetime_manual_test.rs @@ -5,7 +5,7 @@ pub use TheModule::reflect; pub struct Struct1< 'a, 'b > { pub f1 : &'a i32, - pub f2 : String, + pub f2 : i32, pub f3 : &'b str, } @@ -73,8 +73,8 @@ impl< 'a, 'b > reflect::Entity for EntityDescriptor< 'a, 'b, Struct1< 'a, 'b > > { let result = vec! [ - reflect::KeyVal { key : reflect::Primitive::str( "f1" ), val : Box::new( < i32 as reflect::Instance >::Reflect() ) }, - reflect::KeyVal { key : reflect::Primitive::str( "f2" ), val : Box::new( < String as reflect::Instance >::Reflect() ) }, + reflect::KeyVal { key : reflect::Primitive::str( "f1" ), val : Box::new( < &'static i32 as reflect::Instance >::Reflect() ) }, + reflect::KeyVal { key : reflect::Primitive::str( "f2" ), val : Box::new( < i32 as reflect::Instance >::Reflect() ) }, reflect::KeyVal { key : reflect::Primitive::str( "f3" ), val : Box::new( < &'static str as reflect::Instance >::Reflect() ) }, ]; Box::new( result.into_iter() )