diff --git a/.github/workflows/standard_rust_push.yml b/.github/workflows/standard_rust_push.yml index d2fd96bae2..310c7fa765 100644 --- a/.github/workflows/standard_rust_push.yml +++ b/.github/workflows/standard_rust_push.yml @@ -77,7 +77,8 @@ jobs : continue-on-error: true - name: Check the modules dependencies run: cargo +nightly udeps --all-targets --manifest-path ${{ inputs.manifest_path }} - continue-on-error: true +# This part means that all previous steps will be executed and workflow will not stop if they fail, but not this one. + continue-on-error: false # release: # if: contains( inputs.commit_message, '+test' ) || contains( inputs.commit_message, 'merge' ) @@ -125,6 +126,9 @@ jobs : # run: cargo miri test --manifest-path ${{ inputs.manifest_path }} will_test : +# This section ensures that `job` `will_test` will only be executed after `checkmate` and if `checkmate` fails, no tests will be run. + needs: + - checkmate if : contains( inputs.commit_message, '+test' ) || inputs.commiter_username == 'web-flow' || startsWith( inputs.commit_message, 'merge' ) concurrency : group : standard_rust_push_${{ inputs.module_name }}_${{ github.ref }}_${{ matrix.os }} diff --git a/Cargo.toml b/Cargo.toml index 8e5c12e5cc..cb2a9fabd9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -80,7 +80,7 @@ path = "module/alias/std_x" ## data_type [workspace.dependencies.data_type] -version = "~0.9.0" +version = "~0.10.0" path = "module/core/data_type" default-features = false @@ -98,7 +98,7 @@ default-features = false # path = "module/core/type_constructor_derive_pair_meta" [workspace.dependencies.interval_adapter] -version = "~0.23.0" +version = "~0.24.0" path = "module/core/interval_adapter" default-features = false features = [ "enabled" ] @@ -110,7 +110,7 @@ default-features = false features = [ "enabled" ] [workspace.dependencies.collection_tools] -version = "~0.11.0" +version = "~0.12.0" path = "module/core/collection_tools" default-features = false @@ -118,13 +118,13 @@ default-features = false ## derive [workspace.dependencies.derive_tools] -version = "~0.27.0" +version = "~0.28.0" path = "module/core/derive_tools" default-features = false features = [ "enabled" ] [workspace.dependencies.derive_tools_meta] -version = "~0.26.0" +version = "~0.27.0" path = "module/core/derive_tools_meta" default-features = false features = [ "enabled" ] @@ -159,24 +159,24 @@ path = "module/alias/fundamental_data_type" default-features = false [workspace.dependencies.variadic_from] -version = "~0.22.0" +version = "~0.23.0" path = "module/core/variadic_from" default-features = false features = [ "enabled" ] [workspace.dependencies.clone_dyn] -version = "~0.23.0" +version = "~0.24.0" path = "module/core/clone_dyn" default-features = false features = [ "enabled" ] [workspace.dependencies.clone_dyn_meta] -version = "~0.23.0" +version = "~0.24.0" path = "module/core/clone_dyn_meta" features = [ "enabled" ] [workspace.dependencies.clone_dyn_types] -version = "~0.22.0" +version = "~0.23.0" path = "module/core/clone_dyn_types" default-features = false features = [ "enabled" ] @@ -201,7 +201,7 @@ default-features = false ## iter [workspace.dependencies.iter_tools] -version = "~0.20.0" +version = "~0.21.0" path = "module/core/iter_tools" default-features = false @@ -219,7 +219,7 @@ path = "module/core/for_each" default-features = false [workspace.dependencies.former] -version = "~2.8.0" +version = "~2.9.0" path = "module/core/former" default-features = false @@ -229,12 +229,12 @@ default-features = false # default-features = false [workspace.dependencies.former_meta] -version = "~2.8.0" +version = "~2.9.0" path = "module/core/former_meta" default-features = false [workspace.dependencies.former_types] -version = "~2.7.0" +version = "~2.8.0" path = "module/core/former_types" default-features = false @@ -248,12 +248,12 @@ version = "~0.7.0" path = "module/core/impls_index_meta" [workspace.dependencies.mod_interface] -version = "~0.23.0" +version = "~0.24.0" path = "module/core/mod_interface" default-features = false [workspace.dependencies.mod_interface_meta] -version = "~0.23.0" +version = "~0.24.0" path = "module/core/mod_interface_meta" default-features = false @@ -279,7 +279,7 @@ default-features = false ## macro tools [workspace.dependencies.macro_tools] -version = "~0.39.0" +version = "~0.40.0" path = "module/core/macro_tools" default-features = false @@ -333,7 +333,7 @@ default-features = false ## error [workspace.dependencies.error_tools] -version = "~0.16.0" +version = "~0.17.0" path = "module/core/error_tools" default-features = false @@ -345,7 +345,7 @@ path = "module/alias/werror" ## string tools [workspace.dependencies.strs_tools] -version = "~0.16.0" +version = "~0.17.0" path = "module/core/strs_tools" default-features = false @@ -367,7 +367,7 @@ path = "module/alias/file_tools" default-features = false [workspace.dependencies.proper_path_tools] -version = "~0.9.0" +version = "~0.10.0" path = "module/core/proper_path_tools" default-features = false @@ -375,7 +375,7 @@ default-features = false ## process tools [workspace.dependencies.process_tools] -version = "~0.8.0" +version = "~0.9.0" path = "module/core/process_tools" default-features = false @@ -422,7 +422,7 @@ default-features = false ## ca [workspace.dependencies.wca] -version = "~0.20.0" +version = "~0.21.0" path = "module/move/wca" @@ -436,7 +436,7 @@ path = "module/move/wcensor" ## willbe [workspace.dependencies.willbe] -version = "~0.14.0" +version = "~0.15.0" path = "module/move/willbe" @@ -476,7 +476,7 @@ version = "~0.5.0" path = "module/move/deterministic_rand" [workspace.dependencies.crates_tools] -version = "~0.12.0" +version = "~0.13.0" path = "module/move/crates_tools" diff --git a/module/core/clone_dyn/Cargo.toml b/module/core/clone_dyn/Cargo.toml index 922f03fc69..df7631e07c 100644 --- a/module/core/clone_dyn/Cargo.toml +++ b/module/core/clone_dyn/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clone_dyn" -version = "0.23.0" +version = "0.24.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", diff --git a/module/core/clone_dyn_meta/Cargo.toml b/module/core/clone_dyn_meta/Cargo.toml index 35a9783798..2359fb19c7 100644 --- a/module/core/clone_dyn_meta/Cargo.toml +++ b/module/core/clone_dyn_meta/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clone_dyn_meta" -version = "0.23.0" +version = "0.24.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", diff --git a/module/core/clone_dyn_types/Cargo.toml b/module/core/clone_dyn_types/Cargo.toml index 9c5db44b4a..b9c3e6ee14 100644 --- a/module/core/clone_dyn_types/Cargo.toml +++ b/module/core/clone_dyn_types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clone_dyn_types" -version = "0.22.0" +version = "0.23.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", diff --git a/module/core/collection_tools/Cargo.toml b/module/core/collection_tools/Cargo.toml index 303edaa2df..58c96881f9 100644 --- a/module/core/collection_tools/Cargo.toml +++ b/module/core/collection_tools/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "collection_tools" -version = "0.11.0" +version = "0.12.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", diff --git a/module/core/collection_tools/src/lib.rs b/module/core/collection_tools/src/lib.rs index 5d0c5976a4..e447f16f85 100644 --- a/module/core/collection_tools/src/lib.rs +++ b/module/core/collection_tools/src/lib.rs @@ -64,7 +64,7 @@ pub mod exposed pub use prelude::*; #[ doc( inline ) ] - #[ cfg( feature = "collection_constructors" ) ] + #[ cfg( any( feature = "use_alloc", all( feature = "collection_constructors", not( feature = "no_std" ) ) ) ) ] pub use crate:: { vec as dlist, @@ -77,7 +77,7 @@ pub mod exposed }; #[ doc( inline ) ] - #[ cfg( feature = "collection_into_constructors" ) ] + #[ cfg( any( feature = "use_alloc", all( feature = "collection_into_constructors", not( feature = "no_std" ) ) ) ) ] pub use crate:: { into_vec, diff --git a/module/core/collection_tools/tests/inc/deque.rs b/module/core/collection_tools/tests/inc/deque.rs index 41c3d323b1..98ab6498bd 100644 --- a/module/core/collection_tools/tests/inc/deque.rs +++ b/module/core/collection_tools/tests/inc/deque.rs @@ -50,8 +50,8 @@ fn into_constructor() exp.push_front( 3 ); assert_eq!( got, exp ); - let _got : DequeList< &str > = the_module::deque!( "b" ); - let _got : DequeList< &str > = the_module::exposed::deque!( "b" ); + let _got = the_module::deque!( "b" ); + let _got = the_module::exposed::deque!( "b" ); } diff --git a/module/core/collection_tools/tests/inc/vec.rs b/module/core/collection_tools/tests/inc/vec.rs index ff9480659f..c1a5f66804 100644 --- a/module/core/collection_tools/tests/inc/vec.rs +++ b/module/core/collection_tools/tests/inc/vec.rs @@ -1,6 +1,7 @@ use super::*; #[ test ] +#[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] fn reexport() { @@ -12,7 +13,8 @@ fn reexport() let got = vec1.last().unwrap().clone(); assert_eq!( got, 2 ); - let mut vec2 : the_module::DynList< i32 > = the_module::DynList::new(); + use std::vec::Vec as DynList; + let mut vec2 : DynList< i32 > = DynList::new(); vec2.push( 1 ); vec2.push( 2 ); let got = vec2.first().unwrap().clone(); diff --git a/module/core/data_type/Cargo.toml b/module/core/data_type/Cargo.toml index 0328fc7e83..f42fae69bd 100644 --- a/module/core/data_type/Cargo.toml +++ b/module/core/data_type/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "data_type" -version = "0.9.0" +version = "0.10.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", diff --git a/module/core/derive_tools/Cargo.toml b/module/core/derive_tools/Cargo.toml index 3d8f47c0cc..d41086762e 100644 --- a/module/core/derive_tools/Cargo.toml +++ b/module/core/derive_tools/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "derive_tools" -version = "0.27.0" +version = "0.28.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", diff --git a/module/core/derive_tools_meta/Cargo.toml b/module/core/derive_tools_meta/Cargo.toml index 3ab4e3998c..b931c9806a 100644 --- a/module/core/derive_tools_meta/Cargo.toml +++ b/module/core/derive_tools_meta/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "derive_tools_meta" -version = "0.26.0" +version = "0.27.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", diff --git a/module/core/error_tools/Cargo.toml b/module/core/error_tools/Cargo.toml index 1ea9fe9535..62f8ec7e88 100644 --- a/module/core/error_tools/Cargo.toml +++ b/module/core/error_tools/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "error_tools" -version = "0.16.0" +version = "0.17.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", diff --git a/module/core/format_tools/Readme.md b/module/core/format_tools/Readme.md index 19543ef6f4..6fe6e41b5f 100644 --- a/module/core/format_tools/Readme.md +++ b/module/core/format_tools/Readme.md @@ -15,66 +15,70 @@ Using the `to_string_with_fallback` macro to convert values to strings with a pr ```rust fn main() { - // Import necessary traits and the macro from the `format_tools` crate. - use core::fmt; - use format_tools:: + #[ cfg( feature = "enabled" ) ] { - WithDebug, - WithDisplay, - to_string_with_fallback, - }; - // Define a struct that implements both Debug and Display traits. - struct Both; + // Import necessary traits and the macro from the `format_tools` crate. + use core::fmt; + use format_tools:: + { + WithDebug, + WithDisplay, + to_string_with_fallback, + }; - // Implement the Debug trait for the Both struct. - impl fmt::Debug for Both - { - fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> fmt::Result + // Define a struct that implements both Debug and Display traits. + struct Both; + + // Implement the Debug trait for the Both struct. + impl fmt::Debug for Both { - write!( f, "This is debug" ) + fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> fmt::Result + { + write!( f, "This is debug" ) + } } - } - // Implement the Display trait for the Both struct. - impl fmt::Display for Both - { - fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> fmt::Result + // Implement the Display trait for the Both struct. + impl fmt::Display for Both { - write!( f, "This is display" ) + fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> fmt::Result + { + write!( f, "This is display" ) + } } - } - // Define a struct that implements only the Debug trait. - struct OnlyDebug; + // Define a struct that implements only the Debug trait. + struct OnlyDebug; - // Implement the Debug trait for the OnlyDebug struct. - impl fmt::Debug for OnlyDebug - { - fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> fmt::Result + // Implement the Debug trait for the OnlyDebug struct. + impl fmt::Debug for OnlyDebug { - write!( f, "This is debug" ) + fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> fmt::Result + { + write!( f, "This is debug" ) + } } - } - - // Example usage: Using Both which implements both Debug and Display. - let src = Both; - // Convert the struct to a string using `to_string_with_fallback` macro. - // The primary formatting method WithDisplay is used. - let got = to_string_with_fallback!( WithDisplay, WithDebug, &src ); - let exp = "This is display".to_string(); - // Assert that the result matches the expected value. - assert_eq!( got, exp ); - - // Example usage: Using OnlyDebug which implements only Debug. - let src = OnlyDebug; - // Convert the struct to a string using `to_string_with_fallback` macro. - // The primary formatting method WithDisplay is not available, so the fallback WithDebug is used. - let got = to_string_with_fallback!( WithDisplay, WithDebug, &src ); - let exp = "This is debug".to_string(); - // Assert that the result matches the expected value. - assert_eq!( got, exp ); + // Example usage: Using Both which implements both Debug and Display. + let src = Both; + // Convert the struct to a string using `to_string_with_fallback` macro. + // The primary formatting method WithDisplay is used. + let got = to_string_with_fallback!( WithDisplay, WithDebug, &src ); + let exp = "This is display".to_string(); + // Assert that the result matches the expected value. + assert_eq!( got, exp ); + + // Example usage: Using OnlyDebug which implements only Debug. + let src = OnlyDebug; + // Convert the struct to a string using `to_string_with_fallback` macro. + // The primary formatting method WithDisplay is not available, so the fallback WithDebug is used. + let got = to_string_with_fallback!( WithDisplay, WithDebug, &src ); + let exp = "This is debug".to_string(); + // Assert that the result matches the expected value. + assert_eq!( got, exp ); + + } } ``` diff --git a/module/core/format_tools/examples/format_tools_trivial.rs b/module/core/format_tools/examples/format_tools_trivial.rs index 6683ab3f4a..bd7c7208c9 100644 --- a/module/core/format_tools/examples/format_tools_trivial.rs +++ b/module/core/format_tools/examples/format_tools_trivial.rs @@ -5,64 +5,68 @@ fn main() { - // Import necessary traits and the macro from the `format_tools` crate. - use core::fmt; - use format_tools:: + #[ cfg( feature = "enabled" ) ] { - WithDebug, - WithDisplay, - to_string_with_fallback, - }; - // Define a struct that implements both Debug and Display traits. - struct Both; + // Import necessary traits and the macro from the `format_tools` crate. + use core::fmt; + use format_tools:: + { + WithDebug, + WithDisplay, + to_string_with_fallback, + }; - // Implement the Debug trait for the Both struct. - impl fmt::Debug for Both - { - fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> fmt::Result + // Define a struct that implements both Debug and Display traits. + struct Both; + + // Implement the Debug trait for the Both struct. + impl fmt::Debug for Both { - write!( f, "This is debug" ) + fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> fmt::Result + { + write!( f, "This is debug" ) + } } - } - // Implement the Display trait for the Both struct. - impl fmt::Display for Both - { - fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> fmt::Result + // Implement the Display trait for the Both struct. + impl fmt::Display for Both { - write!( f, "This is display" ) + fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> fmt::Result + { + write!( f, "This is display" ) + } } - } - // Define a struct that implements only the Debug trait. - struct OnlyDebug; + // Define a struct that implements only the Debug trait. + struct OnlyDebug; - // Implement the Debug trait for the OnlyDebug struct. - impl fmt::Debug for OnlyDebug - { - fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> fmt::Result + // Implement the Debug trait for the OnlyDebug struct. + impl fmt::Debug for OnlyDebug { - write!( f, "This is debug" ) + fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> fmt::Result + { + write!( f, "This is debug" ) + } } - } - // Example usage: Using Both which implements both Debug and Display. - let src = Both; - // Convert the struct to a string using `to_string_with_fallback` macro. - // The primary formatting method WithDisplay is used. - let got = to_string_with_fallback!( WithDisplay, WithDebug, &src ); - let exp = "This is display".to_string(); - // Assert that the result matches the expected value. - assert_eq!( got, exp ); - - // Example usage: Using OnlyDebug which implements only Debug. - let src = OnlyDebug; - // Convert the struct to a string using `to_string_with_fallback` macro. - // The primary formatting method WithDisplay is not available, so the fallback WithDebug is used. - let got = to_string_with_fallback!( WithDisplay, WithDebug, &src ); - let exp = "This is debug".to_string(); - // Assert that the result matches the expected value. - assert_eq!( got, exp ); + // Example usage: Using Both which implements both Debug and Display. + let src = Both; + // Convert the struct to a string using `to_string_with_fallback` macro. + // The primary formatting method WithDisplay is used. + let got = to_string_with_fallback!( WithDisplay, WithDebug, &src ); + let exp = "This is display".to_string(); + // Assert that the result matches the expected value. + assert_eq!( got, exp ); + // Example usage: Using OnlyDebug which implements only Debug. + let src = OnlyDebug; + // Convert the struct to a string using `to_string_with_fallback` macro. + // The primary formatting method WithDisplay is not available, so the fallback WithDebug is used. + let got = to_string_with_fallback!( WithDisplay, WithDebug, &src ); + let exp = "This is debug".to_string(); + // Assert that the result matches the expected value. + assert_eq!( got, exp ); + + } } \ No newline at end of file diff --git a/module/core/format_tools/src/format/md_math.rs b/module/core/format_tools/src/format/md_math.rs index a53625fc21..d4de6ae6af 100644 --- a/module/core/format_tools/src/format/md_math.rs +++ b/module/core/format_tools/src/format/md_math.rs @@ -29,7 +29,20 @@ mod private /// # Returns /// /// A value of type `T` representing the flat offset. - fn md_offset( & self, md_index : [ T ; 3 ] ) -> T; + fn md_offset( & self, md_index : Self ) -> T; + } + + impl< T > MdOffset< T > for [ T ; 2 ] + where + T : Mul< T, Output = T > + Add< T, Output = T > + PartialOrd + Copy + fmt::Debug, + { + fn md_offset( & self, md_index : [ T ; 2 ] ) -> T + { + debug_assert!( md_index[ 0 ] < self[ 0 ], "md_index : {md_index:?} | md_size : {self:?}" ); + debug_assert!( md_index[ 1 ] < self[ 1 ], "md_index : {md_index:?} | md_size : {self:?}" ); + let m1 = self[ 0 ]; + md_index[ 0 ] + m1 * md_index[ 1 ] + } } impl< T > MdOffset< T > for [ T ; 3 ] diff --git a/module/core/format_tools/src/format/output_format/records.rs b/module/core/format_tools/src/format/output_format/records.rs index 263177edb8..45a1206e41 100644 --- a/module/core/format_tools/src/format/output_format/records.rs +++ b/module/core/format_tools/src/format/output_format/records.rs @@ -39,7 +39,49 @@ use std::sync::OnceLock; /// `Records` provides an implementation for table formatting that outputs /// each row as a separate table with 2 columns, first is name of column in the original data and second is cell value itself. #[derive( Debug )] -pub struct Records; +pub struct Records +{ + /// Prefix added to each row. + pub table_prefix : String, + /// Postfix added to each row. + pub table_postfix : String, + /// Separator used between rows. + pub table_separator : String, + /// Prefix added to each row. + pub row_prefix : String, + /// Postfix added to each row. + pub row_postfix : String, + /// Separator used between rows. + pub row_separator : String, + /// Prefix added to each cell. + pub cell_prefix : String, + /// Postfix added to each cell. + pub cell_postfix : String, + /// Separator used between table columns. + pub cell_separator : String, + // /// Horizontal line character. + // pub h : char, + // /// Vertical line character. + // pub v : char, + // /// Left T-junction character. + // pub t_l : char, + // /// Right T-junction character. + // pub t_r : char, + // /// Top T-junction character. + // pub t_t : char, + // /// Bottom T-junction character. + // pub t_b : char, + // /// Cross junction character. + // pub cross : char, + // /// Top-left corner character. + // pub corner_lt : char, + // /// Top-right corner character. + // pub corner_rt : char, + // /// Bottom-left corner character. + // pub corner_lb : char, + // /// Bottom-right corner character. + // pub corner_rb : char, +} impl Records { @@ -47,7 +89,7 @@ impl Records pub fn instance() -> & 'static dyn TableOutputFormat { static INSTANCE : OnceLock< Records > = OnceLock::new(); - INSTANCE.get_or_init( || Records ) + INSTANCE.get_or_init( || Records::default() ) } } @@ -55,36 +97,128 @@ impl Default for Records { fn default() -> Self { + + let cell_prefix = "".to_string(); + let cell_postfix = "".to_string(); + let cell_separator = " │ ".to_string(); + let row_prefix = "│ ".to_string(); + let row_postfix = " │".to_string(); + let row_separator = "\n".to_string(); + let table_prefix = "".to_string(); + let table_postfix = "".to_string(); + let table_separator = "\n".to_string(); + + // let h = '─'; + // let v = '|'; + // let t_l = '├'; + // let t_r = '┤'; + // let t_t = '┬'; + // let t_b = '┴'; + // let cross = '┼'; + // let corner_lt = '┌'; + // let corner_rt = '┐'; + // let corner_lb = '└'; + // let corner_rb = '┘'; + Self { + table_prefix, + table_postfix, + table_separator, + row_prefix, + row_postfix, + row_separator, + cell_prefix, + cell_postfix, + cell_separator, + // h, + // v, + // t_l, + // t_r, + // t_t, + // t_b, + // cross, + // corner_lt, + // corner_rt, + // corner_lb, + // corner_rb, } } } impl TableOutputFormat for Records { - fn extract_write< 'buf, 'data > - ( + + fn extract_write< 'buf, 'data >( & self, x : & InputExtract< 'data >, c : & mut Context< 'buf >, ) -> fmt::Result { - for ( i, row ) in x.row_descriptors.iter().enumerate() + + let label_width = x.header().fold( 0, | acc, cell | acc.max( cell.1[ 0 ] ) ); + + write!( c.buf, "{}", self.table_prefix )?; + + let mut first = true; + // Write each record + for ( irow, row ) in x.rows() { + if !row.vis { continue; } - writeln!( c.buf, "-[ RECORD {} ]", i + 1 )?; - for ( icol, col ) in x.col_descriptors.iter().enumerate() + + if first + { + first = false; + } + else + { + write!( c.buf, "{}", self.table_separator )?; + } + + let slice_width = x.data[ irow ].iter().fold( 0, | acc, cell | acc.max( cell.1[ 0 ] ) ); + + writeln!( c.buf, " = {}", irow )?; + + for ( icol, _col ) in x.col_descriptors.iter().enumerate() { - // let cell_width = x.data[ i ][ icol ].1[ 0 ]; - let md_index = [ 0, icol, i ]; - let slice = x.slices[ x.slices_dim.md_offset( md_index ) ]; - writeln!( c.buf, "{} | {}", col.width, slice )?; + let cell = &x.data[ irow ][ icol ]; + let height = cell.1[ 1 ]; + + for islice in 0..height + { + let label = x.header_slice( islice, icol ); + let md_index = [ islice, icol, irow ]; + let slice = x.slices[ x.slices_dim.md_offset( md_index ) ]; + + if icol > 0 || islice > 0 + { + write!( c.buf, "{}", self.row_separator )?; + } + + write!( c.buf, "{}", self.row_prefix )?; + + write!( c.buf, "{}", self.cell_prefix )?; + write!( c.buf, "{: { pub icol : usize, pub width : usize, + pub label : &'label str, } /// A struct for extracting and organizing table data for formatting. @@ -270,21 +273,17 @@ mod private /// Descriptors for each column, including optional title, width, and index. // width, index - // pub col_descriptors : Vec< ( usize, usize ) >, - pub col_descriptors : Vec< ColDescriptor >, + pub col_descriptors : Vec< ColDescriptor< 'data > >, /// Descriptors for each row, including height. - // height - // pub row_descriptors : Vec< ( usize, ) >, pub row_descriptors : Vec< RowDescriptor >, /// Extracted data for each cell, including string content and size. // string, size, - pub data : Vec< Vec< ( Cow< 'data, str >, [ usize ; 2 ] ) > >, + pub data : Vec< Vec< ( Cow< 'data, str >, [ usize ; 2 ] ) > >, // xxx : use maybe flat vector /// Dimensions of slices for retrieving data from multi-matrix. pub slices_dim : [ usize ; 3 ], - /// Extracted slices or strings for further processing. pub slices : Vec< &'data str >, @@ -295,6 +294,76 @@ mod private impl< 'data > InputExtract< 'data > { + /// Returns an iterator over the row descriptors, skipping the header if present. + /// + /// This function provides an iterator that yields each row descriptor along with its index. + /// If the table has a header, the first row is skipped, ensuring that iteration starts from + /// the first data row. + /// + /// # Returns + /// + /// An iterator over tuples containing: + /// - `usize`: The index of the row. + /// - `&RowDescriptor`: A reference to the row descriptor. + /// + pub fn rows( & self ) -> impl _IteratorTrait< Item = ( usize, &RowDescriptor ) > + { + self.row_descriptors + .iter() + .enumerate() + .skip( if self.has_header { 1 } else { 0 } ) + } + + /// Returns an iterator over the header cells, or a default value if no header is present. + /// + /// This function provides an iterator that yields each cell in the header row. If the table + /// does not have a header, it returns an iterator over default values, which are empty strings + /// with a size of `[0, 1]`. + /// + /// # Returns + /// + /// A boxed iterator yielding tuples containing: + /// - `Cow<'data, str>`: A clone-on-write string representing the cell content. + /// - `[usize; 2]`: An array representing the size of the cell. + /// + pub fn header( & self ) -> Box< dyn Iterator< Item = ( Cow< 'data, str >, [ usize ; 2 ] ) > + '_ > + { + if self.has_header + { + Box::new( self.data[ 0 ].iter().cloned() ) + } + else + { + Box::new( std::iter::repeat( ( Cow::Borrowed( "" ), [ 0, 1 ] ) ).take( self.mcells[ 0 ] ) ) + } + } + + /// Returns a slice from the header, or an empty string if no header is present. + /// + /// This function retrieves a specific slice from the header row based on the provided indices. + /// If the table does not have a header, it returns an empty string. + /// + /// # Arguments + /// + /// - `islice`: The slice index within the header cell. + /// - `icol`: The column index within the header row. + /// + /// # Returns + /// + /// A string slice representing the header content at the specified indices. + /// + pub fn header_slice( & self, islice : usize, icol : usize ) -> & str + { + if self.has_header + { + let md_index = [ islice, icol, 0 ]; + self.slices[ self.slices_dim.md_offset( md_index ) ] + } + else + { + "" + } + } /// Extract input data from and collect it in a format consumable by output formatter. pub fn extract< 't, 'context, Table, RowKey, Row, CellKey, CellRepr > ( @@ -306,6 +375,7 @@ mod private -> fmt::Result where 'data : 't, + // 't : 'data, Table : TableRows< RowKey = RowKey, Row = Row, CellKey = CellKey, CellRepr = CellRepr >, Table : TableHeader< CellKey = CellKey >, RowKey : table::RowKey, @@ -323,7 +393,7 @@ mod private // key width, index let mut key_to_ikey : HashMap< &'t CellKey, usize > = HashMap::new(); - let mut col_descriptors : Vec< ColDescriptor > = Vec::with_capacity( mcells[ 0 ] ); + let mut col_descriptors : Vec< ColDescriptor< '_ > > = Vec::with_capacity( mcells[ 0 ] ); let mut row_descriptors : Vec< RowDescriptor > = Vec::with_capacity( mcells[ 1 ] ); let mut has_header = false; @@ -377,12 +447,13 @@ mod private { let col = &mut col_descriptors[ *icol ]; col.width = col.width.max( sz[ 0 ] ); + col.label = ""; }) .or_insert_with( || { let icol = l; let width = sz[ 0 ]; - let col = ColDescriptor { width, icol }; + let col = ColDescriptor { width, icol, label : "" }; col_descriptors.push( col ); icol }); @@ -496,7 +567,6 @@ mod private std::mem::swap( &mut x.slices, &mut slices ); let mut irow : isize = -1; - for row_data in x.data.iter() { @@ -513,6 +583,7 @@ mod private slices[ x.slices_dim.md_offset( md_index ) ] = s; }) ; + x.col_descriptors[ icol ].label = cell.0.as_ref(); } } diff --git a/module/core/format_tools/tests/inc/collection_test.rs b/module/core/format_tools/tests/inc/collection_test.rs index 941f9a498b..7e1607820e 100644 --- a/module/core/format_tools/tests/inc/collection_test.rs +++ b/module/core/format_tools/tests/inc/collection_test.rs @@ -12,7 +12,6 @@ use the_module:: use std:: { collections::HashMap, - // borrow::Cow, }; use test_object::TestObject; @@ -185,4 +184,220 @@ fn bmap_basic() } +#[ test ] +fn bset_basic() +{ + + let data : collection_tools::Bset< TestObject > = bset! + { + TestObject + { + id : "1".to_string(), + created_at : 1627845583, + file_ids : vec![ "file1".to_string(), "file2".to_string() ], + tools : None + }, + TestObject + { + id : "2".to_string(), + created_at : 13, + file_ids : vec![ "file3".to_string(), "file4\nmore details".to_string() ], + tools : Some + ( + vec! + [ + { + let mut map = HashMap::new(); + map.insert( "tool1".to_string(), "value1".to_string() ); + map + }, + { + let mut map = HashMap::new(); + map.insert( "tool2".to_string(), "value2".to_string() ); + map + } + ] + ), + }, + }; + + use the_module::TableFormatter; + let _as_table : AsTable< '_, BTreeSet< TestObject >, &str, TestObject, str, WithRef > = AsTable::new( &data ); + let as_table = AsTable::new( &data ); + + let rows = TableRows::rows( &as_table ); + assert_eq!( rows.len(), 2 ); + + let mut output = String::new(); + let mut context = print::Context::new( &mut output, Default::default() ); + let _got = the_module::TableFormatter::fmt( &as_table, &mut context ); + let got = as_table.table_to_string(); + assert!( got.contains( "│ id │ created_at │ file_ids │ tools │" ) ); + assert!( got.contains( "│ 13 │ [ │ [ │" ) ); + assert!( got.contains( "│ 1627845583 │ [ │ │" ) ); + +} + +#[ test ] +fn deque_basic() +{ + + let data : collection_tools::Deque< TestObject > = deque! + { + TestObject + { + id : "1".to_string(), + created_at : 1627845583, + file_ids : vec![ "file1".to_string(), "file2".to_string() ], + tools : None + }, + TestObject + { + id : "2".to_string(), + created_at : 13, + file_ids : vec![ "file3".to_string(), "file4\nmore details".to_string() ], + tools : Some + ( + vec! + [ + { + let mut map = HashMap::new(); + map.insert( "tool1".to_string(), "value1".to_string() ); + map + }, + { + let mut map = HashMap::new(); + map.insert( "tool2".to_string(), "value2".to_string() ); + map + } + ] + ), + }, + }; + + use the_module::TableFormatter; + let _as_table : AsTable< '_, VecDeque< TestObject >, &str, TestObject, str, WithRef > = AsTable::new( &data ); + let as_table = AsTable::new( &data ); + + let rows = TableRows::rows( &as_table ); + assert_eq!( rows.len(), 2 ); + + let mut output = String::new(); + let mut context = print::Context::new( &mut output, Default::default() ); + let _got = the_module::TableFormatter::fmt( &as_table, &mut context ); + let got = as_table.table_to_string(); + assert!( got.contains( "│ id │ created_at │ file_ids │ tools │" ) ); + assert!( got.contains( "│ 13 │ [ │ [ │" ) ); + assert!( got.contains( "│ 1627845583 │ [ │ │" ) ); + +} + +#[ test ] +fn hset_basic() +{ + + let data : collection_tools::Hset< TestObject > = hset! + { + TestObject + { + id : "1".to_string(), + created_at : 1627845583, + file_ids : vec![ "file1".to_string(), "file2".to_string() ], + tools : None + }, + TestObject + { + id : "2".to_string(), + created_at : 13, + file_ids : vec![ "file3".to_string(), "file4\nmore details".to_string() ], + tools : Some + ( + vec! + [ + { + let mut map = HashMap::new(); + map.insert( "tool1".to_string(), "value1".to_string() ); + map + }, + { + let mut map = HashMap::new(); + map.insert( "tool2".to_string(), "value2".to_string() ); + map + } + ] + ), + }, + }; + + use the_module::TableFormatter; + let _as_table : AsTable< '_, HashSet< TestObject >, &str, TestObject, str, WithRef > = AsTable::new( &data ); + let as_table = AsTable::new( &data ); + + let rows = TableRows::rows( &as_table ); + assert_eq!( rows.len(), 2 ); + + let mut output = String::new(); + let mut context = print::Context::new( &mut output, Default::default() ); + let _got = the_module::TableFormatter::fmt( &as_table, &mut context ); + let got = as_table.table_to_string(); + assert!( got.contains( "│ id │ created_at │ file_ids │ tools │" ) ); + assert!( got.contains( "│ 13 │ [ │ [ │" ) ); + assert!( got.contains( "│ 1627845583 │ [ │ │" ) ); + +} + +#[ test ] +fn llist_basic() +{ + + let data : collection_tools::Llist< TestObject > = llist! + { + TestObject + { + id : "1".to_string(), + created_at : 1627845583, + file_ids : vec![ "file1".to_string(), "file2".to_string() ], + tools : None + }, + TestObject + { + id : "2".to_string(), + created_at : 13, + file_ids : vec![ "file3".to_string(), "file4\nmore details".to_string() ], + tools : Some + ( + vec! + [ + { + let mut map = HashMap::new(); + map.insert( "tool1".to_string(), "value1".to_string() ); + map + }, + { + let mut map = HashMap::new(); + map.insert( "tool2".to_string(), "value2".to_string() ); + map + } + ] + ), + }, + }; + + use the_module::TableFormatter; + let _as_table : AsTable< '_, LinkedList< TestObject >, &str, TestObject, str, WithRef > = AsTable::new( &data ); + let as_table = AsTable::new( &data ); + + let rows = TableRows::rows( &as_table ); + assert_eq!( rows.len(), 2 ); + + let mut output = String::new(); + let mut context = print::Context::new( &mut output, Default::default() ); + let _got = the_module::TableFormatter::fmt( &as_table, &mut context ); + let got = as_table.table_to_string(); + assert!( got.contains( "│ id │ created_at │ file_ids │ tools │" ) ); + assert!( got.contains( "│ 13 │ [ │ [ │" ) ); + assert!( got.contains( "│ 1627845583 │ [ │ │" ) ); + +} + // qqq : xxx : implement for other containers diff --git a/module/core/format_tools/tests/inc/format_ordinary_test.rs b/module/core/format_tools/tests/inc/format_ordinary_test.rs index f0854cd6c0..5dbe2a95d2 100644 --- a/module/core/format_tools/tests/inc/format_ordinary_test.rs +++ b/module/core/format_tools/tests/inc/format_ordinary_test.rs @@ -324,3 +324,5 @@ fn filter_row_callback() } // + +// xxx : implement test for vector of vectors diff --git a/module/core/format_tools/tests/inc/format_records_test.rs b/module/core/format_tools/tests/inc/format_records_test.rs index c1e2cf2b26..8325dea020 100644 --- a/module/core/format_tools/tests/inc/format_records_test.rs +++ b/module/core/format_tools/tests/inc/format_records_test.rs @@ -5,16 +5,16 @@ use the_module:: { AsTable, WithRef, - // filter, + filter, print, output_format, }; -// use std:: -// { -// // collections::HashMap, -// // borrow::Cow, -// }; +use std:: +{ + // collections::HashMap, + borrow::Cow, +}; // @@ -34,287 +34,286 @@ fn basic() assert!( got.is_ok() ); println!( "{}", &output ); - // -[ RECORD 1 ] - // sid | 3 - // sname | Alice - // gap | 5 - // -[ RECORD 2 ] - // sid | 6 - // sname | Joe - // gap | 1 - // -[ RECORD 3 ] - // sid | 10 - // sname | Boris - // gap | 5 - - let exp = r#"xxx"#; - // a_id!( output.as_str(), exp ); + let exp = r#" = 1 +│ id │ 1 │ +│ created_at │ 1627845583 │ +│ file_ids │ [ │ +│ │ "file1", │ +│ │ "file2", │ +│ │ ] │ +│ tools │ │ + = 2 +│ id │ 2 │ +│ created_at │ 13 │ +│ file_ids │ [ │ +│ │ "file3", │ +│ │ "file4\nmore details", │ +│ │ ] │ +│ tools │ [ │ +│ │ { │ +│ │ "tool1": "value1", │ +│ │ }, │ +│ │ { │ +│ │ "tool2": "value2", │ +│ │ }, │ +│ │ ] │"#; + a_id!( output.as_str(), exp ); } // -// #[ test ] -// fn table_to_string() -// { -// use the_module::TableFormatter; -// let test_objects = test_object::test_objects_gen(); -// -// // with explicit arguments -// -// let as_table : AsTable< '_, Vec< test_object::TestObject >, usize, test_object::TestObject, str, WithRef > = AsTable::new( &test_objects ); -// let table_string = as_table.table_to_string(); -// println!( "\ntable_string\n{table_string}" ); -// assert!( table_string.contains( "id" ) ); -// assert!( table_string.contains( "created_at" ) ); -// assert!( table_string.contains( "file_ids" ) ); -// assert!( table_string.contains( "tools" ) ); -// -// // without explicit arguments -// -// println!( "" ); -// let as_table = AsTable::new( &test_objects ); -// let table_string = as_table.table_to_string(); -// assert!( table_string.contains( "id" ) ); -// assert!( table_string.contains( "created_at" ) ); -// assert!( table_string.contains( "file_ids" ) ); -// assert!( table_string.contains( "tools" ) ); -// println!( "\ntable_string\n{table_string}" ); -// -// } -// -// // -// -// #[ test ] -// fn custom_format() -// { -// // use the_module::TableFormatter; -// let test_objects = test_object::test_objects_gen(); -// -// let mut format = output_format::Ordinary::default(); -// format.cell_prefix = "( ".into(); -// format.cell_postfix = " )".into(); -// format.cell_separator = "|".into(); -// format.row_prefix = ">".into(); -// format.row_postfix = "<".into(); -// format.row_separator = "\n".into(); -// -// let printer = print::Printer::with_format( &format ); -// let as_table = AsTable::new( &test_objects ); -// let mut output = String::new(); -// let mut context = print::Context::new( &mut output, printer ); -// let result = the_module::TableFormatter::fmt( &as_table, &mut context ); -// assert!( result.is_ok() ); -// -// println!( "\noutput\n{output}" ); -// assert!( output.contains( "id" ) ); -// assert!( output.contains( "created_at" ) ); -// assert!( output.contains( "file_ids" ) ); -// assert!( output.contains( "tools" ) ); -// -// let exp = r#">( id )|( created_at )|( file_ids )|( tools )< -// ───────────────────────────────────────────────────────────────────────────────────── -// >( 1 )|( 1627845583 )|( [ )|( )< -// >( )|( )|( "file1", )|( )< -// >( )|( )|( "file2", )|( )< -// >( )|( )|( ] )|( )< -// >( 2 )|( 13 )|( [ )|( [ )< -// >( )|( )|( "file3", )|( { )< -// >( )|( )|( "file4\nmore details", )|( "tool1": "value1", )< -// >( )|( )|( ] )|( }, )< -// >( )|( )|( )|( { )< -// >( )|( )|( )|( "tool2": "value2", )< -// >( )|( )|( )|( }, )< -// >( )|( )|( )|( ] )<"#; -// a_id!( output.as_str(), exp ); -// -// // using table_to_string_with_format -// -// use the_module::TableFormatter; -// -// let mut format = output_format::Ordinary::default(); -// format.cell_prefix = "( ".into(); -// format.cell_postfix = " )".into(); -// format.cell_separator = "|".into(); -// format.row_prefix = ">".into(); -// format.row_postfix = "<".into(); -// format.row_separator = "\n".into(); -// -// // let as_table = AsTable::new( &test_objects ); -// let got = AsTable::new( &test_objects ).table_to_string_with_format( &format ); -// let exp = r#">( id )|( created_at )|( file_ids )|( tools )< -// ───────────────────────────────────────────────────────────────────────────────────── -// >( 1 )|( 1627845583 )|( [ )|( )< -// >( )|( )|( "file1", )|( )< -// >( )|( )|( "file2", )|( )< -// >( )|( )|( ] )|( )< -// >( 2 )|( 13 )|( [ )|( [ )< -// >( )|( )|( "file3", )|( { )< -// >( )|( )|( "file4\nmore details", )|( "tool1": "value1", )< -// >( )|( )|( ] )|( }, )< -// >( )|( )|( )|( { )< -// >( )|( )|( )|( "tool2": "value2", )< -// >( )|( )|( )|( }, )< -// >( )|( )|( )|( ] )<"#; -// a_id!( got, exp ); -// -// } -// -// -// -// #[ test ] -// fn filter_col_none() -// { -// let test_objects = test_object::test_objects_gen(); -// -// let mut format = output_format::Ordinary::default(); -// format.cell_prefix = "( ".into(); -// format.cell_postfix = " )".into(); -// format.cell_separator = "|".into(); -// format.row_prefix = ">".into(); -// format.row_postfix = "<".into(); -// format.row_separator = "\n".into(); -// -// let mut printer = print::Printer::with_format( &format ); -// printer.filter_col = &filter::None; -// -// let as_table = AsTable::new( &test_objects ); -// let mut output = String::new(); -// let mut context = print::Context::new( &mut output, printer ); -// let result = the_module::TableFormatter::fmt( &as_table, &mut context ); -// assert!( result.is_ok() ); -// -// println!( "\noutput\n{output}" ); -// -// let exp = r#">< -// ── -// >< -// ><"#; -// -// a_id!( output.as_str(), exp ); -// -// } -// -// // -// -// #[ test ] -// fn filter_col_callback() -// { -// let test_objects = test_object::test_objects_gen(); -// -// let mut format = output_format::Ordinary::default(); -// format.cell_prefix = "( ".into(); -// format.cell_postfix = " )".into(); -// format.cell_separator = "|".into(); -// format.row_prefix = ">".into(); -// format.row_postfix = "<".into(); -// format.row_separator = "\n".into(); -// -// let mut printer = print::Printer::with_format( &format ); -// printer.filter_col = &| title : &str | -// { -// title != "tools" -// }; -// -// let as_table = AsTable::new( &test_objects ); -// let mut output = String::new(); -// let mut context = print::Context::new( &mut output, printer ); -// let result = the_module::TableFormatter::fmt( &as_table, &mut context ); -// assert!( result.is_ok() ); -// -// println!( "\noutput\n{output}" ); -// -// let exp = r#">( id )|( created_at )|( file_ids )< -// ────────────────────────────────────────────────────── -// >( 1 )|( 1627845583 )|( [ )< -// >( )|( )|( "file1", )< -// >( )|( )|( "file2", )< -// >( )|( )|( ] )< -// >( 2 )|( 13 )|( [ )< -// >( )|( )|( "file3", )< -// >( )|( )|( "file4\nmore details", )< -// >( )|( )|( ] )<"#; -// -// a_id!( output.as_str(), exp ); -// -// } -// -// // -// -// #[ test ] -// fn filter_row_none() -// { -// let test_objects = test_object::test_objects_gen(); -// -// let mut format = output_format::Ordinary::default(); -// format.cell_prefix = "( ".into(); -// format.cell_postfix = " )".into(); -// format.cell_separator = "|".into(); -// format.row_prefix = ">".into(); -// format.row_postfix = "<".into(); -// format.row_separator = "\n".into(); -// -// let mut printer = print::Printer::with_format( &format ); -// printer.filter_row = &filter::None; -// -// let as_table = AsTable::new( &test_objects ); -// let mut output = String::new(); -// let mut context = print::Context::new( &mut output, printer ); -// let result = the_module::TableFormatter::fmt( &as_table, &mut context ); -// assert!( result.is_ok() ); -// -// println!( "\noutput\n{output}" ); -// -// let exp = r#""#; -// -// a_id!( output.as_str(), exp ); -// -// } -// -// // -// -// #[ test ] -// fn filter_row_callback() -// { -// let test_objects = test_object::test_objects_gen(); -// -// let mut format = output_format::Ordinary::default(); -// format.cell_prefix = "( ".into(); -// format.cell_postfix = " )".into(); -// format.cell_separator = "|".into(); -// format.row_prefix = ">".into(); -// format.row_postfix = "<".into(); -// format.row_separator = "\n".into(); -// -// let mut printer = print::Printer::with_format( &format ); -// printer.filter_row = &| _typ, irow, _row : &[ ( Cow< '_, str >, [ usize ; 2 ] ) ] | -// { -// irow != 1 -// }; -// -// let as_table = AsTable::new( &test_objects ); -// let mut output = String::new(); -// let mut context = print::Context::new( &mut output, printer ); -// let result = the_module::TableFormatter::fmt( &as_table, &mut context ); -// assert!( result.is_ok() ); +#[ test ] +fn custom_format() +{ + // use the_module::TableFormatter; + let test_objects = test_object::test_objects_gen(); + + let mut format = output_format::Records::default(); + format.cell_prefix = "( ".into(); + format.cell_postfix = " )".into(); + format.cell_separator = "|".into(); + format.row_prefix = ">".into(); + format.row_postfix = "<".into(); + format.row_separator = "\n".into(); + + let printer = print::Printer::with_format( &format ); + let as_table = AsTable::new( &test_objects ); + let mut output = String::new(); + let mut context = print::Context::new( &mut output, printer ); + let result = the_module::TableFormatter::fmt( &as_table, &mut context ); + assert!( result.is_ok() ); + + println!( "\noutput\n{output}" ); + + let exp = r#" = 1 +>( id )|( 1 )< +>( created_at )|( 1627845583 )< +>( file_ids )|( [ )< +>( )|( "file1", )< +>( )|( "file2", )< +>( )|( ] )< +>( tools )|( )< + = 2 +>( id )|( 2 )< +>( created_at )|( 13 )< +>( file_ids )|( [ )< +>( )|( "file3", )< +>( )|( "file4\nmore details", )< +>( )|( ] )< +>( tools )|( [ )< +>( )|( { )< +>( )|( "tool1": "value1", )< +>( )|( }, )< +>( )|( { )< +>( )|( "tool2": "value2", )< +>( )|( }, )< +>( )|( ] )<"#; + a_id!( output.as_str(), exp ); + + // using table_to_string_with_format + + use the_module::TableFormatter; + + let mut format = output_format::Records::default(); + format.cell_prefix = "( ".into(); + format.cell_postfix = " )".into(); + format.cell_separator = "|".into(); + format.row_prefix = ">".into(); + format.row_postfix = "<".into(); + format.row_separator = "\n".into(); + + // let as_table = AsTable::new( &test_objects ); + let got = AsTable::new( &test_objects ).table_to_string_with_format( &format ); + let exp = r#" = 1 +>( id )|( 1 )< +>( created_at )|( 1627845583 )< +>( file_ids )|( [ )< +>( )|( "file1", )< +>( )|( "file2", )< +>( )|( ] )< +>( tools )|( )< + = 2 +>( id )|( 2 )< +>( created_at )|( 13 )< +>( file_ids )|( [ )< +>( )|( "file3", )< +>( )|( "file4\nmore details", )< +>( )|( ] )< +>( tools )|( [ )< +>( )|( { )< +>( )|( "tool1": "value1", )< +>( )|( }, )< +>( )|( { )< +>( )|( "tool2": "value2", )< +>( )|( }, )< +>( )|( ] )<"#; + a_id!( got, exp ); + +} + // -// println!( "\noutput\n{output}" ); + +#[ test ] +fn filter_col_none() +{ + let test_objects = test_object::test_objects_gen(); + + let mut format = output_format::Records::default(); + format.cell_prefix = "( ".into(); + format.cell_postfix = " )".into(); + format.cell_separator = "|".into(); + format.row_prefix = ">".into(); + format.row_postfix = "<".into(); + format.row_separator = "\n".into(); + + let mut printer = print::Printer::with_format( &format ); + printer.filter_col = &filter::None; + + let as_table = AsTable::new( &test_objects ); + let mut output = String::new(); + let mut context = print::Context::new( &mut output, printer ); + let result = the_module::TableFormatter::fmt( &as_table, &mut context ); + assert!( result.is_ok() ); + println!( "\noutput\n{output}" ); + + let exp = r#" = 1 + + = 2 +"#; + + a_id!( output.as_str(), exp ); + +} + // -// let exp = r#">( id )|( created_at )|( file_ids )|( tools )< -// ───────────────────────────────────────────────────────────────────────────────────── -// >( 2 )|( 13 )|( [ )|( [ )< -// >( )|( )|( "file3", )|( { )< -// >( )|( )|( "file4\nmore details", )|( "tool1": "value1", )< -// >( )|( )|( ] )|( }, )< -// >( )|( )|( )|( { )< -// >( )|( )|( )|( "tool2": "value2", )< -// >( )|( )|( )|( }, )< -// >( )|( )|( )|( ] )<"#; + +#[ test ] +fn filter_col_callback() +{ + let test_objects = test_object::test_objects_gen(); + + let mut format = output_format::Records::default(); + format.cell_prefix = "( ".into(); + format.cell_postfix = " )".into(); + format.cell_separator = "|".into(); + format.row_prefix = ">".into(); + format.row_postfix = "<".into(); + format.row_separator = "\n".into(); + + let mut printer = print::Printer::with_format( &format ); + printer.filter_col = &| title : &str | + { + title != "tools" + }; + + let as_table = AsTable::new( &test_objects ); + let mut output = String::new(); + let mut context = print::Context::new( &mut output, printer ); + let result = the_module::TableFormatter::fmt( &as_table, &mut context ); + assert!( result.is_ok() ); + println!( "\noutput\n{output}" ); + + let exp = r#" = 1 +>( id )|( 1 )< +>( created_at )|( 1627845583 )< +>( file_ids )|( [ )< +>( )|( "file1", )< +>( )|( "file2", )< +>( )|( ] )< + = 2 +>( id )|( 2 )< +>( created_at )|( 13 )< +>( file_ids )|( [ )< +>( )|( "file3", )< +>( )|( "file4\nmore details", )< +>( )|( ] )<"#; + + a_id!( output.as_str(), exp ); + +} + // -// a_id!( output.as_str(), exp ); + +#[ test ] +fn filter_row_none() +{ + let test_objects = test_object::test_objects_gen(); + + let mut format = output_format::Records::default(); + format.cell_prefix = "( ".into(); + format.cell_postfix = " )".into(); + format.cell_separator = "|".into(); + format.row_prefix = ">".into(); + format.row_postfix = "<".into(); + format.row_separator = "\n".into(); + + let mut printer = print::Printer::with_format( &format ); + printer.filter_row = &filter::None; + + let as_table = AsTable::new( &test_objects ); + let mut output = String::new(); + let mut context = print::Context::new( &mut output, printer ); + let result = the_module::TableFormatter::fmt( &as_table, &mut context ); + assert!( result.is_ok() ); + + println!( "\noutput\n{output}" ); + + let exp = r#""#; + + a_id!( output.as_str(), exp ); + +} + // -// } + +#[ test ] +fn filter_row_callback() +{ + let test_objects = test_object::test_objects_gen(); + + let mut format = output_format::Records::default(); + format.cell_prefix = "( ".into(); + format.cell_postfix = " )".into(); + format.cell_separator = "|".into(); + format.row_prefix = ">".into(); + format.row_postfix = "<".into(); + format.row_separator = "\n".into(); + + let mut printer = print::Printer::with_format( &format ); + printer.filter_row = &| _typ, irow, _row : &[ ( Cow< '_, str >, [ usize ; 2 ] ) ] | + { + irow != 1 + }; + + let as_table = AsTable::new( &test_objects ); + let mut output = String::new(); + let mut context = print::Context::new( &mut output, printer ); + let result = the_module::TableFormatter::fmt( &as_table, &mut context ); + assert!( result.is_ok() ); + + println!( "\noutput\n{output}" ); + + let exp = r#" = 2 +>( id )|( 2 )< +>( created_at )|( 13 )< +>( file_ids )|( [ )< +>( )|( "file3", )< +>( )|( "file4\nmore details", )< +>( )|( ] )< +>( tools )|( [ )< +>( )|( { )< +>( )|( "tool1": "value1", )< +>( )|( }, )< +>( )|( { )< +>( )|( "tool2": "value2", )< +>( )|( }, )< +>( )|( ] )<"#; + + a_id!( output.as_str(), exp ); + +} + // -// // // xxx : enable \ No newline at end of file diff --git a/module/core/format_tools/tests/inc/test_object.rs b/module/core/format_tools/tests/inc/test_object.rs index 729a96fa85..6bb7555aa8 100644 --- a/module/core/format_tools/tests/inc/test_object.rs +++ b/module/core/format_tools/tests/inc/test_object.rs @@ -13,6 +13,9 @@ use the_module:: use std:: { collections::HashMap, + hash::Hasher, + hash::Hash, + cmp::Ordering // borrow::Cow, }; @@ -58,6 +61,74 @@ for TestObject } +impl Hash for TestObject +{ + + fn hash< H: Hasher >( &self, state: &mut H ) + { + self.id.hash( state ); + self.created_at.hash( state ); + self.file_ids.hash( state ); + + if let Some( tools ) = &self.tools + { + for tool in tools + { + for ( key, value ) in tool + { + key.hash( state ); + value.hash( state ); + } + } + } + else + { + state.write_u8( 0 ); + } + } + +} + +impl PartialEq for TestObject +{ + + fn eq( &self, other: &Self ) -> bool + { + self.id == other.id && + self.created_at == other.created_at && + self.file_ids == other.file_ids && + self.tools == other.tools + } + +} + +impl Eq for TestObject +{ +} + +impl PartialOrd for TestObject +{ + + fn partial_cmp( &self, other: &Self ) -> Option< Ordering > + { + Some( self.cmp( other ) ) + } + +} + +impl Ord for TestObject +{ + + fn cmp( &self, other: &Self ) -> Ordering + { + self.id + .cmp( &other.id ) + .then_with( | | self.created_at.cmp( &other.created_at ) ) + .then_with( | | self.file_ids.cmp( &other.file_ids ) ) + } + +} + // pub fn test_objects_gen() -> Vec< TestObject > diff --git a/module/core/former/Cargo.toml b/module/core/former/Cargo.toml index 255f72c486..6ccdadb0b4 100644 --- a/module/core/former/Cargo.toml +++ b/module/core/former/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "former" -version = "2.8.0" +version = "2.9.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", diff --git a/module/core/former_meta/Cargo.toml b/module/core/former_meta/Cargo.toml index 537a170711..1612da9af5 100644 --- a/module/core/former_meta/Cargo.toml +++ b/module/core/former_meta/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "former_meta" -version = "2.8.0" +version = "2.9.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", diff --git a/module/core/former_types/Cargo.toml b/module/core/former_types/Cargo.toml index 75ae5bce43..6baa5017e7 100644 --- a/module/core/former_types/Cargo.toml +++ b/module/core/former_types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "former_types" -version = "2.7.0" +version = "2.8.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", diff --git a/module/core/interval_adapter/Cargo.toml b/module/core/interval_adapter/Cargo.toml index 40b7639448..cf0fd7fe6c 100644 --- a/module/core/interval_adapter/Cargo.toml +++ b/module/core/interval_adapter/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "interval_adapter" -version = "0.23.0" +version = "0.24.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", diff --git a/module/core/iter_tools/Cargo.toml b/module/core/iter_tools/Cargo.toml index ea0b221df3..68cafe52bf 100644 --- a/module/core/iter_tools/Cargo.toml +++ b/module/core/iter_tools/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "iter_tools" -version = "0.20.0" +version = "0.21.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", diff --git a/module/core/macro_tools/Cargo.toml b/module/core/macro_tools/Cargo.toml index cb1e7be33e..1213064721 100644 --- a/module/core/macro_tools/Cargo.toml +++ b/module/core/macro_tools/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "macro_tools" -version = "0.39.0" +version = "0.40.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", diff --git a/module/core/mod_interface/Cargo.toml b/module/core/mod_interface/Cargo.toml index 38f56efef2..438141b1e3 100644 --- a/module/core/mod_interface/Cargo.toml +++ b/module/core/mod_interface/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mod_interface" -version = "0.23.0" +version = "0.24.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", diff --git a/module/core/mod_interface_meta/Cargo.toml b/module/core/mod_interface_meta/Cargo.toml index 05f0bbf285..b3de1c7f95 100644 --- a/module/core/mod_interface_meta/Cargo.toml +++ b/module/core/mod_interface_meta/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mod_interface_meta" -version = "0.23.0" +version = "0.24.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", diff --git a/module/core/process_tools/Cargo.toml b/module/core/process_tools/Cargo.toml index 8b43896373..308881a600 100644 --- a/module/core/process_tools/Cargo.toml +++ b/module/core/process_tools/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "process_tools" -version = "0.8.0" +version = "0.9.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", diff --git a/module/core/proper_path_tools/Cargo.toml b/module/core/proper_path_tools/Cargo.toml index a9de7e5f46..5c6387502b 100644 --- a/module/core/proper_path_tools/Cargo.toml +++ b/module/core/proper_path_tools/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "proper_path_tools" -version = "0.9.0" +version = "0.10.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", diff --git a/module/core/proper_path_tools/src/lib.rs b/module/core/proper_path_tools/src/lib.rs index 1ac23b4abd..fe0f646c03 100644 --- a/module/core/proper_path_tools/src/lib.rs +++ b/module/core/proper_path_tools/src/lib.rs @@ -23,6 +23,7 @@ mod_interface! #[ cfg( feature = "path_utf8" ) ] own use ::camino::{ Utf8Path, Utf8PathBuf }; + #[ cfg( not( feature = "no_std" ) ) ] own use ::std::path::{ PathBuf, Path }; } diff --git a/module/core/proper_path_tools/src/path/absolute_path.rs b/module/core/proper_path_tools/src/path/absolute_path.rs index 60a3587a81..ba6e37f3ba 100644 --- a/module/core/proper_path_tools/src/path/absolute_path.rs +++ b/module/core/proper_path_tools/src/path/absolute_path.rs @@ -21,8 +21,11 @@ mod private }, }; - #[cfg(feature="no_std")] + #[ cfg( feature="no_std" ) ] extern crate std; + + #[ cfg( feature="no_std" ) ] + use alloc::string::String; #[ cfg( feature = "derive_serde" ) ] use serde::{ Serialize, Deserialize }; diff --git a/module/core/proper_path_tools/src/path/canonical_path.rs b/module/core/proper_path_tools/src/path/canonical_path.rs index 45886ded78..d6c84168da 100644 --- a/module/core/proper_path_tools/src/path/canonical_path.rs +++ b/module/core/proper_path_tools/src/path/canonical_path.rs @@ -21,9 +21,12 @@ mod private }, }; - #[cfg(feature="no_std")] + #[ cfg( feature="no_std" ) ] extern crate std; + #[ cfg( feature="no_std" ) ] + use alloc::string::String; + #[ cfg( feature = "derive_serde" ) ] use serde::{ Serialize, Deserialize }; diff --git a/module/core/proper_path_tools/src/path/current_path.rs b/module/core/proper_path_tools/src/path/current_path.rs index f9e5a83293..a35c927c0f 100644 --- a/module/core/proper_path_tools/src/path/current_path.rs +++ b/module/core/proper_path_tools/src/path/current_path.rs @@ -3,6 +3,7 @@ mod private { use crate::*; + #[ cfg( not( feature = "no_std" ) ) ] use std::env; /// Symbolize current path. @@ -10,8 +11,10 @@ mod private pub struct CurrentPath; #[ cfg( feature = "path_utf8" ) ] + #[ cfg( not( feature = "no_std" ) ) ] impl TryFrom< CurrentPath > for Utf8PathBuf { + #[ cfg( not( feature = "no_std" ) ) ] type Error = std::io::Error; #[ inline ] @@ -22,6 +25,7 @@ mod private ( | err | { + #[ cfg( not( feature = "no_std" ) ) ] std::io::Error::new ( std::io::ErrorKind::NotFound, @@ -32,8 +36,10 @@ mod private } } + #[ cfg( not( feature = "no_std" ) ) ] impl TryFrom< CurrentPath > for PathBuf { + #[ cfg( not( feature = "no_std" ) ) ] type Error = std::io::Error; #[ inline ] @@ -42,9 +48,11 @@ mod private env::current_dir() } } - + + #[ cfg( not( feature = "no_std" ) ) ] impl TryFrom< CurrentPath > for AbsolutePath { + #[ cfg( not( feature = "no_std" ) ) ] type Error = std::io::Error; #[ inline ] diff --git a/module/core/proper_path_tools/src/path/native_path.rs b/module/core/proper_path_tools/src/path/native_path.rs index df2e7ca559..d41b449acc 100644 --- a/module/core/proper_path_tools/src/path/native_path.rs +++ b/module/core/proper_path_tools/src/path/native_path.rs @@ -21,9 +21,12 @@ mod private }, }; - #[cfg(feature="no_std")] + #[ cfg( feature="no_std" ) ] extern crate std; + #[ cfg( feature="no_std" ) ] + use alloc::string::String; + #[ cfg( feature = "derive_serde" ) ] use serde::{ Serialize, Deserialize }; diff --git a/module/core/proper_path_tools/tests/inc/absolute_path.rs b/module/core/proper_path_tools/tests/inc/absolute_path.rs index 247be8c4b4..94e4ff2ab2 100644 --- a/module/core/proper_path_tools/tests/inc/absolute_path.rs +++ b/module/core/proper_path_tools/tests/inc/absolute_path.rs @@ -1,6 +1,7 @@ #[ allow( unused_imports ) ] use super::*; +#[ cfg( not( feature="no_std" ) ) ] use the_module:: { AbsolutePath, @@ -8,6 +9,9 @@ use the_module:: PathBuf, }; +#[ cfg( feature="no_std" ) ] +use crate::the_module::AbsolutePath; + // #[ cfg( feature = "path_utf8" ) ] // use the_module::Utf8PathBuf; @@ -37,6 +41,7 @@ fn test_to_string_lossy_hard() } #[test] +#[ cfg( not( feature="no_std" ) ) ] fn test_try_from_pathbuf() { @@ -46,6 +51,7 @@ fn test_try_from_pathbuf() } #[test] +#[ cfg( not( feature="no_std" ) ) ] fn test_try_from_path() { let path = Path::new( "/path/to/some/file.txt" ); @@ -79,6 +85,7 @@ fn test_relative_path_try_from_str() } #[test] +#[ cfg( not( feature="no_std" ) ) ] fn test_relative_path_try_from_pathbuf() { let rel_path_buf = PathBuf::from( "src/main.rs" ); @@ -87,6 +94,7 @@ fn test_relative_path_try_from_pathbuf() } #[test] +#[ cfg( not( feature="no_std" ) ) ] fn test_relative_path_try_from_path() { let rel_path = Path::new( "src/main.rs" ); diff --git a/module/core/proper_path_tools/tests/inc/current_path.rs b/module/core/proper_path_tools/tests/inc/current_path.rs index 628873a346..88703f0ec6 100644 --- a/module/core/proper_path_tools/tests/inc/current_path.rs +++ b/module/core/proper_path_tools/tests/inc/current_path.rs @@ -1,6 +1,7 @@ #[ allow( unused_imports ) ] use super::*; +#[ cfg( not( feature="no_std" ) ) ] use the_module:: { AbsolutePath, @@ -12,6 +13,7 @@ use the_module:: use the_module::Utf8PathBuf; #[ test ] +#[ cfg( not( feature="no_std" ) ) ] fn basic() { @@ -24,6 +26,7 @@ fn basic() println!( "absolute_path : {absolute_path:?}" ); #[ cfg( feature = "path_utf8" ) ] + #[ cfg( not( feature="no_std" ) ) ] { let cd = the_module::CurrentPath; let utf8_path : Utf8PathBuf = cd.try_into().unwrap(); diff --git a/module/core/proper_path_tools/tests/inc/path_canonicalize.rs b/module/core/proper_path_tools/tests/inc/path_canonicalize.rs index 64cd4665f2..9e0c5c10e0 100644 --- a/module/core/proper_path_tools/tests/inc/path_canonicalize.rs +++ b/module/core/proper_path_tools/tests/inc/path_canonicalize.rs @@ -7,10 +7,10 @@ use the_module::path; fn assumptions() { - assert_eq!( PathBuf::from( "c:/src/" ).is_absolute(), true ); - assert_eq!( PathBuf::from( "/c/src/" ).is_absolute(), false ); - assert_eq!( PathBuf::from( "/c:/src/" ).is_absolute(), false ); - assert_eq!( PathBuf::from( "/c/src/" ).is_absolute(), false ); + assert_eq!( PathBuf::from( "c:/src/" ).is_absolute(), false ); + assert_eq!( PathBuf::from( "/c/src/" ).is_absolute(), true ); + assert_eq!( PathBuf::from( "/c:/src/" ).is_absolute(), true ); + assert_eq!( PathBuf::from( "/c/src/" ).is_absolute(), true ); } @@ -23,11 +23,11 @@ fn basic() assert_eq!( got.unwrap(), exp ); let got = path::canonicalize( PathBuf::from( "\\src" ) ); - let exp = PathBuf::from( "/src" ); + let exp = PathBuf::from( "\\src" ); assert_eq!( got.unwrap(), exp ); let got = path::canonicalize( PathBuf::from( "\\src\\" ) ); - let exp = PathBuf::from( "/src/" ); + let exp = PathBuf::from( "\\src\\" ); assert_eq!( got.unwrap(), exp ); let got = path::canonicalize( PathBuf::from( "/src" ) ); diff --git a/module/core/reflect_tools/src/reflect/fields.rs b/module/core/reflect_tools/src/reflect/fields.rs index 428c95237b..edbdfbc9b4 100644 --- a/module/core/reflect_tools/src/reflect/fields.rs +++ b/module/core/reflect_tools/src/reflect/fields.rs @@ -112,6 +112,10 @@ mod private mod vec; mod hmap; mod bmap; +mod hset; +mod bset; +mod deque; +mod llist; #[ doc( inline ) ] #[ allow( unused_imports ) ] diff --git a/module/core/reflect_tools/src/reflect/fields/bset.rs b/module/core/reflect_tools/src/reflect/fields/bset.rs new file mode 100644 index 0000000000..e68d4d7e4b --- /dev/null +++ b/module/core/reflect_tools/src/reflect/fields/bset.rs @@ -0,0 +1,65 @@ +//! +//! Implement fields for BTreeSet. +//! + +use crate::*; +use std::borrow::Cow; +use collection_tools::BTreeSet; + +impl< V, Borrowed > Fields< usize, &'_ Borrowed > for BTreeSet< V > +where + Borrowed : std::borrow::ToOwned + 'static + ?Sized, + V : std::borrow::Borrow< Borrowed >, +{ + + type Key< 'k > = usize + where Self : 'k, usize : 'k; + + type Val< 'v > = &'v Borrowed + where Self : 'v, V : 'v; + + fn fields< 's >( &'s self ) -> impl IteratorTrait< Item = ( Self::Key< 's >, Self::Val< 's > ) > + { + self.iter().enumerate().map( move | ( key, val ) | ( key, val.borrow() ) ) + } + +} + +impl< V, Borrowed > Fields< usize, Option< Cow< '_, Borrowed > > > for BTreeSet< V > +where + Borrowed : std::borrow::ToOwned + 'static + ?Sized, + V : std::borrow::Borrow< Borrowed >, +{ + + type Key< 'k > = usize + where Self : 'k, usize : 'k; + + type Val< 'v > = Option< Cow< 'v, Borrowed > > + where Self : 'v; + + fn fields< 's >( &'s self ) -> impl IteratorTrait< Item = ( Self::Key< 's >, Self::Val< 's > ) > + { + self.iter().enumerate().map( move | ( key, val ) | ( key, Some( Cow::Borrowed( val.borrow() ) ) ) ) + } + +} + +impl< V, Borrowed, Marker > Fields< usize, OptionalCow< '_, Borrowed, Marker > > for BTreeSet< V > +where + Borrowed : std::borrow::ToOwned + 'static + ?Sized, + V : std::borrow::Borrow< Borrowed >, + Marker : Clone + Copy + 'static, +{ + + type Key< 'k > = usize + where Self : 'k, usize : 'k; + + type Val< 'v > = OptionalCow< 'v, Borrowed, Marker > + where Self : 'v; + + fn fields< 's >( &'s self ) -> impl IteratorTrait< Item = ( Self::Key< 's >, Self::Val< 's > ) > + { + self.iter().enumerate().map( move | ( key, val ) | ( key, OptionalCow::from( val.borrow() ) ) ) + } + +} diff --git a/module/core/reflect_tools/src/reflect/fields/deque.rs b/module/core/reflect_tools/src/reflect/fields/deque.rs new file mode 100644 index 0000000000..734255ad1a --- /dev/null +++ b/module/core/reflect_tools/src/reflect/fields/deque.rs @@ -0,0 +1,65 @@ +//! +//! Implement fields for Deque. +//! + +use crate::*; +use std::borrow::Cow; +use collection_tools::VecDeque; + +impl< V, Borrowed > Fields< usize, &'_ Borrowed > for VecDeque< V > +where + Borrowed : std::borrow::ToOwned + 'static + ?Sized, + V : std::borrow::Borrow< Borrowed >, +{ + + type Key< 'k > = usize + where Self : 'k, usize : 'k; + + type Val< 'v > = &'v Borrowed + where Self : 'v, V : 'v; + + fn fields< 's >( &'s self ) -> impl IteratorTrait< Item = ( Self::Key< 's >, Self::Val< 's > ) > + { + self.iter().enumerate().map( move | ( key, val ) | ( key, val.borrow() ) ) + } + +} + +impl< V, Borrowed > Fields< usize, Option< Cow< '_, Borrowed > > > for VecDeque< V > +where + Borrowed : std::borrow::ToOwned + 'static + ?Sized, + V : std::borrow::Borrow< Borrowed >, +{ + + type Key< 'k > = usize + where Self : 'k, usize : 'k; + + type Val< 'v > = Option< Cow< 'v, Borrowed > > + where Self : 'v; + + fn fields< 's >( &'s self ) -> impl IteratorTrait< Item = ( Self::Key< 's >, Self::Val< 's > ) > + { + self.iter().enumerate().map( move | ( key, val ) | ( key, Some( Cow::Borrowed( val.borrow() ) ) ) ) + } + +} + +impl< V, Borrowed, Marker > Fields< usize, OptionalCow< '_, Borrowed, Marker > > for VecDeque< V > +where + Borrowed : std::borrow::ToOwned + 'static + ?Sized, + V : std::borrow::Borrow< Borrowed >, + Marker : Clone + Copy + 'static, +{ + + type Key< 'k > = usize + where Self : 'k, usize : 'k; + + type Val< 'v > = OptionalCow< 'v, Borrowed, Marker > + where Self : 'v; + + fn fields< 's >( &'s self ) -> impl IteratorTrait< Item = ( Self::Key< 's >, Self::Val< 's > ) > + { + self.iter().enumerate().map( move | ( key, val ) | ( key, OptionalCow::from( val.borrow() ) ) ) + } + +} diff --git a/module/core/reflect_tools/src/reflect/fields/hset.rs b/module/core/reflect_tools/src/reflect/fields/hset.rs new file mode 100644 index 0000000000..cfc01be06e --- /dev/null +++ b/module/core/reflect_tools/src/reflect/fields/hset.rs @@ -0,0 +1,65 @@ +//! +//! Implement fields for HashSet. +//! + +use crate::*; +use std::borrow::Cow; +use std::collections::HashSet; + +impl< V, Borrowed > Fields< usize, &'_ Borrowed > for HashSet< V > +where + Borrowed : std::borrow::ToOwned + 'static + ?Sized, + V : std::borrow::Borrow< Borrowed >, +{ + + type Key< 'k > = usize + where Self : 'k, usize : 'k; + + type Val< 'v > = &'v Borrowed + where Self : 'v, V : 'v; + + fn fields< 's >( &'s self ) -> impl IteratorTrait< Item = ( Self::Key< 's >, Self::Val< 's > ) > + { + self.iter().enumerate().map( move | ( key, val ) | ( key, val.borrow() ) ) + } + +} + +impl< V, Borrowed > Fields< usize, Option< Cow< '_, Borrowed > > > for HashSet< V > +where + Borrowed : std::borrow::ToOwned + 'static + ?Sized, + V : std::borrow::Borrow< Borrowed >, +{ + + type Key< 'k > = usize + where Self : 'k, usize : 'k; + + type Val< 'v > = Option< Cow< 'v, Borrowed > > + where Self : 'v; + + fn fields< 's >( &'s self ) -> impl IteratorTrait< Item = ( Self::Key< 's >, Self::Val< 's > ) > + { + self.iter().enumerate().map( move | ( key, val ) | ( key, Some( Cow::Borrowed( val.borrow() ) ) ) ) + } + +} + +impl< V, Borrowed, Marker > Fields< usize, OptionalCow< '_, Borrowed, Marker > > for HashSet< V > +where + Borrowed : std::borrow::ToOwned + 'static + ?Sized, + V : std::borrow::Borrow< Borrowed >, + Marker : Clone + Copy + 'static, +{ + + type Key< 'k > = usize + where Self : 'k, usize : 'k; + + type Val< 'v > = OptionalCow< 'v, Borrowed, Marker > + where Self : 'v; + + fn fields< 's >( &'s self ) -> impl IteratorTrait< Item = ( Self::Key< 's >, Self::Val< 's > ) > + { + self.iter().enumerate().map( move | ( key, val ) | ( key, OptionalCow::from( val.borrow() ) ) ) + } + +} diff --git a/module/core/reflect_tools/src/reflect/fields/llist.rs b/module/core/reflect_tools/src/reflect/fields/llist.rs new file mode 100644 index 0000000000..40ca1ced98 --- /dev/null +++ b/module/core/reflect_tools/src/reflect/fields/llist.rs @@ -0,0 +1,65 @@ +//! +//! Implement fields for LinkedList. +//! + +use crate::*; +use std::borrow::Cow; +use collection_tools::LinkedList; + +impl< V, Borrowed > Fields< usize, &'_ Borrowed > for LinkedList< V > +where + Borrowed : std::borrow::ToOwned + 'static + ?Sized, + V : std::borrow::Borrow< Borrowed >, +{ + + type Key< 'k > = usize + where Self : 'k, usize : 'k; + + type Val< 'v > = &'v Borrowed + where Self : 'v, V : 'v; + + fn fields< 's >( &'s self ) -> impl IteratorTrait< Item = ( Self::Key< 's >, Self::Val< 's > ) > + { + self.iter().enumerate().map( move | ( key, val ) | ( key, val.borrow() ) ) + } + +} + +impl< V, Borrowed > Fields< usize, Option< Cow< '_, Borrowed > > > for LinkedList< V > +where + Borrowed : std::borrow::ToOwned + 'static + ?Sized, + V : std::borrow::Borrow< Borrowed >, +{ + + type Key< 'k > = usize + where Self : 'k, usize : 'k; + + type Val< 'v > = Option< Cow< 'v, Borrowed > > + where Self : 'v; + + fn fields< 's >( &'s self ) -> impl IteratorTrait< Item = ( Self::Key< 's >, Self::Val< 's > ) > + { + self.iter().enumerate().map( move | ( key, val ) | ( key, Some( Cow::Borrowed( val.borrow() ) ) ) ) + } + +} + +impl< V, Borrowed, Marker > Fields< usize, OptionalCow< '_, Borrowed, Marker > > for LinkedList< V > +where + Borrowed : std::borrow::ToOwned + 'static + ?Sized, + V : std::borrow::Borrow< Borrowed >, + Marker : Clone + Copy + 'static, +{ + + type Key< 'k > = usize + where Self : 'k, usize : 'k; + + type Val< 'v > = OptionalCow< 'v, Borrowed, Marker > + where Self : 'v; + + fn fields< 's >( &'s self ) -> impl IteratorTrait< Item = ( Self::Key< 's >, Self::Val< 's > ) > + { + self.iter().enumerate().map( move | ( key, val ) | ( key, OptionalCow::from( val.borrow() ) ) ) + } + +} diff --git a/module/core/reflect_tools/tests/inc/fundamental/fields_bset.rs b/module/core/reflect_tools/tests/inc/fundamental/fields_bset.rs new file mode 100644 index 0000000000..5a811ad569 --- /dev/null +++ b/module/core/reflect_tools/tests/inc/fundamental/fields_bset.rs @@ -0,0 +1,61 @@ +#[ allow( unused_imports ) ] +use super::*; + +use the_module:: +{ + Fields, + +}; + +// xxx : implement for other collections + +use std:: +{ + borrow::Cow, +}; + +#[ test ] +fn bset_string_fields() +{ + let collection : BTreeSet< String > = bset! + [ + "a".to_string(), + "b".to_string(), + ]; + + // k, v + let got : BTreeSet< _ > = Fields::< usize, &str >::fields( &collection ).collect(); + assert_eq!( got.len(), 2 ); + let exp = bset![ ( 0, "a" ), ( 1, "b" ) ]; + assert_eq!( got, exp ); + + // k, Option< Cow< '_, str > > + let got : BTreeSet< _ > = Fields::< usize, Option< Cow< '_, str > > >::fields( &collection ).collect(); + assert_eq!( got.len(), 2 ); + let exp = bset![ ( 0, Some( Cow::Borrowed( "a" ) ) ), ( 1, Some( Cow::Borrowed( "b" ) ) ) ]; + assert_eq!( got, exp ); + +} + +#[ test ] +fn bset_str_fields() +{ + let collection : BTreeSet< &str > = bset! + [ + "a", + "b", + ]; + + // k, v + let got : BTreeSet< _ > = Fields::< usize, &str >::fields( &collection ).collect(); + assert_eq!( got.len(), 2 ); + let exp = bset![ ( 0, "a" ), ( 1, "b" ) ]; + assert_eq!( got, exp ); + + // k, Option< Cow< '_, str > > + let got : BTreeSet< _ > = Fields::< usize, Option< Cow< '_, str > > >::fields( &collection ).collect(); + assert_eq!( got.len(), 2 ); + let exp = bset![ ( 0, Some( Cow::Borrowed( "a" ) ) ), ( 1, Some( Cow::Borrowed( "b" ) ) ) ]; + assert_eq!( got, exp ); + +} diff --git a/module/core/reflect_tools/tests/inc/fundamental/fields_deque.rs b/module/core/reflect_tools/tests/inc/fundamental/fields_deque.rs new file mode 100644 index 0000000000..190d8fc57b --- /dev/null +++ b/module/core/reflect_tools/tests/inc/fundamental/fields_deque.rs @@ -0,0 +1,73 @@ +#[ allow( unused_imports ) ] +use super::*; + +use the_module:: +{ + Fields, + OptionalCow, +}; + +// xxx : implement for other collections + +use std:: +{ + borrow::Cow, +}; + +#[ test ] +fn deque_string_fields() +{ + let collection = deque! + [ + "a".to_string(), + "b".to_string(), + ]; + + // k, v + let got : VecDeque< _ > = Fields::< usize, &str >::fields( &collection ).collect(); + assert_eq!( got.len(), 2 ); + let exp = deque![ ( 0, "a" ), ( 1, "b" ) ]; + assert_eq!( got, exp ); + + // k, Option< Cow< '_, str > > + let got : VecDeque< _ > = Fields::< usize, Option< Cow< '_, str > > >::fields( &collection ).collect(); + assert_eq!( got.len(), 2 ); + let exp = deque![ ( 0, Some( Cow::Borrowed( "a" ) ) ), ( 1, Some( Cow::Borrowed( "b" ) ) ) ]; + assert_eq!( got, exp ); + + // k, OptionalCow< '_, str, () > + let got : VecDeque< _ > = Fields::< usize, OptionalCow< '_, str, () > >::fields( &collection ).collect(); + assert_eq!( got.len(), 2 ); + let exp = deque![ ( 0, OptionalCow::from( "a" ) ), ( 1, OptionalCow::from( "b" ) ) ]; + assert_eq!( got, exp ); + +} + +#[ test ] +fn deque_str_fields() +{ + let collection = deque! + [ + "a", + "b", + ]; + + // k, v + let got : VecDeque< _ > = Fields::< usize, &str >::fields( &collection ).collect(); + assert_eq!( got.len(), 2 ); + let exp = deque![ ( 0, "a" ), ( 1, "b" ) ]; + assert_eq!( got, exp ); + + // k, Option< Cow< '_, str > > + let got : VecDeque< _ > = Fields::< usize, Option< Cow< '_, str > > >::fields( &collection ).collect(); + assert_eq!( got.len(), 2 ); + let exp = deque![ ( 0, Some( Cow::Borrowed( "a" ) ) ), ( 1, Some( Cow::Borrowed( "b" ) ) ) ]; + assert_eq!( got, exp ); + + // k, OptionalCow< '_, str, () > + let got : VecDeque< _ > = Fields::< usize, OptionalCow< '_, str, () > >::fields( &collection ).collect(); + assert_eq!( got.len(), 2 ); + let exp = deque![ ( 0, OptionalCow::from( "a" ) ), ( 1, OptionalCow::from( "b" ) ) ]; + assert_eq!( got, exp ); + +} diff --git a/module/core/reflect_tools/tests/inc/fundamental/fields_hset.rs b/module/core/reflect_tools/tests/inc/fundamental/fields_hset.rs new file mode 100644 index 0000000000..fddc44dc94 --- /dev/null +++ b/module/core/reflect_tools/tests/inc/fundamental/fields_hset.rs @@ -0,0 +1,60 @@ +#[ allow( unused_imports ) ] +use super::*; + +use the_module:: +{ + Fields, +}; + +// xxx : implement for other collections + +use std:: +{ + borrow::Cow, +}; + +#[ test ] +fn hset_string_fields() +{ + let collection : HashSet< String > = hset! + [ + "a".to_string(), + "b".to_string(), + ]; + + // k, v + let got : HashSet< _ > = Fields::< usize, &str >::fields( &collection ).collect(); + assert_eq!( got.len(), 2 ); + assert!( got.contains(&( 0, "a" ) ) || got.contains(&( 1, "a" ) ) ); + assert!( got.contains(&( 0, "b" ) ) || got.contains(&( 1, "b" ) ) ); + + // k, Option< Cow< '_, str > > + let got : HashSet< _ > = Fields::< usize, Option< Cow< '_, str > > >::fields( &collection ).collect(); + assert_eq!( got.len(), 2 ); + assert!( got.contains(&( 0, Some( Cow::Borrowed( "a" ) ) ) ) || got.contains(&( 1, Some( Cow::Borrowed( "a" ) ) ) ) ); + assert!( got.contains(&( 0, Some( Cow::Borrowed( "b" ) ) ) ) || got.contains(&( 1, Some( Cow::Borrowed( "b" ) ) ) ) ); + +} + +#[ test ] +fn hset_str_fields() +{ + let collection : HashSet< &str > = hset! + [ + "a", + "b", + ]; + + // k, v + let got : HashSet< _ > = Fields::< usize, &str >::fields( &collection ).collect(); + assert_eq!( got.len(), 2 ); + assert!( got.contains(&( 0, "a" ) ) || got.contains(&( 1, "a" ) ) ); + assert!( got.contains(&( 0, "b" ) ) || got.contains(&( 1, "b" ) ) ); + + // k, Option< Cow< '_, str > > + let got : HashSet< _ > = Fields::< usize, Option< Cow< '_, str > > >::fields( &collection ).collect(); + assert_eq!( got.len(), 2 ); + assert!( got.contains(&( 0, Some( Cow::Borrowed( "a" ) ) ) ) || got.contains(&( 1, Some( Cow::Borrowed( "a" ) ) ) ) ); + assert!( got.contains(&( 0, Some( Cow::Borrowed( "b" ) ) ) ) || got.contains(&( 1, Some( Cow::Borrowed( "b" ) ) ) ) ); + +} diff --git a/module/core/reflect_tools/tests/inc/fundamental/fields_llist.rs b/module/core/reflect_tools/tests/inc/fundamental/fields_llist.rs new file mode 100644 index 0000000000..dc93d87c0a --- /dev/null +++ b/module/core/reflect_tools/tests/inc/fundamental/fields_llist.rs @@ -0,0 +1,73 @@ +#[ allow( unused_imports ) ] +use super::*; + +use the_module:: +{ + Fields, + OptionalCow, +}; + +// xxx : implement for other collections + +use std:: +{ + borrow::Cow, +}; + +#[ test ] +fn llist_string_fields() +{ + let collection = llist! + [ + "a".to_string(), + "b".to_string(), + ]; + + // k, v + let got : LinkedList< _ > = Fields::< usize, &str >::fields( &collection ).collect(); + assert_eq!( got.len(), 2 ); + let exp = llist![ ( 0, "a" ), ( 1, "b" ) ]; + assert_eq!( got, exp ); + + // k, Option< Cow< '_, str > > + let got : LinkedList< _ > = Fields::< usize, Option< Cow< '_, str > > >::fields( &collection ).collect(); + assert_eq!( got.len(), 2 ); + let exp = llist![ ( 0, Some( Cow::Borrowed( "a" ) ) ), ( 1, Some( Cow::Borrowed( "b" ) ) ) ]; + assert_eq!( got, exp ); + + // k, OptionalCow< '_, str, () > + let got : LinkedList< _ > = Fields::< usize, OptionalCow< '_, str, () > >::fields( &collection ).collect(); + assert_eq!( got.len(), 2 ); + let exp = llist![ ( 0, OptionalCow::from( "a" ) ), ( 1, OptionalCow::from( "b" ) ) ]; + assert_eq!( got, exp ); + +} + +#[ test ] +fn llist_str_fields() +{ + let collection = llist! + [ + "a", + "b", + ]; + + // k, v + let got : LinkedList< _ > = Fields::< usize, &str >::fields( &collection ).collect(); + assert_eq!( got.len(), 2 ); + let exp = llist![ ( 0, "a" ), ( 1, "b" ) ]; + assert_eq!( got, exp ); + + // k, Option< Cow< '_, str > > + let got : LinkedList< _ > = Fields::< usize, Option< Cow< '_, str > > >::fields( &collection ).collect(); + assert_eq!( got.len(), 2 ); + let exp = llist![ ( 0, Some( Cow::Borrowed( "a" ) ) ), ( 1, Some( Cow::Borrowed( "b" ) ) ) ]; + assert_eq!( got, exp ); + + // k, OptionalCow< '_, str, () > + let got : LinkedList< _ > = Fields::< usize, OptionalCow< '_, str, () > >::fields( &collection ).collect(); + assert_eq!( got.len(), 2 ); + let exp = llist![ ( 0, OptionalCow::from( "a" ) ), ( 1, OptionalCow::from( "b" ) ) ]; + assert_eq!( got, exp ); + +} diff --git a/module/core/reflect_tools/tests/inc/mod.rs b/module/core/reflect_tools/tests/inc/mod.rs index de4b0b494e..d0ec8fff41 100644 --- a/module/core/reflect_tools/tests/inc/mod.rs +++ b/module/core/reflect_tools/tests/inc/mod.rs @@ -12,6 +12,10 @@ mod fundamental mod fields_vec; mod fields_hmap; mod fields_bmap; + mod fields_bset; + mod fields_deque; + mod fields_hset; + mod fields_llist; } diff --git a/module/core/reflect_tools_meta/src/implementation/reflect.rs b/module/core/reflect_tools_meta/src/implementation/reflect.rs index 34d239b8d9..04799d0a5a 100644 --- a/module/core/reflect_tools_meta/src/implementation/reflect.rs +++ b/module/core/reflect_tools_meta/src/implementation/reflect.rs @@ -1,7 +1,7 @@ // use macro_tools::proc_macro2::TokenStream; use crate::*; -use macro_tools::{ Result, attr, diag }; +use macro_tools::{ Result, attr, diag, qt, proc_macro2, syn }; // diff --git a/module/core/strs_tools/Cargo.toml b/module/core/strs_tools/Cargo.toml index 507791fffb..77dd2eeab5 100644 --- a/module/core/strs_tools/Cargo.toml +++ b/module/core/strs_tools/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "strs_tools" -version = "0.16.0" +version = "0.17.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", diff --git a/module/core/strs_tools/tests/inc/number_test.rs b/module/core/strs_tools/tests/inc/number_test.rs index cc8bf03006..2c03f223d1 100644 --- a/module/core/strs_tools/tests/inc/number_test.rs +++ b/module/core/strs_tools/tests/inc/number_test.rs @@ -1,5 +1,4 @@ use super::*; - // tests_impls! @@ -10,43 +9,43 @@ tests_impls! /* test.case( "parse" ); */ { - a_id!( the_module::number::parse::< f32, _ >( "1.0" ), Ok( 1.0 ) ); + a_id!( crate::the_module::string::number::parse::< f32, _ >( "1.0" ), Ok( 1.0 ) ); } /* test.case( "parse_partial" ); */ { - a_id!( the_module::number::parse_partial::< i32, _ >( "1a" ), Ok( ( 1, 1 ) ) ); + a_id!( crate::the_module::string::number::parse_partial::< i32, _ >( "1a" ), Ok( ( 1, 1 ) ) ); } /* test.case( "parse_partial_with_options" ); */ { - const FORMAT : u128 = the_module::number::format::STANDARD; - let options = the_module::number::ParseFloatOptions::builder() + const FORMAT : u128 = crate::the_module::string::number::format::STANDARD; + let options = crate::the_module::string::number::ParseFloatOptions::builder() .exponent( b'^' ) .decimal_point( b',' ) .build() .unwrap(); - let got = the_module::number::parse_partial_with_options::< f32, _, FORMAT >( "0", &options ); + let got = crate::the_module::string::number::parse_partial_with_options::< f32, _, FORMAT >( "0", &options ); let exp = Ok( ( 0.0, 1 ) ); a_id!( got, exp ); } /* test.case( "parse_with_options" ); */ { - const FORMAT: u128 = the_module::number::format::STANDARD; - let options = the_module::number::ParseFloatOptions::builder() + const FORMAT: u128 = crate::the_module::string::number::format::STANDARD; + let options = crate::the_module::string::number::ParseFloatOptions::builder() .exponent( b'^' ) .decimal_point( b',' ) .build() .unwrap(); - let got = the_module::number::parse_with_options::< f32, _, FORMAT >( "1,2345", &options ); + let got = crate::the_module::string::number::parse_with_options::< f32, _, FORMAT >( "1,2345", &options ); let exp = Ok( 1.2345 ); a_id!( got, exp ); } /* test.case( "to_string" ); */ { - a_id!( the_module::number::to_string( 5 ), "5" ); + a_id!( crate::the_module::string::number::to_string( 5 ), "5" ); } } diff --git a/module/core/variadic_from/Cargo.toml b/module/core/variadic_from/Cargo.toml index 616b747a6c..e3d1871e12 100644 --- a/module/core/variadic_from/Cargo.toml +++ b/module/core/variadic_from/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "variadic_from" -version = "0.22.0" +version = "0.23.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", diff --git a/module/move/crates_tools/Cargo.toml b/module/move/crates_tools/Cargo.toml index 3bc5d48dab..d36a25f270 100644 --- a/module/move/crates_tools/Cargo.toml +++ b/module/move/crates_tools/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "crates_tools" -version = "0.12.0" +version = "0.13.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", diff --git a/module/move/wca/Cargo.toml b/module/move/wca/Cargo.toml index 2d69a8aaff..eab9096bd4 100644 --- a/module/move/wca/Cargo.toml +++ b/module/move/wca/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wca" -version = "0.20.0" +version = "0.21.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", diff --git a/module/move/wca/src/ca/aggregator.rs b/module/move/wca/src/ca/aggregator.rs index 05575b9136..60668ad4a0 100644 --- a/module/move/wca/src/ca/aggregator.rs +++ b/module/move/wca/src/ca/aggregator.rs @@ -5,7 +5,7 @@ mod private { Verifier, Executor, - grammar::command::private:: + grammar::command:: { CommandFormer, CommandAsSubformer, diff --git a/module/move/wca/src/ca/executor/executor.rs b/module/move/wca/src/ca/executor/executor.rs index fe1cbff998..224aacd489 100644 --- a/module/move/wca/src/ca/executor/executor.rs +++ b/module/move/wca/src/ca/executor/executor.rs @@ -4,7 +4,7 @@ mod private // use wtools::error::Result; use error::return_err; - use ca::help::private::{ HelpGeneratorOptions, LevelOfDetail, generate_help_content }; + use ca::help::{ HelpGeneratorOptions, generate_help_content, LevelOfDetail }; // aaa : for Bohdan : how is it useful? where is it used? // aaa : `ExecutorType` has been removed diff --git a/module/move/wca/src/ca/formatter.rs b/module/move/wca/src/ca/formatter.rs index 59fb4b31ff..d528ef7f6d 100644 --- a/module/move/wca/src/ca/formatter.rs +++ b/module/move/wca/src/ca/formatter.rs @@ -3,7 +3,7 @@ mod private use crate::*; use iter_tools::Itertools; - use ca::aggregator::private::Order; + use ca::aggregator::Order; /// - #[ derive( Debug, Clone, PartialEq ) ] @@ -91,5 +91,6 @@ mod private crate::mod_interface! { - + own use HelpFormat; + own use md_generator; } \ No newline at end of file diff --git a/module/move/wca/src/ca/grammar/command.rs b/module/move/wca/src/ca/grammar/command.rs index 3bfbd7a695..ad34d5ef85 100644 --- a/module/move/wca/src/ca/grammar/command.rs +++ b/module/move/wca/src/ca/grammar/command.rs @@ -249,6 +249,11 @@ crate::mod_interface! exposed use Command; exposed use CommandFormer; own use ValueDescription; + + own use CommandAsSubformer; + own use CommandAsSubformerEnd; + own use CommandFormerStorage; + } // qqq : use orphan instead of exposed for ALL files in the folder, dont use prelude for structs \ No newline at end of file diff --git a/module/move/wca/src/ca/help.rs b/module/move/wca/src/ca/help.rs index b7d0593634..bfc8edbfe1 100644 --- a/module/move/wca/src/ca/help.rs +++ b/module/move/wca/src/ca/help.rs @@ -6,7 +6,7 @@ mod private Command, Routine, Type, - formatter::private:: + formatter:: { HelpFormat, md_generator @@ -64,7 +64,7 @@ mod private } // qqq : for Barsik : make possible to change properties order - pub( crate ) fn generate_help_content( dictionary : &Dictionary, o : HelpGeneratorOptions< '_ > ) -> String + pub fn generate_help_content( dictionary : &Dictionary, o : HelpGeneratorOptions< '_ > ) -> String { struct Row { @@ -418,5 +418,9 @@ crate::mod_interface! { own use HelpGeneratorFn; own use HelpGeneratorOptions; + own use LevelOfDetail; + own use generate_help_content; + prelude use HelpVariants; + } diff --git a/module/move/wca/src/ca/verifier/verifier.rs b/module/move/wca/src/ca/verifier/verifier.rs index 6fc13fc28e..a595521755 100644 --- a/module/move/wca/src/ca/verifier/verifier.rs +++ b/module/move/wca/src/ca/verifier/verifier.rs @@ -8,7 +8,7 @@ mod private use indexmap::IndexMap; // use wtools::{ error, error::Result, err }; use error::err; - use ca::help::private::{ HelpGeneratorOptions, LevelOfDetail, generate_help_content }; + use ca::help::{ HelpGeneratorOptions, LevelOfDetail, generate_help_content }; // xxx /// Converts a `ParsedCommand` to a `VerifiedCommand` by performing validation and type casting on values. @@ -249,4 +249,8 @@ mod private crate::mod_interface! { exposed use Verifier; + + // own use LevelOfDetail; + // own use generate_help_content; + } diff --git a/module/move/willbe/Cargo.toml b/module/move/willbe/Cargo.toml index d87621762c..a1cd2b21d8 100644 --- a/module/move/willbe/Cargo.toml +++ b/module/move/willbe/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "willbe" -version = "0.14.0" +version = "0.15.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", diff --git a/module/move/willbe/template/workflow/standard_rust_push.yml b/module/move/willbe/template/workflow/standard_rust_push.yml index d2fd96bae2..2f6103ebc2 100644 --- a/module/move/willbe/template/workflow/standard_rust_push.yml +++ b/module/move/willbe/template/workflow/standard_rust_push.yml @@ -77,7 +77,8 @@ jobs : continue-on-error: true - name: Check the modules dependencies run: cargo +nightly udeps --all-targets --manifest-path ${{ inputs.manifest_path }} - continue-on-error: true + # This part means that all previous steps will be executed and workflow will not stop if they fail, but not this one. + continue-on-error: false # release: # if: contains( inputs.commit_message, '+test' ) || contains( inputs.commit_message, 'merge' ) @@ -125,6 +126,9 @@ jobs : # run: cargo miri test --manifest-path ${{ inputs.manifest_path }} will_test : +# This section ensures that `job` `will_test` will only be executed after `checkmate` and if `checkmate` fails, no tests will be run. + needs : + - checkmate if : contains( inputs.commit_message, '+test' ) || inputs.commiter_username == 'web-flow' || startsWith( inputs.commit_message, 'merge' ) concurrency : group : standard_rust_push_${{ inputs.module_name }}_${{ github.ref }}_${{ matrix.os }} diff --git a/module/move/willbe/tests/inc/action_tests/test.rs b/module/move/willbe/tests/inc/action_tests/test.rs index 6d7d7898d9..16a4e8cd6a 100644 --- a/module/move/willbe/tests/inc/action_tests/test.rs +++ b/module/move/willbe/tests/inc/action_tests/test.rs @@ -1,6 +1,7 @@ use super::*; -use the_module::*; +// use the_module::*; +// qqq : for Bohdan : bad. don't import the_module::* use inc::helper:: { ProjectBuilder, @@ -17,12 +18,15 @@ use collection::BTreeSet; // use path::{ Path, PathBuf }; use assert_fs::TempDir; -use action::test::{ test, TestsCommandOptions }; -use channel::*; -use optimization::*; +use the_module::action::test::{ test, TestsCommandOptions }; +use the_module::channel::*; +// use the_module::optimization::*; +use the_module::optimization::{ self, Optimization }; +use the_module::AbsolutePath; // qqq : for Petro : no astersisks import use willbe::test::TestVariant; + #[ test ] // if the test fails => the report is returned as an error ( Err(Report) ) fn fail_test() diff --git a/module/move/willbe/tests/inc/tool/graph_test.rs b/module/move/willbe/tests/inc/tool/graph_test.rs index d6f5c38986..75a2b29db3 100644 --- a/module/move/willbe/tests/inc/tool/graph_test.rs +++ b/module/move/willbe/tests/inc/tool/graph_test.rs @@ -1,7 +1,8 @@ use super::*; -use the_module::*; -use graph::toposort; +// qqq : for Bohdan : bad. don't import the_module::* +// use the_module::*; +use the_module::graph::toposort; use collection::HashMap; use petgraph::Graph; use willbe::graph::topological_sort_with_grouping;