From 76f404200f57bf3bd0424ec54fe72abf3a52b4ba Mon Sep 17 00:00:00 2001 From: Wandalen Date: Tue, 13 Aug 2024 16:22:41 +0300 Subject: [PATCH] Format tools experiment 1 (#1431) format_tools : evolve --- .github/workflows/module_assistant_push.yml | 23 + .github/workflows/module_brain_tools_push.yml | 23 + .../workflows/module_clone_dyn_types_push.yml | 23 + .github/workflows/module_drawboard_push.yml | 23 + .github/workflows/module_drawql_push.yml | 23 + .../workflows/module_format_tools_push.yml | 23 + .github/workflows/module_paths_tools_push.yml | 23 + .../workflows/module_second_brain_push.yml | 23 + .github/workflows/module_step_push.yml | 23 + .github/workflows/standard_rust_push.yml | 6 +- .gitignore | 4 +- Cargo.toml | 75 +- Readme.md | 7 +- bash.exe.stackdump | 38 - module/alias/cargo_will/src/bin/cargo-will.rs | 2 +- module/alias/cargo_will/src/bin/will.rs | 2 +- module/alias/cargo_will/src/bin/willbe.rs | 2 +- module/alias/cargo_will/tests/smoke_test.rs | 4 +- module/alias/file_tools/tests/smoke_test.rs | 4 +- .../fundamental_data_type/tests/smoke_test.rs | 4 +- .../instance_of/src/typing/implements_lib.rs | 23 +- .../src/typing/inspect_type_lib.rs | 20 +- .../instance_of/src/typing/is_slice_lib.rs | 23 +- module/alias/instance_of/src/typing/typing.rs | 20 +- module/alias/instance_of/tests/smoke_test.rs | 4 +- module/alias/multilayer/tests/smoke_test.rs | 4 +- .../proc_macro_tools/tests/smoke_test.rs | 4 +- module/alias/proper_tools/tests/smoke_test.rs | 4 +- module/alias/werror/Cargo.toml | 16 +- module/alias/werror/tests/smoke_test.rs | 4 +- module/alias/willbe2/src/main.rs | 2 +- module/alias/willbe2/tests/smoke_test.rs | 4 +- module/alias/winterval/Cargo.toml | 2 +- module/alias/wproc_macro/tests/smoke_test.rs | 4 +- .../alias/wstring_tools/tests/smoke_test.rs | 4 +- module/alias/wtest/Cargo.toml | 2 +- module/alias/wtest/tests/smoke_test.rs | 4 +- .../wtest_basic/src/_blank/standard_lib.rs | 18 +- .../wtest_basic/src/test/wtest_basic_lib.rs | 4 +- module/alias/wtest_basic/tests/smoke_test.rs | 4 +- module/blank/brain_tools/Cargo.toml | 34 + .../blank/{willbe_old => brain_tools}/License | 0 module/blank/brain_tools/Readme.md | 33 + module/blank/brain_tools/src/lib.rs | 11 + .../blank/brain_tools/tests/inc/basic_test.rs | 7 + module/blank/brain_tools/tests/inc/mod.rs | 4 + .../tests/smoke_test.rs | 3 - module/blank/brain_tools/tests/tests.rs | 10 + module/blank/draw_lang/Cargo.toml | 34 + module/blank/draw_lang/License | 22 + module/blank/draw_lang/Readme.md | 33 + module/blank/draw_lang/src/lib.rs | 11 + .../blank/draw_lang/tests/inc/basic_test.rs | 7 + module/blank/draw_lang/tests/inc/mod.rs | 4 + module/blank/draw_lang/tests/smoke_test.rs | 14 + module/blank/draw_lang/tests/tests.rs | 10 + module/blank/drawboard/Cargo.toml | 34 + module/blank/drawboard/License | 22 + module/blank/drawboard/Readme.md | 33 + module/blank/drawboard/src/lib.rs | 11 + .../blank/drawboard/tests/inc/basic_test.rs | 7 + module/blank/drawboard/tests/inc/mod.rs | 4 + module/blank/drawboard/tests/smoke_test.rs | 14 + module/blank/drawboard/tests/tests.rs | 10 + module/blank/drawql/Cargo.toml | 34 + module/blank/drawql/License | 22 + module/blank/drawql/Readme.md | 33 + module/blank/drawql/src/lib.rs | 11 + module/blank/drawql/tests/inc/basic_test.rs | 7 + module/blank/drawql/tests/inc/mod.rs | 4 + module/blank/drawql/tests/smoke_test.rs | 14 + module/blank/drawql/tests/tests.rs | 10 + module/blank/exe_tools/src/lib.rs | 2 +- module/blank/exe_tools/tests/smoke_test.rs | 4 +- module/blank/image_tools/src/lib.rs | 2 +- module/blank/image_tools/tests/smoke_test.rs | 4 +- module/blank/math_tools/tests/smoke_test.rs | 4 +- module/blank/paths_tools/Cargo.toml | 34 + module/blank/paths_tools/License | 22 + module/blank/paths_tools/Readme.md | 33 + module/blank/paths_tools/src/lib.rs | 11 + .../blank/paths_tools/tests/inc/basic_test.rs | 7 + module/blank/paths_tools/tests/inc/mod.rs | 4 + module/blank/paths_tools/tests/smoke_test.rs | 12 + module/blank/paths_tools/tests/tests.rs | 10 + module/blank/rustql/src/lib.rs | 2 +- module/blank/rustql/tests/smoke_test.rs | 4 +- module/blank/second_brain/Cargo.toml | 34 + module/blank/second_brain/License | 22 + module/blank/second_brain/Readme.md | 33 + module/blank/second_brain/src/lib.rs | 11 + .../second_brain/tests/inc/basic_test.rs | 7 + module/blank/second_brain/tests/inc/mod.rs | 4 + module/blank/second_brain/tests/smoke_test.rs | 12 + module/blank/second_brain/tests/tests.rs | 10 + module/blank/w4d/tests/smoke_test.rs | 4 +- module/blank/willbe_old/Cargo.toml | 80 -- module/blank/willbe_old/Readme.md | 35 - .../src/willbe_old/commands/each.rs | 119 --- .../willbe_old/src/willbe_old/commands/end.rs | 61 -- .../src/willbe_old/commands/init.rs | 43 - .../willbe_old/src/willbe_old/commands/mod.rs | 66 -- .../src/willbe_old/commands/package/info.rs | 80 -- .../src/willbe_old/commands/package/mod.rs | 8 - .../willbe_old/commands/package/publish.rs | 66 -- .../src/willbe_old/core/entities/mod.rs | 10 - .../core/entities/package/metadata.rs | 119 --- .../willbe_old/core/entities/package/mod.rs | 10 - .../core/entities/package/package.rs | 53 -- .../core/entities/package/verification.rs | 65 -- .../src/willbe_old/core/entities/utility.rs | 124 --- .../src/willbe_old/core/entities/workspace.rs | 95 -- .../src/willbe_old/core/iterators.rs | 36 - .../willbe_old/src/willbe_old/core/mod.rs | 9 - .../blank/willbe_old/src/willbe_old/files.rs | 34 - .../willbe_old/src/willbe_old/willbe_entry.rs | 34 - .../willbe_old/src/willbe_old/willbe_lib.rs | 36 - .../tests/willbe_old/_asset/empty/.gitignore | 4 - .../willbe_old/_asset/package/Cargo.toml | 9 - .../tests/willbe_old/_asset/package/Readme.md | 0 .../willbe_old/_asset/package/src/lib.rs | 15 - .../willbe_old/_asset/package/src/main.rs | 3 - .../_asset/package_no_verified/Cargo.toml | 8 - .../_asset/package_no_verified/src/lib.rs | 8 - .../_asset/package_no_verified/src/main.rs | 3 - .../_asset/workspace_with_deps/Cargo.toml | 8 - .../module/module1/Cargo.toml | 8 - .../module/module1/src/lib.rs | 14 - .../module/module2/Cargo.toml | 9 - .../module/module2/src/lib.rs | 14 - .../module/module3/Cargo.toml | 9 - .../module/module3/src/lib.rs | 14 - .../willbe_old/_asset/workspaces/Cargo.toml | 9 - .../_asset/workspaces/workspace1/Cargo.toml | 8 - .../workspace1/module/module1/Cargo.toml | 8 - .../workspace1/module/module1/src/lib.rs | 14 - .../workspace1/module/module2/Cargo.toml | 8 - .../workspace1/module/module2/src/lib.rs | 14 - .../_asset/workspaces/workspace2/Cargo.toml | 8 - .../workspace2/module/module3/Cargo.toml | 8 - .../workspace2/module/module3/src/lib.rs | 14 - .../workspace2/module/module4/Cargo.toml | 8 - .../workspace2/module/module4/src/lib.rs | 14 - .../workspace2/module/module5/Cargo.toml | 8 - .../workspace2/module/module5/src/lib.rs | 14 - .../willbe_old/tests/willbe_old/tests/from.rs | 38 - .../willbe_old/tests/integration/each.rs | 130 --- .../willbe_old/tests/integration/info.rs | 78 -- .../tests/willbe_old/tests/integration/mod.rs | 8 - .../tests/willbe_old/tests/iterator.rs | 149 --- .../tests/willbe_old/tests/metadata.rs | 24 - .../willbe_old/tests/willbe_old/tests/mod.rs | 11 - .../tests/willbe_old/tests/ordering/mod.rs | 6 - .../tests/ordering/through_workspaces.rs | 74 -- .../willbe_old/tests/ordering/workspace.rs | 103 --- .../tests/willbe_old/tests/verification.rs | 26 - .../willbe_old/tests/willbe_old/utility.rs | 71 -- .../tests/willbe_old/willbe_test.rs | 7 - module/blank/wlang/Cargo.toml | 2 +- module/blank/wlang/src/standard_lib.rs | 20 +- module/blank/wlang/tests/smoke_test.rs | 4 +- module/core/clone_dyn/Cargo.toml | 18 +- module/core/clone_dyn/Readme.md | 200 +++- .../clone_dyn/examples/clone_dyn_trivial.rs | 135 ++- module/core/clone_dyn/src/lib.rs | 82 +- module/core/clone_dyn/tests/inc/basic.rs | 57 ++ .../core/clone_dyn/tests/inc/basic_manual.rs | 95 ++ module/core/clone_dyn/tests/inc/mod.rs | 162 +--- .../clone_dyn/tests/inc/only_test/basic.rs | 103 +++ .../core/clone_dyn/tests/inc/parametrized.rs | 131 +++ module/core/clone_dyn/tests/smoke_test.rs | 4 +- module/core/clone_dyn_meta/Cargo.toml | 9 +- module/core/clone_dyn_meta/src/derive.rs | 161 +++- .../core/clone_dyn_meta/tests/smoke_test.rs | 4 +- module/core/clone_dyn_types/Cargo.toml | 36 + module/core/clone_dyn_types/License | 22 + module/core/clone_dyn_types/Readme.md | 239 +++++ .../examples/clone_dyn_types_trivial.rs | 151 +++ module/core/clone_dyn_types/src/lib.rs | 262 ++++++ module/core/clone_dyn_types/tests/inc/mod.rs | 15 + .../core/clone_dyn_types/tests/smoke_test.rs | 14 + module/core/clone_dyn_types/tests/tests.rs | 8 + module/core/collection_tools/Cargo.toml | 2 +- module/core/collection_tools/Readme.md | 2 +- .../examples/collection_tools_trivial.rs | 2 +- .../core/collection_tools/src/collections.rs | 14 +- module/core/collection_tools/src/lib.rs | 23 +- .../core/collection_tools/tests/smoke_test.rs | 4 +- module/core/data_type/Cargo.toml | 10 +- module/core/data_type/Readme.md | 20 +- .../data_type/examples/data_type_trivial.rs | 32 +- module/core/data_type/src/dt.rs | 23 +- module/core/data_type/src/lib.rs | 25 +- module/core/data_type/tests/inc/mod.rs | 2 +- module/core/data_type/tests/smoke_test.rs | 4 +- module/core/data_type/tests/tests.rs | 6 +- module/core/derive_tools/Cargo.toml | 36 +- module/core/derive_tools/build.rs | 12 +- module/core/derive_tools/src/lib.rs | 176 +--- .../core/derive_tools/tests/inc/basic_test.rs | 6 - .../basic_manual_test.rs} | 2 +- .../{deref_test.rs => deref/basic_test.rs} | 2 +- .../tests/inc/deref/bounds_inlined.rs | 2 +- .../tests/inc/deref/bounds_inlined_manual.rs | 2 +- .../tests/inc/deref/bounds_mixed.rs | 2 +- .../tests/inc/deref/bounds_mixed_manual.rs | 2 +- .../tests/inc/deref/bounds_where.rs | 2 +- .../tests/inc/deref/bounds_where_manual.rs | 2 +- .../tests/inc/deref/enum_named.rs | 2 +- .../tests/inc/deref/enum_named_empty.rs | 2 +- .../inc/deref/enum_named_empty_manual.rs | 4 +- .../tests/inc/deref/enum_named_manual.rs | 2 +- .../tests/inc/deref/enum_tuple.rs | 2 +- .../tests/inc/deref/enum_tuple_empty.rs | 2 +- .../inc/deref/enum_tuple_empty_manual.rs | 2 +- .../tests/inc/deref/enum_tuple_manual.rs | 2 +- .../derive_tools/tests/inc/deref/enum_unit.rs | 2 +- .../tests/inc/deref/enum_unit_manual.rs | 2 +- .../tests/inc/deref/generics_constants.rs | 2 +- .../inc/deref/generics_constants_default.rs | 2 +- .../generics_constants_default_manual.rs | 2 +- .../inc/deref/generics_constants_manual.rs | 2 +- .../tests/inc/deref/generics_lifetimes.rs | 2 +- .../inc/deref/generics_lifetimes_manual.rs | 2 +- .../tests/inc/deref/generics_types.rs | 2 +- .../tests/inc/deref/generics_types_default.rs | 2 +- .../deref/generics_types_default_manual.rs | 2 +- .../tests/inc/deref/generics_types_manual.rs | 2 +- .../tests/inc/deref/name_collisions.rs | 2 +- .../deref.rs => deref/only_test/basic.rs} | 0 .../bounds_inlined.rs | 0 .../{only_tests => only_test}/bounds_mixed.rs | 0 .../{only_tests => only_test}/bounds_where.rs | 0 .../{only_tests => only_test}/enum_named.rs | 0 .../enum_named_empty.rs | 0 .../{only_tests => only_test}/enum_tuple.rs | 0 .../enum_tuple_empty.rs | 0 .../{only_tests => only_test}/enum_unit.rs | 0 .../generics_constants.rs | 0 .../generics_constants_default.rs | 0 .../generics_lifetimes.rs | 0 .../generics_types.rs | 0 .../generics_types_default.rs | 0 .../name_collisions.rs | 0 .../{only_tests => only_test}/struct_named.rs | 0 .../struct_named_empty.rs | 0 .../{only_tests => only_test}/struct_tuple.rs | 0 .../struct_tuple_empty.rs | 0 .../{only_tests => only_test}/struct_unit.rs | 0 .../tests/inc/deref/struct_named.rs | 2 +- .../tests/inc/deref/struct_named_empty.rs | 2 +- .../inc/deref/struct_named_empty_manual.rs | 2 +- .../tests/inc/deref/struct_named_manual.rs | 2 +- .../tests/inc/deref/struct_tuple.rs | 2 +- .../tests/inc/deref/struct_tuple_empty.rs | 2 +- .../inc/deref/struct_tuple_empty_manual.rs | 2 +- .../tests/inc/deref/struct_tuple_manual.rs | 2 +- .../tests/inc/deref/struct_unit.rs | 2 +- .../tests/inc/deref/struct_unit_manual.rs | 2 +- .../basic_manual_test.rs} | 2 +- .../basic_test.rs} | 2 +- .../tests/inc/deref_mut/bounds_inlined.rs | 17 +- .../inc/deref_mut/bounds_inlined_manual.rs | 2 +- .../tests/inc/deref_mut/bounds_mixed.rs | 19 +- .../inc/deref_mut/bounds_mixed_manual.rs | 2 +- .../tests/inc/deref_mut/bounds_where.rs | 20 +- .../inc/deref_mut/bounds_where_manual.rs | 2 +- .../tests/inc/deref_mut/enum_named.rs | 20 +- .../tests/inc/deref_mut/enum_named_manual.rs | 2 +- .../tests/inc/deref_mut/enum_tuple.rs | 20 +- .../tests/inc/deref_mut/enum_tuple_manual.rs | 2 +- .../tests/inc/deref_mut/generics_constants.rs | 17 +- .../deref_mut/generics_constants_default.rs | 17 +- .../generics_constants_default_manual.rs | 2 +- .../deref_mut/generics_constants_manual.rs | 2 +- .../tests/inc/deref_mut/generics_lifetimes.rs | 17 +- .../deref_mut/generics_lifetimes_manual.rs | 2 +- .../tests/inc/deref_mut/generics_types.rs | 17 +- .../inc/deref_mut/generics_types_default.rs | 17 +- .../generics_types_default_manual.rs | 2 +- .../inc/deref_mut/generics_types_manual.rs | 2 +- .../tests/inc/deref_mut/name_collisions.rs | 15 +- .../only_test/basic.rs} | 0 .../bounds_inlined.rs | 0 .../{only_tests => only_test}/bounds_mixed.rs | 0 .../{only_tests => only_test}/bounds_where.rs | 0 .../{only_tests => only_test}/enum_named.rs | 0 .../{only_tests => only_test}/enum_tuple.rs | 0 .../generics_constants.rs | 0 .../generics_constants_default.rs | 0 .../generics_lifetimes.rs | 0 .../generics_types.rs | 0 .../generics_types_default.rs | 0 .../name_collisions.rs | 0 .../{only_tests => only_test}/struct_named.rs | 0 .../{only_tests => only_test}/struct_tuple.rs | 0 .../tests/inc/deref_mut/struct_named.rs | 17 +- .../inc/deref_mut/struct_named_manual.rs | 2 +- .../tests/inc/deref_mut/struct_tuple.rs | 17 +- .../inc/deref_mut/struct_tuple_manual.rs | 2 +- .../{manual_test.rs => basic_manual_test.rs} | 0 .../tests/inc/from/{test.rs => basic_test.rs} | 0 .../inc/from/multiple_named_manual_test.rs | 6 +- .../tests/inc/from/multiple_named_test.rs | 4 +- ...est.rs => multiple_unnamed_manual_test.rs} | 2 +- ...tiple_test.rs => multiple_unnamed_test.rs} | 2 +- .../tests/inc/from/named_manual_test.rs | 4 +- .../tests/inc/from/only_test/basic.rs | 2 + .../{multiple.rs => multiple_unnamed.rs} | 0 .../tests/inc/from/variants_collisions.rs | 2 + .../tests/inc/index/compiletime/enum.rs | 13 + .../tests/inc/index/compiletime/enum.stderr | 7 + .../tests/inc/index/compiletime/struct.rs | 14 + .../tests/inc/index/compiletime/struct.stderr | 8 + .../index/compiletime/struct_named_empty.rs | 10 + .../compiletime/struct_named_empty.stderr | 7 + .../inc/index/compiletime/struct_unit.rs | 9 + .../inc/index/compiletime/struct_unit.stderr | 7 + .../index/only_test/struct_multiple_named.rs | 14 + .../index/only_test/struct_multiple_tuple.rs | 8 + .../tests/inc/index/only_test/struct_named.rs | 13 + .../tests/inc/index/only_test/struct_tuple.rs | 9 + .../tests/inc/index/struct_collisions.rs | 23 + .../inc/index/struct_multiple_named_field.rs | 14 + .../inc/index/struct_multiple_named_item.rs | 13 + .../inc/index/struct_multiple_named_manual.rs | 20 + .../tests/inc/index/struct_multiple_tuple.rs | 13 + .../inc/index/struct_multiple_tuple_manual.rs | 16 + .../tests/inc/index/struct_named.rs | 12 + .../tests/inc/index/struct_named_manual.rs | 19 + .../tests/inc/index/struct_tuple.rs | 11 + .../tests/inc/index/struct_tuple_manual.rs | 16 + .../tests/inc/index_mut/compiletime/enum.rs | 13 + .../inc/index_mut/compiletime/enum.stderr | 7 + .../tests/inc/index_mut/compiletime/struct.rs | 14 + .../inc/index_mut/compiletime/struct.stderr | 8 + .../compiletime/struct_named_empty.rs | 10 + .../compiletime/struct_named_empty.stderr | 7 + .../inc/index_mut/compiletime/struct_unit.rs | 9 + .../index_mut/compiletime/struct_unit.stderr | 7 + .../only_test/struct_multiple_named.rs | 20 + .../only_test/struct_multiple_tuple.rs | 14 + .../inc/index_mut/only_test/struct_named.rs | 18 + .../inc/index_mut/only_test/struct_tuple.rs | 14 + .../tests/inc/index_mut/struct_collisions.rs | 22 + .../index_mut/struct_multiple_named_field.rs | 14 + .../index_mut/struct_multiple_named_item.rs | 15 + .../index_mut/struct_multiple_named_manual.rs | 30 + .../inc/index_mut/struct_multiple_tuple.rs | 15 + .../index_mut/struct_multiple_tuple_manual.rs | 27 + .../tests/inc/index_mut/struct_named.rs | 12 + .../inc/index_mut/struct_named_manual.rs | 28 + .../tests/inc/index_mut/struct_tuple.rs | 12 + .../inc/index_mut/struct_tuple_manual.rs | 26 + .../{manual_test.rs => basic_manual_test.rs} | 0 .../inc/inner_from/{test.rs => basic_test.rs} | 0 .../inner_from/multiple_named_manual_test.rs | 4 +- .../inc/inner_from/multiple_named_test.rs | 4 +- ...est.rs => multiple_unnamed_manual_test.rs} | 0 ...tiple_test.rs => multiple_unnamed_test.rs} | 0 .../tests/inc/inner_from/named_manual_test.rs | 2 +- .../tests/inc/inner_from/named_test.rs | 2 +- .../inner_from/only_test/multiple_named.rs | 2 +- .../tests/inc/inner_from/only_test/named.rs | 4 +- module/core/derive_tools/tests/inc/mod.rs | 326 ++++++- .../tests/inc/new/basic_manual_test.rs | 15 + .../derive_tools/tests/inc/new/basic_test.rs | 6 + .../inc/new/multiple_named_manual_test.rs | 19 + .../tests/inc/new/multiple_named_test.rs | 11 + .../inc/new/multiple_unnamed_manual_test.rs | 15 + .../tests/inc/new/multiple_unnamed_test.rs | 6 + .../tests/inc/new/named_manual_test.rs | 18 + .../derive_tools/tests/inc/new/named_test.rs | 9 + .../tests/inc/new/only_test/basic.rs | 13 + .../tests/inc/new/only_test/multiple_named.rs | 7 + .../inc/new/only_test/multiple_unnamed.rs | 7 + .../tests/inc/new/only_test/named.rs | 7 + .../tests/inc/new/only_test/unit.rs | 7 + .../tests/inc/new/unit_manual_test.rs | 15 + .../derive_tools/tests/inc/new/unit_test.rs | 6 + .../tests/inc/not/bounds_inlined.rs | 13 + .../tests/inc/not/bounds_inlined_manual.rs | 21 + .../tests/inc/not/bounds_mixed.rs | 15 + .../tests/inc/not/bounds_mixed_manual.rs | 25 + .../tests/inc/not/bounds_where.rs | 16 + .../tests/inc/not/bounds_where_manual.rs | 27 + .../tests/inc/not/name_collisions.rs | 14 + .../tests/inc/not/named_default_off.rs | 12 + .../tests/inc/not/named_default_off_manual.rs | 20 + .../inc/not/named_default_off_reference_on.rs | 13 + .../named_default_off_reference_on_manual.rs | 20 + .../inc/not/named_default_off_some_on.rs | 13 + .../not/named_default_off_some_on_manual.rs | 20 + .../not/named_default_on_mut_reference_off.rs | 12 + ...med_default_on_mut_reference_off_manual.rs | 20 + .../inc/not/named_default_on_some_off.rs | 12 + .../not/named_default_on_some_off_manual.rs | 20 + .../inc/not/named_mut_reference_field.rs | 11 + .../not/named_mut_reference_field_manual.rs | 21 + .../tests/inc/not/named_reference_field.rs | 11 + .../inc/not/named_reference_field_manual.rs | 20 + .../tests/inc/not/only_test/bounds_inlined.rs | 10 + .../tests/inc/not/only_test/bounds_mixed.rs | 10 + .../tests/inc/not/only_test/bounds_where.rs | 10 + .../inc/not/only_test/name_collisions.rs | 10 + .../inc/not/only_test/named_default_off.rs | 10 + .../named_default_off_reference_on.rs | 11 + .../only_test/named_default_off_some_on.rs | 10 + .../named_default_on_mut_reference_off.rs | 11 + .../only_test/named_default_on_some_off.rs | 10 + .../only_test/named_mut_reference_field.rs | 11 + .../not/only_test/named_reference_field.rs | 11 + .../tests/inc/not/only_test/struct_named.rs | 10 + .../inc/not/only_test/struct_named_empty.rs | 6 + .../tests/inc/not/only_test/struct_tuple.rs | 10 + .../inc/not/only_test/struct_tuple_empty.rs | 6 + .../tests/inc/not/only_test/struct_unit.rs | 6 + .../inc/not/only_test/tuple_default_off.rs | 10 + .../tuple_default_off_reference_on.rs | 11 + .../only_test/tuple_default_off_some_on.rs | 10 + .../tuple_default_on_mut_reference_off.rs | 11 + .../only_test/tuple_default_on_some_off.rs | 10 + .../only_test/tuple_mut_reference_field.rs | 11 + .../not/only_test/tuple_reference_field.rs | 11 + .../inc/not/only_test/with_custom_type.rs | 10 + .../tests/inc/not/struct_named.rs | 11 + .../tests/inc/not/struct_named_empty.rs | 7 + .../inc/not/struct_named_empty_manual.rs | 15 + .../tests/inc/not/struct_named_manual.rs | 20 + .../tests/inc/not/struct_tuple.rs | 7 + .../tests/inc/not/struct_tuple_empty.rs | 7 + .../inc/not/struct_tuple_empty_manual.rs | 16 + .../tests/inc/not/struct_tuple_manual.rs | 16 + .../derive_tools/tests/inc/not/struct_unit.rs | 7 + .../tests/inc/not/struct_unit_manual.rs | 15 + .../tests/inc/not/tuple_default_off.rs | 8 + .../tests/inc/not/tuple_default_off_manual.rs | 16 + .../inc/not/tuple_default_off_reference_on.rs | 8 + .../tuple_default_off_reference_on_manual.rs | 16 + .../inc/not/tuple_default_off_some_on.rs | 8 + .../not/tuple_default_off_some_on_manual.rs | 16 + .../not/tuple_default_on_mut_reference_off.rs | 7 + ...ple_default_on_mut_reference_off_manual.rs | 16 + .../inc/not/tuple_default_on_some_off.rs | 7 + .../not/tuple_default_on_some_off_manual.rs | 16 + .../inc/not/tuple_mut_reference_field.rs | 7 + .../not/tuple_mut_reference_field_manual.rs | 17 + .../tests/inc/not/tuple_reference_field.rs | 7 + .../inc/not/tuple_reference_field_manual.rs | 16 + .../tests/inc/not/with_custom_type.rs | 28 + .../tests/inc/phantom/bounds_inlined.rs | 8 + .../inc/phantom/bounds_inlined_manual.rs | 13 + .../tests/inc/phantom/bounds_mixed.rs | 11 + .../tests/inc/phantom/bounds_mixed_manual.rs | 15 + .../tests/inc/phantom/bounds_where.rs | 12 + .../tests/inc/phantom/bounds_where_manual.rs | 16 + .../tests/inc/phantom/compiletime/enum.rs | 13 + .../tests/inc/phantom/compiletime/enum.stderr | 5 + .../inc/phantom/compiletime/invariant_type.rs | 18 + .../phantom/compiletime/invariant_type.stderr | 12 + .../tests/inc/phantom/contravariant_type.rs | 10 + .../inc/phantom/contravariant_type_manual.rs | 10 + .../tests/inc/phantom/covariant_type.rs | 10 + .../inc/phantom/covariant_type_manual.rs | 10 + .../tests/inc/phantom/name_collisions.rs | 15 + .../inc/phantom/only_test/bounds_inlined.rs | 5 + .../inc/phantom/only_test/bounds_mixed.rs | 5 + .../inc/phantom/only_test/bounds_where.rs | 5 + .../phantom/only_test/contravariant_type.rs | 18 + .../inc/phantom/only_test/covariant_type.rs | 12 + .../inc/phantom/only_test/name_collisions.rs | 5 + .../inc/phantom/only_test/send_sync_type.rs | 9 + .../inc/phantom/only_test/struct_named.rs | 5 + .../phantom/only_test/struct_named_empty.rs | 5 + .../inc/phantom/only_test/struct_tuple.rs | 5 + .../phantom/only_test/struct_tuple_empty.rs | 5 + .../phantom/only_test/struct_unit_to_tuple.rs | 5 + .../tests/inc/phantom/send_sync_type.rs | 10 + .../inc/phantom/send_sync_type_manual.rs | 10 + .../tests/inc/phantom/struct_named.rs | 11 + .../tests/inc/phantom/struct_named_empty.rs | 7 + .../inc/phantom/struct_named_empty_manual.rs | 9 + .../tests/inc/phantom/struct_named_manual.rs | 11 + .../tests/inc/phantom/struct_tuple.rs | 7 + .../tests/inc/phantom/struct_tuple_empty.rs | 7 + .../inc/phantom/struct_tuple_empty_manual.rs | 6 + .../tests/inc/phantom/struct_tuple_manual.rs | 6 + .../tests/inc/phantom/struct_unit_to_tuple.rs | 7 + .../phantom/struct_unit_to_tuple_manual.rs | 6 + module/core/derive_tools/tests/smoke_test.rs | 4 +- module/core/derive_tools/tests/tests.rs | 3 +- module/core/derive_tools_meta/Cargo.toml | 26 +- module/core/derive_tools_meta/src/derive.rs | 12 +- .../derive_tools_meta/src/derive/deref_mut.rs | 58 +- .../core/derive_tools_meta/src/derive/from.rs | 23 +- .../src/derive/from/field_attributes.rs | 5 +- .../src/derive/from/item_attributes.rs | 5 +- .../derive_tools_meta/src/derive/index.rs | 350 +++++++ .../src/derive/index/field_attributes.rs | 99 ++ .../src/derive/index/item_attributes.rs | 233 +++++ .../derive_tools_meta/src/derive/index_mut.rs | 362 ++++++++ .../src/derive/inner_from.rs | 1 + .../core/derive_tools_meta/src/derive/new.rs | 42 +- .../core/derive_tools_meta/src/derive/not.rs | 200 ++++ .../src/derive/not/field_attributes.rs | 203 ++++ .../src/derive/not/item_attributes.rs | 187 ++++ .../derive_tools_meta/src/derive/phantom.rs | 122 +++ module/core/derive_tools_meta/src/lib.rs | 282 +++++- module/core/diagnostics_tools/Cargo.toml | 2 +- module/core/diagnostics_tools/src/diag/cta.rs | 26 +- .../core/diagnostics_tools/src/diag/layout.rs | 26 +- module/core/diagnostics_tools/src/diag/mod.rs | 23 +- module/core/diagnostics_tools/src/diag/rta.rs | 37 +- module/core/diagnostics_tools/src/lib.rs | 23 +- .../diagnostics_tools/tests/smoke_test.rs | 4 +- module/core/error_tools/Cargo.toml | 16 +- module/core/error_tools/Readme.md | 2 +- .../examples/error_tools_trivial.rs | 2 +- module/core/error_tools/src/assert.rs | 31 +- module/core/error_tools/src/error.rs | 145 ++- module/core/error_tools/src/lib.rs | 109 ++- module/core/error_tools/src/result.rs | 14 +- module/core/error_tools/src/typed.rs | 61 ++ module/core/error_tools/src/untyped.rs | 68 ++ .../core/error_tools/tests/inc/basic_test.rs | 6 +- .../error_tools/tests/inc/err_with_test.rs | 31 + module/core/error_tools/tests/inc/mod.rs | 6 +- .../inc/{for_app_test.rs => untyped_test.rs} | 8 +- module/core/error_tools/tests/smoke_test.rs | 4 +- .../tests/{error_tools_tests.rs => tests.rs} | 0 module/core/for_each/Cargo.toml | 2 +- module/core/for_each/src/lib.rs | 29 +- module/core/for_each/tests/smoke_test.rs | 4 +- module/core/format_tools/Cargo.toml | 50 + module/core/format_tools/License | 22 + module/core/format_tools/Readme.md | 94 ++ module/core/format_tools/build.rs | 25 + .../examples/format_tools_trivial.rs | 68 ++ module/core/format_tools/src/format.rs | 346 +++++++ .../core/format_tools/src/format/as_table.rs | 261 ++++++ .../core/format_tools/src/format/md_math.rs | 94 ++ module/core/format_tools/src/format/print.rs | 512 ++++++++++ module/core/format_tools/src/format/string.rs | 220 +++++ module/core/format_tools/src/format/table.rs | 242 +++++ .../core/format_tools/src/format/to_string.rs | 160 ++++ .../format_tools/src/format/to_string/aref.rs | 79 ++ .../src/format/to_string_with_fallback.rs | 262 ++++++ .../format/to_string_with_fallback/aref.rs | 113 +++ module/core/format_tools/src/lib.rs | 92 ++ .../format_tools/tests/inc/fields_test.rs | 135 +++ .../format_tools/tests/inc/md_math_test.rs | 17 + module/core/format_tools/tests/inc/mod.rs | 18 + .../core/format_tools/tests/inc/print_test.rs | 191 ++++ .../format_tools/tests/inc/string_test.rs | 144 +++ .../format_tools/tests/inc/to_string_test.rs | 104 +++ .../tests/inc/to_string_with_fallback_test.rs | 285 ++++++ module/core/format_tools/tests/smoke_test.rs | 14 + module/core/format_tools/tests/tests.rs | 10 + module/core/former/Cargo.toml | 29 +- module/core/former/Readme.md | 46 +- .../examples/former_collection_hashmap.rs | 2 +- .../examples/former_collection_hashset.rs | 2 +- .../examples/former_collection_vector.rs | 2 +- .../former/examples/former_custom_mutator.rs | 2 +- .../examples/former_custom_scalar_setter.rs | 2 +- .../former_custom_subform_collection.rs | 2 +- .../examples/former_custom_subform_entry.rs | 2 +- .../examples/former_custom_subform_entry2.rs | 2 +- .../examples/former_custom_subform_scalar.rs | 2 +- module/core/former/examples/former_trivial.rs | 17 +- .../former/examples/former_trivial_expaned.rs | 18 +- module/core/former/src/lib.rs | 73 +- .../inc/components_tests/component_assign.rs | 1 + .../only_test/component_assign.rs | 7 + ...lision_former_hashmap_without_parameter.rs | 2 + ...llision_former_vector_without_parameter.rs | 2 + .../tests/inc/former_tests/name_collisions.rs | 2 + .../former_tests/parametrized_slice_manual.rs | 8 +- module/core/former/tests/smoke_test.rs | 4 +- module/core/former_meta/Cargo.toml | 27 +- module/core/former_meta/Readme.md | 2 +- .../former_meta/src/derive_former/field.rs | 2 +- .../src/derive_former/field_attrs.rs | 13 +- .../src/derive_former/struct_attrs.rs | 5 +- module/core/former_meta/src/lib.rs | 22 +- module/core/former_meta/tests/smoke_test.rs | 4 +- module/core/former_types/Cargo.toml | 15 +- module/core/former_types/Readme.md | 6 +- .../examples/former_types_trivial.rs | 4 +- module/core/former_types/src/collection.rs | 26 +- .../src/collection/binary_heap.rs | 3 +- module/core/former_types/src/component.rs | 12 + module/core/former_types/src/definition.rs | 2 +- module/core/former_types/src/lib.rs | 58 +- module/core/former_types/src/storage.rs | 2 +- module/core/former_types/tests/inc/mod.rs | 3 +- module/core/former_types/tests/smoke_test.rs | 4 +- module/core/former_types/tests/tests.rs | 2 +- module/core/fs_tools/src/fs/fs.rs | 23 +- module/core/fs_tools/src/fs/lib.rs | 23 +- module/core/fs_tools/tests/smoke_test.rs | 4 +- module/core/implements/Cargo.toml | 2 +- module/core/implements/src/lib.rs | 26 +- module/core/implements/tests/smoke_test.rs | 4 +- .../core/impls_index/src/impls_index/func.rs | 17 +- .../core/impls_index/src/impls_index/impls.rs | 10 +- .../core/impls_index/src/impls_index/mod.rs | 23 +- module/core/impls_index/src/lib.rs | 23 +- module/core/impls_index/tests/smoke_test.rs | 4 +- module/core/impls_index_meta/Cargo.toml | 4 +- module/core/include_md/Cargo.toml | 2 +- .../include_md/src/_blank/standard_lib.rs | 20 +- module/core/include_md/tests/smoke_test.rs | 4 +- module/core/inspect_type/Cargo.toml | 5 - module/core/inspect_type/build.rs | 6 +- module/core/inspect_type/src/lib.rs | 48 +- module/core/inspect_type/tests/smoke_test.rs | 4 +- module/core/inspect_type/tests/tests.rs | 2 + module/core/interval_adapter/Cargo.toml | 7 +- module/core/interval_adapter/src/lib.rs | 42 +- module/core/interval_adapter/tests/inc/mod.rs | 3 + .../interval_adapter/tests/interval_tests.rs | 2 + module/core/is_slice/Cargo.toml | 4 - module/core/is_slice/src/lib.rs | 46 +- module/core/is_slice/tests/inc/mod.rs | 2 + module/core/is_slice/tests/smoke_test.rs | 4 +- module/core/iter_tools/Cargo.toml | 24 +- module/core/iter_tools/src/iter.rs | 261 +++++- module/core/iter_tools/src/lib.rs | 42 +- module/core/iter_tools/tests/smoke_test.rs | 4 +- module/core/macro_tools/Cargo.toml | 78 +- module/core/macro_tools/Readme.md | 26 +- .../examples/macro_tools_attr_prop.rs | 23 +- .../examples/macro_tools_trivial.rs | 4 +- module/core/macro_tools/src/attr.rs | 124 +-- module/core/macro_tools/src/attr_prop.rs | 70 +- .../core/macro_tools/src/attr_prop/boolean.rs | 2 +- .../src/attr_prop/boolean_optional.rs | 2 +- .../macro_tools/src/attr_prop/singletone.rs | 2 +- .../src/attr_prop/singletone_optional.rs | 2 +- module/core/macro_tools/src/attr_prop/syn.rs | 2 +- .../macro_tools/src/attr_prop/syn_optional.rs | 2 +- module/core/macro_tools/src/components.rs | 70 ++ module/core/macro_tools/src/container_kind.rs | 30 +- module/core/macro_tools/src/ct.rs | 64 ++ module/core/macro_tools/src/ct/str.rs | 8 + module/core/macro_tools/src/derive.rs | 34 +- module/core/macro_tools/src/diag.rs | 50 +- module/core/macro_tools/src/drop.rs | 96 -- module/core/macro_tools/src/equation.rs | 32 +- module/core/macro_tools/src/generic_args.rs | 37 +- module/core/macro_tools/src/generic_params.rs | 42 +- module/core/macro_tools/src/item.rs | 34 +- module/core/macro_tools/src/item_struct.rs | 46 +- module/core/macro_tools/src/iter.rs | 117 +-- module/core/macro_tools/src/kw.rs | 71 ++ module/core/macro_tools/src/lib.rs | 393 +++++--- module/core/macro_tools/src/name.rs | 30 +- module/core/macro_tools/src/phantom.rs | 51 +- module/core/macro_tools/src/punctuated.rs | 32 +- module/core/macro_tools/src/quantifier.rs | 97 +- module/core/macro_tools/src/struct_like.rs | 89 +- module/core/macro_tools/src/tokens.rs | 31 +- module/core/macro_tools/src/typ.rs | 52 +- module/core/macro_tools/src/typed.rs | 61 ++ .../macro_tools/tests/inc/attr_prop_test.rs | 11 +- .../core/macro_tools/tests/inc/attr_test.rs | 66 ++ .../tests/inc/compile_time_test.rs | 40 + .../tests/inc/container_kind_test.rs | 1 + .../core/macro_tools/tests/inc/derive_test.rs | 6 +- .../core/macro_tools/tests/inc/diag_test.rs | 1 + .../macro_tools/tests/inc/equation_test.rs | 3 + .../tests/inc/generic_args_test.rs | 1 + .../tests/inc/generic_params_test.rs | 1 + module/core/macro_tools/tests/inc/mod.rs | 20 +- .../macro_tools/tests/inc/phantom_test.rs | 1 + .../macro_tools/tests/inc/quantifier_test.rs | 1 + .../core/macro_tools/tests/inc/syntax_test.rs | 83 -- .../core/macro_tools/tests/inc/tokens_test.rs | 1 + .../tests/inc/{typ_Test.rs => typ_test.rs} | 19 +- module/core/macro_tools/tests/smoke_test.rs | 4 +- module/core/mem_tools/Cargo.toml | 2 +- module/core/mem_tools/src/lib.rs | 23 +- module/core/mem_tools/src/mem.rs | 19 +- module/core/mem_tools/tests/smoke_test.rs | 4 +- module/core/meta_tools/Cargo.toml | 2 +- module/core/meta_tools/tests/smoke_test.rs | 4 +- module/core/mod_interface/Cargo.toml | 4 +- module/core/mod_interface/Readme.md | 34 +- module/core/mod_interface/src/lib.rs | 23 +- .../tests/inc/derive/attr_debug/layer_a.rs | 27 +- .../tests/inc/derive/layer/layer_a.rs | 27 +- .../tests/inc/derive/layer/layer_b.rs | 27 +- .../tests/inc/derive/layer_bad_vis/layer_a.rs | 27 +- .../inc/derive/layer_have_layer/layer_a.rs | 8 +- .../inc/derive/layer_have_layer/layer_b.rs | 6 +- .../derive/layer_have_layer_cfg/layer_a.rs | 8 +- .../derive/layer_have_layer_cfg/layer_b.rs | 6 +- .../layer_have_layer_separate_use/layer_a.rs | 6 +- .../layer_have_layer_separate_use/layer_b.rs | 6 +- .../layer_a.rs | 6 +- .../layer_b.rs | 6 +- .../inc/derive/layer_unknown_vis/layer_a.rs | 27 +- .../tests/inc/derive/layer_use_cfg/layer_a.rs | 8 +- .../tests/inc/derive/layer_use_cfg/layer_b.rs | 6 +- .../tests/inc/derive/micro_modules/mod.rs | 4 +- .../inc/derive/micro_modules/mod_protected.rs | 4 +- .../tests/inc/derive/micro_modules_two/mod.rs | 8 +- .../micro_modules_two/mod_protected1.rs | 4 +- .../micro_modules_two/mod_protected2.rs | 4 +- .../derive/micro_modules_two_joined/mod.rs | 10 +- .../mod_protected1.rs | 4 +- .../mod_protected2.rs | 4 +- .../tests/inc/derive/use_as/layer_x.rs | 27 +- .../tests/inc/derive/use_as/layer_y.rs | 27 +- .../tests/inc/derive/use_as/manual_only.rs | 12 +- .../tests/inc/derive/use_basic/layer_a.rs | 27 +- .../tests/inc/derive/use_basic/layer_b.rs | 27 +- .../tests/inc/manual/layer/layer_a.rs | 27 +- .../tests/inc/manual/layer/layer_b.rs | 27 +- .../tests/inc/manual/layer/mod.rs | 23 +- .../tests/inc/manual/layer_use/layer_a.rs | 35 +- .../tests/inc/manual/layer_use/layer_b.rs | 35 +- .../tests/inc/manual/layer_use/mod.rs | 23 +- .../tests/inc/manual/micro_modules/mod.rs | 27 +- .../inc/manual/micro_modules/mod_protected.rs | 4 +- .../tests/inc/manual/micro_modules_two/mod.rs | 31 +- .../micro_modules_two/mod_protected1.rs | 4 +- .../micro_modules_two/mod_protected2.rs | 4 +- .../inc/only_test/layer_simple_only_test.rs | 36 +- .../inc/only_test/layer_single_only_test.rs | 18 +- .../inc/only_test/micro_modules_only_test.rs | 20 +- .../only_test/micro_modules_two_only_test.rs | 36 +- .../inc/only_test/use_non_layer_only_test.rs | 24 +- module/core/mod_interface/tests/smoke_test.rs | 4 +- module/core/mod_interface_meta/Cargo.toml | 4 +- module/core/mod_interface_meta/src/impls.rs | 94 +- module/core/mod_interface_meta/src/lib.rs | 43 +- module/core/mod_interface_meta/src/record.rs | 42 +- .../core/mod_interface_meta/src/use_tree.rs | 36 +- .../core/mod_interface_meta/src/visibility.rs | 72 +- .../mod_interface_meta/tests/smoke_test.rs | 4 +- module/core/process_tools/Cargo.toml | 6 +- module/core/process_tools/src/environment.rs | 2 +- module/core/process_tools/src/process.rs | 16 +- module/core/process_tools/tests/smoke_test.rs | 4 +- module/core/program_tools/Cargo.toml | 2 +- module/core/program_tools/src/lib.rs | 2 +- module/core/program_tools/src/program.rs | 2 +- module/core/program_tools/tests/smoke_test.rs | 4 +- module/core/proper_path_tools/Cargo.toml | 16 +- module/core/proper_path_tools/src/lib.rs | 7 + module/core/proper_path_tools/src/path.rs | 283 +++--- .../src/path/absolute_path.rs | 279 +++++- .../src/path/canonical_path.rs | 287 ++++++ .../src/path/current_path.rs | 62 ++ .../proper_path_tools/src/path/native_path.rs | 302 ++++++ .../core/proper_path_tools/src/transitive.rs | 201 ++++ .../tests/inc/absolute_path.rs | 40 +- .../tests/inc/current_path.rs | 33 + .../core/proper_path_tools/tests/inc/mod.rs | 3 + .../tests/inc/path_canonicalize.rs | 50 + .../proper_path_tools/tests/inc/path_join.rs | 476 +++++++--- .../tests/inc/path_relative.rs | 86 +- .../proper_path_tools/tests/inc/transitive.rs | 86 ++ .../proper_path_tools/tests/smoke_test.rs | 4 +- module/core/reflect_tools/Cargo.toml | 22 +- module/core/reflect_tools/src/lib.rs | 39 +- module/core/reflect_tools/src/reflect.rs | 54 +- .../reflect_tools/src/reflect/axiomatic.rs | 35 +- .../reflect_tools/src/reflect/entity_array.rs | 25 +- .../src/reflect/entity_hashmap.rs | 29 +- .../src/reflect/entity_hashset.rs | 27 +- .../reflect_tools/src/reflect/entity_slice.rs | 37 +- .../reflect_tools/src/reflect/entity_vec.rs | 27 +- .../core/reflect_tools/src/reflect/fields.rs | 207 +++++ .../reflect_tools/src/reflect/primitive.rs | 25 +- .../core/reflect_tools/src/reflect/wrapper.rs | 52 ++ .../src/reflect/wrapper/maybe_as.rs | 214 +++++ .../tests/inc/fundamental/fields_test.rs | 153 +++ .../array_test.rs} | 0 .../common_test.rs} | 0 .../hashmap_test.rs} | 0 .../hashset_test.rs} | 0 .../inc/{ => group1}/newtype_experiment.rs | 0 .../tests/inc/{ => group1}/only_test/all.rs | 0 .../{ => group1}/only_test/reflect_struct.rs | 2 +- .../only_test/reflect_struct_in_struct.rs | 6 +- .../only_test/reflect_struct_with_lifetime.rs | 2 +- .../primitive_test.rs} | 0 .../slice_test.rs} | 0 .../struct_in_struct_manual_test.rs} | 0 .../struct_manual_test.rs} | 0 .../struct_with_lifetime_manual_test.rs} | 0 .../vec_test.rs} | 0 module/core/reflect_tools/tests/inc/mod.rs | 54 +- module/core/reflect_tools/tests/smoke_test.rs | 4 +- module/core/reflect_tools_meta/Cargo.toml | 12 +- .../src/implementation/reflect.rs | 4 +- module/core/reflect_tools_meta/src/lib.rs | 23 +- module/core/strs_tools/Cargo.toml | 4 +- module/core/strs_tools/src/lib.rs | 20 +- .../core/strs_tools/src/string/indentation.rs | 30 +- module/core/strs_tools/src/string/isolate.rs | 16 +- module/core/strs_tools/src/string/mod.rs | 19 +- module/core/strs_tools/src/string/number.rs | 31 +- .../strs_tools/src/string/parse_request.rs | 27 +- module/core/strs_tools/src/string/split.rs | 27 +- module/core/strs_tools/tests/smoke_test.rs | 4 +- module/core/test_tools/Cargo.toml | 2 +- module/core/test_tools/build.rs | 4 + module/core/test_tools/src/lib.rs | 2 +- module/core/test_tools/src/test/asset.rs | 2 +- .../core/test_tools/src/test/compiletime.rs | 2 +- .../dynamic/namespace_does_not_exists.stderr | 4 +- module/core/test_tools/tests/smoke_test.rs | 4 +- module/core/time_tools/Cargo.toml | 2 +- module/core/time_tools/src/lib.rs | 23 +- module/core/time_tools/tests/smoke_test.rs | 4 +- module/core/typing_tools/Cargo.toml | 2 +- module/core/typing_tools/src/lib.rs | 23 +- module/core/typing_tools/src/typing.rs | 23 +- module/core/typing_tools/tests/smoke_test.rs | 4 +- module/core/variadic_from/Cargo.toml | 4 +- module/core/variadic_from/Readme.md | 8 +- .../examples/variadic_from_trivial.rs | 4 +- .../variadic_from_trivial_expanded.rs | 4 +- module/core/variadic_from/src/lib.rs | 26 +- module/core/variadic_from/src/variadic.rs | 29 +- module/core/variadic_from/tests/smoke_test.rs | 4 +- module/core/wtools/Cargo.toml | 14 +- module/core/wtools/src/lib.rs | 23 +- module/core/wtools/tests/smoke_test.rs | 4 +- module/move/assistant/Cargo.toml | 45 + module/move/assistant/License | 22 + module/move/assistant/Readme.md | 33 + module/move/assistant/api/list.http | 3 + module/move/assistant/src/client.rs | 96 ++ module/move/assistant/src/lib.rs | 84 ++ module/move/assistant/src/main.rs | 28 + module/move/assistant/tests/inc/basic_test.rs | 7 + .../assistant/tests/inc/experiment.rs} | 0 module/move/assistant/tests/inc/mod.rs | 6 + module/move/assistant/tests/smoke_test.rs | 12 + module/move/assistant/tests/tests.rs | 10 + module/move/crates_tools/Cargo.toml | 2 +- module/move/crates_tools/src/lib.rs | 22 +- module/move/crates_tools/tests/smoke_test.rs | 4 +- module/move/deterministic_rand/Cargo.toml | 2 +- module/move/deterministic_rand/src/lib.rs | 2 +- module/move/graphs_tools/Cargo.toml | 2 +- module/move/graphs_tools/src/lib.rs | 2 +- module/move/graphs_tools/tests/smoke_test.rs | 4 +- .../optimization_tools/.cargo/config.toml | 4 +- .../src/problems/traveling_salesman.rs | 12 +- .../optimization_tools/tests/optimization.rs | 1 - module/move/plot_interface/Cargo.toml | 2 +- .../plot_interface/src/plot/abs/change.rs | 2 +- .../plot_interface/src/plot/abs/changer.rs | 2 +- .../plot_interface/src/plot/abs/context.rs | 2 +- .../plot_interface/src/plot/abs/identity.rs | 2 +- .../plot_interface/src/plot/abs/registry.rs | 2 +- module/move/plot_interface/src/plot/color.rs | 4 +- .../plot_interface/src/plot/sys/context.rs | 4 +- .../src/plot/sys/context_changer.rs | 2 +- .../plot_interface/src/plot/sys/drawing.rs | 2 +- .../src/plot/sys/drawing/change_new.rs | 2 +- .../src/plot/sys/drawing/changer.rs | 2 +- .../src/plot/sys/drawing/command.rs | 2 +- .../src/plot/sys/drawing/queue.rs | 2 +- .../src/plot/sys/drawing/rect_change_new.rs | 2 +- .../plot/sys/drawing/rect_change_region.rs | 2 +- .../src/plot/sys/drawing/rect_changer.rs | 2 +- .../src/plot/sys/stroke_brush.rs | 2 +- .../src/plot/sys/stroke_brush/change_color.rs | 2 +- .../src/plot/sys/stroke_brush/change_new.rs | 2 +- .../src/plot/sys/stroke_brush/change_width.rs | 2 +- .../src/plot/sys/stroke_brush/changer.rs | 2 +- .../move/plot_interface/src/plot/wplot_lib.rs | 2 +- .../move/plot_interface/tests/smoke_test.rs | 4 +- module/move/refiner/tests/smoke_test.rs | 4 +- module/move/sqlx_query/Cargo.toml | 2 +- module/move/sqlx_query/src/lib.rs | 20 +- module/move/sqlx_query/tests/smoke_test.rs | 4 +- module/move/unitore/src/action/config.rs | 4 +- module/move/unitore/src/action/feed.rs | 2 +- module/move/unitore/src/action/frame.rs | 2 +- module/move/unitore/src/action/query.rs | 2 +- module/move/unitore/src/action/table.rs | 2 +- module/move/unitore/src/command/config.rs | 2 +- module/move/unitore/src/command/feed.rs | 2 +- module/move/unitore/src/command/frame.rs | 2 +- module/move/unitore/src/command/query.rs | 2 +- module/move/unitore/src/command/table.rs | 2 +- module/move/unitore/src/entity/config.rs | 2 +- module/move/unitore/src/entity/feed.rs | 2 +- module/move/unitore/src/entity/frame.rs | 2 +- module/move/unitore/src/entity/table.rs | 2 +- module/move/unitore/src/executor.rs | 2 +- module/move/unitore/src/feed_config.rs | 2 +- module/move/unitore/src/retriever.rs | 2 +- .../move/unitore/src/sled_adapter/config.rs | 2 +- module/move/unitore/src/sled_adapter/feed.rs | 6 +- module/move/unitore/src/sled_adapter/frame.rs | 8 +- module/move/unitore/src/sled_adapter/mod.rs | 2 +- module/move/unitore/src/sled_adapter/table.rs | 2 +- module/move/unitore/tests/basic.rs | 2 +- module/move/unitore/tests/config_add.rs | 2 +- module/move/unitore/tests/config_delete.rs | 2 +- module/move/unitore/tests/frames_download.rs | 4 +- module/move/unitore/tests/query_execute.rs | 2 +- module/move/unitore/tests/table_list.rs | 2 +- module/move/unitore/tests/tables_list.rs | 2 +- module/move/wca/Cargo.toml | 3 +- module/move/wca/examples/wca_fluent.rs | 7 +- module/move/wca/src/ca/aggregator.rs | 14 +- module/move/wca/src/ca/executor/executor.rs | 36 +- module/move/wca/src/ca/executor/routine.rs | 52 +- module/move/wca/src/ca/facade.rs | 690 +++++++------- module/move/wca/src/ca/formatter.rs | 2 +- module/move/wca/src/ca/grammar/command.rs | 8 +- module/move/wca/src/ca/grammar/dictionary.rs | 2 +- module/move/wca/src/ca/grammar/types.rs | 20 +- module/move/wca/src/ca/help.rs | 28 +- module/move/wca/src/ca/mod.rs | 9 +- module/move/wca/src/ca/parser/parser.rs | 31 +- module/move/wca/src/ca/tool/mod.rs | 8 + module/move/wca/src/ca/tool/table.rs | 30 +- module/move/wca/src/ca/verifier/verifier.rs | 233 +---- module/move/wca/src/lib.rs | 15 +- module/move/wca/src/wtools.rs | 35 +- module/move/wca/tests/inc/executor/mod.rs | 4 +- module/move/wca/tests/inc/executor/program.rs | 2 +- module/move/wca/tests/inc/mod.rs | 4 + module/move/wca/tests/smoke_test.rs | 4 +- module/move/wca/tests/wca_tests.rs | 4 +- module/move/willbe/Cargo.toml | 39 +- .../willbe/src/{description.md => Readme.md} | 0 module/move/willbe/src/action/cicd_renew.rs | 274 ++++-- module/move/willbe/src/action/deploy_renew.rs | 317 ++++--- module/move/willbe/src/action/features.rs | 43 +- module/move/willbe/src/action/list.rs | 692 ++++++++------ module/move/willbe/src/action/main_header.rs | 165 ++-- module/move/willbe/src/action/mod.rs | 2 - module/move/willbe/src/action/publish.rs | 177 ++-- module/move/willbe/src/action/publish_diff.rs | 122 ++- .../src/action/readme_health_table_renew.rs | 490 ++++++---- .../action/readme_modules_headers_renew.rs | 237 +++-- module/move/willbe/src/action/test.rs | 158 ++-- .../move/willbe/src/action/workspace_renew.rs | 150 +-- module/move/willbe/src/bin/cargo-will.rs | 2 +- module/move/willbe/src/bin/will.rs | 5 +- module/move/willbe/src/bin/willbe.rs | 2 +- module/move/willbe/src/command/cicd_renew.rs | 11 +- .../move/willbe/src/command/deploy_renew.rs | 16 +- module/move/willbe/src/command/features.rs | 25 +- module/move/willbe/src/command/list.rs | 55 +- module/move/willbe/src/command/main_header.rs | 16 +- module/move/willbe/src/command/mod.rs | 19 +- module/move/willbe/src/command/publish.rs | 67 +- .../move/willbe/src/command/publish_diff.rs | 19 +- .../src/command/readme_headers_renew.rs | 52 +- .../src/command/readme_health_table_renew.rs | 11 +- .../command/readme_modules_headers_renew.rs | 16 +- module/move/willbe/src/command/test.rs | 93 +- .../willbe/src/command/workspace_renew.rs | 22 +- module/move/willbe/src/entity/channel.rs | 35 +- module/move/willbe/src/entity/code.rs | 43 + module/move/willbe/src/entity/dependency.rs | 287 ++++++ module/move/willbe/src/entity/diff.rs | 24 +- module/move/willbe/src/entity/features.rs | 33 +- module/move/willbe/src/entity/files.rs | 54 ++ .../move/willbe/src/entity/files/crate_dir.rs | 259 ++++++ module/move/willbe/src/entity/files/either.rs | 90 ++ .../willbe/src/entity/files/manifest_file.rs | 276 ++++++ .../willbe/src/entity/files/source_file.rs | 270 ++++++ module/move/willbe/src/entity/git.rs | 88 ++ module/move/willbe/src/entity/manifest.rs | 206 +---- module/move/willbe/src/entity/mod.rs | 87 +- module/move/willbe/src/entity/optimization.rs | 21 +- module/move/willbe/src/entity/package.rs | 873 ++---------------- .../willbe/src/entity/package_md_extension.rs | 152 +++ module/move/willbe/src/entity/packages.rs | 40 +- module/move/willbe/src/entity/packed_crate.rs | 19 +- module/move/willbe/src/entity/progress_bar.rs | 108 +++ module/move/willbe/src/entity/publish.rs | 442 +++++++++ module/move/willbe/src/entity/table.rs | 26 +- module/move/willbe/src/entity/test.rs | 352 +++---- module/move/willbe/src/entity/version.rs | 166 ++-- module/move/willbe/src/entity/workspace.rs | 481 ++++------ .../move/willbe/src/entity/workspace_graph.rs | 38 + .../src/entity/workspace_md_extension.rs | 70 ++ .../willbe/src/entity/workspace_package.rs | 212 +++++ module/move/willbe/src/lib.rs | 12 +- module/move/willbe/src/tool/_path.rs | 170 ---- module/move/willbe/src/tool/cargo.rs | 89 +- module/move/willbe/src/tool/collection.rs | 12 + module/move/willbe/src/tool/error.rs | 21 + module/move/willbe/src/tool/files.rs | 10 +- module/move/willbe/src/tool/git.rs | 58 +- module/move/willbe/src/tool/graph.rs | 81 +- module/move/willbe/src/tool/http.rs | 8 +- module/move/willbe/src/tool/iter.rs | 12 + module/move/willbe/src/tool/macros.rs | 12 + module/move/willbe/src/tool/mod.rs | 53 +- module/move/willbe/src/tool/path.rs | 12 + module/move/willbe/src/tool/query.rs | 28 +- module/move/willbe/src/tool/repository.rs | 61 ++ module/move/willbe/src/tool/sha.rs | 26 - module/move/willbe/src/tool/template.rs | 227 +++-- module/move/willbe/src/tool/tree.rs | 167 ++++ module/move/willbe/src/tool/url.rs | 19 +- module/move/willbe/src/wtools.rs | 56 +- .../move/willbe/template/deploy/Makefile.hbs | 128 +-- .../template/workflow/standard_rust_push.yml | 6 +- .../move/willbe/template/workspace/Makefile | 78 +- .../workspace/module/module1/Cargo.toml.x | 2 +- .../module1/examples/module1_example.rs | 4 +- .../workspace/module/module1/src/lib.rs | 2 +- .../module/module1/tests/hello_test.rs | 2 +- .../Cargo.toml | 2 +- ...e_variadic_tag_configurations_c_trivial.rs | 0 .../src/lib.rs | 0 .../module/test_module/Cargo.toml | 2 +- .../test_module/Cargo.toml | 2 +- .../tests/asset/three_packages/b/Cargo.toml | 4 +- .../tests/asset/three_packages/c/Cargo.toml | 2 +- .../tests/asset/three_packages/d/Cargo.toml | 2 +- .../three_packages_with_features/b/Cargo.toml | 6 +- .../three_packages_with_features/c/Cargo.toml | 2 +- .../three_packages_with_features/d/Cargo.toml | 2 +- .../{action => action_tests}/cicd_renew.rs | 18 +- .../inc/{action => action_tests}/features.rs | 49 +- .../inc/{action => action_tests}/list.rs | 0 .../inc/{action => action_tests}/list/data.rs | 48 +- .../{action => action_tests}/list/format.rs | 89 +- .../{action => action_tests}/main_header.rs | 2 +- .../tests/inc/{action => action_tests}/mod.rs | 0 .../readme_health_table_renew.rs | 12 +- .../readme_modules_headers_renew.rs | 30 +- .../inc/{action => action_tests}/test.rs | 132 +-- .../workspace_renew.rs | 0 .../willbe/tests/inc/command/tests_run.rs | 9 +- .../willbe/tests/inc/entity/dependencies.rs | 129 ++- module/move/willbe/tests/inc/entity/diff.rs | 27 +- .../move/willbe/tests/inc/entity/features.rs | 28 +- .../move/willbe/tests/inc/entity/version.rs | 46 +- module/move/willbe/tests/inc/helper.rs | 116 +++ module/move/willbe/tests/inc/helpers.rs | 1 - module/move/willbe/tests/inc/mod.rs | 22 +- module/move/willbe/tests/inc/package.rs | 8 +- module/move/willbe/tests/inc/tool/graph.rs | 217 ----- .../move/willbe/tests/inc/tool/graph_test.rs | 215 +++++ module/move/willbe/tests/inc/tool/mod.rs | 9 +- module/move/willbe/tests/inc/tool/process.rs | 65 -- .../inc/tool/{query.rs => query_test.rs} | 11 +- module/move/willbe/tests/smoke_test.rs | 4 +- module/move/wplot/Cargo.toml | 2 +- module/move/wplot/src/plot/abs/change.rs | 2 +- module/move/wplot/src/plot/abs/changer.rs | 2 +- module/move/wplot/src/plot/abs/context.rs | 2 +- module/move/wplot/src/plot/abs/identity.rs | 2 +- module/move/wplot/src/plot/abs/registry.rs | 2 +- module/move/wplot/src/plot/color.rs | 4 +- module/move/wplot/src/plot/sys/context.rs | 4 +- .../wplot/src/plot/sys/context_changer.rs | 2 +- module/move/wplot/src/plot/sys/drawing.rs | 2 +- .../wplot/src/plot/sys/drawing/change_new.rs | 2 +- .../wplot/src/plot/sys/drawing/changer.rs | 2 +- .../wplot/src/plot/sys/drawing/command.rs | 2 +- .../move/wplot/src/plot/sys/drawing/queue.rs | 2 +- .../src/plot/sys/drawing/rect_change_new.rs | 2 +- .../plot/sys/drawing/rect_change_region.rs | 2 +- .../src/plot/sys/drawing/rect_changer.rs | 2 +- .../move/wplot/src/plot/sys/stroke_brush.rs | 2 +- .../src/plot/sys/stroke_brush/change_color.rs | 2 +- .../src/plot/sys/stroke_brush/change_new.rs | 2 +- .../src/plot/sys/stroke_brush/change_width.rs | 2 +- .../src/plot/sys/stroke_brush/changer.rs | 2 +- module/move/wplot/src/plot/wplot_lib.rs | 4 +- module/move/wplot/tests/smoke_test.rs | 4 +- module/postponed/_video_experiment/Cargo.toml | 2 +- .../_video_experiment/tests/smoke_test.rs | 4 +- .../automata_tools/tests/smoke_test.rs | 4 +- module/postponed/non_std/Cargo.toml | 12 +- module/postponed/non_std/tests/smoke_test.rs | 4 +- module/postponed/std_tools/Cargo.toml | 12 +- .../postponed/std_tools/tests/smoke_test.rs | 4 +- module/postponed/std_x/Cargo.toml | 12 +- module/postponed/std_x/tests/smoke_test.rs | 4 +- module/postponed/type_constructor/Cargo.toml | 2 +- module/postponed/type_constructor/src/lib.rs | 22 +- .../src/type_constuctor/enumerable.rs | 26 +- .../src/type_constuctor/helper.rs | 23 +- .../src/type_constuctor/make.rs | 14 +- .../src/type_constuctor/many.rs | 26 +- .../src/type_constuctor/mod.rs | 20 +- .../src/type_constuctor/no_many.rs | 23 +- .../src/type_constuctor/pair.rs | 26 +- .../src/type_constuctor/single.rs | 26 +- .../src/type_constuctor/traits.rs | 23 +- .../src/type_constuctor/types.rs | 23 +- .../src/type_constuctor/vectorized_from.rs | 23 +- .../type_constructor/tests/smoke_test.rs | 4 +- .../postponed/wautomata/tests/smoke_test.rs | 4 +- module/postponed/wpublisher/Cargo.toml | 2 +- .../postponed/wpublisher/tests/smoke_test.rs | 4 +- .../_template_procedural_macro/front/lib.rs | 16 +- .../_template_procedural_macro/runtime/lib.rs | 16 +- module/step/meta/tests/smoke_test.rs | 4 +- module/template/layer/layer.rs | 29 +- .../template_alias/Cargo.toml.template | 2 - module/template/template_alias/src/lib.rs | 1 - module/template/template_alias/src/main.rs | 1 - .../template_alias/tests/smoke_test.rs | 4 +- .../template_blank/Cargo.toml.template | 2 - module/template/template_blank/src/lib.rs | 1 - .../template_blank/tests/smoke_test.rs | 2 - .../tests/smoke_test.rs | 4 +- .../tests/smoke_test.rs | 4 +- .../tests/smoke_test.rs | 4 +- step/Cargo.toml | 24 + step/src/bin/sources.rs | 66 ++ 1123 files changed, 25432 insertions(+), 10850 deletions(-) create mode 100644 .github/workflows/module_assistant_push.yml create mode 100644 .github/workflows/module_brain_tools_push.yml create mode 100644 .github/workflows/module_clone_dyn_types_push.yml create mode 100644 .github/workflows/module_drawboard_push.yml create mode 100644 .github/workflows/module_drawql_push.yml create mode 100644 .github/workflows/module_format_tools_push.yml create mode 100644 .github/workflows/module_paths_tools_push.yml create mode 100644 .github/workflows/module_second_brain_push.yml create mode 100644 .github/workflows/module_step_push.yml delete mode 100644 bash.exe.stackdump create mode 100644 module/blank/brain_tools/Cargo.toml rename module/blank/{willbe_old => brain_tools}/License (100%) create mode 100644 module/blank/brain_tools/Readme.md create mode 100644 module/blank/brain_tools/src/lib.rs create mode 100644 module/blank/brain_tools/tests/inc/basic_test.rs create mode 100644 module/blank/brain_tools/tests/inc/mod.rs rename module/blank/{willbe_old => brain_tools}/tests/smoke_test.rs (67%) create mode 100644 module/blank/brain_tools/tests/tests.rs create mode 100644 module/blank/draw_lang/Cargo.toml create mode 100644 module/blank/draw_lang/License create mode 100644 module/blank/draw_lang/Readme.md create mode 100644 module/blank/draw_lang/src/lib.rs create mode 100644 module/blank/draw_lang/tests/inc/basic_test.rs create mode 100644 module/blank/draw_lang/tests/inc/mod.rs create mode 100644 module/blank/draw_lang/tests/smoke_test.rs create mode 100644 module/blank/draw_lang/tests/tests.rs create mode 100644 module/blank/drawboard/Cargo.toml create mode 100644 module/blank/drawboard/License create mode 100644 module/blank/drawboard/Readme.md create mode 100644 module/blank/drawboard/src/lib.rs create mode 100644 module/blank/drawboard/tests/inc/basic_test.rs create mode 100644 module/blank/drawboard/tests/inc/mod.rs create mode 100644 module/blank/drawboard/tests/smoke_test.rs create mode 100644 module/blank/drawboard/tests/tests.rs create mode 100644 module/blank/drawql/Cargo.toml create mode 100644 module/blank/drawql/License create mode 100644 module/blank/drawql/Readme.md create mode 100644 module/blank/drawql/src/lib.rs create mode 100644 module/blank/drawql/tests/inc/basic_test.rs create mode 100644 module/blank/drawql/tests/inc/mod.rs create mode 100644 module/blank/drawql/tests/smoke_test.rs create mode 100644 module/blank/drawql/tests/tests.rs create mode 100644 module/blank/paths_tools/Cargo.toml create mode 100644 module/blank/paths_tools/License create mode 100644 module/blank/paths_tools/Readme.md create mode 100644 module/blank/paths_tools/src/lib.rs create mode 100644 module/blank/paths_tools/tests/inc/basic_test.rs create mode 100644 module/blank/paths_tools/tests/inc/mod.rs create mode 100644 module/blank/paths_tools/tests/smoke_test.rs create mode 100644 module/blank/paths_tools/tests/tests.rs create mode 100644 module/blank/second_brain/Cargo.toml create mode 100644 module/blank/second_brain/License create mode 100644 module/blank/second_brain/Readme.md create mode 100644 module/blank/second_brain/src/lib.rs create mode 100644 module/blank/second_brain/tests/inc/basic_test.rs create mode 100644 module/blank/second_brain/tests/inc/mod.rs create mode 100644 module/blank/second_brain/tests/smoke_test.rs create mode 100644 module/blank/second_brain/tests/tests.rs delete mode 100644 module/blank/willbe_old/Cargo.toml delete mode 100644 module/blank/willbe_old/Readme.md delete mode 100644 module/blank/willbe_old/src/willbe_old/commands/each.rs delete mode 100644 module/blank/willbe_old/src/willbe_old/commands/end.rs delete mode 100644 module/blank/willbe_old/src/willbe_old/commands/init.rs delete mode 100644 module/blank/willbe_old/src/willbe_old/commands/mod.rs delete mode 100644 module/blank/willbe_old/src/willbe_old/commands/package/info.rs delete mode 100644 module/blank/willbe_old/src/willbe_old/commands/package/mod.rs delete mode 100644 module/blank/willbe_old/src/willbe_old/commands/package/publish.rs delete mode 100644 module/blank/willbe_old/src/willbe_old/core/entities/mod.rs delete mode 100644 module/blank/willbe_old/src/willbe_old/core/entities/package/metadata.rs delete mode 100644 module/blank/willbe_old/src/willbe_old/core/entities/package/mod.rs delete mode 100644 module/blank/willbe_old/src/willbe_old/core/entities/package/package.rs delete mode 100644 module/blank/willbe_old/src/willbe_old/core/entities/package/verification.rs delete mode 100644 module/blank/willbe_old/src/willbe_old/core/entities/utility.rs delete mode 100644 module/blank/willbe_old/src/willbe_old/core/entities/workspace.rs delete mode 100644 module/blank/willbe_old/src/willbe_old/core/iterators.rs delete mode 100644 module/blank/willbe_old/src/willbe_old/core/mod.rs delete mode 100644 module/blank/willbe_old/src/willbe_old/files.rs delete mode 100644 module/blank/willbe_old/src/willbe_old/willbe_entry.rs delete mode 100644 module/blank/willbe_old/src/willbe_old/willbe_lib.rs delete mode 100644 module/blank/willbe_old/tests/willbe_old/_asset/empty/.gitignore delete mode 100644 module/blank/willbe_old/tests/willbe_old/_asset/package/Cargo.toml delete mode 100644 module/blank/willbe_old/tests/willbe_old/_asset/package/Readme.md delete mode 100644 module/blank/willbe_old/tests/willbe_old/_asset/package/src/lib.rs delete mode 100644 module/blank/willbe_old/tests/willbe_old/_asset/package/src/main.rs delete mode 100644 module/blank/willbe_old/tests/willbe_old/_asset/package_no_verified/Cargo.toml delete mode 100644 module/blank/willbe_old/tests/willbe_old/_asset/package_no_verified/src/lib.rs delete mode 100644 module/blank/willbe_old/tests/willbe_old/_asset/package_no_verified/src/main.rs delete mode 100644 module/blank/willbe_old/tests/willbe_old/_asset/workspace_with_deps/Cargo.toml delete mode 100644 module/blank/willbe_old/tests/willbe_old/_asset/workspace_with_deps/module/module1/Cargo.toml delete mode 100644 module/blank/willbe_old/tests/willbe_old/_asset/workspace_with_deps/module/module1/src/lib.rs delete mode 100644 module/blank/willbe_old/tests/willbe_old/_asset/workspace_with_deps/module/module2/Cargo.toml delete mode 100644 module/blank/willbe_old/tests/willbe_old/_asset/workspace_with_deps/module/module2/src/lib.rs delete mode 100644 module/blank/willbe_old/tests/willbe_old/_asset/workspace_with_deps/module/module3/Cargo.toml delete mode 100644 module/blank/willbe_old/tests/willbe_old/_asset/workspace_with_deps/module/module3/src/lib.rs delete mode 100644 module/blank/willbe_old/tests/willbe_old/_asset/workspaces/Cargo.toml delete mode 100644 module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace1/Cargo.toml delete mode 100644 module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace1/module/module1/Cargo.toml delete mode 100644 module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace1/module/module1/src/lib.rs delete mode 100644 module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace1/module/module2/Cargo.toml delete mode 100644 module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace1/module/module2/src/lib.rs delete mode 100644 module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace2/Cargo.toml delete mode 100644 module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace2/module/module3/Cargo.toml delete mode 100644 module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace2/module/module3/src/lib.rs delete mode 100644 module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace2/module/module4/Cargo.toml delete mode 100644 module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace2/module/module4/src/lib.rs delete mode 100644 module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace2/module/module5/Cargo.toml delete mode 100644 module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace2/module/module5/src/lib.rs delete mode 100644 module/blank/willbe_old/tests/willbe_old/tests/from.rs delete mode 100644 module/blank/willbe_old/tests/willbe_old/tests/integration/each.rs delete mode 100644 module/blank/willbe_old/tests/willbe_old/tests/integration/info.rs delete mode 100644 module/blank/willbe_old/tests/willbe_old/tests/integration/mod.rs delete mode 100644 module/blank/willbe_old/tests/willbe_old/tests/iterator.rs delete mode 100644 module/blank/willbe_old/tests/willbe_old/tests/metadata.rs delete mode 100644 module/blank/willbe_old/tests/willbe_old/tests/mod.rs delete mode 100644 module/blank/willbe_old/tests/willbe_old/tests/ordering/mod.rs delete mode 100644 module/blank/willbe_old/tests/willbe_old/tests/ordering/through_workspaces.rs delete mode 100644 module/blank/willbe_old/tests/willbe_old/tests/ordering/workspace.rs delete mode 100644 module/blank/willbe_old/tests/willbe_old/tests/verification.rs delete mode 100644 module/blank/willbe_old/tests/willbe_old/utility.rs delete mode 100644 module/blank/willbe_old/tests/willbe_old/willbe_test.rs create mode 100644 module/core/clone_dyn/tests/inc/basic.rs create mode 100644 module/core/clone_dyn/tests/inc/basic_manual.rs create mode 100644 module/core/clone_dyn/tests/inc/only_test/basic.rs create mode 100644 module/core/clone_dyn/tests/inc/parametrized.rs create mode 100644 module/core/clone_dyn_types/Cargo.toml create mode 100644 module/core/clone_dyn_types/License create mode 100644 module/core/clone_dyn_types/Readme.md create mode 100644 module/core/clone_dyn_types/examples/clone_dyn_types_trivial.rs create mode 100644 module/core/clone_dyn_types/src/lib.rs create mode 100644 module/core/clone_dyn_types/tests/inc/mod.rs create mode 100644 module/core/clone_dyn_types/tests/smoke_test.rs create mode 100644 module/core/clone_dyn_types/tests/tests.rs rename module/core/derive_tools/tests/inc/{deref_manual_test.rs => deref/basic_manual_test.rs} (95%) rename module/core/derive_tools/tests/inc/{deref_test.rs => deref/basic_test.rs} (92%) rename module/core/derive_tools/tests/inc/{only_test/deref.rs => deref/only_test/basic.rs} (100%) rename module/core/derive_tools/tests/inc/deref/{only_tests => only_test}/bounds_inlined.rs (100%) rename module/core/derive_tools/tests/inc/deref/{only_tests => only_test}/bounds_mixed.rs (100%) rename module/core/derive_tools/tests/inc/deref/{only_tests => only_test}/bounds_where.rs (100%) rename module/core/derive_tools/tests/inc/deref/{only_tests => only_test}/enum_named.rs (100%) rename module/core/derive_tools/tests/inc/deref/{only_tests => only_test}/enum_named_empty.rs (100%) rename module/core/derive_tools/tests/inc/deref/{only_tests => only_test}/enum_tuple.rs (100%) rename module/core/derive_tools/tests/inc/deref/{only_tests => only_test}/enum_tuple_empty.rs (100%) rename module/core/derive_tools/tests/inc/deref/{only_tests => only_test}/enum_unit.rs (100%) rename module/core/derive_tools/tests/inc/deref/{only_tests => only_test}/generics_constants.rs (100%) rename module/core/derive_tools/tests/inc/deref/{only_tests => only_test}/generics_constants_default.rs (100%) rename module/core/derive_tools/tests/inc/deref/{only_tests => only_test}/generics_lifetimes.rs (100%) rename module/core/derive_tools/tests/inc/deref/{only_tests => only_test}/generics_types.rs (100%) rename module/core/derive_tools/tests/inc/deref/{only_tests => only_test}/generics_types_default.rs (100%) rename module/core/derive_tools/tests/inc/deref/{only_tests => only_test}/name_collisions.rs (100%) rename module/core/derive_tools/tests/inc/deref/{only_tests => only_test}/struct_named.rs (100%) rename module/core/derive_tools/tests/inc/deref/{only_tests => only_test}/struct_named_empty.rs (100%) rename module/core/derive_tools/tests/inc/deref/{only_tests => only_test}/struct_tuple.rs (100%) rename module/core/derive_tools/tests/inc/deref/{only_tests => only_test}/struct_tuple_empty.rs (100%) rename module/core/derive_tools/tests/inc/deref/{only_tests => only_test}/struct_unit.rs (100%) rename module/core/derive_tools/tests/inc/{deref_mut_manual_test.rs => deref_mut/basic_manual_test.rs} (96%) rename module/core/derive_tools/tests/inc/{deref_mut_test.rs => deref_mut/basic_test.rs} (92%) rename module/core/derive_tools/tests/inc/{only_test/deref_mut.rs => deref_mut/only_test/basic.rs} (100%) rename module/core/derive_tools/tests/inc/deref_mut/{only_tests => only_test}/bounds_inlined.rs (100%) rename module/core/derive_tools/tests/inc/deref_mut/{only_tests => only_test}/bounds_mixed.rs (100%) rename module/core/derive_tools/tests/inc/deref_mut/{only_tests => only_test}/bounds_where.rs (100%) rename module/core/derive_tools/tests/inc/deref_mut/{only_tests => only_test}/enum_named.rs (100%) rename module/core/derive_tools/tests/inc/deref_mut/{only_tests => only_test}/enum_tuple.rs (100%) rename module/core/derive_tools/tests/inc/deref_mut/{only_tests => only_test}/generics_constants.rs (100%) rename module/core/derive_tools/tests/inc/deref_mut/{only_tests => only_test}/generics_constants_default.rs (100%) rename module/core/derive_tools/tests/inc/deref_mut/{only_tests => only_test}/generics_lifetimes.rs (100%) rename module/core/derive_tools/tests/inc/deref_mut/{only_tests => only_test}/generics_types.rs (100%) rename module/core/derive_tools/tests/inc/deref_mut/{only_tests => only_test}/generics_types_default.rs (100%) rename module/core/derive_tools/tests/inc/deref_mut/{only_tests => only_test}/name_collisions.rs (100%) rename module/core/derive_tools/tests/inc/deref_mut/{only_tests => only_test}/struct_named.rs (100%) rename module/core/derive_tools/tests/inc/deref_mut/{only_tests => only_test}/struct_tuple.rs (100%) rename module/core/derive_tools/tests/inc/from/{manual_test.rs => basic_manual_test.rs} (100%) rename module/core/derive_tools/tests/inc/from/{test.rs => basic_test.rs} (100%) rename module/core/derive_tools/tests/inc/from/{multiple_manual_test.rs => multiple_unnamed_manual_test.rs} (84%) rename module/core/derive_tools/tests/inc/from/{multiple_test.rs => multiple_unnamed_test.rs} (70%) rename module/core/derive_tools/tests/inc/from/only_test/{multiple.rs => multiple_unnamed.rs} (100%) create mode 100644 module/core/derive_tools/tests/inc/index/compiletime/enum.rs create mode 100644 module/core/derive_tools/tests/inc/index/compiletime/enum.stderr create mode 100644 module/core/derive_tools/tests/inc/index/compiletime/struct.rs create mode 100644 module/core/derive_tools/tests/inc/index/compiletime/struct.stderr create mode 100644 module/core/derive_tools/tests/inc/index/compiletime/struct_named_empty.rs create mode 100644 module/core/derive_tools/tests/inc/index/compiletime/struct_named_empty.stderr create mode 100644 module/core/derive_tools/tests/inc/index/compiletime/struct_unit.rs create mode 100644 module/core/derive_tools/tests/inc/index/compiletime/struct_unit.stderr create mode 100644 module/core/derive_tools/tests/inc/index/only_test/struct_multiple_named.rs create mode 100644 module/core/derive_tools/tests/inc/index/only_test/struct_multiple_tuple.rs create mode 100644 module/core/derive_tools/tests/inc/index/only_test/struct_named.rs create mode 100644 module/core/derive_tools/tests/inc/index/only_test/struct_tuple.rs create mode 100644 module/core/derive_tools/tests/inc/index/struct_collisions.rs create mode 100644 module/core/derive_tools/tests/inc/index/struct_multiple_named_field.rs create mode 100644 module/core/derive_tools/tests/inc/index/struct_multiple_named_item.rs create mode 100644 module/core/derive_tools/tests/inc/index/struct_multiple_named_manual.rs create mode 100644 module/core/derive_tools/tests/inc/index/struct_multiple_tuple.rs create mode 100644 module/core/derive_tools/tests/inc/index/struct_multiple_tuple_manual.rs create mode 100644 module/core/derive_tools/tests/inc/index/struct_named.rs create mode 100644 module/core/derive_tools/tests/inc/index/struct_named_manual.rs create mode 100644 module/core/derive_tools/tests/inc/index/struct_tuple.rs create mode 100644 module/core/derive_tools/tests/inc/index/struct_tuple_manual.rs create mode 100644 module/core/derive_tools/tests/inc/index_mut/compiletime/enum.rs create mode 100644 module/core/derive_tools/tests/inc/index_mut/compiletime/enum.stderr create mode 100644 module/core/derive_tools/tests/inc/index_mut/compiletime/struct.rs create mode 100644 module/core/derive_tools/tests/inc/index_mut/compiletime/struct.stderr create mode 100644 module/core/derive_tools/tests/inc/index_mut/compiletime/struct_named_empty.rs create mode 100644 module/core/derive_tools/tests/inc/index_mut/compiletime/struct_named_empty.stderr create mode 100644 module/core/derive_tools/tests/inc/index_mut/compiletime/struct_unit.rs create mode 100644 module/core/derive_tools/tests/inc/index_mut/compiletime/struct_unit.stderr create mode 100644 module/core/derive_tools/tests/inc/index_mut/only_test/struct_multiple_named.rs create mode 100644 module/core/derive_tools/tests/inc/index_mut/only_test/struct_multiple_tuple.rs create mode 100644 module/core/derive_tools/tests/inc/index_mut/only_test/struct_named.rs create mode 100644 module/core/derive_tools/tests/inc/index_mut/only_test/struct_tuple.rs create mode 100644 module/core/derive_tools/tests/inc/index_mut/struct_collisions.rs create mode 100644 module/core/derive_tools/tests/inc/index_mut/struct_multiple_named_field.rs create mode 100644 module/core/derive_tools/tests/inc/index_mut/struct_multiple_named_item.rs create mode 100644 module/core/derive_tools/tests/inc/index_mut/struct_multiple_named_manual.rs create mode 100644 module/core/derive_tools/tests/inc/index_mut/struct_multiple_tuple.rs create mode 100644 module/core/derive_tools/tests/inc/index_mut/struct_multiple_tuple_manual.rs create mode 100644 module/core/derive_tools/tests/inc/index_mut/struct_named.rs create mode 100644 module/core/derive_tools/tests/inc/index_mut/struct_named_manual.rs create mode 100644 module/core/derive_tools/tests/inc/index_mut/struct_tuple.rs create mode 100644 module/core/derive_tools/tests/inc/index_mut/struct_tuple_manual.rs rename module/core/derive_tools/tests/inc/inner_from/{manual_test.rs => basic_manual_test.rs} (100%) rename module/core/derive_tools/tests/inc/inner_from/{test.rs => basic_test.rs} (100%) rename module/core/derive_tools/tests/inc/inner_from/{multiple_manual_test.rs => multiple_unnamed_manual_test.rs} (100%) rename module/core/derive_tools/tests/inc/inner_from/{multiple_test.rs => multiple_unnamed_test.rs} (100%) create mode 100644 module/core/derive_tools/tests/inc/new/basic_manual_test.rs create mode 100644 module/core/derive_tools/tests/inc/new/basic_test.rs create mode 100644 module/core/derive_tools/tests/inc/new/multiple_named_manual_test.rs create mode 100644 module/core/derive_tools/tests/inc/new/multiple_named_test.rs create mode 100644 module/core/derive_tools/tests/inc/new/multiple_unnamed_manual_test.rs create mode 100644 module/core/derive_tools/tests/inc/new/multiple_unnamed_test.rs create mode 100644 module/core/derive_tools/tests/inc/new/named_manual_test.rs create mode 100644 module/core/derive_tools/tests/inc/new/named_test.rs create mode 100644 module/core/derive_tools/tests/inc/new/only_test/basic.rs create mode 100644 module/core/derive_tools/tests/inc/new/only_test/multiple_named.rs create mode 100644 module/core/derive_tools/tests/inc/new/only_test/multiple_unnamed.rs create mode 100644 module/core/derive_tools/tests/inc/new/only_test/named.rs create mode 100644 module/core/derive_tools/tests/inc/new/only_test/unit.rs create mode 100644 module/core/derive_tools/tests/inc/new/unit_manual_test.rs create mode 100644 module/core/derive_tools/tests/inc/new/unit_test.rs create mode 100644 module/core/derive_tools/tests/inc/not/bounds_inlined.rs create mode 100644 module/core/derive_tools/tests/inc/not/bounds_inlined_manual.rs create mode 100644 module/core/derive_tools/tests/inc/not/bounds_mixed.rs create mode 100644 module/core/derive_tools/tests/inc/not/bounds_mixed_manual.rs create mode 100644 module/core/derive_tools/tests/inc/not/bounds_where.rs create mode 100644 module/core/derive_tools/tests/inc/not/bounds_where_manual.rs create mode 100644 module/core/derive_tools/tests/inc/not/name_collisions.rs create mode 100644 module/core/derive_tools/tests/inc/not/named_default_off.rs create mode 100644 module/core/derive_tools/tests/inc/not/named_default_off_manual.rs create mode 100644 module/core/derive_tools/tests/inc/not/named_default_off_reference_on.rs create mode 100644 module/core/derive_tools/tests/inc/not/named_default_off_reference_on_manual.rs create mode 100644 module/core/derive_tools/tests/inc/not/named_default_off_some_on.rs create mode 100644 module/core/derive_tools/tests/inc/not/named_default_off_some_on_manual.rs create mode 100644 module/core/derive_tools/tests/inc/not/named_default_on_mut_reference_off.rs create mode 100644 module/core/derive_tools/tests/inc/not/named_default_on_mut_reference_off_manual.rs create mode 100644 module/core/derive_tools/tests/inc/not/named_default_on_some_off.rs create mode 100644 module/core/derive_tools/tests/inc/not/named_default_on_some_off_manual.rs create mode 100644 module/core/derive_tools/tests/inc/not/named_mut_reference_field.rs create mode 100644 module/core/derive_tools/tests/inc/not/named_mut_reference_field_manual.rs create mode 100644 module/core/derive_tools/tests/inc/not/named_reference_field.rs create mode 100644 module/core/derive_tools/tests/inc/not/named_reference_field_manual.rs create mode 100644 module/core/derive_tools/tests/inc/not/only_test/bounds_inlined.rs create mode 100644 module/core/derive_tools/tests/inc/not/only_test/bounds_mixed.rs create mode 100644 module/core/derive_tools/tests/inc/not/only_test/bounds_where.rs create mode 100644 module/core/derive_tools/tests/inc/not/only_test/name_collisions.rs create mode 100644 module/core/derive_tools/tests/inc/not/only_test/named_default_off.rs create mode 100644 module/core/derive_tools/tests/inc/not/only_test/named_default_off_reference_on.rs create mode 100644 module/core/derive_tools/tests/inc/not/only_test/named_default_off_some_on.rs create mode 100644 module/core/derive_tools/tests/inc/not/only_test/named_default_on_mut_reference_off.rs create mode 100644 module/core/derive_tools/tests/inc/not/only_test/named_default_on_some_off.rs create mode 100644 module/core/derive_tools/tests/inc/not/only_test/named_mut_reference_field.rs create mode 100644 module/core/derive_tools/tests/inc/not/only_test/named_reference_field.rs create mode 100644 module/core/derive_tools/tests/inc/not/only_test/struct_named.rs create mode 100644 module/core/derive_tools/tests/inc/not/only_test/struct_named_empty.rs create mode 100644 module/core/derive_tools/tests/inc/not/only_test/struct_tuple.rs create mode 100644 module/core/derive_tools/tests/inc/not/only_test/struct_tuple_empty.rs create mode 100644 module/core/derive_tools/tests/inc/not/only_test/struct_unit.rs create mode 100644 module/core/derive_tools/tests/inc/not/only_test/tuple_default_off.rs create mode 100644 module/core/derive_tools/tests/inc/not/only_test/tuple_default_off_reference_on.rs create mode 100644 module/core/derive_tools/tests/inc/not/only_test/tuple_default_off_some_on.rs create mode 100644 module/core/derive_tools/tests/inc/not/only_test/tuple_default_on_mut_reference_off.rs create mode 100644 module/core/derive_tools/tests/inc/not/only_test/tuple_default_on_some_off.rs create mode 100644 module/core/derive_tools/tests/inc/not/only_test/tuple_mut_reference_field.rs create mode 100644 module/core/derive_tools/tests/inc/not/only_test/tuple_reference_field.rs create mode 100644 module/core/derive_tools/tests/inc/not/only_test/with_custom_type.rs create mode 100644 module/core/derive_tools/tests/inc/not/struct_named.rs create mode 100644 module/core/derive_tools/tests/inc/not/struct_named_empty.rs create mode 100644 module/core/derive_tools/tests/inc/not/struct_named_empty_manual.rs create mode 100644 module/core/derive_tools/tests/inc/not/struct_named_manual.rs create mode 100644 module/core/derive_tools/tests/inc/not/struct_tuple.rs create mode 100644 module/core/derive_tools/tests/inc/not/struct_tuple_empty.rs create mode 100644 module/core/derive_tools/tests/inc/not/struct_tuple_empty_manual.rs create mode 100644 module/core/derive_tools/tests/inc/not/struct_tuple_manual.rs create mode 100644 module/core/derive_tools/tests/inc/not/struct_unit.rs create mode 100644 module/core/derive_tools/tests/inc/not/struct_unit_manual.rs create mode 100644 module/core/derive_tools/tests/inc/not/tuple_default_off.rs create mode 100644 module/core/derive_tools/tests/inc/not/tuple_default_off_manual.rs create mode 100644 module/core/derive_tools/tests/inc/not/tuple_default_off_reference_on.rs create mode 100644 module/core/derive_tools/tests/inc/not/tuple_default_off_reference_on_manual.rs create mode 100644 module/core/derive_tools/tests/inc/not/tuple_default_off_some_on.rs create mode 100644 module/core/derive_tools/tests/inc/not/tuple_default_off_some_on_manual.rs create mode 100644 module/core/derive_tools/tests/inc/not/tuple_default_on_mut_reference_off.rs create mode 100644 module/core/derive_tools/tests/inc/not/tuple_default_on_mut_reference_off_manual.rs create mode 100644 module/core/derive_tools/tests/inc/not/tuple_default_on_some_off.rs create mode 100644 module/core/derive_tools/tests/inc/not/tuple_default_on_some_off_manual.rs create mode 100644 module/core/derive_tools/tests/inc/not/tuple_mut_reference_field.rs create mode 100644 module/core/derive_tools/tests/inc/not/tuple_mut_reference_field_manual.rs create mode 100644 module/core/derive_tools/tests/inc/not/tuple_reference_field.rs create mode 100644 module/core/derive_tools/tests/inc/not/tuple_reference_field_manual.rs create mode 100644 module/core/derive_tools/tests/inc/not/with_custom_type.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/bounds_inlined.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/bounds_inlined_manual.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/bounds_mixed.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/bounds_mixed_manual.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/bounds_where.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/bounds_where_manual.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/compiletime/enum.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/compiletime/enum.stderr create mode 100644 module/core/derive_tools/tests/inc/phantom/compiletime/invariant_type.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/compiletime/invariant_type.stderr create mode 100644 module/core/derive_tools/tests/inc/phantom/contravariant_type.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/contravariant_type_manual.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/covariant_type.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/covariant_type_manual.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/name_collisions.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/only_test/bounds_inlined.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/only_test/bounds_mixed.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/only_test/bounds_where.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/only_test/contravariant_type.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/only_test/covariant_type.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/only_test/name_collisions.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/only_test/send_sync_type.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/only_test/struct_named.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/only_test/struct_named_empty.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/only_test/struct_tuple.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/only_test/struct_tuple_empty.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/only_test/struct_unit_to_tuple.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/send_sync_type.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/send_sync_type_manual.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/struct_named.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/struct_named_empty.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/struct_named_empty_manual.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/struct_named_manual.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/struct_tuple.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/struct_tuple_empty.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/struct_tuple_empty_manual.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/struct_tuple_manual.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/struct_unit_to_tuple.rs create mode 100644 module/core/derive_tools/tests/inc/phantom/struct_unit_to_tuple_manual.rs create mode 100644 module/core/derive_tools_meta/src/derive/index.rs create mode 100644 module/core/derive_tools_meta/src/derive/index/field_attributes.rs create mode 100644 module/core/derive_tools_meta/src/derive/index/item_attributes.rs create mode 100644 module/core/derive_tools_meta/src/derive/index_mut.rs create mode 100644 module/core/derive_tools_meta/src/derive/not.rs create mode 100644 module/core/derive_tools_meta/src/derive/not/field_attributes.rs create mode 100644 module/core/derive_tools_meta/src/derive/not/item_attributes.rs create mode 100644 module/core/derive_tools_meta/src/derive/phantom.rs create mode 100644 module/core/error_tools/src/typed.rs create mode 100644 module/core/error_tools/src/untyped.rs create mode 100644 module/core/error_tools/tests/inc/err_with_test.rs rename module/core/error_tools/tests/inc/{for_app_test.rs => untyped_test.rs} (55%) rename module/core/error_tools/tests/{error_tools_tests.rs => tests.rs} (100%) create mode 100644 module/core/format_tools/Cargo.toml create mode 100644 module/core/format_tools/License create mode 100644 module/core/format_tools/Readme.md create mode 100644 module/core/format_tools/build.rs create mode 100644 module/core/format_tools/examples/format_tools_trivial.rs create mode 100644 module/core/format_tools/src/format.rs create mode 100644 module/core/format_tools/src/format/as_table.rs create mode 100644 module/core/format_tools/src/format/md_math.rs create mode 100644 module/core/format_tools/src/format/print.rs create mode 100644 module/core/format_tools/src/format/string.rs create mode 100644 module/core/format_tools/src/format/table.rs create mode 100644 module/core/format_tools/src/format/to_string.rs create mode 100644 module/core/format_tools/src/format/to_string/aref.rs create mode 100644 module/core/format_tools/src/format/to_string_with_fallback.rs create mode 100644 module/core/format_tools/src/format/to_string_with_fallback/aref.rs create mode 100644 module/core/format_tools/src/lib.rs create mode 100644 module/core/format_tools/tests/inc/fields_test.rs create mode 100644 module/core/format_tools/tests/inc/md_math_test.rs create mode 100644 module/core/format_tools/tests/inc/mod.rs create mode 100644 module/core/format_tools/tests/inc/print_test.rs create mode 100644 module/core/format_tools/tests/inc/string_test.rs create mode 100644 module/core/format_tools/tests/inc/to_string_test.rs create mode 100644 module/core/format_tools/tests/inc/to_string_with_fallback_test.rs create mode 100644 module/core/format_tools/tests/smoke_test.rs create mode 100644 module/core/format_tools/tests/tests.rs create mode 100644 module/core/macro_tools/src/components.rs create mode 100644 module/core/macro_tools/src/ct.rs create mode 100644 module/core/macro_tools/src/ct/str.rs delete mode 100644 module/core/macro_tools/src/drop.rs create mode 100644 module/core/macro_tools/src/kw.rs create mode 100644 module/core/macro_tools/src/typed.rs create mode 100644 module/core/macro_tools/tests/inc/compile_time_test.rs delete mode 100644 module/core/macro_tools/tests/inc/syntax_test.rs rename module/core/macro_tools/tests/inc/{typ_Test.rs => typ_test.rs} (94%) create mode 100644 module/core/proper_path_tools/src/path/canonical_path.rs create mode 100644 module/core/proper_path_tools/src/path/current_path.rs create mode 100644 module/core/proper_path_tools/src/path/native_path.rs create mode 100644 module/core/proper_path_tools/src/transitive.rs create mode 100644 module/core/proper_path_tools/tests/inc/current_path.rs create mode 100644 module/core/proper_path_tools/tests/inc/path_canonicalize.rs create mode 100644 module/core/proper_path_tools/tests/inc/transitive.rs create mode 100644 module/core/reflect_tools/src/reflect/fields.rs create mode 100644 module/core/reflect_tools/src/reflect/wrapper.rs create mode 100644 module/core/reflect_tools/src/reflect/wrapper/maybe_as.rs create mode 100644 module/core/reflect_tools/tests/inc/fundamental/fields_test.rs rename module/core/reflect_tools/tests/inc/{reflect_array_test.rs => group1/array_test.rs} (100%) rename module/core/reflect_tools/tests/inc/{reflect_common_test.rs => group1/common_test.rs} (100%) rename module/core/reflect_tools/tests/inc/{reflect_hashmap_test.rs => group1/hashmap_test.rs} (100%) rename module/core/reflect_tools/tests/inc/{reflect_hashset_test.rs => group1/hashset_test.rs} (100%) rename module/core/reflect_tools/tests/inc/{ => group1}/newtype_experiment.rs (100%) rename module/core/reflect_tools/tests/inc/{ => group1}/only_test/all.rs (100%) rename module/core/reflect_tools/tests/inc/{ => group1}/only_test/reflect_struct.rs (90%) rename module/core/reflect_tools/tests/inc/{ => group1}/only_test/reflect_struct_in_struct.rs (84%) rename module/core/reflect_tools/tests/inc/{ => group1}/only_test/reflect_struct_with_lifetime.rs (94%) rename module/core/reflect_tools/tests/inc/{reflect_primitive_test.rs => group1/primitive_test.rs} (100%) rename module/core/reflect_tools/tests/inc/{reflect_slice_test.rs => group1/slice_test.rs} (100%) rename module/core/reflect_tools/tests/inc/{reflect_struct_in_struct_manual_test.rs => group1/struct_in_struct_manual_test.rs} (100%) rename module/core/reflect_tools/tests/inc/{reflect_struct_manual_test.rs => group1/struct_manual_test.rs} (100%) rename module/core/reflect_tools/tests/inc/{reflect_struct_with_lifetime_manual_test.rs => group1/struct_with_lifetime_manual_test.rs} (100%) rename module/core/reflect_tools/tests/inc/{reflect_vec_test.rs => group1/vec_test.rs} (100%) create mode 100644 module/move/assistant/Cargo.toml create mode 100644 module/move/assistant/License create mode 100644 module/move/assistant/Readme.md create mode 100644 module/move/assistant/api/list.http create mode 100644 module/move/assistant/src/client.rs create mode 100644 module/move/assistant/src/lib.rs create mode 100644 module/move/assistant/src/main.rs create mode 100644 module/move/assistant/tests/inc/basic_test.rs rename module/{blank/willbe_old/tests/willbe_old/_asset/package/License => move/assistant/tests/inc/experiment.rs} (100%) create mode 100644 module/move/assistant/tests/inc/mod.rs create mode 100644 module/move/assistant/tests/smoke_test.rs create mode 100644 module/move/assistant/tests/tests.rs rename module/move/willbe/src/{description.md => Readme.md} (100%) create mode 100644 module/move/willbe/src/entity/code.rs create mode 100644 module/move/willbe/src/entity/dependency.rs create mode 100644 module/move/willbe/src/entity/files.rs create mode 100644 module/move/willbe/src/entity/files/crate_dir.rs create mode 100644 module/move/willbe/src/entity/files/either.rs create mode 100644 module/move/willbe/src/entity/files/manifest_file.rs create mode 100644 module/move/willbe/src/entity/files/source_file.rs create mode 100644 module/move/willbe/src/entity/git.rs create mode 100644 module/move/willbe/src/entity/package_md_extension.rs create mode 100644 module/move/willbe/src/entity/progress_bar.rs create mode 100644 module/move/willbe/src/entity/publish.rs create mode 100644 module/move/willbe/src/entity/workspace_graph.rs create mode 100644 module/move/willbe/src/entity/workspace_md_extension.rs create mode 100644 module/move/willbe/src/entity/workspace_package.rs delete mode 100644 module/move/willbe/src/tool/_path.rs create mode 100644 module/move/willbe/src/tool/collection.rs create mode 100644 module/move/willbe/src/tool/error.rs create mode 100644 module/move/willbe/src/tool/iter.rs create mode 100644 module/move/willbe/src/tool/macros.rs create mode 100644 module/move/willbe/src/tool/path.rs create mode 100644 module/move/willbe/src/tool/repository.rs delete mode 100644 module/move/willbe/src/tool/sha.rs create mode 100644 module/move/willbe/src/tool/tree.rs rename module/move/willbe/tests/asset/full_config/{_willbe_variadic_tag_configurations_c => _willbe_variadic_tag_configurations_full_config_c}/Cargo.toml (77%) rename module/move/willbe/tests/asset/full_config/{_willbe_variadic_tag_configurations_c => _willbe_variadic_tag_configurations_full_config_c}/examples/_willbe_variadic_tag_configurations_c_trivial.rs (100%) rename module/move/willbe/tests/asset/full_config/{_willbe_variadic_tag_configurations_c => _willbe_variadic_tag_configurations_full_config_c}/src/lib.rs (100%) rename module/move/willbe/tests/inc/{action => action_tests}/cicd_renew.rs (92%) rename module/move/willbe/tests/inc/{action => action_tests}/features.rs (69%) rename module/move/willbe/tests/inc/{action => action_tests}/list.rs (100%) rename module/move/willbe/tests/inc/{action => action_tests}/list/data.rs (87%) rename module/move/willbe/tests/inc/{action => action_tests}/list/format.rs (82%) rename module/move/willbe/tests/inc/{action => action_tests}/main_header.rs (99%) rename module/move/willbe/tests/inc/{action => action_tests}/mod.rs (100%) rename module/move/willbe/tests/inc/{action => action_tests}/readme_health_table_renew.rs (82%) rename module/move/willbe/tests/inc/{action => action_tests}/readme_modules_headers_renew.rs (83%) rename module/move/willbe/tests/inc/{action => action_tests}/test.rs (68%) rename module/move/willbe/tests/inc/{action => action_tests}/workspace_renew.rs (100%) create mode 100644 module/move/willbe/tests/inc/helper.rs delete mode 100644 module/move/willbe/tests/inc/helpers.rs delete mode 100644 module/move/willbe/tests/inc/tool/graph.rs create mode 100644 module/move/willbe/tests/inc/tool/graph_test.rs delete mode 100644 module/move/willbe/tests/inc/tool/process.rs rename module/move/willbe/tests/inc/tool/{query.rs => query_test.rs} (97%) create mode 100644 step/Cargo.toml create mode 100644 step/src/bin/sources.rs diff --git a/.github/workflows/module_assistant_push.yml b/.github/workflows/module_assistant_push.yml new file mode 100644 index 0000000000..5d3036f5a1 --- /dev/null +++ b/.github/workflows/module_assistant_push.yml @@ -0,0 +1,23 @@ +name : assistant + +on : + push : + branches : + - 'alpha' + - 'beta' + - 'master' + + +env : + CARGO_TERM_COLOR : always + +jobs : + + # assistant + + test : + uses : Wandalen/wTools/.github/workflows/standard_rust_push.yml@alpha + with : + manifest_path : 'module/move/assistant/Cargo.toml' + module_name : 'assistant' + commit_message : ${{ github.event.head_commit.message }} diff --git a/.github/workflows/module_brain_tools_push.yml b/.github/workflows/module_brain_tools_push.yml new file mode 100644 index 0000000000..a15bc4d240 --- /dev/null +++ b/.github/workflows/module_brain_tools_push.yml @@ -0,0 +1,23 @@ +name : brain_tools + +on : + push : + branches : + - 'alpha' + - 'beta' + - 'master' + + +env : + CARGO_TERM_COLOR : always + +jobs : + + # brain_tools + + test : + uses : Wandalen/wTools/.github/workflows/standard_rust_push.yml@alpha + with : + manifest_path : 'module/blank/brain_tools/Cargo.toml' + module_name : 'brain_tools' + commit_message : ${{ github.event.head_commit.message }} diff --git a/.github/workflows/module_clone_dyn_types_push.yml b/.github/workflows/module_clone_dyn_types_push.yml new file mode 100644 index 0000000000..a3046a8fe0 --- /dev/null +++ b/.github/workflows/module_clone_dyn_types_push.yml @@ -0,0 +1,23 @@ +name : clone_dyn_types + +on : + push : + branches : + - 'alpha' + - 'beta' + - 'master' + + +env : + CARGO_TERM_COLOR : always + +jobs : + + # clone_dyn_types + + test : + uses : Wandalen/wTools/.github/workflows/standard_rust_push.yml@alpha + with : + manifest_path : 'module/core/clone_dyn_types/Cargo.toml' + module_name : 'clone_dyn_types' + commit_message : ${{ github.event.head_commit.message }} diff --git a/.github/workflows/module_drawboard_push.yml b/.github/workflows/module_drawboard_push.yml new file mode 100644 index 0000000000..001808b348 --- /dev/null +++ b/.github/workflows/module_drawboard_push.yml @@ -0,0 +1,23 @@ +name : drawboard + +on : + push : + branches : + - 'alpha' + - 'beta' + - 'master' + + +env : + CARGO_TERM_COLOR : always + +jobs : + + # drawboard + + test : + uses : Wandalen/wTools/.github/workflows/standard_rust_push.yml@alpha + with : + manifest_path : 'module/blank/drawboard/Cargo.toml' + module_name : 'drawboard' + commit_message : ${{ github.event.head_commit.message }} diff --git a/.github/workflows/module_drawql_push.yml b/.github/workflows/module_drawql_push.yml new file mode 100644 index 0000000000..8f0d13cda4 --- /dev/null +++ b/.github/workflows/module_drawql_push.yml @@ -0,0 +1,23 @@ +name : drawql + +on : + push : + branches : + - 'alpha' + - 'beta' + - 'master' + + +env : + CARGO_TERM_COLOR : always + +jobs : + + # drawql + + test : + uses : Wandalen/wTools/.github/workflows/standard_rust_push.yml@alpha + with : + manifest_path : 'module/blank/drawql/Cargo.toml' + module_name : 'drawql' + commit_message : ${{ github.event.head_commit.message }} diff --git a/.github/workflows/module_format_tools_push.yml b/.github/workflows/module_format_tools_push.yml new file mode 100644 index 0000000000..77ea104acd --- /dev/null +++ b/.github/workflows/module_format_tools_push.yml @@ -0,0 +1,23 @@ +name : format_tools + +on : + push : + branches : + - 'alpha' + - 'beta' + - 'master' + + +env : + CARGO_TERM_COLOR : always + +jobs : + + # format_tools + + test : + uses : Wandalen/wTools/.github/workflows/standard_rust_push.yml@alpha + with : + manifest_path : 'module/core/format_tools/Cargo.toml' + module_name : 'format_tools' + commit_message : ${{ github.event.head_commit.message }} diff --git a/.github/workflows/module_paths_tools_push.yml b/.github/workflows/module_paths_tools_push.yml new file mode 100644 index 0000000000..c09fa32066 --- /dev/null +++ b/.github/workflows/module_paths_tools_push.yml @@ -0,0 +1,23 @@ +name : paths_tools + +on : + push : + branches : + - 'alpha' + - 'beta' + - 'master' + + +env : + CARGO_TERM_COLOR : always + +jobs : + + # paths_tools + + test : + uses : Wandalen/wTools/.github/workflows/standard_rust_push.yml@alpha + with : + manifest_path : 'module/blank/paths_tools/Cargo.toml' + module_name : 'paths_tools' + commit_message : ${{ github.event.head_commit.message }} diff --git a/.github/workflows/module_second_brain_push.yml b/.github/workflows/module_second_brain_push.yml new file mode 100644 index 0000000000..cbe4ed3523 --- /dev/null +++ b/.github/workflows/module_second_brain_push.yml @@ -0,0 +1,23 @@ +name : second_brain + +on : + push : + branches : + - 'alpha' + - 'beta' + - 'master' + + +env : + CARGO_TERM_COLOR : always + +jobs : + + # second_brain + + test : + uses : Wandalen/wTools/.github/workflows/standard_rust_push.yml@alpha + with : + manifest_path : 'module/blank/second_brain/Cargo.toml' + module_name : 'second_brain' + commit_message : ${{ github.event.head_commit.message }} diff --git a/.github/workflows/module_step_push.yml b/.github/workflows/module_step_push.yml new file mode 100644 index 0000000000..de2310fcc4 --- /dev/null +++ b/.github/workflows/module_step_push.yml @@ -0,0 +1,23 @@ +name : step + +on : + push : + branches : + - 'alpha' + - 'beta' + - 'master' + + +env : + CARGO_TERM_COLOR : always + +jobs : + + # step + + test : + uses : Wandalen/wTools/.github/workflows/standard_rust_push.yml@alpha + with : + manifest_path : 'step/Cargo.toml' + module_name : 'step' + commit_message : ${{ github.event.head_commit.message }} diff --git a/.github/workflows/standard_rust_push.yml b/.github/workflows/standard_rust_push.yml index 1812c69512..958901ba1f 100644 --- a/.github/workflows/standard_rust_push.yml +++ b/.github/workflows/standard_rust_push.yml @@ -23,7 +23,7 @@ concurrency : group : standard_rust_push_${{ inputs.module_name }}_${{ github.ref }}_ ${{ contains( inputs.commit_message, '+test' ) || startsWith( inputs.commit_message, 'merge' ) }} - cancel-in-progress : true + cancel-in-progress : ${{ contains( inputs.commit_message, '+test' ) || startsWith( inputs.commit_message, 'merge' ) }} env : @@ -57,8 +57,10 @@ jobs : - name: Set MANIFEST_ROOT_PATH id: rootpath run: echo "::set-output name=path::$(dirname ${{ inputs.manifest_path }})" + - name: Build module + run: cd ${{ steps.rootpath.outputs.path }} && cargo build && cd - - name: Audit the modules - run: cd ${{ steps.rootpath.outputs.path }} && make audit + run: make audit continue-on-error: true - name: Generate documentation for the modules run: make doc open=no manifest_path=${{ inputs.manifest_path }} diff --git a/.gitignore b/.gitignore index 8cba9a9a97..62e8d7dec7 100755 --- a/.gitignore +++ b/.gitignore @@ -3,17 +3,17 @@ !/.circleci !/.* -/build -/builder /binding /target /node_modules /.module +/.data /package-lock.json /Cargo.lock /.vscode /_* +.env _key _data target diff --git a/Cargo.toml b/Cargo.toml index 4e75221932..ec38d89c7e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ members = [ "module/core/*", "module/move/*", "module/test/*", + "step", ] exclude = [ "-*", @@ -45,6 +46,11 @@ restriction = "warn" pedantic = "warn" # Denies undocumented unsafe blocks. undocumented_unsafe_blocks = "deny" +# xxx : check +# Warns if core could be used instead of std, but didn't +std_instead_of_core = "warn" +# Warns if alloc could be used instead of std, but didn't +std_instead_of_alloc = "warn" # xxx : document single_call_fn = "allow" inline_always = "allow" @@ -74,7 +80,7 @@ path = "module/alias/std_x" ## data_type [workspace.dependencies.data_type] -version = "~0.7.0" +version = "~0.8.0" path = "module/core/data_type" default-features = false @@ -92,7 +98,7 @@ default-features = false # path = "module/core/type_constructor_derive_pair_meta" [workspace.dependencies.interval_adapter] -version = "~0.21.0" +version = "~0.23.0" path = "module/core/interval_adapter" default-features = false features = [ "enabled" ] @@ -104,7 +110,7 @@ default-features = false features = [ "enabled" ] [workspace.dependencies.collection_tools] -version = "~0.8.0" +version = "~0.11.0" path = "module/core/collection_tools" default-features = false @@ -112,29 +118,36 @@ default-features = false ## derive [workspace.dependencies.derive_tools] -version = "~0.24.0" +version = "~0.26.0" path = "module/core/derive_tools" default-features = false features = [ "enabled" ] [workspace.dependencies.derive_tools_meta] -version = "~0.23.0" +version = "~0.25.0" path = "module/core/derive_tools_meta" default-features = false features = [ "enabled" ] [workspace.dependencies.reflect_tools] -version = "~0.2.0" +version = "~0.3.0" path = "module/core/reflect_tools" default-features = false features = [ "enabled" ] [workspace.dependencies.reflect_tools_meta] -version = "~0.2.0" +version = "~0.3.0" path = "module/core/reflect_tools_meta" default-features = false features = [ "enabled" ] +[workspace.dependencies.format_tools] +version = "~0.2.0" +path = "module/core/format_tools" +default-features = false +features = [ "enabled" ] +# xxx : remove features, maybe + # [workspace.dependencies.type_constructor] # version = "~0.3.0" # path = "module/core/type_constructor" @@ -146,22 +159,28 @@ path = "module/alias/fundamental_data_type" default-features = false [workspace.dependencies.variadic_from] -version = "~0.19.0" +version = "~0.21.0" path = "module/core/variadic_from" default-features = false features = [ "enabled" ] [workspace.dependencies.clone_dyn] -version = "~0.18.0" +version = "~0.22.0" path = "module/core/clone_dyn" default-features = false features = [ "enabled" ] [workspace.dependencies.clone_dyn_meta] -version = "~0.18.0" +version = "~0.22.0" path = "module/core/clone_dyn_meta" features = [ "enabled" ] +[workspace.dependencies.clone_dyn_types] +version = "~0.22.0" +path = "module/core/clone_dyn_types" +default-features = false +features = [ "enabled" ] + ## mem @@ -182,7 +201,7 @@ default-features = false ## iter [workspace.dependencies.iter_tools] -version = "~0.17.0" +version = "~0.20.0" path = "module/core/iter_tools" default-features = false @@ -200,22 +219,22 @@ path = "module/core/for_each" default-features = false [workspace.dependencies.former] -version = "~2.2.0" +version = "~2.7.0" path = "module/core/former" default-features = false -[workspace.dependencies.former_stable] -package = "former" -version = "=2.0.0" -default-features = false +# [workspace.dependencies.former_stable] +# package = "former" +# version = "=2.2.0" +# default-features = false [workspace.dependencies.former_meta] -version = "~2.2.0" +version = "~2.7.0" path = "module/core/former_meta" default-features = false [workspace.dependencies.former_types] -version = "~2.2.0" +version = "~2.7.0" path = "module/core/former_types" default-features = false @@ -229,12 +248,12 @@ version = "~0.7.0" path = "module/core/impls_index_meta" [workspace.dependencies.mod_interface] -version = "~0.21.0" +version = "~0.22.0" path = "module/core/mod_interface" default-features = false [workspace.dependencies.mod_interface_meta] -version = "~0.21.0" +version = "~0.22.0" path = "module/core/mod_interface_meta" default-features = false @@ -260,7 +279,7 @@ default-features = false ## macro tools [workspace.dependencies.macro_tools] -version = "~0.28.0" +version = "~0.38.0" path = "module/core/macro_tools" default-features = false @@ -314,7 +333,7 @@ default-features = false ## error [workspace.dependencies.error_tools] -version = "~0.14.0" +version = "~0.15.0" path = "module/core/error_tools" default-features = false @@ -326,7 +345,7 @@ path = "module/alias/werror" ## string tools [workspace.dependencies.strs_tools] -version = "~0.14.0" +version = "~0.15.0" path = "module/core/strs_tools" default-features = false @@ -348,7 +367,7 @@ path = "module/alias/file_tools" default-features = false [workspace.dependencies.proper_path_tools] -version = "~0.7.0" +version = "~0.8.0" path = "module/core/proper_path_tools" default-features = false @@ -356,7 +375,7 @@ default-features = false ## process tools [workspace.dependencies.process_tools] -version = "~0.6.0" +version = "~0.7.0" path = "module/core/process_tools" default-features = false @@ -403,7 +422,7 @@ default-features = false ## ca [workspace.dependencies.wca] -version = "~0.18.0" +version = "~0.19.0" path = "module/move/wca" @@ -417,7 +436,7 @@ path = "module/move/wcensor" ## willbe [workspace.dependencies.willbe] -version = "~0.12.0" +version = "~0.13.0" path = "module/move/willbe" @@ -457,7 +476,7 @@ version = "~0.5.0" path = "module/move/deterministic_rand" [workspace.dependencies.crates_tools] -version = "~0.10.0" +version = "~0.11.0" path = "module/move/crates_tools" diff --git a/Readme.md b/Readme.md index 966a6516c6..36612d9970 100644 --- a/Readme.md +++ b/Readme.md @@ -16,6 +16,7 @@ Collection of general purpose tools for solving problems. Fundamentally extend t | Module | Stability | master | alpha | Docs | Sample | |--------|-----------|--------|--------|:----:|:------:| +| [clone_dyn_types](module/core/clone_dyn_types) | [![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/module_clone_dyn_types_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_clone_dyn_types_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_clone_dyn_types_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_clone_dyn_types_push.yml?query=branch%3Aalpha) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/clone_dyn_types) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=module%2Fcore%2Fclone_dyn_types%2Fexamples%2Fclone_dyn_types_trivial.rs,RUN_POSTFIX=--example%20clone_dyn_types_trivial/https://github.com/Wandalen/wTools) | | [collection_tools](module/core/collection_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/module_collection_tools_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_collection_tools_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_collection_tools_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_collection_tools_push.yml?query=branch%3Aalpha) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/collection_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=module%2Fcore%2Fcollection_tools%2Fexamples%2Fcollection_tools_trivial.rs,RUN_POSTFIX=--example%20collection_tools_trivial/https://github.com/Wandalen/wTools) | | [former_types](module/core/former_types) | [![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/module_former_types_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_former_types_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_former_types_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_former_types_push.yml?query=branch%3Aalpha) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/former_types) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=module%2Fcore%2Fformer_types%2Fexamples%2Fformer_types_trivial.rs,RUN_POSTFIX=--example%20former_types_trivial/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/module_interval_adapter_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_interval_adapter_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_interval_adapter_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_interval_adapter_push.yml?query=branch%3Aalpha) | [![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=module%2Fcore%2Finterval_adapter%2Fexamples%2Finterval_adapter_trivial.rs,RUN_POSTFIX=--example%20interval_adapter_trivial/https://github.com/Wandalen/wTools) | @@ -36,21 +37,22 @@ Collection of general purpose tools for solving problems. Fundamentally extend t | [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/module_inspect_type_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_inspect_type_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_inspect_type_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_inspect_type_push.yml?query=branch%3Aalpha) | [![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=module%2Fcore%2Finspect_type%2Fexamples%2Finspect_type_trivial.rs,RUN_POSTFIX=--example%20inspect_type_trivial/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/module_is_slice_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_is_slice_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_is_slice_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_is_slice_push.yml?query=branch%3Aalpha) | [![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=module%2Fcore%2Fis_slice%2Fexamples%2Fis_slice_trivial.rs,RUN_POSTFIX=--example%20is_slice_trivial/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/module_mod_interface_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_mod_interface_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_mod_interface_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_mod_interface_push.yml?query=branch%3Aalpha) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/mod_interface) | | +| [reflect_tools_meta](module/core/reflect_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/module_reflect_tools_meta_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_reflect_tools_meta_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_reflect_tools_meta_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_reflect_tools_meta_push.yml?query=branch%3Aalpha) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/reflect_tools_meta) | | | [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/module_data_type_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_data_type_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_data_type_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_data_type_push.yml?query=branch%3Aalpha) | [![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=module%2Fcore%2Fdata_type%2Fexamples%2Fdata_type_trivial.rs,RUN_POSTFIX=--example%20data_type_trivial/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/module_diagnostics_tools_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_diagnostics_tools_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_diagnostics_tools_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_diagnostics_tools_push.yml?query=branch%3Aalpha) | [![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=module%2Fcore%2Fdiagnostics_tools%2Fexamples%2Fdiagnostics_tools_trivial.rs,RUN_POSTFIX=--example%20diagnostics_tools_trivial/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/module_error_tools_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_error_tools_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_error_tools_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_error_tools_push.yml?query=branch%3Aalpha) | [![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=module%2Fcore%2Ferror_tools%2Fexamples%2Ferror_tools_trivial.rs,RUN_POSTFIX=--example%20error_tools_trivial/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/module_mem_tools_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_mem_tools_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_mem_tools_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_mem_tools_push.yml?query=branch%3Aalpha) | [![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=module%2Fcore%2Fmem_tools%2Fexamples%2Fmem_tools_trivial.rs,RUN_POSTFIX=--example%20mem_tools_trivial/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/module_meta_tools_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_meta_tools_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_meta_tools_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_meta_tools_push.yml?query=branch%3Aalpha) | [![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=module%2Fcore%2Fmeta_tools%2Fexamples%2Fmeta_tools_trivial.rs,RUN_POSTFIX=--example%20meta_tools_trivial/https://github.com/Wandalen/wTools) | | [proper_path_tools](module/core/proper_path_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/module_proper_path_tools_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_proper_path_tools_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_proper_path_tools_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_proper_path_tools_push.yml?query=branch%3Aalpha) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/proper_path_tools) | | -| [reflect_tools_meta](module/core/reflect_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/module_reflect_tools_meta_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_reflect_tools_meta_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_reflect_tools_meta_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_reflect_tools_meta_push.yml?query=branch%3Aalpha) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/reflect_tools_meta) | | +| [reflect_tools](module/core/reflect_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/module_reflect_tools_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_reflect_tools_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_reflect_tools_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_reflect_tools_push.yml?query=branch%3Aalpha) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/reflect_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=module%2Fcore%2Freflect_tools%2Fexamples%2Freflect_tools_trivial.rs,RUN_POSTFIX=--example%20reflect_tools_trivial/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/module_strs_tools_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_strs_tools_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_strs_tools_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_strs_tools_push.yml?query=branch%3Aalpha) | [![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=module%2Fcore%2Fstrs_tools%2Fexamples%2Fstrs_tools_trivial.rs,RUN_POSTFIX=--example%20strs_tools_trivial/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/module_time_tools_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_time_tools_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_time_tools_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_time_tools_push.yml?query=branch%3Aalpha) | [![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=module%2Fcore%2Ftime_tools%2Fexamples%2Ftime_tools_trivial.rs,RUN_POSTFIX=--example%20time_tools_trivial/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/module_typing_tools_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_typing_tools_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_typing_tools_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_typing_tools_push.yml?query=branch%3Aalpha) | [![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=module%2Fcore%2Ftyping_tools%2Fexamples%2Ftyping_tools_trivial.rs,RUN_POSTFIX=--example%20typing_tools_trivial/https://github.com/Wandalen/wTools) | +| [format_tools](module/core/format_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/module_format_tools_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_format_tools_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_format_tools_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_format_tools_push.yml?query=branch%3Aalpha) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/format_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=module%2Fcore%2Fformat_tools%2Fexamples%2Fformat_tools_trivial.rs,RUN_POSTFIX=--example%20format_tools_trivial/https://github.com/Wandalen/wTools) | | [fs_tools](module/core/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/module_fs_tools_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_fs_tools_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_fs_tools_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_fs_tools_push.yml?query=branch%3Aalpha) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/fs_tools) | | | [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/module_include_md_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_include_md_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_include_md_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_include_md_push.yml?query=branch%3Aalpha) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/include_md) | | | [process_tools](module/core/process_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/module_process_tools_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_process_tools_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_process_tools_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_process_tools_push.yml?query=branch%3Aalpha) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/process_tools) | | | [program_tools](module/core/program_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/module_program_tools_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_program_tools_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_program_tools_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_program_tools_push.yml?query=branch%3Aalpha) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/program_tools) | | -| [reflect_tools](module/core/reflect_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/module_reflect_tools_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_reflect_tools_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_reflect_tools_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_reflect_tools_push.yml?query=branch%3Aalpha) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/reflect_tools) | [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=module%2Fcore%2Freflect_tools%2Fexamples%2Freflect_tools_trivial.rs,RUN_POSTFIX=--example%20reflect_tools_trivial/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/module_test_tools_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_test_tools_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_test_tools_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_test_tools_push.yml?query=branch%3Aalpha) | [![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=module%2Fcore%2Ftest_tools%2Fexamples%2Ftest_tools_trivial.rs,RUN_POSTFIX=--example%20test_tools_trivial/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/module_wtools_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_wtools_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_wtools_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_wtools_push.yml?query=branch%3Aalpha) | [![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=module%2Fcore%2Fwtools%2Fexamples%2Fwtools_trivial.rs,RUN_POSTFIX=--example%20wtools_trivial/https://github.com/Wandalen/wTools) | @@ -64,6 +66,7 @@ Collection of general purpose tools for solving problems. Fundamentally extend t | [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/module_deterministic_rand_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_deterministic_rand_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_deterministic_rand_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_deterministic_rand_push.yml?query=branch%3Aalpha) | [![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=module%2Fmove%2Fdeterministic_rand%2Fexamples%2Fdeterministic_rand_trivial.rs,RUN_POSTFIX=--example%20deterministic_rand_trivial/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/module_wca_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_wca_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_wca_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_wca_push.yml?query=branch%3Aalpha) | [![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=module%2Fmove%2Fwca%2Fexamples%2Fwca_trivial.rs,RUN_POSTFIX=--example%20wca_trivial/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/module_wplot_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_wplot_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_wplot_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_wplot_push.yml?query=branch%3Aalpha) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/wplot) | | +| [assistant](module/move/assistant) | [![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/module_assistant_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_assistant_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_assistant_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_assistant_push.yml?query=branch%3Aalpha) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/assistant) | | | [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/module_graphs_tools_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_graphs_tools_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_graphs_tools_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_graphs_tools_push.yml?query=branch%3Aalpha) | [![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=module%2Fmove%2Fgraphs_tools%2Fexamples%2Fgraphs_tools_trivial.rs,RUN_POSTFIX=--example%20graphs_tools_trivial/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/module_optimization_tools_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_optimization_tools_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_optimization_tools_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_optimization_tools_push.yml?query=branch%3Aalpha) | [![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=module%2Fmove%2Foptimization_tools%2Fexamples%2Foptimization_tools_trivial.rs,RUN_POSTFIX=--example%20optimization_tools_trivial/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/module_plot_interface_push.yml?label=&branch=master)](https://github.com/Wandalen/wTools/actions/workflows/module_plot_interface_push.yml?query=branch%3Amaster) | [![rust-status](https://img.shields.io/github/actions/workflow/status/Wandalen/wTools/module_plot_interface_push.yml?label=&branch=alpha)](https://github.com/Wandalen/wTools/actions/workflows/module_plot_interface_push.yml?query=branch%3Aalpha) | [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/plot_interface) | | diff --git a/bash.exe.stackdump b/bash.exe.stackdump deleted file mode 100644 index ef9b31e0d7..0000000000 --- a/bash.exe.stackdump +++ /dev/null @@ -1,38 +0,0 @@ -Stack trace: -Frame Function Args -0000005FF160 00021006118E (0002102B5B12, 000210272B3E, 00000000005E, 0000005FACC0) msys-2.0.dll+0x2118E -0000005FF160 0002100469BA (000000000000, 000000000000, 000000000130, 000000001000) msys-2.0.dll+0x69BA -0000005FF160 0002100469F2 (000000000000, 0000000005AF, 00000000005E, 000000000000) msys-2.0.dll+0x69F2 -0000005FF160 0002101791E8 (0002102B5892, 000800000000, 00080000DFB8, 000000000000) msys-2.0.dll+0x1391E8 -0000005FF160 000210183B67 (000000000000, 0002102280C8, 0002102280B0, 0000005FD320) msys-2.0.dll+0x143B67 -0000005FF160 000210046DF4 (00021031C800, 0000005FD320, 000000000000, 000000000000) msys-2.0.dll+0x6DF4 -0000005FF160 00021004850F (00007FFE0384, 000000000000, 000000000000, 000000000000) msys-2.0.dll+0x850F -0000005FF160 00021007251C (000000000000, 000000713234, 000000000000, 000000000000) msys-2.0.dll+0x3251C -0000005FF400 7FFF332D869F (000210040000, 000000000001, 000000000000, 7FFF333E8A70) ntdll.dll+0x2869F -0000005FF400 7FFF3331D03D (0000005FF300, 000000000000, 00000071A078, 000000000001) ntdll.dll+0x6D03D -0000005FF400 7FFF3331CDEE (0000007130D0, 0000005FF400, 000000718450, 000000000000) ntdll.dll+0x6CDEE -0000005FF400 7FFF3331CE60 (7FFF333EB860, 000000000000, 000000213000, 7FFF00000000) ntdll.dll+0x6CE60 -000000000000 7FFF3338EA39 (000000000000, 000000000000, 000000000001, 000000000000) ntdll.dll+0xDEA39 -000000000000 7FFF3337A744 (7FFF332B0000, 000000213050, 0000002157EE, 000000000000) ntdll.dll+0xCA744 -000000000000 7FFF33323EA3 (000000000000, 0000005FFAD0, 000000000000, 000000000000) ntdll.dll+0x73EA3 -000000000000 7FFF33323DCE (000000000000, 0000005FFAD0, 000000000000, 000000000000) ntdll.dll+0x73DCE -End of stack trace -Loaded modules: -000100400000 bash.exe -7FFF332B0000 ntdll.dll -7FFF32910000 KERNEL32.DLL -7FFF307E0000 KERNELBASE.dll -7FFF330C0000 USER32.dll -7FFF307B0000 win32u.dll -000210040000 msys-2.0.dll -7FFF328E0000 GDI32.dll -7FFF305D0000 gdi32full.dll -7FFF30ED0000 msvcp_win.dll -7FFF30C10000 ucrtbase.dll -7FFF31660000 advapi32.dll -7FFF326C0000 msvcrt.dll -7FFF31D90000 sechost.dll -7FFF30D30000 bcrypt.dll -7FFF30FE0000 RPCRT4.dll -7FFF2FE30000 CRYPTBASE.DLL -7FFF30B90000 bcryptPrimitives.dll diff --git a/module/alias/cargo_will/src/bin/cargo-will.rs b/module/alias/cargo_will/src/bin/cargo-will.rs index 71af648670..e249459706 100644 --- a/module/alias/cargo_will/src/bin/cargo-will.rs +++ b/module/alias/cargo_will/src/bin/cargo-will.rs @@ -6,7 +6,7 @@ #[ allow( unused_imports ) ] use::willbe::*; -fn main() -> Result< (), wtools::error::for_app::Error > +fn main() -> Result< (), wtools::error::untyped::Error > { let args = std::env::args().skip( 1 ).collect(); Ok( willbe::run( args )? ) diff --git a/module/alias/cargo_will/src/bin/will.rs b/module/alias/cargo_will/src/bin/will.rs index 4824eb07f4..9f74f92a12 100644 --- a/module/alias/cargo_will/src/bin/will.rs +++ b/module/alias/cargo_will/src/bin/will.rs @@ -10,7 +10,7 @@ #[ allow( unused_imports ) ] use::willbe::*; -fn main() -> Result< (), wtools::error::for_app::Error > +fn main() -> Result< (), wtools::error::untyped::Error > { Ok( willbe::run( std::env::args().collect() )? ) } diff --git a/module/alias/cargo_will/src/bin/willbe.rs b/module/alias/cargo_will/src/bin/willbe.rs index faa9c297ea..39d2429139 100644 --- a/module/alias/cargo_will/src/bin/willbe.rs +++ b/module/alias/cargo_will/src/bin/willbe.rs @@ -6,7 +6,7 @@ #[ allow( unused_imports ) ] use::willbe::*; -fn main() -> Result< (), wtools::error::for_app::Error > +fn main() -> Result< (), wtools::error::untyped::Error > { Ok( willbe::run( std::env::args().collect() )? ) } diff --git a/module/alias/cargo_will/tests/smoke_test.rs b/module/alias/cargo_will/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/alias/cargo_will/tests/smoke_test.rs +++ b/module/alias/cargo_will/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/alias/file_tools/tests/smoke_test.rs b/module/alias/file_tools/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/alias/file_tools/tests/smoke_test.rs +++ b/module/alias/file_tools/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/alias/fundamental_data_type/tests/smoke_test.rs b/module/alias/fundamental_data_type/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/alias/fundamental_data_type/tests/smoke_test.rs +++ b/module/alias/fundamental_data_type/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/alias/instance_of/src/typing/implements_lib.rs b/module/alias/instance_of/src/typing/implements_lib.rs index 4b7067310e..7db1b3e07b 100644 --- a/module/alias/instance_of/src/typing/implements_lib.rs +++ b/module/alias/instance_of/src/typing/implements_lib.rs @@ -67,40 +67,47 @@ pub( crate ) mod private pub use instance_of; } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { implements, instance_of, diff --git a/module/alias/instance_of/src/typing/inspect_type_lib.rs b/module/alias/instance_of/src/typing/inspect_type_lib.rs index 26cb2b6a24..35bf93a289 100644 --- a/module/alias/instance_of/src/typing/inspect_type_lib.rs +++ b/module/alias/instance_of/src/typing/inspect_type_lib.rs @@ -66,37 +66,45 @@ mod nightly #[ allow( unused_imports ) ] // pub use nightly::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ cfg( feature = "nightly" ) ] #[ doc( inline ) ] #[ allow( unused_imports ) ] diff --git a/module/alias/instance_of/src/typing/is_slice_lib.rs b/module/alias/instance_of/src/typing/is_slice_lib.rs index a65f9f68c8..85c3c8561c 100644 --- a/module/alias/instance_of/src/typing/is_slice_lib.rs +++ b/module/alias/instance_of/src/typing/is_slice_lib.rs @@ -71,40 +71,47 @@ pub( crate ) mod private pub use is_slice; } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { is_slice, }; diff --git a/module/alias/instance_of/src/typing/typing.rs b/module/alias/instance_of/src/typing/typing.rs index 312d1bf158..ce76751733 100644 --- a/module/alias/instance_of/src/typing/typing.rs +++ b/module/alias/instance_of/src/typing/typing.rs @@ -1,10 +1,12 @@ -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use ::inspect_type::orphan::*; @@ -18,22 +20,26 @@ pub mod protected #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use ::inspect_type::exposed::*; @@ -46,8 +52,10 @@ pub mod exposed } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use ::inspect_type::prelude::*; diff --git a/module/alias/instance_of/tests/smoke_test.rs b/module/alias/instance_of/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/alias/instance_of/tests/smoke_test.rs +++ b/module/alias/instance_of/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/alias/multilayer/tests/smoke_test.rs b/module/alias/multilayer/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/alias/multilayer/tests/smoke_test.rs +++ b/module/alias/multilayer/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/alias/proc_macro_tools/tests/smoke_test.rs b/module/alias/proc_macro_tools/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/alias/proc_macro_tools/tests/smoke_test.rs +++ b/module/alias/proc_macro_tools/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/alias/proper_tools/tests/smoke_test.rs b/module/alias/proper_tools/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/alias/proper_tools/tests/smoke_test.rs +++ b/module/alias/proper_tools/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/alias/werror/Cargo.toml b/module/alias/werror/Cargo.toml index 31884116ec..ca345c91c3 100644 --- a/module/alias/werror/Cargo.toml +++ b/module/alias/werror/Cargo.toml @@ -29,23 +29,23 @@ all-features = false [features] default = [ "enabled", - "error_for_lib", - "error_for_app" + "error_typed", + "error_untyped" ] full = [ "enabled", - "error_for_lib", - "error_for_app" + "error_typed", + "error_untyped" ] no_std = [ "error_tools/no_std" ] use_alloc = [ "error_tools/use_alloc" ] enabled = [ "error_tools/enabled" ] -error_for_lib = [ - "error_tools/error_for_lib" +error_typed = [ + "error_tools/error_typed" ] -error_for_app = [ - "error_tools/error_for_app" +error_untyped = [ + "error_tools/error_untyped" ] [dependencies] diff --git a/module/alias/werror/tests/smoke_test.rs b/module/alias/werror/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/alias/werror/tests/smoke_test.rs +++ b/module/alias/werror/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/alias/willbe2/src/main.rs b/module/alias/willbe2/src/main.rs index 63d99d2aa7..853d4b4bcb 100644 --- a/module/alias/willbe2/src/main.rs +++ b/module/alias/willbe2/src/main.rs @@ -6,7 +6,7 @@ #[ allow( unused_imports ) ] use ::willbe2::*; -// fn main() -> Result< (), wtools::error::for_app::Error > +// fn main() -> Result< (), wtools::error::untyped::Error > // { // Ok( willbe::run()? ) // } diff --git a/module/alias/willbe2/tests/smoke_test.rs b/module/alias/willbe2/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/alias/willbe2/tests/smoke_test.rs +++ b/module/alias/willbe2/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/alias/winterval/Cargo.toml b/module/alias/winterval/Cargo.toml index 385471c227..8b523e9388 100644 --- a/module/alias/winterval/Cargo.toml +++ b/module/alias/winterval/Cargo.toml @@ -24,7 +24,7 @@ workspace = true features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] + [features] default = [ "enabled" ] diff --git a/module/alias/wproc_macro/tests/smoke_test.rs b/module/alias/wproc_macro/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/alias/wproc_macro/tests/smoke_test.rs +++ b/module/alias/wproc_macro/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/alias/wstring_tools/tests/smoke_test.rs b/module/alias/wstring_tools/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/alias/wstring_tools/tests/smoke_test.rs +++ b/module/alias/wstring_tools/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/alias/wtest/Cargo.toml b/module/alias/wtest/Cargo.toml index 4cb3aad3a8..a3b92484b8 100644 --- a/module/alias/wtest/Cargo.toml +++ b/module/alias/wtest/Cargo.toml @@ -23,7 +23,7 @@ workspace = true [package.metadata.docs.rs] features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] + include = [ "/rust/impl/test", "/Cargo.toml", diff --git a/module/alias/wtest/tests/smoke_test.rs b/module/alias/wtest/tests/smoke_test.rs index fddef25d11..dda3313c2e 100644 --- a/module/alias/wtest/tests/smoke_test.rs +++ b/module/alias/wtest/tests/smoke_test.rs @@ -1,5 +1,5 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] #[ ignore ] fn local_smoke_test() @@ -7,7 +7,7 @@ fn local_smoke_test() ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/alias/wtest_basic/src/_blank/standard_lib.rs b/module/alias/wtest_basic/src/_blank/standard_lib.rs index bd56ee14ed..a4245f4423 100644 --- a/module/alias/wtest_basic/src/_blank/standard_lib.rs +++ b/module/alias/wtest_basic/src/_blank/standard_lib.rs @@ -21,29 +21,35 @@ pub mod dependency { } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Parented namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; } // #[ doc( inline ) ] @@ -51,6 +57,8 @@ pub mod exposed // pub use exposed::*; /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; } diff --git a/module/alias/wtest_basic/src/test/wtest_basic_lib.rs b/module/alias/wtest_basic/src/test/wtest_basic_lib.rs index 3eb13b9abe..3ee84abaf5 100644 --- a/module/alias/wtest_basic/src/test/wtest_basic_lib.rs +++ b/module/alias/wtest_basic/src/test/wtest_basic_lib.rs @@ -61,8 +61,8 @@ mod_interface! use super::exposed::dt; use super::exposed::diagnostics; - protected use super::dependency; - protected use super::dependency::*; + own use super::dependency; + own use super::dependency::*; prelude use ::meta_tools as meta; prelude use ::mem_tools as mem; diff --git a/module/alias/wtest_basic/tests/smoke_test.rs b/module/alias/wtest_basic/tests/smoke_test.rs index fddef25d11..dda3313c2e 100644 --- a/module/alias/wtest_basic/tests/smoke_test.rs +++ b/module/alias/wtest_basic/tests/smoke_test.rs @@ -1,5 +1,5 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] #[ ignore ] fn local_smoke_test() @@ -7,7 +7,7 @@ fn local_smoke_test() ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/blank/brain_tools/Cargo.toml b/module/blank/brain_tools/Cargo.toml new file mode 100644 index 0000000000..be2c9858a0 --- /dev/null +++ b/module/blank/brain_tools/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name = "brain_tools" +version = "0.1.0" +edition = "2021" +authors = [ + "Kostiantyn Wandalen ", +] +license = "MIT" +readme = "Readme.md" +documentation = "https://docs.rs/brain_tools" +repository = "https://github.com/Wandalen/wTools/tree/master/module/core/brain_tools" +homepage = "https://github.com/Wandalen/wTools/tree/master/module/core/brain_tools" +description = """ +Tools for second brain. +""" +categories = [ "algorithms", "development-tools" ] +keywords = [ "fundamental", "general-purpose" ] + +[lints] +workspace = true + +[package.metadata.docs.rs] +features = [ "full" ] +all-features = false + +[features] +default = [ "enabled" ] +full = [ "enabled" ] +enabled = [] + +[dependencies] + +[dev-dependencies] +test_tools = { workspace = true } diff --git a/module/blank/willbe_old/License b/module/blank/brain_tools/License similarity index 100% rename from module/blank/willbe_old/License rename to module/blank/brain_tools/License diff --git a/module/blank/brain_tools/Readme.md b/module/blank/brain_tools/Readme.md new file mode 100644 index 0000000000..37d9acc46e --- /dev/null +++ b/module/blank/brain_tools/Readme.md @@ -0,0 +1,33 @@ + + +# Module :: brain_tools +[![experimental](https://raster.shields.io/static/v1?label=stability&message=experimental&color=orange&logoColor=eee)](https://github.com/emersion/stability-badges#experimental) [![rust-status](https://github.com/Wandalen/wTools/actions/workflows/Modulebrain_toolsPush.yml/badge.svg)](https://github.com/Wandalen/wTools/actions/workflows/Modulebrain_toolsPush.yml) [![docs.rs](https://img.shields.io/docsrs/brain_tools?color=e3e8f0&logo=docs.rs)](https://docs.rs/brain_tools) [![discord](https://img.shields.io/discord/872391416519737405?color=eee&logo=discord&logoColor=eee&label=ask)](https://discord.gg/m3YfbXpUUY) + +Tools for second brain. + + diff --git a/module/blank/brain_tools/src/lib.rs b/module/blank/brain_tools/src/lib.rs new file mode 100644 index 0000000000..4168554e8f --- /dev/null +++ b/module/blank/brain_tools/src/lib.rs @@ -0,0 +1,11 @@ + +#![ 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/brain_tools/latest/brain_tools/" ) ] +#![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/", "Readme.md" ) ) ] + +/// Function description. +#[ cfg( feature = "enabled" ) ] +pub fn f1() +{ +} diff --git a/module/blank/brain_tools/tests/inc/basic_test.rs b/module/blank/brain_tools/tests/inc/basic_test.rs new file mode 100644 index 0000000000..60c9a81cfb --- /dev/null +++ b/module/blank/brain_tools/tests/inc/basic_test.rs @@ -0,0 +1,7 @@ +#[ allow( unused_imports ) ] +use super::*; + +#[ test ] +fn basic() +{ +} diff --git a/module/blank/brain_tools/tests/inc/mod.rs b/module/blank/brain_tools/tests/inc/mod.rs new file mode 100644 index 0000000000..dde9de6f94 --- /dev/null +++ b/module/blank/brain_tools/tests/inc/mod.rs @@ -0,0 +1,4 @@ +#[ allow( unused_imports ) ] +use super::*; + +mod basic_test; diff --git a/module/blank/willbe_old/tests/smoke_test.rs b/module/blank/brain_tools/tests/smoke_test.rs similarity index 67% rename from module/blank/willbe_old/tests/smoke_test.rs rename to module/blank/brain_tools/tests/smoke_test.rs index 8a9c649677..663dd6fb9f 100644 --- a/module/blank/willbe_old/tests/smoke_test.rs +++ b/module/blank/brain_tools/tests/smoke_test.rs @@ -1,14 +1,11 @@ -// #[ cfg( feature = "default" ) ] #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] #[ test ] -#[ ignore ] fn published_smoke_test() { ::test_tools::smoke_test_for_published_run(); diff --git a/module/blank/brain_tools/tests/tests.rs b/module/blank/brain_tools/tests/tests.rs new file mode 100644 index 0000000000..574f34b114 --- /dev/null +++ b/module/blank/brain_tools/tests/tests.rs @@ -0,0 +1,10 @@ + +include!( "../../../../module/step/meta/src/module/terminal.rs" ); + +#[ allow( unused_imports ) ] +use brain_tools as the_module; +#[ allow( unused_imports ) ] +use test_tools::exposed::*; + +#[ cfg( feature = "enabled" ) ] +mod inc; diff --git a/module/blank/draw_lang/Cargo.toml b/module/blank/draw_lang/Cargo.toml new file mode 100644 index 0000000000..0fbe918a0f --- /dev/null +++ b/module/blank/draw_lang/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name = "draw_lang" +version = "0.1.0" +edition = "2021" +authors = [ + "Kostiantyn Wandalen ", +] +license = "MIT" +readme = "Readme.md" +documentation = "https://docs.rs/draw_lang" +repository = "https://github.com/Wandalen/wTools/tree/master/module/core/draw_lang" +homepage = "https://github.com/Wandalen/wTools/tree/master/module/core/draw_lang" +description = """ +Draw language. +""" +categories = [ "algorithms", "development-tools" ] +keywords = [ "fundamental", "general-purpose" ] + +[lints] +workspace = true + +[package.metadata.docs.rs] +features = [ "full" ] +all-features = false + +[features] +default = [ "enabled" ] +full = [ "enabled" ] +enabled = [] + +[dependencies] + +[dev-dependencies] +test_tools = { workspace = true } diff --git a/module/blank/draw_lang/License b/module/blank/draw_lang/License new file mode 100644 index 0000000000..6d5ef8559f --- /dev/null +++ b/module/blank/draw_lang/License @@ -0,0 +1,22 @@ +Copyright Kostiantyn W and Out of the Box Systems (c) 2013-2024 + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/module/blank/draw_lang/Readme.md b/module/blank/draw_lang/Readme.md new file mode 100644 index 0000000000..3a3390cd6c --- /dev/null +++ b/module/blank/draw_lang/Readme.md @@ -0,0 +1,33 @@ + + +# Module :: draw_lang +[![experimental](https://raster.shields.io/static/v1?label=stability&message=experimental&color=orange&logoColor=eee)](https://github.com/emersion/stability-badges#experimental) [![rust-status](https://github.com/Wandalen/wTools/actions/workflows/Moduledraw_langPush.yml/badge.svg)](https://github.com/Wandalen/wTools/actions/workflows/Moduledraw_langPush.yml) [![docs.rs](https://img.shields.io/docsrs/draw_lang?color=e3e8f0&logo=docs.rs)](https://docs.rs/draw_lang) [![discord](https://img.shields.io/discord/872391416519737405?color=eee&logo=discord&logoColor=eee&label=ask)](https://discord.gg/m3YfbXpUUY) + +Draw language. + + diff --git a/module/blank/draw_lang/src/lib.rs b/module/blank/draw_lang/src/lib.rs new file mode 100644 index 0000000000..4ef561428b --- /dev/null +++ b/module/blank/draw_lang/src/lib.rs @@ -0,0 +1,11 @@ + +#![ 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/draw_lang/latest/draw_lang/" ) ] +#![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/", "Readme.md" ) ) ] + +/// Function description. +#[ cfg( feature = "enabled" ) ] +pub fn f1() +{ +} diff --git a/module/blank/draw_lang/tests/inc/basic_test.rs b/module/blank/draw_lang/tests/inc/basic_test.rs new file mode 100644 index 0000000000..60c9a81cfb --- /dev/null +++ b/module/blank/draw_lang/tests/inc/basic_test.rs @@ -0,0 +1,7 @@ +#[ allow( unused_imports ) ] +use super::*; + +#[ test ] +fn basic() +{ +} diff --git a/module/blank/draw_lang/tests/inc/mod.rs b/module/blank/draw_lang/tests/inc/mod.rs new file mode 100644 index 0000000000..dde9de6f94 --- /dev/null +++ b/module/blank/draw_lang/tests/inc/mod.rs @@ -0,0 +1,4 @@ +#[ allow( unused_imports ) ] +use super::*; + +mod basic_test; diff --git a/module/blank/draw_lang/tests/smoke_test.rs b/module/blank/draw_lang/tests/smoke_test.rs new file mode 100644 index 0000000000..828e9b016b --- /dev/null +++ b/module/blank/draw_lang/tests/smoke_test.rs @@ -0,0 +1,14 @@ + + +#[ test ] +fn local_smoke_test() +{ + ::test_tools::smoke_test_for_local_run(); +} + + +#[ test ] +fn published_smoke_test() +{ + ::test_tools::smoke_test_for_published_run(); +} diff --git a/module/blank/draw_lang/tests/tests.rs b/module/blank/draw_lang/tests/tests.rs new file mode 100644 index 0000000000..0a3de03a72 --- /dev/null +++ b/module/blank/draw_lang/tests/tests.rs @@ -0,0 +1,10 @@ + +include!( "../../../../module/step/meta/src/module/terminal.rs" ); + +#[ allow( unused_imports ) ] +use draw_lang as the_module; +#[ allow( unused_imports ) ] +use test_tools::exposed::*; + +#[ cfg( feature = "enabled" ) ] +mod inc; diff --git a/module/blank/drawboard/Cargo.toml b/module/blank/drawboard/Cargo.toml new file mode 100644 index 0000000000..cafdb5d639 --- /dev/null +++ b/module/blank/drawboard/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name = "drawboard" +version = "0.1.0" +edition = "2021" +authors = [ + "Kostiantyn Wandalen ", +] +license = "MIT" +readme = "Readme.md" +documentation = "https://docs.rs/drawboard" +repository = "https://github.com/Wandalen/wTools/tree/master/module/core/drawboard" +homepage = "https://github.com/Wandalen/wTools/tree/master/module/core/drawboard" +description = """ +Draw engine. +""" +categories = [ "algorithms", "development-tools" ] +keywords = [ "fundamental", "general-purpose" ] + +[lints] +workspace = true + +[package.metadata.docs.rs] +features = [ "full" ] +all-features = false + +[features] +default = [ "enabled" ] +full = [ "enabled" ] +enabled = [] + +[dependencies] + +[dev-dependencies] +test_tools = { workspace = true } diff --git a/module/blank/drawboard/License b/module/blank/drawboard/License new file mode 100644 index 0000000000..6d5ef8559f --- /dev/null +++ b/module/blank/drawboard/License @@ -0,0 +1,22 @@ +Copyright Kostiantyn W and Out of the Box Systems (c) 2013-2024 + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/module/blank/drawboard/Readme.md b/module/blank/drawboard/Readme.md new file mode 100644 index 0000000000..c10e35a284 --- /dev/null +++ b/module/blank/drawboard/Readme.md @@ -0,0 +1,33 @@ + + +# Module :: drawboard +[![experimental](https://raster.shields.io/static/v1?label=stability&message=experimental&color=orange&logoColor=eee)](https://github.com/emersion/stability-badges#experimental) [![rust-status](https://github.com/Wandalen/wTools/actions/workflows/ModuledrawboardPush.yml/badge.svg)](https://github.com/Wandalen/wTools/actions/workflows/ModuledrawboardPush.yml) [![docs.rs](https://img.shields.io/docsrs/drawboard?color=e3e8f0&logo=docs.rs)](https://docs.rs/drawboard) [![discord](https://img.shields.io/discord/872391416519737405?color=eee&logo=discord&logoColor=eee&label=ask)](https://discord.gg/m3YfbXpUUY) + +Draw engine. + + diff --git a/module/blank/drawboard/src/lib.rs b/module/blank/drawboard/src/lib.rs new file mode 100644 index 0000000000..d6a4e99b98 --- /dev/null +++ b/module/blank/drawboard/src/lib.rs @@ -0,0 +1,11 @@ + +#![ 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/drawboard/latest/drawboard/" ) ] +#![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/", "Readme.md" ) ) ] + +/// Function description. +#[ cfg( feature = "enabled" ) ] +pub fn f1() +{ +} diff --git a/module/blank/drawboard/tests/inc/basic_test.rs b/module/blank/drawboard/tests/inc/basic_test.rs new file mode 100644 index 0000000000..60c9a81cfb --- /dev/null +++ b/module/blank/drawboard/tests/inc/basic_test.rs @@ -0,0 +1,7 @@ +#[ allow( unused_imports ) ] +use super::*; + +#[ test ] +fn basic() +{ +} diff --git a/module/blank/drawboard/tests/inc/mod.rs b/module/blank/drawboard/tests/inc/mod.rs new file mode 100644 index 0000000000..dde9de6f94 --- /dev/null +++ b/module/blank/drawboard/tests/inc/mod.rs @@ -0,0 +1,4 @@ +#[ allow( unused_imports ) ] +use super::*; + +mod basic_test; diff --git a/module/blank/drawboard/tests/smoke_test.rs b/module/blank/drawboard/tests/smoke_test.rs new file mode 100644 index 0000000000..828e9b016b --- /dev/null +++ b/module/blank/drawboard/tests/smoke_test.rs @@ -0,0 +1,14 @@ + + +#[ test ] +fn local_smoke_test() +{ + ::test_tools::smoke_test_for_local_run(); +} + + +#[ test ] +fn published_smoke_test() +{ + ::test_tools::smoke_test_for_published_run(); +} diff --git a/module/blank/drawboard/tests/tests.rs b/module/blank/drawboard/tests/tests.rs new file mode 100644 index 0000000000..2a19dfd2f8 --- /dev/null +++ b/module/blank/drawboard/tests/tests.rs @@ -0,0 +1,10 @@ + +include!( "../../../../module/step/meta/src/module/terminal.rs" ); + +#[ allow( unused_imports ) ] +use drawboard as the_module; +#[ allow( unused_imports ) ] +use test_tools::exposed::*; + +#[ cfg( feature = "enabled" ) ] +mod inc; diff --git a/module/blank/drawql/Cargo.toml b/module/blank/drawql/Cargo.toml new file mode 100644 index 0000000000..331bdf9e15 --- /dev/null +++ b/module/blank/drawql/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name = "drawql" +version = "0.1.0" +edition = "2021" +authors = [ + "Kostiantyn Wandalen ", +] +license = "MIT" +readme = "Readme.md" +documentation = "https://docs.rs/drawql" +repository = "https://github.com/Wandalen/wTools/tree/master/module/core/drawql" +homepage = "https://github.com/Wandalen/wTools/tree/master/module/core/drawql" +description = """ +Draw query language. +""" +categories = [ "algorithms", "development-tools" ] +keywords = [ "fundamental", "general-purpose" ] + +[lints] +workspace = true + +[package.metadata.docs.rs] +features = [ "full" ] +all-features = false + +[features] +default = [ "enabled" ] +full = [ "enabled" ] +enabled = [] + +[dependencies] + +[dev-dependencies] +test_tools = { workspace = true } diff --git a/module/blank/drawql/License b/module/blank/drawql/License new file mode 100644 index 0000000000..6d5ef8559f --- /dev/null +++ b/module/blank/drawql/License @@ -0,0 +1,22 @@ +Copyright Kostiantyn W and Out of the Box Systems (c) 2013-2024 + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/module/blank/drawql/Readme.md b/module/blank/drawql/Readme.md new file mode 100644 index 0000000000..5505ef07b5 --- /dev/null +++ b/module/blank/drawql/Readme.md @@ -0,0 +1,33 @@ + + +# Module :: drawql +[![experimental](https://raster.shields.io/static/v1?label=stability&message=experimental&color=orange&logoColor=eee)](https://github.com/emersion/stability-badges#experimental) [![rust-status](https://github.com/Wandalen/wTools/actions/workflows/ModuledrawqlPush.yml/badge.svg)](https://github.com/Wandalen/wTools/actions/workflows/ModuledrawqlPush.yml) [![docs.rs](https://img.shields.io/docsrs/drawql?color=e3e8f0&logo=docs.rs)](https://docs.rs/drawql) [![discord](https://img.shields.io/discord/872391416519737405?color=eee&logo=discord&logoColor=eee&label=ask)](https://discord.gg/m3YfbXpUUY) + +Draw query language. + + diff --git a/module/blank/drawql/src/lib.rs b/module/blank/drawql/src/lib.rs new file mode 100644 index 0000000000..303b2cc3eb --- /dev/null +++ b/module/blank/drawql/src/lib.rs @@ -0,0 +1,11 @@ + +#![ 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/drawql/latest/drawql/" ) ] +#![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/", "Readme.md" ) ) ] + +/// Function description. +#[ cfg( feature = "enabled" ) ] +pub fn f1() +{ +} diff --git a/module/blank/drawql/tests/inc/basic_test.rs b/module/blank/drawql/tests/inc/basic_test.rs new file mode 100644 index 0000000000..60c9a81cfb --- /dev/null +++ b/module/blank/drawql/tests/inc/basic_test.rs @@ -0,0 +1,7 @@ +#[ allow( unused_imports ) ] +use super::*; + +#[ test ] +fn basic() +{ +} diff --git a/module/blank/drawql/tests/inc/mod.rs b/module/blank/drawql/tests/inc/mod.rs new file mode 100644 index 0000000000..dde9de6f94 --- /dev/null +++ b/module/blank/drawql/tests/inc/mod.rs @@ -0,0 +1,4 @@ +#[ allow( unused_imports ) ] +use super::*; + +mod basic_test; diff --git a/module/blank/drawql/tests/smoke_test.rs b/module/blank/drawql/tests/smoke_test.rs new file mode 100644 index 0000000000..828e9b016b --- /dev/null +++ b/module/blank/drawql/tests/smoke_test.rs @@ -0,0 +1,14 @@ + + +#[ test ] +fn local_smoke_test() +{ + ::test_tools::smoke_test_for_local_run(); +} + + +#[ test ] +fn published_smoke_test() +{ + ::test_tools::smoke_test_for_published_run(); +} diff --git a/module/blank/drawql/tests/tests.rs b/module/blank/drawql/tests/tests.rs new file mode 100644 index 0000000000..8efe0ed842 --- /dev/null +++ b/module/blank/drawql/tests/tests.rs @@ -0,0 +1,10 @@ + +include!( "../../../../module/step/meta/src/module/terminal.rs" ); + +#[ allow( unused_imports ) ] +use drawql as the_module; +#[ allow( unused_imports ) ] +use test_tools::exposed::*; + +#[ cfg( feature = "enabled" ) ] +mod inc; diff --git a/module/blank/exe_tools/src/lib.rs b/module/blank/exe_tools/src/lib.rs index 8232f96ec6..72a6d98e77 100644 --- a/module/blank/exe_tools/src/lib.rs +++ b/module/blank/exe_tools/src/lib.rs @@ -1,4 +1,4 @@ -#![ cfg_attr( feature = "no_std", no_std ) ] + #![ 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/exe_tools/latest/exe_tools/" ) ] diff --git a/module/blank/exe_tools/tests/smoke_test.rs b/module/blank/exe_tools/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/blank/exe_tools/tests/smoke_test.rs +++ b/module/blank/exe_tools/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/blank/image_tools/src/lib.rs b/module/blank/image_tools/src/lib.rs index 39d9969091..b65129453a 100644 --- a/module/blank/image_tools/src/lib.rs +++ b/module/blank/image_tools/src/lib.rs @@ -1,4 +1,4 @@ -#![ cfg_attr( feature = "no_std", no_std ) ] + #![ 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/image_tools/latest/image_tools/" ) ] diff --git a/module/blank/image_tools/tests/smoke_test.rs b/module/blank/image_tools/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/blank/image_tools/tests/smoke_test.rs +++ b/module/blank/image_tools/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/blank/math_tools/tests/smoke_test.rs b/module/blank/math_tools/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/blank/math_tools/tests/smoke_test.rs +++ b/module/blank/math_tools/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/blank/paths_tools/Cargo.toml b/module/blank/paths_tools/Cargo.toml new file mode 100644 index 0000000000..e71fb6027c --- /dev/null +++ b/module/blank/paths_tools/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name = "paths_tools" +version = "0.1.0" +edition = "2021" +authors = [ + "Kostiantyn Wandalen ", +] +license = "MIT" +readme = "Readme.md" +documentation = "https://docs.rs/paths_tools" +repository = "https://github.com/Wandalen/wTools/tree/master/module/core/paths_tools" +homepage = "https://github.com/Wandalen/wTools/tree/master/module/core/paths_tools" +description = """ +Tools to work with file paths. +""" +categories = [ "algorithms", "development-tools" ] +keywords = [ "fundamental", "general-purpose" ] + +[lints] +workspace = true + +[package.metadata.docs.rs] +features = [ "full" ] +all-features = false + +[features] +default = [ "enabled" ] +full = [ "enabled" ] +enabled = [] + +[dependencies] + +[dev-dependencies] +test_tools = { workspace = true } diff --git a/module/blank/paths_tools/License b/module/blank/paths_tools/License new file mode 100644 index 0000000000..6d5ef8559f --- /dev/null +++ b/module/blank/paths_tools/License @@ -0,0 +1,22 @@ +Copyright Kostiantyn W and Out of the Box Systems (c) 2013-2024 + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/module/blank/paths_tools/Readme.md b/module/blank/paths_tools/Readme.md new file mode 100644 index 0000000000..adbca63b03 --- /dev/null +++ b/module/blank/paths_tools/Readme.md @@ -0,0 +1,33 @@ + + +# Module :: paths_tools +[![experimental](https://raster.shields.io/static/v1?label=stability&message=experimental&color=orange&logoColor=eee)](https://github.com/emersion/stability-badges#experimental) [![rust-status](https://github.com/Wandalen/wTools/actions/workflows/Modulepaths_toolsPush.yml/badge.svg)](https://github.com/Wandalen/wTools/actions/workflows/Modulepaths_toolsPush.yml) [![docs.rs](https://img.shields.io/docsrs/paths_tools?color=e3e8f0&logo=docs.rs)](https://docs.rs/paths_tools) [![discord](https://img.shields.io/discord/872391416519737405?color=eee&logo=discord&logoColor=eee&label=ask)](https://discord.gg/m3YfbXpUUY) + +Tools to work with file paths. + + diff --git a/module/blank/paths_tools/src/lib.rs b/module/blank/paths_tools/src/lib.rs new file mode 100644 index 0000000000..19a2b46268 --- /dev/null +++ b/module/blank/paths_tools/src/lib.rs @@ -0,0 +1,11 @@ + +#![ 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/paths_tools/latest/paths_tools/" ) ] +#![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/", "Readme.md" ) ) ] + +/// Function description. +#[ cfg( feature = "enabled" ) ] +pub fn f1() +{ +} diff --git a/module/blank/paths_tools/tests/inc/basic_test.rs b/module/blank/paths_tools/tests/inc/basic_test.rs new file mode 100644 index 0000000000..60c9a81cfb --- /dev/null +++ b/module/blank/paths_tools/tests/inc/basic_test.rs @@ -0,0 +1,7 @@ +#[ allow( unused_imports ) ] +use super::*; + +#[ test ] +fn basic() +{ +} diff --git a/module/blank/paths_tools/tests/inc/mod.rs b/module/blank/paths_tools/tests/inc/mod.rs new file mode 100644 index 0000000000..dde9de6f94 --- /dev/null +++ b/module/blank/paths_tools/tests/inc/mod.rs @@ -0,0 +1,4 @@ +#[ allow( unused_imports ) ] +use super::*; + +mod basic_test; diff --git a/module/blank/paths_tools/tests/smoke_test.rs b/module/blank/paths_tools/tests/smoke_test.rs new file mode 100644 index 0000000000..663dd6fb9f --- /dev/null +++ b/module/blank/paths_tools/tests/smoke_test.rs @@ -0,0 +1,12 @@ + +#[ test ] +fn local_smoke_test() +{ + ::test_tools::smoke_test_for_local_run(); +} + +#[ test ] +fn published_smoke_test() +{ + ::test_tools::smoke_test_for_published_run(); +} diff --git a/module/blank/paths_tools/tests/tests.rs b/module/blank/paths_tools/tests/tests.rs new file mode 100644 index 0000000000..7900d6181b --- /dev/null +++ b/module/blank/paths_tools/tests/tests.rs @@ -0,0 +1,10 @@ + +include!( "../../../../module/step/meta/src/module/terminal.rs" ); + +#[ allow( unused_imports ) ] +use paths_tools as the_module; +#[ allow( unused_imports ) ] +use test_tools::exposed::*; + +#[ cfg( feature = "enabled" ) ] +mod inc; diff --git a/module/blank/rustql/src/lib.rs b/module/blank/rustql/src/lib.rs index e8dceed08a..1cfdb4344f 100644 --- a/module/blank/rustql/src/lib.rs +++ b/module/blank/rustql/src/lib.rs @@ -1,4 +1,4 @@ -#![ cfg_attr( feature = "no_std", no_std ) ] + #![ 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/rustql/latest/rustql/" ) ] diff --git a/module/blank/rustql/tests/smoke_test.rs b/module/blank/rustql/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/blank/rustql/tests/smoke_test.rs +++ b/module/blank/rustql/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/blank/second_brain/Cargo.toml b/module/blank/second_brain/Cargo.toml new file mode 100644 index 0000000000..1242baec92 --- /dev/null +++ b/module/blank/second_brain/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name = "second_brain" +version = "0.1.0" +edition = "2021" +authors = [ + "Kostiantyn Wandalen ", +] +license = "MIT" +readme = "Readme.md" +documentation = "https://docs.rs/second_brain" +repository = "https://github.com/Wandalen/wTools/tree/master/module/core/second_brain" +homepage = "https://github.com/Wandalen/wTools/tree/master/module/core/second_brain" +description = """ +Tools for second brain. +""" +categories = [ "algorithms", "development-tools" ] +keywords = [ "fundamental", "general-purpose" ] + +[lints] +workspace = true + +[package.metadata.docs.rs] +features = [ "full" ] +all-features = false + +[features] +default = [ "enabled" ] +full = [ "enabled" ] +enabled = [] + +[dependencies] + +[dev-dependencies] +test_tools = { workspace = true } diff --git a/module/blank/second_brain/License b/module/blank/second_brain/License new file mode 100644 index 0000000000..6d5ef8559f --- /dev/null +++ b/module/blank/second_brain/License @@ -0,0 +1,22 @@ +Copyright Kostiantyn W and Out of the Box Systems (c) 2013-2024 + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/module/blank/second_brain/Readme.md b/module/blank/second_brain/Readme.md new file mode 100644 index 0000000000..8680c3b72a --- /dev/null +++ b/module/blank/second_brain/Readme.md @@ -0,0 +1,33 @@ + + +# Module :: second_brain +[![experimental](https://raster.shields.io/static/v1?label=stability&message=experimental&color=orange&logoColor=eee)](https://github.com/emersion/stability-badges#experimental) [![rust-status](https://github.com/Wandalen/wTools/actions/workflows/Modulesecond_brainPush.yml/badge.svg)](https://github.com/Wandalen/wTools/actions/workflows/Modulesecond_brainPush.yml) [![docs.rs](https://img.shields.io/docsrs/second_brain?color=e3e8f0&logo=docs.rs)](https://docs.rs/second_brain) [![discord](https://img.shields.io/discord/872391416519737405?color=eee&logo=discord&logoColor=eee&label=ask)](https://discord.gg/m3YfbXpUUY) + +Tools for second brain. + + diff --git a/module/blank/second_brain/src/lib.rs b/module/blank/second_brain/src/lib.rs new file mode 100644 index 0000000000..3c3afbe76a --- /dev/null +++ b/module/blank/second_brain/src/lib.rs @@ -0,0 +1,11 @@ + +#![ 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/second_brain/latest/second_brain/" ) ] +#![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/", "Readme.md" ) ) ] + +/// Function description. +#[ cfg( feature = "enabled" ) ] +pub fn f1() +{ +} diff --git a/module/blank/second_brain/tests/inc/basic_test.rs b/module/blank/second_brain/tests/inc/basic_test.rs new file mode 100644 index 0000000000..60c9a81cfb --- /dev/null +++ b/module/blank/second_brain/tests/inc/basic_test.rs @@ -0,0 +1,7 @@ +#[ allow( unused_imports ) ] +use super::*; + +#[ test ] +fn basic() +{ +} diff --git a/module/blank/second_brain/tests/inc/mod.rs b/module/blank/second_brain/tests/inc/mod.rs new file mode 100644 index 0000000000..dde9de6f94 --- /dev/null +++ b/module/blank/second_brain/tests/inc/mod.rs @@ -0,0 +1,4 @@ +#[ allow( unused_imports ) ] +use super::*; + +mod basic_test; diff --git a/module/blank/second_brain/tests/smoke_test.rs b/module/blank/second_brain/tests/smoke_test.rs new file mode 100644 index 0000000000..663dd6fb9f --- /dev/null +++ b/module/blank/second_brain/tests/smoke_test.rs @@ -0,0 +1,12 @@ + +#[ test ] +fn local_smoke_test() +{ + ::test_tools::smoke_test_for_local_run(); +} + +#[ test ] +fn published_smoke_test() +{ + ::test_tools::smoke_test_for_published_run(); +} diff --git a/module/blank/second_brain/tests/tests.rs b/module/blank/second_brain/tests/tests.rs new file mode 100644 index 0000000000..962e97321e --- /dev/null +++ b/module/blank/second_brain/tests/tests.rs @@ -0,0 +1,10 @@ + +include!( "../../../../module/step/meta/src/module/terminal.rs" ); + +#[ allow( unused_imports ) ] +use second_brain as the_module; +#[ allow( unused_imports ) ] +use test_tools::exposed::*; + +#[ cfg( feature = "enabled" ) ] +mod inc; diff --git a/module/blank/w4d/tests/smoke_test.rs b/module/blank/w4d/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/blank/w4d/tests/smoke_test.rs +++ b/module/blank/w4d/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/blank/willbe_old/Cargo.toml b/module/blank/willbe_old/Cargo.toml deleted file mode 100644 index 56716163d5..0000000000 --- a/module/blank/willbe_old/Cargo.toml +++ /dev/null @@ -1,80 +0,0 @@ -[package] -name = "willbe_old" -version = "0.1.0" -edition = "2021" -authors = [ - "Kostiantyn Wandalen ", - "Dmytro Kryvoruchko ", -] -license = "MIT" -readme = "Readme.md" -documentation = "https://docs.rs/willbe" -repository = "https://github.com/Wandalen/wTools/tree/master/module/core/willbe_old" -homepage = "https://github.com/Wandalen/wTools/tree/master/module/core/willbe_old" -description = """ -___ -""" -categories = [ "algorithms", "development-tools" ] -keywords = [ "fundamental", "general-purpose" ] -publish = false - -[lints] -workspace = true - -[package.metadata.docs.rs] -features = [ "full" ] -all-features = false -# exclude = [ "/tests", "/examples", "-*" ] -include = [ - "/rust/impl/willbe_old", - "/Cargo.toml", - "/Readme.md", - "/License", -] - -[features] -default = [ "enabled" ] -full = [ "enabled" ] -no_std = [] -use_alloc = [ "no_std" ] -enabled = [] - -[lib] -name = "willbe_old" -path = "src/willbe_old/willbe_lib.rs" - -[[bin]] -name = "willbe_old" -path = "src/willbe_old/willbe_entry.rs" - -[[test]] -name = "willbe_test" -path = "tests/willbe_old/willbe_test.rs" - -# disable for now -# [[test]] -# name = "willbe_smoke_test" -# path = "tests/_integration_test/smoke_test.rs" -# -# [[example]] -# name = "willbe_trivial" -# path = "examples/willbe_trivial/src/main.rs" - -[dependencies] -wtools = { workspace = true } -wca = { workspace = true } -mod_interface = { workspace = true, features = [ "default" ] } -iter_tools = { workspace = true, features = [ "default" ] } -error_tools = { workspace = true, features = [ "default" ] } -toml = "0.5" -globwalk = "0.8" -cargo_metadata = "0.15" -path-absolutize = "3" -petgraph = "~0.6" -rand = "0.8.4" - -[dev-dependencies] -test_tools = { workspace = true } -tempfile = "3" -assert_cmd = "2.0" -predicates = "2.1" diff --git a/module/blank/willbe_old/Readme.md b/module/blank/willbe_old/Readme.md deleted file mode 100644 index 7028ba383c..0000000000 --- a/module/blank/willbe_old/Readme.md +++ /dev/null @@ -1,35 +0,0 @@ - - -# Module :: willbe - - [![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) [![rust-status](https://github.com/Wandalen/wTools/actions/workflows/module_willbe_old_push.yml/badge.svg)](https://github.com/Wandalen/wTools/actions/workflows/module_willbe_old_push.yml) [![docs.rs](https://img.shields.io/docsrs/willbe_old?color=e3e8f0&logo=docs.rs)](https://docs.rs/willbe_old) [![discord](https://img.shields.io/discord/872391416519737405?color=eee&logo=discord&logoColor=eee&label=ask)](https://discord.gg/m3YfbXpUUY) - - -___ - -### Basic use-case - - - -```rust -use willbe_old::*; - -fn main() -{ -} -``` - -### To add to your project - -```bash -cargo add willbe -``` - -### Try out from the repository - -``` shell test -git clone https://github.com/Wandalen/wTools -cd wTools -cd examples/willbe_trivial -cargo run -``` diff --git a/module/blank/willbe_old/src/willbe_old/commands/each.rs b/module/blank/willbe_old/src/willbe_old/commands/each.rs deleted file mode 100644 index 21a81accae..0000000000 --- a/module/blank/willbe_old/src/willbe_old/commands/each.rs +++ /dev/null @@ -1,119 +0,0 @@ -/// Internal namespace. -pub( crate ) mod private -{ - use std::{ env, rc::Rc, cell::RefCell, }; - use wca:: - { - Args, Props, - Context, - }; - use error_tools::{ Result, BasicError }; - - use crate::protected::*; - use crate::commands::{ StartPointStack, EndPointStack }; - - #[ derive( Clone ) ] - struct PackagesIterator - ( - Rc< RefCell< dyn Iterator< Item = Package > > > - ); - - impl< I > From< I > for PackagesIterator - where - I : Iterator< Item = Package > + 'static - { - fn from( iter : I ) -> Self - { - Self( Rc::new( RefCell::new( iter ) ) ) - } - } - - impl PackagesIterator - { - fn next( &self ) -> Option< Package > - { - self.0.borrow_mut().next() - } - } - - /// Each command declaration - pub fn each_command() -> wca::Command - { - wca::Command::former() - .hint( "Iterate over packages" ) - .long_hint( "Iterates over all packages from current directory" ) - .phrase( "each" ) - .form() - } - - /// - /// Iterate over packages - /// - - pub fn each( _ : ( Args, Props ), mut ctx : Context ) -> Result< () > - { - println!( "[LOG] Called each command" ); - - // Already iterate - if let Some( iter ) = ctx.get_mut::< PackagesIterator >() - { - // It isn't end of iterator - let is_current_package_exists = ctx.get_ref::< Option< Package > >().and_then( | p | p.as_ref() ).is_some(); - let next_package = iter.next(); - if is_current_package_exists && next_package.is_some() - { - ctx.insert( next_package ); - } - else - { - ctx.remove::< Option< Package > >(); - ctx.remove::< PackagesIterator >(); - // At the end of each - go to first endpoint - // remove self from startpoints - ctx.get_mut::< StartPointStack >().and_then( | sp | sp.pop() ); - // go to endpoint - let prog_state = ctx.get_mut::< wca::RuntimeState >() - .ok_or_else( || BasicError::new( "Have no Program State" ) )?; - - ctx.get_mut::< EndPointStack >() - .and_then( | ep | ep.pop() ) - .map( | point | prog_state.pos = point ) - //? What is better - panic or go to the end of the program when endpoints doesn't exists for any reason - .unwrap_or_else( || prog_state.pos = usize::MAX ); - } - } - else - { - // Begin iteration - let current_path = env::current_dir().unwrap(); - let mut packages_iter = packages_iterate( current_path ); - - let package = packages_iter.next(); - - // But anyway program must found the end of `.each` - if package.is_none() - { - println!( "Any package was found at current directory" ); - } - - // Add current package and the iterator to context - ctx.insert( package ); - ctx.insert::< PackagesIterator >( packages_iter.into() ); - - // Start point to previous instruction( back to current ) - let prog_state = ctx.get_ref::< wca::RuntimeState >() - .ok_or_else( || BasicError::new( "Have no Program State" ) )?; - ctx.get_or_default::< StartPointStack >().push( prog_state.pos - 1 ); - } - - Ok( () ) - } -} - -// - -crate::mod_interface! -{ - prelude use each_command; - prelude use each; -} diff --git a/module/blank/willbe_old/src/willbe_old/commands/end.rs b/module/blank/willbe_old/src/willbe_old/commands/end.rs deleted file mode 100644 index b7931a06dd..0000000000 --- a/module/blank/willbe_old/src/willbe_old/commands/end.rs +++ /dev/null @@ -1,61 +0,0 @@ -/// Internal namespace. -pub( crate ) mod private -{ - use wca:: - { - Args, Props, - Context, - }; - use error_tools::{ Result, BasicError }; - - use crate::commands::{ StartPointStack, EndPointStack }; - - // ! TODO: Remove this command somehow - - /// End command declaration - pub fn end_command() -> wca::Command - { - wca::Command::former() - .hint( "Command that is end of a block or a program" ) - .phrase( "end" ) - .form() - } - - /// - /// End of loop/program - /// - - pub fn end( _ : ( Args, Props ), ctx : Context ) -> Result< () > - { - println!( "[LOG] end called" ); - - if let Some( startpoints ) = ctx.get_ref::< StartPointStack >() - { - if let Some( point ) = startpoints.last() - { - let prog_state = ctx.get_mut::< wca::RuntimeState >() - .ok_or_else( || BasicError::new( "Have no Program State" ) )?; - - let endpoints = ctx.get_or_default::< EndPointStack >(); - // if has no point at current instruction - push it - if endpoints.last() != Some( &( prog_state.pos - 1 ) ) - { - endpoints.push( prog_state.pos - 1 ); - } - - // Go to start point - prog_state.pos = *point; - } - } - - Ok( () ) - } -} - -// - -crate::mod_interface! -{ - prelude use end_command; - prelude use end; -} diff --git a/module/blank/willbe_old/src/willbe_old/commands/init.rs b/module/blank/willbe_old/src/willbe_old/commands/init.rs deleted file mode 100644 index ddfa273b42..0000000000 --- a/module/blank/willbe_old/src/willbe_old/commands/init.rs +++ /dev/null @@ -1,43 +0,0 @@ -/// Internal namespace. -pub( crate ) mod private -{ - use crate::commands; - - /// - /// Form CA commands grammar. - /// - - pub fn grammar_form() -> Vec< wca::Command > - { - vec! - [ - commands::each::each_command(), - commands::package::info::info_command(), - commands::package::publish::publish_command(), - commands::end::end_command(), - ] - } - - /// - /// Form CA commands executor. - /// - - pub fn executor_form() -> std::collections::HashMap< String, wca::Routine > - { - std::collections::HashMap::from( - [ - ( "each".to_owned(), wca::Routine::new_with_ctx( commands::each::each ) ), - ( "crate.info".to_owned(), wca::Routine::new_with_ctx( commands::package::info::info ) ), - ( "crate.publish".to_owned(), wca::Routine::new_with_ctx( commands::package::publish::publish ) ), - ( "end".to_owned(), wca::Routine::new_with_ctx( commands::end::end ) ), - ]) - } -} - -// - -crate::mod_interface! -{ - prelude use grammar_form; - prelude use executor_form; -} diff --git a/module/blank/willbe_old/src/willbe_old/commands/mod.rs b/module/blank/willbe_old/src/willbe_old/commands/mod.rs deleted file mode 100644 index 5f0d00ec1c..0000000000 --- a/module/blank/willbe_old/src/willbe_old/commands/mod.rs +++ /dev/null @@ -1,66 +0,0 @@ -crate::mod_interface! -{ - /// Init aggregator commands. - prelude mod init; - - /// Works with crates - prelude mod package; - - /// Iterate over subject - prelude mod each; - - /// End of loop/program - prelude mod end; - - protected use super::init::protected::*; - - protected use super::private::StartPointStack; - protected use super::private::EndPointStack; -} - -mod private -{ - /// Allow to go back to the iterator - #[ derive( Debug, Default, Clone ) ] - pub struct StartPointStack( Vec< usize > ); - - impl std::ops::Deref for StartPointStack - { - type Target = Vec< usize >; - - fn deref( &self ) -> &Self::Target - { - &self.0 - } - } - - impl std::ops::DerefMut for StartPointStack - { - fn deref_mut( &mut self ) -> &mut Self::Target - { - &mut self.0 - } - } - - /// Allow to go back to the end - #[ derive( Debug, Default, Clone ) ] - pub struct EndPointStack( Vec< usize > ); - - impl std::ops::Deref for EndPointStack - { - type Target = Vec< usize >; - - fn deref( &self ) -> &Self::Target - { - &self.0 - } - } - - impl std::ops::DerefMut for EndPointStack - { - fn deref_mut( &mut self ) -> &mut Self::Target - { - &mut self.0 - } - } -} diff --git a/module/blank/willbe_old/src/willbe_old/commands/package/info.rs b/module/blank/willbe_old/src/willbe_old/commands/package/info.rs deleted file mode 100644 index 30121caf50..0000000000 --- a/module/blank/willbe_old/src/willbe_old/commands/package/info.rs +++ /dev/null @@ -1,80 +0,0 @@ -/// Internal namespace. -pub( crate ) mod private -{ - use crate::protected::*; - use std::env; - use wca:: - { - Args, Props, - Context, - }; - use error_tools::{ Result, for_app::format_err }; - - /// Info command declaration - pub fn info_command() -> wca::Command - { - wca::Command::former() - .hint( "Prints information about package" ) - .long_hint( "Prints information about package at current directory" ) - .phrase( "crate.info" ) - .form() - } - - /// - /// Prints information about package - /// - - pub fn info( _ : ( Args, Props ), ctx : Context ) -> Result< () > - { - println!( "[LOG] Called info command" ); - - // Get package from context or try to read package at current directory - let package = match ctx.get_ref::< Option< Package > >() - { - Some( Some( package ) ) => package.to_owned(), - None => - { - let path = env::current_dir().unwrap().to_owned(); - Package::try_from( path ) - .map_err( | _ | format_err!( "Package not found at current directory" ) )? - } - _ => return Ok( () ) - }; - - let info = PackageMetadata::try_from( package ) - .map_err( | _ | format_err!( "Can not parse package metadata" ) )?; - let info = info.all().to_owned(); - - println! - ( - r#" -Name: "{}" -Version: "{}" -Description: "{}" -Documentation: "{}" -License: "{}" -Readme: "{}" -Dependencies: {:?} -Location: "{}" - "#, - info.name, - info.version, - info.description.unwrap_or_else( || "Not found".to_string() ), - info.documentation.unwrap_or_else( || "Not found".to_string() ), - info.license.unwrap_or_else( || "Not found".to_string() ), - info.readme.map( String::from ).unwrap_or_else( || "Not found".to_string() ), - info.dependencies.iter().map( | d | &d.name ).collect::< Vec< _ > >(), - info.manifest_path.parent().unwrap() - ); - - Ok( () ) - } -} - -// - -crate::mod_interface! -{ - prelude use info_command; - prelude use info; -} diff --git a/module/blank/willbe_old/src/willbe_old/commands/package/mod.rs b/module/blank/willbe_old/src/willbe_old/commands/package/mod.rs deleted file mode 100644 index 777f955a8c..0000000000 --- a/module/blank/willbe_old/src/willbe_old/commands/package/mod.rs +++ /dev/null @@ -1,8 +0,0 @@ -crate::mod_interface! -{ - /// Information about package - prelude mod info; - - /// Publish package - prelude mod publish; -} diff --git a/module/blank/willbe_old/src/willbe_old/commands/package/publish.rs b/module/blank/willbe_old/src/willbe_old/commands/package/publish.rs deleted file mode 100644 index 622f34bbfb..0000000000 --- a/module/blank/willbe_old/src/willbe_old/commands/package/publish.rs +++ /dev/null @@ -1,66 +0,0 @@ -/// Internal namespace. -pub( crate ) mod private -{ - use crate::protected::*; - use std::env; - use wca:: - { - Args, Props, - Context, - }; - use error_tools::{ Result, for_app::format_err }; - - /// Publish command declaration - pub fn publish_command() -> wca::Command - { - wca::Command::former() - .hint( "Publish a package" ) - .long_hint( "Validate, runs tests and publish a package" ) - .phrase( "crate.publish" ) - .form() - } - - /// - /// Verify and publish a package - /// - - pub fn publish( _ : ( Args, Props ), ctx : Context ) -> Result< () > - { - println!( "[LOG] Called publish command" ); - - // Get package from context or try to read package at current directory - let package = match ctx.get_ref::< Option< Package > >() - { - Some( Some( package ) ) => package.to_owned(), - None => - { - let path = env::current_dir().unwrap().to_owned(); - Package::try_from( path ) - .map_err( | _ | format_err!( "Package not found at current directory" ) )? - } - _ => return Ok( () ) - }; - - let info = PackageMetadata::try_from( package ) - .map_err( | _ | format_err!( "Can not parse package metadata" ) )?; - - println! - ( - "=== Verification ===\nLicense: {}\nReadme: {}\nDocumentation: {}\nTests: {}", - if info.has_license() { "Yes" } else { "No" }, - if info.has_readme() { "Yes" } else { "No" }, - if info.has_documentation() { "Yes" } else { "No" }, - if info.is_tests_passed() { "Passed" } else { "Failed" } - ); - - Ok( () ) - } -} - -// - -crate::mod_interface! -{ - prelude use publish_command; - prelude use publish; -} diff --git a/module/blank/willbe_old/src/willbe_old/core/entities/mod.rs b/module/blank/willbe_old/src/willbe_old/core/entities/mod.rs deleted file mode 100644 index 768053c884..0000000000 --- a/module/blank/willbe_old/src/willbe_old/core/entities/mod.rs +++ /dev/null @@ -1,10 +0,0 @@ - -crate::mod_interface! -{ - /// Package - layer package; - /// Workspace - layer workspace; - /// Auxiliary entities - layer utility; -} diff --git a/module/blank/willbe_old/src/willbe_old/core/entities/package/metadata.rs b/module/blank/willbe_old/src/willbe_old/core/entities/package/metadata.rs deleted file mode 100644 index 3ba8640877..0000000000 --- a/module/blank/willbe_old/src/willbe_old/core/entities/package/metadata.rs +++ /dev/null @@ -1,119 +0,0 @@ -/// Internal namespace. -pub( crate ) mod private -{ - use std::path::PathBuf; - - use cargo_metadata::MetadataCommand; - - use error_tools::{ BasicError, err }; - - use crate::Package; - - /// Package metadata - #[ derive( Debug ) ] - pub struct PackageMetadata - { - package : Package, - metadata : cargo_metadata::Package, - } - - impl TryFrom< PathBuf > for PackageMetadata - { - type Error = BasicError; - - fn try_from( value : PathBuf ) -> Result< Self, Self::Error > - { - let package = Package::try_from( value )?; - package.try_into() - } - } - - impl TryFrom< Package > for PackageMetadata - { - type Error = BasicError; - - fn try_from( value : Package ) -> Result< Self, Self::Error > - { - let path = value.path().join( "Cargo.toml" ); - let meta = MetadataCommand::new() - .manifest_path( &path ) - .no_deps() - .exec() - .map_err( | _ | err!( "Can not read metadata" ) )?; - - let metadata = meta.packages.iter() - .find( | p | p.manifest_path == path ) - .ok_or_else( || err!( "Can not parse metadata for current package" ) )? - .to_owned(); - Ok( Self - { - package : value, - metadata - }) - } - } - impl PackageMetadata - { - /// Returns name - pub fn name( &self ) -> &String - { - &self.metadata.name - } - - /// Returns version - pub fn version( &self ) -> String - { - self.metadata.version.to_string() - } - } - - impl PackageMetadata - { - /// Returns license from `Cargo.toml` - pub fn license( &self ) -> Option< String > - { - self.metadata.license.to_owned() - } - - /// Returns path to license file if exists - pub fn license_file( &self ) -> Option< PathBuf > - { - self.metadata.license_file.as_ref().map( | r | r.to_owned().into_std_path_buf() ) - } - - /// Returns path to Readme file - pub fn readme( &self ) -> Option< PathBuf > - { - self.metadata.readme.as_ref().map( | r | r.to_owned().into_std_path_buf() ) - } - - /// Returns url to documentation if it is exists - pub fn documentation( &self ) -> Option< String > - { - self.metadata.documentation.to_owned() - } - } - - impl PackageMetadata - { - /// Returns reference to Package - pub fn as_package( &self ) -> &Package - { - &self.package - } - - /// Returns all metadata - pub fn all( &self ) -> &cargo_metadata::Package - { - &self.metadata - } - } - -} - -// - -crate::mod_interface! -{ - prelude use PackageMetadata; -} diff --git a/module/blank/willbe_old/src/willbe_old/core/entities/package/mod.rs b/module/blank/willbe_old/src/willbe_old/core/entities/package/mod.rs deleted file mode 100644 index 62bf81332d..0000000000 --- a/module/blank/willbe_old/src/willbe_old/core/entities/package/mod.rs +++ /dev/null @@ -1,10 +0,0 @@ - -crate::mod_interface! -{ - /// Package - layer package; - /// Metadata - layer metadata; - /// Verification methods - layer verification; -} diff --git a/module/blank/willbe_old/src/willbe_old/core/entities/package/package.rs b/module/blank/willbe_old/src/willbe_old/core/entities/package/package.rs deleted file mode 100644 index a455cd1cc1..0000000000 --- a/module/blank/willbe_old/src/willbe_old/core/entities/package/package.rs +++ /dev/null @@ -1,53 +0,0 @@ -/// Internal namespace. -pub( crate ) mod private -{ - use std::path::PathBuf; - use toml::Value; - - use error_tools::{ BasicError, err }; - - /// Package - #[ derive( Debug, Clone ) ] - pub struct Package - { - path : PathBuf, - } - - impl TryFrom< PathBuf > for Package - { - type Error = BasicError; - - fn try_from( path : PathBuf ) -> Result< Self, Self::Error > - { - let config_str = std::fs::read_to_string( path.join( "Cargo.toml" ) ) - .map_err( | _ | err!( "Can not read \"Cargo.toml\"" ) )?; - let toml = config_str.parse::< Value >() - .map_err( | _ | err!( "Can not parse \"Cargo.toml\"" ) )?; - - if toml.get( "package" ).is_some() - { - Ok( Self{ path } ) - } - else - { - Err( err!( "\"package\" into \"Cargo.toml\" not found" ) ) - } - } - } - - impl Package - { - /// Gets path of package - pub fn path( &self ) -> &PathBuf - { - &self.path - } - } -} - -// - -crate::mod_interface! -{ - prelude use Package; -} diff --git a/module/blank/willbe_old/src/willbe_old/core/entities/package/verification.rs b/module/blank/willbe_old/src/willbe_old/core/entities/package/verification.rs deleted file mode 100644 index 0098940074..0000000000 --- a/module/blank/willbe_old/src/willbe_old/core/entities/package/verification.rs +++ /dev/null @@ -1,65 +0,0 @@ -/// Internal namespace. -pub( crate ) mod private -{ - use std::process::Command; - - use crate::PackageMetadata; - - /// All package verification methods - pub trait Verification - { - /// Do all checks - fn check_all( &self ) -> bool - { - self.has_readme() - && self.has_documentation() - && self.has_license() - && self.is_tests_passed() - } - /// Check if readme exists - fn has_readme( &self ) -> bool; - /// Check if documentation exists - fn has_documentation( &self ) -> bool; - /// Check if the package has a license - fn has_license( &self ) -> bool; - /// Check if all tests is passed - fn is_tests_passed( &self ) -> bool; - } - - impl Verification for PackageMetadata - { - fn has_readme( &self ) -> bool - { - self.readme().is_some() - } - - fn has_documentation( &self ) -> bool - { - self.documentation().is_some() - } - - fn has_license( &self ) -> bool - { - self.license().is_some() - || - self.license_file().is_some() - } - - fn is_tests_passed( &self ) -> bool - { - let tests_output = Command::new( "cargo" ) - .current_dir( self.as_package().path() ) - .args([ "test" ]) - .output().unwrap(); - - tests_output.status.success() - } - } -} - -// - -crate::mod_interface! -{ - prelude use Verification; -} diff --git a/module/blank/willbe_old/src/willbe_old/core/entities/utility.rs b/module/blank/willbe_old/src/willbe_old/core/entities/utility.rs deleted file mode 100644 index 3968aad1af..0000000000 --- a/module/blank/willbe_old/src/willbe_old/core/entities/utility.rs +++ /dev/null @@ -1,124 +0,0 @@ -/// Internal namespace. -pub( crate ) mod private -{ - use crate::{ Package, PackageMetadata }; - use iter_tools::prelude::*; - - /// Represent with which order strategy to iterate over packages - #[ derive( Debug, Clone, Copy ) ] - pub enum OrderStrategy - { - /// Alphabetical by package name - Alphabetical, - /// Based on their dependencies - Topological, - /// Shuffle packages - Random, - } - - /// This trait defines a method to sort packages by selected order strategy - pub trait Ordered : Iterator - where - Vec< Package > : FromIterator< < Self as Iterator >::Item > - { - /// Collect all iterator elements into a sorted vector - fn ordered( self, order : OrderStrategy ) -> Vec< Package > - where - Self : Sized - { - let v : Vec< Package > = self.collect(); - - match order - { - OrderStrategy::Alphabetical => alphabetical( v ), - OrderStrategy::Topological => toposort( v ), - OrderStrategy::Random => shuffle( v ), - } - } - - /// Returns iterator over sorted Packages - fn ordered_iter( self, order : OrderStrategy ) -> Box< dyn Iterator< Item = Package > > - where - Self : Sized - { - Box::new( self.ordered( order ).into_iter() ) - } - } - - fn alphabetical( packages : Vec< Package > ) -> Vec< Package > - { - packages.iter().cloned() - .filter_map( | p | - { - PackageMetadata::try_from( p ).ok() - }) - - .sorted_by_key( | meta | meta.name().to_owned() ) - - .map( | meta | meta.as_package().to_owned() ) - .collect_vec() - } - - fn toposort( packages : Vec< Package > ) -> Vec< Package > - { - use petgraph::Graph; - use cargo_metadata::DependencyKind; - use std::collections::HashMap; - - let ( deps, package_map ) = packages.iter() - .filter_map( | p | PackageMetadata::try_from( p.to_owned() ).ok() ) - .fold( ( Graph::new(), HashMap::new() ), | ( mut deps, mut packages ), meta | - { - packages.insert( meta.name().to_owned(), meta.as_package().to_owned() ); - - let root_node = if let Some( node ) = deps.node_indices().find( | i | deps[ *i ] == meta.name().to_owned() ) - { node } - else - { deps.add_node( meta.name().to_owned() ) }; - - for dep in &meta.all().dependencies - { - if dep.path.is_some() && dep.kind != DependencyKind::Development - { - let dep_node = if let Some( node ) = deps.node_indices().find( | i | deps[ *i ] == dep.name ) - { node } - else - { deps.add_node( dep.name.to_owned() ) }; - - deps.add_edge( root_node, dep_node, () ); - } - } - - ( deps, packages ) - }); - - let sorted = petgraph::algo::toposort( &deps, None ).unwrap(); - sorted.iter() - .rev() - .map( | &dep_idx | deps.node_weight( dep_idx ).unwrap().to_owned() ) - .filter_map( | name | package_map.get( &name ) ) - .cloned().collect::< Vec< Package > >() - } - - fn shuffle( mut packages : Vec< Package > ) -> Vec< Package > - { - use rand::seq::SliceRandom; - - let mut rng = rand::thread_rng(); - packages.shuffle( &mut rng ); - - packages - } - - - impl< T : ?Sized > Ordered for T - where T : Iterator, Vec< Package >: FromIterator< < T as Iterator >::Item > {} -} - -// - -crate::mod_interface! -{ - prelude use OrderStrategy; - prelude use Ordered; -} diff --git a/module/blank/willbe_old/src/willbe_old/core/entities/workspace.rs b/module/blank/willbe_old/src/willbe_old/core/entities/workspace.rs deleted file mode 100644 index 941f65753b..0000000000 --- a/module/blank/willbe_old/src/willbe_old/core/entities/workspace.rs +++ /dev/null @@ -1,95 +0,0 @@ -/// Internal namespace. -pub( crate ) mod private -{ - use std::path::PathBuf; - use toml::Value; - - use error_tools::{ BasicError, err }; - - use crate::{ Package, unique_walk }; - - /// Workspace - #[ derive( Debug, Clone ) ] - pub struct Workspace - { - path : PathBuf, - } - - impl TryFrom< PathBuf > for Workspace - { - type Error = BasicError; - - fn try_from( path : PathBuf ) -> Result< Self, Self::Error > - { - let config_str = std::fs::read_to_string( path.join( "Cargo.toml" ) ) - .map_err( | _ | err!( "Can not read \"Cargo.toml\"" ) )?; - let toml = config_str.parse::< Value >() - .map_err( | _ | err!( "Can not parse \"Cargo.toml\"" ) )?; - - if toml.get( "workspace" ).is_some() - { - Ok( Self{ path } ) - } - else - { - Err( err!( "\"workspace\" into \"Cargo.toml\" not found" ) ) - } - } - } - - impl Workspace - { - /// Gets list of packages into workspace - pub fn packages( &self ) -> Vec< Package > - { - let config_str = std::fs::read_to_string( self.path.join( "Cargo.toml" ) ).unwrap(); - let toml = config_str.parse::< Value >().unwrap(); - - // iterate over members into workspace - toml[ "workspace" ] - // members can be doesn't setted - .get( "members" ) - .unwrap_or( &Value::Array( vec![] ) ).as_array() - .unwrap_or( &vec![] ) - .iter() - // fold all packages from members - .fold( vec![], | mut acc, member | - { - let packages_paths = unique_walk - ( - self.path.to_owned(), - &[ member.as_str().unwrap().to_string() ] - ); - - packages_paths - .fold( &mut acc, | acc, package_path | - { - if let Ok( package ) = Package::try_from( package_path.to_owned() ) - { - acc.push( package ); - } - // workspaces into workspace - else if let Ok( workspace ) = Workspace::try_from( package_path ) - { - acc.extend( workspace.packages() ); - } - acc - }); - acc - }) - } - - /// iterate over packages into workspace - pub fn packages_iterate( &self ) -> impl Iterator< Item = Package > - { - self.packages().into_iter() - } - } -} - -// - -crate::mod_interface! -{ - prelude use Workspace; -} diff --git a/module/blank/willbe_old/src/willbe_old/core/iterators.rs b/module/blank/willbe_old/src/willbe_old/core/iterators.rs deleted file mode 100644 index 191d28c61f..0000000000 --- a/module/blank/willbe_old/src/willbe_old/core/iterators.rs +++ /dev/null @@ -1,36 +0,0 @@ -/// Internal namespace. -pub( crate ) mod private -{ - use std::path::PathBuf; - use crate::*; - - /// Iterate over all packages by PathBuf - pub fn packages_iterate( path : PathBuf ) -> Box< dyn Iterator< Item = Package > > - { - if let Ok( package ) = Package::try_from( path.to_owned() ) - { - return Box::new( Some( package ).into_iter() ) - } - - if let Ok( workspace ) = Workspace::try_from( path ) - { - return Box::new( workspace.packages_iterate() ) - } - - Box::new( None.into_iter() ) - } - - /// Iterate over workspaces iterator - pub fn workspaces_packages_iterate( workspaces : impl Iterator< Item = Workspace > ) -> impl Iterator< Item = Package > - { - workspaces.flat_map( move | workspace | workspace.packages_iterate() ) - } -} - -// - -crate::mod_interface! -{ - prelude use packages_iterate; - prelude use workspaces_packages_iterate; -} diff --git a/module/blank/willbe_old/src/willbe_old/core/mod.rs b/module/blank/willbe_old/src/willbe_old/core/mod.rs deleted file mode 100644 index 23c69db43e..0000000000 --- a/module/blank/willbe_old/src/willbe_old/core/mod.rs +++ /dev/null @@ -1,9 +0,0 @@ - -crate::mod_interface! -{ - /// Entities of the program - layer entities; - - /// Iterators over packages - layer iterators; -} diff --git a/module/blank/willbe_old/src/willbe_old/files.rs b/module/blank/willbe_old/src/willbe_old/files.rs deleted file mode 100644 index 19e480b1c7..0000000000 --- a/module/blank/willbe_old/src/willbe_old/files.rs +++ /dev/null @@ -1,34 +0,0 @@ -/// Internal namespace. -pub( crate ) mod private -{ - use std::path::{ Path, PathBuf }; - - use path_absolutize::*; - - use iter_tools::Itertools; - - /// - /// Iterate over unique files in directory using globs - /// - - pub fn unique_walk< P, S >( base_dir : P, patterns : &[ S ] ) -> impl Iterator< Item = PathBuf > - where - P: AsRef< Path >, - S: AsRef< str >, - { - globwalk::GlobWalkerBuilder::from_patterns( base_dir, patterns ) - .follow_links( true ) - .build().unwrap() - .into_iter() - .filter_map( Result::ok ) - .filter_map( | s | s.path().absolutize().map( | p | p.to_path_buf() ).ok() ) - .unique() - } -} - -// - -crate::mod_interface! -{ - prelude use unique_walk; -} diff --git a/module/blank/willbe_old/src/willbe_old/willbe_entry.rs b/module/blank/willbe_old/src/willbe_old/willbe_entry.rs deleted file mode 100644 index a3c1823a48..0000000000 --- a/module/blank/willbe_old/src/willbe_old/willbe_entry.rs +++ /dev/null @@ -1,34 +0,0 @@ -#![ cfg_attr( feature = "no_std", no_std ) ] -#![ 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/wpublisher/" ) ] -// #![ deny( rust_2018_idioms ) ] -// #![ deny( missing_debug_implementations ) ] -// #![ deny( missing_docs ) ] - -//! -//! ___. -//! - -#![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/", "Readme.md" ) ) ] - -#[ allow( unused_imports ) ] -use ::willbe_old::*; - -// - -#[ cfg( not( feature = "no_std" ) ) ] -fn main() -> error_tools::Result< () > -{ - let args = std::env::args().skip( 1 ).collect::< Vec< String > >(); - - let ca = wca::CommandsAggregator::former() - .grammar( commands::grammar_form() ) - .executor( commands::executor_form() ) - .perform(); - - Ok( ca.perform( if args.is_empty() { "".to_owned() } else { args.join( " " ) + " .end" } )? ) -} - -#[ cfg( feature = "no_std" ) ] -fn main() {} diff --git a/module/blank/willbe_old/src/willbe_old/willbe_lib.rs b/module/blank/willbe_old/src/willbe_old/willbe_lib.rs deleted file mode 100644 index bfbcd09466..0000000000 --- a/module/blank/willbe_old/src/willbe_old/willbe_lib.rs +++ /dev/null @@ -1,36 +0,0 @@ -#![ cfg_attr( feature = "no_std", no_std ) ] -#![ 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/_blank/latest/_blank/" ) ] -// #![ deny( rust_2018_idioms ) ] -// #![ deny( missing_debug_implementations ) ] -// #![ deny( missing_docs ) ] - -// #![ feature( type_name_of_val ) ] -// #![ feature( trace_macros ) ] - -//! -//! ___. -//! - -#![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/", "Readme.md" ) ) ] - -// -use mod_interface::mod_interface; - -mod_interface! -{ - /// Features of Application Programming Interface that 100% should be implemented - #[ cfg( not( feature = "no_std" ) ) ] - layer core; - - /// Library of utility to work with commands. - #[ cfg( not( feature = "no_std" ) ) ] - layer commands; - - /// Operate over files. - #[ cfg( not( feature = "no_std" ) ) ] - layer files; - - protected( crate ) use ::wtools::prelude::*; -} diff --git a/module/blank/willbe_old/tests/willbe_old/_asset/empty/.gitignore b/module/blank/willbe_old/tests/willbe_old/_asset/empty/.gitignore deleted file mode 100644 index 44c5ea8fa7..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/_asset/empty/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -# Ignore everything in this directory -* -# Except this file -!.gitignore \ No newline at end of file diff --git a/module/blank/willbe_old/tests/willbe_old/_asset/package/Cargo.toml b/module/blank/willbe_old/tests/willbe_old/_asset/package/Cargo.toml deleted file mode 100644 index 7f16e6e19e..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/_asset/package/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "willbe_verified_package" -version = "0.1.0" -edition = "2021" -documentation = "Documentation text" -license = "MIT" -readme = "Readme.md" - -[dependencies] diff --git a/module/blank/willbe_old/tests/willbe_old/_asset/package/Readme.md b/module/blank/willbe_old/tests/willbe_old/_asset/package/Readme.md deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/module/blank/willbe_old/tests/willbe_old/_asset/package/src/lib.rs b/module/blank/willbe_old/tests/willbe_old/_asset/package/src/lib.rs deleted file mode 100644 index 1ccf57060e..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/_asset/package/src/lib.rs +++ /dev/null @@ -1,15 +0,0 @@ -/// Adds two numbers and returns result -pub fn add(left: usize, right: usize) -> usize { - left + right -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } -} diff --git a/module/blank/willbe_old/tests/willbe_old/_asset/package/src/main.rs b/module/blank/willbe_old/tests/willbe_old/_asset/package/src/main.rs deleted file mode 100644 index 80a1832bfa..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/_asset/package/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - println!("Hello, world!"); -} diff --git a/module/blank/willbe_old/tests/willbe_old/_asset/package_no_verified/Cargo.toml b/module/blank/willbe_old/tests/willbe_old/_asset/package_no_verified/Cargo.toml deleted file mode 100644 index 766bac3bee..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/_asset/package_no_verified/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "willbe_no_verified_package" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] diff --git a/module/blank/willbe_old/tests/willbe_old/_asset/package_no_verified/src/lib.rs b/module/blank/willbe_old/tests/willbe_old/_asset/package_no_verified/src/lib.rs deleted file mode 100644 index 20cb385493..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/_asset/package_no_verified/src/lib.rs +++ /dev/null @@ -1,8 +0,0 @@ -#[cfg(test)] -mod tests { - #[test] - fn failed() - { - assert!( false ); - } -} diff --git a/module/blank/willbe_old/tests/willbe_old/_asset/package_no_verified/src/main.rs b/module/blank/willbe_old/tests/willbe_old/_asset/package_no_verified/src/main.rs deleted file mode 100644 index 80a1832bfa..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/_asset/package_no_verified/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - println!("Hello, world!"); -} diff --git a/module/blank/willbe_old/tests/willbe_old/_asset/workspace_with_deps/Cargo.toml b/module/blank/willbe_old/tests/willbe_old/_asset/workspace_with_deps/Cargo.toml deleted file mode 100644 index ad7fb73a88..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/_asset/workspace_with_deps/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[workspace] -resolver = "2" -members = [ - "module/*", -] -exclude = [ - "*", -] diff --git a/module/blank/willbe_old/tests/willbe_old/_asset/workspace_with_deps/module/module1/Cargo.toml b/module/blank/willbe_old/tests/willbe_old/_asset/workspace_with_deps/module/module1/Cargo.toml deleted file mode 100644 index a183e1b93a..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/_asset/workspace_with_deps/module/module1/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "willbe_with_deps_module1" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] diff --git a/module/blank/willbe_old/tests/willbe_old/_asset/workspace_with_deps/module/module1/src/lib.rs b/module/blank/willbe_old/tests/willbe_old/_asset/workspace_with_deps/module/module1/src/lib.rs deleted file mode 100644 index 3b9acffd5a..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/_asset/workspace_with_deps/module/module1/src/lib.rs +++ /dev/null @@ -1,14 +0,0 @@ -pub fn add(left: usize, right: usize) -> usize { - left + right -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } -} diff --git a/module/blank/willbe_old/tests/willbe_old/_asset/workspace_with_deps/module/module2/Cargo.toml b/module/blank/willbe_old/tests/willbe_old/_asset/workspace_with_deps/module/module2/Cargo.toml deleted file mode 100644 index e362e58a66..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/_asset/workspace_with_deps/module/module2/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "willbe_with_deps_module2" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -willbe_with_deps_module1 = { version = "*", path = "../module1" } \ No newline at end of file diff --git a/module/blank/willbe_old/tests/willbe_old/_asset/workspace_with_deps/module/module2/src/lib.rs b/module/blank/willbe_old/tests/willbe_old/_asset/workspace_with_deps/module/module2/src/lib.rs deleted file mode 100644 index 3b9acffd5a..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/_asset/workspace_with_deps/module/module2/src/lib.rs +++ /dev/null @@ -1,14 +0,0 @@ -pub fn add(left: usize, right: usize) -> usize { - left + right -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } -} diff --git a/module/blank/willbe_old/tests/willbe_old/_asset/workspace_with_deps/module/module3/Cargo.toml b/module/blank/willbe_old/tests/willbe_old/_asset/workspace_with_deps/module/module3/Cargo.toml deleted file mode 100644 index f0302e1626..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/_asset/workspace_with_deps/module/module3/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "willbe_with_deps_module3" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -willbe_with_deps_module2 = { version = "*", path = "../module2" } \ No newline at end of file diff --git a/module/blank/willbe_old/tests/willbe_old/_asset/workspace_with_deps/module/module3/src/lib.rs b/module/blank/willbe_old/tests/willbe_old/_asset/workspace_with_deps/module/module3/src/lib.rs deleted file mode 100644 index 3b9acffd5a..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/_asset/workspace_with_deps/module/module3/src/lib.rs +++ /dev/null @@ -1,14 +0,0 @@ -pub fn add(left: usize, right: usize) -> usize { - left + right -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } -} diff --git a/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/Cargo.toml b/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/Cargo.toml deleted file mode 100644 index c5fc8a2bc2..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[workspace] -resolver = "2" -members = [ - "workspace1", - "workspace2", -] -exclude = [ - "*", -] diff --git a/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace1/Cargo.toml b/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace1/Cargo.toml deleted file mode 100644 index ad7fb73a88..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace1/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[workspace] -resolver = "2" -members = [ - "module/*", -] -exclude = [ - "*", -] diff --git a/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace1/module/module1/Cargo.toml b/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace1/module/module1/Cargo.toml deleted file mode 100644 index ca345d6e39..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace1/module/module1/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "willbe_workspace1_module1" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] diff --git a/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace1/module/module1/src/lib.rs b/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace1/module/module1/src/lib.rs deleted file mode 100644 index 3b9acffd5a..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace1/module/module1/src/lib.rs +++ /dev/null @@ -1,14 +0,0 @@ -pub fn add(left: usize, right: usize) -> usize { - left + right -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } -} diff --git a/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace1/module/module2/Cargo.toml b/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace1/module/module2/Cargo.toml deleted file mode 100644 index d7de79e725..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace1/module/module2/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "willbe_workspace1_module2" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] \ No newline at end of file diff --git a/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace1/module/module2/src/lib.rs b/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace1/module/module2/src/lib.rs deleted file mode 100644 index 3b9acffd5a..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace1/module/module2/src/lib.rs +++ /dev/null @@ -1,14 +0,0 @@ -pub fn add(left: usize, right: usize) -> usize { - left + right -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } -} diff --git a/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace2/Cargo.toml b/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace2/Cargo.toml deleted file mode 100644 index ad7fb73a88..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace2/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[workspace] -resolver = "2" -members = [ - "module/*", -] -exclude = [ - "*", -] diff --git a/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace2/module/module3/Cargo.toml b/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace2/module/module3/Cargo.toml deleted file mode 100644 index 1e5b37708b..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace2/module/module3/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "willbe_workspace2_module3" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] diff --git a/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace2/module/module3/src/lib.rs b/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace2/module/module3/src/lib.rs deleted file mode 100644 index 3b9acffd5a..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace2/module/module3/src/lib.rs +++ /dev/null @@ -1,14 +0,0 @@ -pub fn add(left: usize, right: usize) -> usize { - left + right -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } -} diff --git a/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace2/module/module4/Cargo.toml b/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace2/module/module4/Cargo.toml deleted file mode 100644 index ce7cc9e559..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace2/module/module4/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "willbe_workspace2_module4" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] diff --git a/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace2/module/module4/src/lib.rs b/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace2/module/module4/src/lib.rs deleted file mode 100644 index 3b9acffd5a..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace2/module/module4/src/lib.rs +++ /dev/null @@ -1,14 +0,0 @@ -pub fn add(left: usize, right: usize) -> usize { - left + right -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } -} diff --git a/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace2/module/module5/Cargo.toml b/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace2/module/module5/Cargo.toml deleted file mode 100644 index ca174d8156..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace2/module/module5/Cargo.toml +++ /dev/null @@ -1,8 +0,0 @@ -[package] -name = "willbe_workspace2_module5" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] diff --git a/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace2/module/module5/src/lib.rs b/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace2/module/module5/src/lib.rs deleted file mode 100644 index 3b9acffd5a..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/_asset/workspaces/workspace2/module/module5/src/lib.rs +++ /dev/null @@ -1,14 +0,0 @@ -pub fn add(left: usize, right: usize) -> usize { - left + right -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } -} diff --git a/module/blank/willbe_old/tests/willbe_old/tests/from.rs b/module/blank/willbe_old/tests/willbe_old/tests/from.rs deleted file mode 100644 index 0b3a81d171..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/tests/from.rs +++ /dev/null @@ -1,38 +0,0 @@ -use super::*; - -#[ test ] -fn from_empty_asset() -{ - let asset = Asset::from( PathBuf::from( ASSET_PATH ).join( "empty" ) ); - let path = asset.path_buf(); - - let package = Package::try_from( path.to_owned() ); - assert!( package.is_err() ); - - let workspace = Workspace::try_from( path.to_owned() ); - assert!( workspace.is_err() ); -} - -#[ test ] -fn package_from_path() -{ - let asset = Asset::from( PathBuf::from( ASSET_PATH ).join( "package" ) ); - let path = asset.path_buf(); - - let package = Package::try_from( path.to_owned() ); - - assert!( package.is_ok() ); - assert_eq!( *path, *package.unwrap().path() ); -} - -#[ test ] -fn workspace_from_path() -{ - let package_asset = Asset::from( PathBuf::from( ASSET_PATH ).join( "package" ) ); - let package_path = package_asset.path_buf(); - assert!( Workspace::try_from( package_path.to_owned() ).is_err() ); - - let workspace_asset = Asset::from( PathBuf::from( ASSET_PATH ).join( "workspaces/workspace1" ) ); - let workspace_path = workspace_asset.path_buf(); - assert!( Workspace::try_from( workspace_path.to_owned() ).is_ok() ); -} diff --git a/module/blank/willbe_old/tests/willbe_old/tests/integration/each.rs b/module/blank/willbe_old/tests/willbe_old/tests/integration/each.rs deleted file mode 100644 index 21ede7825a..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/tests/integration/each.rs +++ /dev/null @@ -1,130 +0,0 @@ -use super::*; - -#[ test ] -fn many_workspaces_each_info() -> Result< (), Box< dyn std::error::Error > > -{ - let mut cmd = Command::cargo_bin( MODULE_NAME )?; - let package_asset = Asset::from( PathBuf::from( ASSET_PATH ).join( "workspaces" ) ).copied(); - let package_path = package_asset.path_buf(); - - cmd.current_dir( package_path ); - cmd.arg( ".each .crate.info" ); - - cmd - .assert() - .success() - .stdout - ( - predicate::str::contains( "Name: \"willbe_workspace1_module1\"" ).count( 1 ) - .and - ( - predicate::str::contains( "Name: \"willbe_workspace1_module2\"" ).count( 1 ) - ) - .and - ( - predicate::str::contains( "Name: \"willbe_workspace2_module3\"" ).count( 1 ) - ) - .and - ( - predicate::str::contains( "Name: \"willbe_workspace2_module4\"" ).count( 1 ) - ) - .and - ( - predicate::str::contains( "Name: \"willbe_workspace2_module5\"" ).count( 1 ) - ) - ); - - Ok( () ) -} - -#[ test ] -fn workspace_each_info() -> Result< (), Box< dyn std::error::Error > > -{ - let mut cmd = Command::cargo_bin( MODULE_NAME )?; - let package_asset = Asset::from( PathBuf::from( ASSET_PATH ).join( "workspace_with_deps" ) ).copied(); - let package_path = package_asset.path_buf(); - - cmd.current_dir( package_path ); - cmd.arg( ".each .crate.info" ); - - cmd - .assert() - .success() - .stdout - ( - predicate::str::contains( "Name: \"willbe_with_deps_module1\"" ).count( 1 ) - .and - ( - predicate::str::contains( "Name: \"willbe_with_deps_module2\"" ).count( 1 ) - ) - .and - ( - predicate::str::contains( "Name: \"willbe_with_deps_module3\"" ).count( 1 ) - ) - ); - - Ok( () ) -} - -#[ test ] -fn single_package_each_info() -> Result< (), Box< dyn std::error::Error > > -{ - let mut cmd = Command::cargo_bin( MODULE_NAME )?; - let package_asset = Asset::from( PathBuf::from( ASSET_PATH ).join( "package" ) ).copied(); - let package_path = package_asset.path_buf(); - - cmd.current_dir( package_path ); - cmd.arg( ".each .crate.info" ); - - cmd - .assert() - .success() - .stdout - ( - predicate::str::contains( "Name: \"willbe_verified_package\"" ).count( 1 ) - ); - - Ok( () ) -} - -#[ test ] -fn empty_path_each_info() -> Result< (), Box< dyn std::error::Error > > -{ - let mut cmd = Command::cargo_bin( MODULE_NAME )?; - let package_asset = Asset::from( PathBuf::from( ASSET_PATH ).join( "empty" ) ).copied(); - let package_path = package_asset.path_buf(); - - cmd.current_dir( package_path ); - cmd.arg( ".each .crate.info" ); - - cmd - .assert() - .success() - .stdout - ( - predicate::str::contains( "Any package was found at current directory" ) - ); - - Ok( () ) -} - -#[ test ] -fn another_command_after_each() -> Result< (), Box< dyn std::error::Error > > -{ - let mut cmd = Command::cargo_bin( MODULE_NAME )?; - let package_asset = Asset::from( PathBuf::from( ASSET_PATH ).join( "package" ) ).copied(); - let package_path = package_asset.path_buf(); - - cmd.current_dir( package_path ); - cmd.arg( ".each .crate.info .end .crate.info" ); - - cmd - .assert() - .success() - .stdout - ( - predicate::str::contains( "Name: \"willbe_verified_package\"" ).count( 2 ) - ); - - Ok( () ) -} diff --git a/module/blank/willbe_old/tests/willbe_old/tests/integration/info.rs b/module/blank/willbe_old/tests/willbe_old/tests/integration/info.rs deleted file mode 100644 index f9957e9942..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/tests/integration/info.rs +++ /dev/null @@ -1,78 +0,0 @@ -use super::*; - -#[ test ] -fn package_info() -> Result< (), Box< dyn std::error::Error > > -{ - let mut cmd = Command::cargo_bin( MODULE_NAME )?; - let package_asset = Asset::from( PathBuf::from( ASSET_PATH ).join( "package" ) ).copied(); - let package_path = package_asset.path_buf(); - - cmd.current_dir( package_path ); - cmd.arg( ".crate.info" ); - - cmd - .assert() - .success() - .stdout - ( - predicate::str::contains( "Name: \"willbe_verified_package\"" ) - .and - ( - predicate::str::contains( "Version: \"0.1.0\"" ) - ) - .and - ( - predicate::str::contains( "Description: \"Not found\"" ) - ) - .and - ( - predicate::str::contains( "Documentation: \"Documentation text\"" ) - ) - .and - ( - predicate::str::contains( "License: \"MIT\"" ) - ) - .and - ( - predicate::str::contains( "Dependencies: []" ) - ) - ); - - Ok( () ) -} - -#[ test ] -fn workspace_path_info() -> Result< (), Box< dyn std::error::Error > > -{ - let mut cmd = Command::cargo_bin( MODULE_NAME )?; - let package_asset = Asset::from( PathBuf::from( ASSET_PATH ).join( "workspaces/workspace1" ) ).copied(); - let package_path = package_asset.path_buf(); - - cmd.current_dir( package_path ); - cmd.arg( ".crate.info" ); - - cmd - .assert() - .failure() - .stderr( predicate::str::contains( "Package not found at current directory" ) ); - - Ok( () ) -} - -#[ test ] -fn empty_path_info() -> Result< (), Box< dyn std::error::Error > > -{ - let mut cmd = Command::cargo_bin( MODULE_NAME )?; - let package_asset = Asset::from( PathBuf::from( ASSET_PATH ).join( "empty" ) ).copied(); - let package_path = package_asset.path_buf(); - - cmd.current_dir( package_path ); - cmd.arg( ".crate.info" ); - - cmd - .assert() - .failure() - .stderr( predicate::str::contains( "Package not found at current directory" ) ); - - Ok( () ) -} diff --git a/module/blank/willbe_old/tests/willbe_old/tests/integration/mod.rs b/module/blank/willbe_old/tests/willbe_old/tests/integration/mod.rs deleted file mode 100644 index 6ac91b348b..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/tests/integration/mod.rs +++ /dev/null @@ -1,8 +0,0 @@ -use super::*; -use assert_cmd::Command; -use predicates::prelude::*; - -const MODULE_NAME : &str = "willbe_old"; - -mod each; -mod info; diff --git a/module/blank/willbe_old/tests/willbe_old/tests/iterator.rs b/module/blank/willbe_old/tests/willbe_old/tests/iterator.rs deleted file mode 100644 index 38354cbc40..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/tests/iterator.rs +++ /dev/null @@ -1,149 +0,0 @@ -use super::*; - -#[ test ] -fn over_workspace() -{ - use std::collections::HashSet; - - let workspace_asset = Asset::from( PathBuf::from( ASSET_PATH ).join( "workspaces/workspace1" ) ); - let workspace_path = workspace_asset.path_buf(); - let workspace = Workspace::try_from( workspace_path.to_owned() ).unwrap(); - // `workspace.packages()` and `workspace.packages_iterate().collect::< Vec< _ > >()` is the same - let packages = workspace.packages(); - - let expected = HashSet::from([ "willbe_workspace1_module1".to_owned(), "willbe_workspace1_module2".to_owned() ]); - - assert_eq!( expected.len(), packages.len() ); - assert_eq! - ( - expected, - packages.iter().cloned() - .filter_map( | p | - { - PackageMetadata::try_from( p ).ok() - }) - .map( | meta | meta.name().to_owned() ) - .collect::< HashSet< _ > >() - ); -} - -#[ test ] -fn over_workspaces_iterator() -{ - use std::collections::HashSet; - - let assets = vec! - [ - Asset::from( PathBuf::from( ASSET_PATH ).join( "workspaces/workspace1" ) ), - Asset::from( PathBuf::from( ASSET_PATH ).join( "workspaces/workspace2" ) ), - ]; - let workspaces = assets.iter() - .map( | asset | Workspace::try_from( asset.path_buf().to_owned() ) ) - .filter_map( Result::ok ) - .collect::< Vec< _ > >(); - - let packages = workspaces_packages_iterate( workspaces.into_iter() ) - .collect::< Vec< _ > >(); - - let expected = HashSet::from( - [ - "willbe_workspace1_module1".to_owned(), - "willbe_workspace1_module2".to_owned(), - - "willbe_workspace2_module3".to_owned(), - "willbe_workspace2_module4".to_owned(), - "willbe_workspace2_module5".to_owned(), - ]); - - assert_eq!( expected.len(), packages.len() ); - assert_eq! - ( - expected, - packages.iter().cloned() - .filter_map( | p | - { - PackageMetadata::try_from( p ).ok() - }) - .map( | meta | meta.name().to_owned() ) - .collect::< HashSet< _ > >() - ); -} - -#[ test ] -fn over_empty_path() -{ - let empty_asset = Asset::from( PathBuf::from( ASSET_PATH ).join( "empty" ) ); - let empty_path = empty_asset.path_buf(); - let packages = packages_iterate( empty_path.to_owned() ).collect::< Vec< _ > >(); - - assert!( packages.is_empty() ); -} - -#[ test ] -fn over_single_package_path() -{ - let package_asset = Asset::from( PathBuf::from( ASSET_PATH ).join( "package" ) ).copied(); - let package_path = package_asset.path_buf(); - let package = packages_iterate( package_path.to_owned() ).collect::< Vec< _ > >(); - - assert_eq!( 1, package.len() ); - assert_eq!( "willbe_verified_package", PackageMetadata::try_from( package[ 0 ].clone() ).unwrap().all().name.as_str() ); -} - -#[ test ] -fn over_single_workspace_path() -{ - use std::collections::HashSet; - - let workspace_asset = Asset::from( PathBuf::from( ASSET_PATH ).join( "workspaces/workspace1" ) ).copied(); - let workspace_path = workspace_asset.path_buf(); - let packages = packages_iterate( workspace_path.to_owned() ).collect::< Vec< _ > >(); - - let expected = HashSet::from([ "willbe_workspace1_module1".to_owned(), "willbe_workspace1_module2".to_owned() ]); - - assert_eq!( expected.len(), packages.len() ); - assert_eq! - ( - expected, - packages.iter().cloned() - .filter_map( | p | - { - PackageMetadata::try_from( p ).ok() - }) - .map( | meta | meta.name().to_owned() ) - .collect::< HashSet< _ > >() - ); -} - -#[ test ] -fn over_workspaces_root_path() -{ - use std::collections::HashSet; - - let many_workspaces_asset = Asset::from( PathBuf::from( ASSET_PATH ).join( "workspaces" ) ).copied(); - let many_workspaces_path = many_workspaces_asset.path_buf(); - let packages = packages_iterate( many_workspaces_path.to_owned() ).collect::< Vec< _ > >(); - - let expected = HashSet::from( - [ - "willbe_workspace1_module1".to_owned(), - "willbe_workspace1_module2".to_owned(), - - "willbe_workspace2_module3".to_owned(), - "willbe_workspace2_module4".to_owned(), - "willbe_workspace2_module5".to_owned(), - ]); - - assert_eq!( expected.len(), packages.len() ); - assert_eq! - ( - expected, - packages.iter().cloned() - .filter_map( | p | - { - PackageMetadata::try_from( p ).ok() - }) - .map( | meta | meta.name().to_owned() ) - .collect::< HashSet< _ > >() - ); -} diff --git a/module/blank/willbe_old/tests/willbe_old/tests/metadata.rs b/module/blank/willbe_old/tests/willbe_old/tests/metadata.rs deleted file mode 100644 index efd11d457c..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/tests/metadata.rs +++ /dev/null @@ -1,24 +0,0 @@ -use super::*; - -#[ test ] -fn try_get_from_empty_asset() -{ - let empty_asset = Asset::from( PathBuf::from( ASSET_PATH ).join( "empty" ) ).copied(); - let empty_asset_path = empty_asset.path_buf(); - - let meta = PackageMetadata::try_from( empty_asset_path.to_owned() ); - - assert!( meta.is_err() ); -} - -#[ test ] -fn get_info() -{ - let package_asset = Asset::from( PathBuf::from( ASSET_PATH ).join( "package" ) ).copied(); - let package_path = package_asset.path_buf(); - - let meta = PackageMetadata::try_from( package_path.to_owned() ).unwrap(); - - assert!( !meta.name().is_empty() ); - assert!( !meta.version().is_empty() ); -} diff --git a/module/blank/willbe_old/tests/willbe_old/tests/mod.rs b/module/blank/willbe_old/tests/willbe_old/tests/mod.rs deleted file mode 100644 index 20e46e0375..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/tests/mod.rs +++ /dev/null @@ -1,11 +0,0 @@ -use super::*; -use utility::*; - -const ASSET_PATH : &str = concat!( env!("CARGO_MANIFEST_DIR"), "/tests/willbe_old/_asset" ); - -mod integration; -mod ordering; -mod from; -mod iterator; -mod verification; -mod metadata; diff --git a/module/blank/willbe_old/tests/willbe_old/tests/ordering/mod.rs b/module/blank/willbe_old/tests/willbe_old/tests/ordering/mod.rs deleted file mode 100644 index 683c5f15eb..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/tests/ordering/mod.rs +++ /dev/null @@ -1,6 +0,0 @@ -use super::*; - -//? Write test for iteration over path has no reason because it delegates everything to another functions - -mod workspace; -mod through_workspaces; diff --git a/module/blank/willbe_old/tests/willbe_old/tests/ordering/through_workspaces.rs b/module/blank/willbe_old/tests/willbe_old/tests/ordering/through_workspaces.rs deleted file mode 100644 index 58ab7788a4..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/tests/ordering/through_workspaces.rs +++ /dev/null @@ -1,74 +0,0 @@ -use super::*; - -#[ test ] -fn alphabetical() -{ - let workspace_asset = Asset::from( PathBuf::from( ASSET_PATH ).join( "workspaces/workspace1" ) ).copied(); - let workspace_path = workspace_asset.path_buf(); - let first_workspace = Workspace::try_from( workspace_path.to_owned() ).unwrap(); - - let workspace_asset = Asset::from( PathBuf::from( ASSET_PATH ).join( "workspaces/workspace2" ) ).copied(); - let workspace_path = workspace_asset.path_buf(); - let second_workspace = Workspace::try_from( workspace_path.to_owned() ).unwrap(); - - let source = - [ - &second_workspace, // module3, module4, module 5 - &first_workspace, // module1, module2 - ]; - - let expected = - [ - "willbe_workspace1_module1", - "willbe_workspace1_module2", - - "willbe_workspace2_module3", - "willbe_workspace2_module4", - "willbe_workspace2_module5" - ]; - - assert_eq! - ( - expected.iter().map( | m | m.to_string() ).collect::< Vec< _ > >(), - workspaces_packages_iterate( source.into_iter().cloned() ) - - .ordered_iter( OrderStrategy::Alphabetical ) - - .filter_map( | p | PackageMetadata::try_from( p ).ok() ) - .map( | p | p.name().to_owned() ) - .collect::< Vec< _ > >() - ); -} - -#[ test ] -fn random() -{ - let workspace_asset = Asset::from( PathBuf::from( ASSET_PATH ).join( "workspaces/workspace1" ) ).copied(); - let workspace_path = workspace_asset.path_buf(); - let first_workspace = Workspace::try_from( workspace_path.to_owned() ).unwrap(); - - let workspace_asset = Asset::from( PathBuf::from( ASSET_PATH ).join( "workspaces/workspace2" ) ).copied(); - let workspace_path = workspace_asset.path_buf(); - let second_workspace = Workspace::try_from( workspace_path.to_owned() ).unwrap(); - - let source = - [ - &second_workspace, // module3, module4, module 5 - &first_workspace, // module1, module2 - ]; - - dbg! - ( - workspaces_packages_iterate( source.into_iter().cloned() ) - - .ordered( OrderStrategy::Random ) - - .iter().cloned() - .filter_map( | p | PackageMetadata::try_from( p ).ok() ) - .map( | p | p.name().to_owned() ) - .collect::< Vec< _ > >() - ); - - // TODO: make some check. Eg: source is not equal to ordered, but... It may be equal because random - assert!( true ); -} diff --git a/module/blank/willbe_old/tests/willbe_old/tests/ordering/workspace.rs b/module/blank/willbe_old/tests/willbe_old/tests/ordering/workspace.rs deleted file mode 100644 index 644fef1118..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/tests/ordering/workspace.rs +++ /dev/null @@ -1,103 +0,0 @@ -use super::*; - -#[ test ] -fn alphabetical() -{ - let package_asset = Asset::from( PathBuf::from( ASSET_PATH ).join( "workspaces/workspace1/module/module1" ) ).copied(); - let package_path = package_asset.path_buf(); - let first_package = Package::try_from( package_path.to_owned() ).unwrap(); - - let package_asset = Asset::from( PathBuf::from( ASSET_PATH ).join( "workspaces/workspace1/module/module2" ) ).copied(); - let package_path = package_asset.path_buf(); - let second_package = Package::try_from( package_path.to_owned() ).unwrap(); - - let package_asset = Asset::from( PathBuf::from( ASSET_PATH ).join( "workspaces/workspace2/module/module3" ) ).copied(); - let package_path = package_asset.path_buf(); - let third_package = Package::try_from( package_path.to_owned() ).unwrap(); - - let source = - [ - &second_package, // module2 - &first_package, // module1 - &third_package, // module3 - ]; - - let expected = vec![ &first_package, &second_package, &third_package ]; - - assert_eq! - ( - expected.iter().map( | p | p.path().to_owned() ).collect::< Vec< _ > >(), - source.into_iter().cloned() - - .ordered_iter( OrderStrategy::Alphabetical ) - - .map( | p | p.path().to_owned() ).collect::< Vec< _ > >() - ); -} - -#[ test ] -fn topological() -{ - let workspace_asset = Asset::from( PathBuf::from( ASSET_PATH ).join( "workspace_with_deps" ) ).copied(); - let workspace_path = workspace_asset.path_buf(); - let first_package = Package::try_from( workspace_path.to_owned().join( "module/module1" ) ).unwrap(); - let second_package = Package::try_from( workspace_path.to_owned().join( "module/module2" ) ).unwrap(); - let third_package = Package::try_from( workspace_path.to_owned().join( "module/module3" ) ).unwrap(); - - let source = - [ - &third_package, // module3 dependent on module2 - &first_package, // module1 - &second_package, // module2 dependent on module1 - ]; - - let expected = vec![ &first_package, &second_package, &third_package ]; - - assert_eq! - ( - expected.iter().map( | p | p.path().to_owned() ).collect::< Vec< _ > >(), - source.into_iter().cloned() - - .ordered_iter( OrderStrategy::Topological ) - - .map( | p | p.path().to_owned() ).collect::< Vec< _ > >() - ); -} - -#[ test ] -fn random() -{ - let package_asset = Asset::from( PathBuf::from( ASSET_PATH ).join( "workspaces/workspace1/module/module1" ) ).copied(); - let package_path = package_asset.path_buf(); - let first_package = Package::try_from( package_path.to_owned() ).unwrap(); - - let package_asset = Asset::from( PathBuf::from( ASSET_PATH ).join( "workspaces/workspace1/module/module2" ) ).copied(); - let package_path = package_asset.path_buf(); - let second_package = Package::try_from( package_path.to_owned() ).unwrap(); - - let package_asset = Asset::from( PathBuf::from( ASSET_PATH ).join( "workspaces/workspace2/module/module3" ) ).copied(); - let package_path = package_asset.path_buf(); - let third_package = Package::try_from( package_path.to_owned() ).unwrap(); - - let source = - [ - &second_package, // module2 - &first_package, // module1 - &third_package, // module3 - ]; - - dbg! - ( - source.into_iter().cloned() - - .ordered( OrderStrategy::Random ) - - .iter().cloned() - .filter_map( | p | PackageMetadata::try_from( p ).ok() ) - .map( | p | p.name().to_owned() ) - .collect::< Vec< _ > >() - ); - - // TODO: make some check. Eg: source is not equal to ordered, but... It may be equal because random - assert!( true ); -} diff --git a/module/blank/willbe_old/tests/willbe_old/tests/verification.rs b/module/blank/willbe_old/tests/willbe_old/tests/verification.rs deleted file mode 100644 index 091a678ed3..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/tests/verification.rs +++ /dev/null @@ -1,26 +0,0 @@ -use super::*; - -#[ test ] -fn verified() -{ - let asset = Asset::from( PathBuf::from( ASSET_PATH ).join( "package" ) ).copied(); - let path = asset.path_buf(); - - let meta = PackageMetadata::try_from( path.to_owned() ).unwrap(); - - assert!( meta.check_all() ); -} - -#[ test ] -fn no_verified() -{ - let asset = Asset::from( PathBuf::from( ASSET_PATH ).join( "package_no_verified" ) ).copied(); - let path = asset.path_buf(); - - let meta = PackageMetadata::try_from( path.to_owned() ).unwrap(); - - assert!( !meta.has_license() ); - assert!( !meta.has_readme() ); - assert!( !meta.has_documentation() ); - assert!( !meta.is_tests_passed() ); -} diff --git a/module/blank/willbe_old/tests/willbe_old/utility.rs b/module/blank/willbe_old/tests/willbe_old/utility.rs deleted file mode 100644 index 9b5a83b0ea..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/utility.rs +++ /dev/null @@ -1,71 +0,0 @@ -use std::{ io, fs }; -use std::path::Path; - -pub use std::path::PathBuf; - -#[ derive( Debug ) ] -pub struct Asset -{ - remove_after_use : bool, - path : PathBuf, -} - -impl From< PathBuf > for Asset -{ - fn from( path : PathBuf ) -> Self - { - Self{ remove_after_use : false, path } - } -} - -impl Asset -{ - pub fn path_buf( &self ) -> &PathBuf - { - &self.path - } - - pub fn copied( mut self ) -> Self - { - let tmp_dir = tempfile::tempdir().unwrap(); - - Self::copy_dir_all( &self.path, &tmp_dir ).unwrap(); - self.path = tmp_dir.into_path(); - self.remove_after_use = true; - - self - } -} - -impl Asset -{ - fn copy_dir_all( src : impl AsRef< Path >, dst : impl AsRef< Path > ) -> io::Result< () > - { - fs::create_dir_all(&dst)?; - for entry in fs::read_dir(src)? - { - let entry = entry?; - let ty = entry.file_type()?; - if ty.is_dir() - { - Asset::copy_dir_all( entry.path(), dst.as_ref().join( entry.file_name() ) )?; - } else - { - fs::copy( entry.path(), dst.as_ref().join( entry.file_name() ) )?; - } - } - Ok( () ) - } -} - -impl Drop for Asset -{ - fn drop( &mut self ) - { - if self.remove_after_use - { - fs::remove_dir_all( &self.path ) - .expect( &format!( "Can not delete \"{}\"", &self.path.display() ) ) - } - } -} diff --git a/module/blank/willbe_old/tests/willbe_old/willbe_test.rs b/module/blank/willbe_old/tests/willbe_old/willbe_test.rs deleted file mode 100644 index 2e70508245..0000000000 --- a/module/blank/willbe_old/tests/willbe_old/willbe_test.rs +++ /dev/null @@ -1,7 +0,0 @@ -use willbe_old::*; - -#[ cfg( not( feature = "no_std" ) ) ] -mod utility; - -#[ cfg( not( feature = "no_std" ) ) ] -mod tests; diff --git a/module/blank/wlang/Cargo.toml b/module/blank/wlang/Cargo.toml index 828d17a7c3..0b207714df 100644 --- a/module/blank/wlang/Cargo.toml +++ b/module/blank/wlang/Cargo.toml @@ -22,7 +22,7 @@ workspace = true [package.metadata.docs.rs] features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] + include = [ "/rust/impl/_blank", "/Cargo.toml", diff --git a/module/blank/wlang/src/standard_lib.rs b/module/blank/wlang/src/standard_lib.rs index 656b3eb36e..aac4eeefdf 100644 --- a/module/blank/wlang/src/standard_lib.rs +++ b/module/blank/wlang/src/standard_lib.rs @@ -1,4 +1,4 @@ -#![ cfg_attr( feature = "no_std", no_std ) ] + #![ 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/_blank/latest/_blank/" ) ] @@ -17,30 +17,38 @@ pub mod dependency #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } /// Parented namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; } diff --git a/module/blank/wlang/tests/smoke_test.rs b/module/blank/wlang/tests/smoke_test.rs index fddef25d11..dda3313c2e 100644 --- a/module/blank/wlang/tests/smoke_test.rs +++ b/module/blank/wlang/tests/smoke_test.rs @@ -1,5 +1,5 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] #[ ignore ] fn local_smoke_test() @@ -7,7 +7,7 @@ fn local_smoke_test() ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/core/clone_dyn/Cargo.toml b/module/core/clone_dyn/Cargo.toml index 0c2804d339..0d3d4658b2 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.18.0" +version = "0.22.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", @@ -23,18 +23,20 @@ workspace = true [package.metadata.docs.rs] features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] [features] -default = [ "enabled" ] -full = [ "enabled" ] -no_std = [] -use_alloc = [ "no_std" ] -enabled = [ "clone_dyn_meta/enabled" ] +default = [ "enabled", "clone_dyn_types", "clone_dyn_meta" ] +full = [ "enabled", "clone_dyn_types", "clone_dyn_meta" ] +enabled = [] + +clone_dyn_types = [ "dep:clone_dyn_types", "clone_dyn_types/enabled" ] +clone_dyn_meta = [ "dep:clone_dyn_meta", "clone_dyn_meta/enabled", "clone_dyn_types" ] [dependencies] -clone_dyn_meta = { workspace = true } +clone_dyn_meta = { workspace = true, optional = true } +clone_dyn_types = { workspace = true, optional = true } [dev-dependencies] test_tools = { workspace = true } +inspect_type = { workspace = true, features = [ "full" ] } diff --git a/module/core/clone_dyn/Readme.md b/module/core/clone_dyn/Readme.md index 4a8efa5ae2..f23c03a8c9 100644 --- a/module/core/clone_dyn/Readme.md +++ b/module/core/clone_dyn/Readme.md @@ -10,28 +10,210 @@ By default, Rust does not support cloning for trait objects due to the `Clone` t ### Alternative -There are few alternatives [dyn-clone](https://github.com/dtolnay/dyn-clone), [dyn-clonable](https://github.com/kardeiz/objekt-clonable). Unlike other options, this solution is more concise and demands less effort to use, all without compromising the quality of the outcome. Also, you can ask an inquiry and get answers, which is problematic in the case of alternatives. +There are few alternatives [dyn-clone](https://github.com/dtolnay/dyn-clone), [dyn-clonable](https://github.com/kardeiz/objekt-clonable). Unlike other options, this solution is more concise and demands less effort to use, all without compromising the quality of the outcome. -### Basic use-case +## Basic use-case + +Demonstrates the usage of `clone_dyn` to enable cloning for trait objects. + +By default, Rust does not support cloning for trait objects due to the `Clone` trait +requiring compile-time knowledge of the type's size. The `clone_dyn` crate addresses +this limitation through procedural macros, allowing for cloning collections of trait objects. + +##### Overview + +This example shows how to use the `clone_dyn` crate to enable cloning for trait objects, +specifically for iterators. It defines a custom trait, `IterTrait`, that encapsulates +an iterator with specific characteristics and demonstrates how to use `CloneDyn` to +overcome the object safety constraints of the `Clone` trait. + +##### The `IterTrait` Trait + +The `IterTrait` trait is designed to represent iterators that yield references to items (`&'a T`). +These iterators must also implement the `ExactSizeIterator` and `DoubleEndedIterator` traits. +Additionally, the iterator must implement the `CloneDyn` trait, which allows cloning of trait objects. + +The trait is implemented for any type that meets the specified requirements. + +##### Cloning Trait Objects + +Rust's type system does not allow trait objects to implement the `Clone` trait directly due to object safety constraints. +Specifically, the `Clone` trait requires knowledge of the concrete type at compile time, which is not available for trait objects. + +The `CloneDyn` trait from the `clone_dyn` crate provides a workaround for this limitation by allowing trait objects to be cloned. +Procedural macros generates the necessary code for cloning trait objects, making it possible to clone collections of trait objects. + +The example demonstrates how to implement `Clone` for boxed `IterTrait` trait objects. + +##### `get_iter` Function + +The `get_iter` function returns a boxed iterator that implements the `IterTrait` trait. +If the input is `Some`, it returns an iterator over the vector. +If the input is `None`, it returns an empty iterator. + +It's not possible to use `impl Iterator` here because the code returns iterators of two different types: +- `std::slice::Iter` when the input is `Some`. +- `std::iter::Empty` when the input is `None`. + +To handle this, the function returns a trait object ( `Box< dyn IterTrait >` ). +However, Rust's `Clone` trait cannot be implemented for trait objects due to object safety constraints. +The `CloneDyn` trait addresses this problem by enabling cloning of trait objects. + +##### `use_iter` Function + +The `use_iter` function demonstrates the use of the `CloneDyn` trait by cloning the iterator. +It then iterates over the cloned iterator and prints each element. + +##### Main Function + +The main function demonstrates the overall usage by creating a vector, obtaining an iterator, and using the iterator to print elements. - ```rust -# #[ cfg( all( feature = "enabled", any( not( feature = "no_std" ), feature = "use_alloc" ) ) ) ] +# #[ cfg( not( all( feature = "enabled", feature = "clone_dyn_meta" ) ) ) ] +# fn main() {} +# #[ cfg( all( feature = "enabled", feature = "clone_dyn_meta" ) ) ] +# fn main() # { - use clone_dyn::clone_dyn; + use clone_dyn::{ clone_dyn, CloneDyn }; + + /// Trait that encapsulates an iterator with specific characteristics, tailored for your needs. + // Uncomment to see what macro expand into + // #[ clone_dyn( debug ) ] #[ clone_dyn ] - trait Trait1 + pub trait IterTrait< 'a, T > + where + T : 'a, + Self : Iterator< Item = T > + ExactSizeIterator< Item = T > + DoubleEndedIterator, + // Self : CloneDyn, + // There’s no need to explicitly define this bound because the macro will handle it for you. + { + } + + impl< 'a, T, I > IterTrait< 'a, T > for I + where + T : 'a, + Self : Iterator< Item = T > + ExactSizeIterator< Item = T > + DoubleEndedIterator, + Self : CloneDyn, + { + } + + /// + /// Function to get an iterator over a vector of integers. + /// + /// This function returns a boxed iterator that implements the `IterTrait` trait. + /// If the input is `Some`, it returns an iterator over the vector. + /// If the input is `None`, it returns an empty iterator. + /// + /// Rust's type system does not allow trait objects to implement the `Clone` trait directly due to object safety constraints. + /// Specifically, the `Clone` trait requires knowledge of the concrete type at compile time, which is not available for trait objects. + /// + /// In this example, we need to return an iterator that can be cloned. Since we are returning a trait object ( `Box< dyn IterTrait >` ), + /// we cannot directly implement `Clone` for this trait object. This is where the `CloneDyn` trait from the `clone_dyn` crate comes in handy. + /// + /// The `CloneDyn` trait provides a workaround for this limitation by allowing trait objects to be cloned. + /// It uses procedural macros to generate the necessary code for cloning trait objects, making it possible to clone collections of trait objects. + /// + /// It's not possible to use `impl Iterator` here because the code returns iterators of two different types: + /// - `std::slice::Iter` when the input is `Some`. + /// - `std::iter::Empty` when the input is `None`. + /// + /// To handle this, the function returns a trait object (`Box`). + /// However, Rust's `Clone` trait cannot be implemented for trait objects due to object safety constraints. + /// The `CloneDyn` trait addresses this problem by enabling cloning of trait objects. + + pub fn get_iter< 'a >( src : Option< &'a Vec< i32 > > ) -> Box< dyn IterTrait< 'a, &'a i32 > + 'a > { + match &src + { + Some( src ) => Box::new( src.iter() ), + _ => Box::new( core::iter::empty() ), + } } - let vec = Vec::< Box< dyn Trait1 > >::new(); - let vec2 = vec.clone(); /* <- it does not work without `clone_dyn` */ + /// Function to use an iterator and print its elements. + /// + /// This function demonstrates the use of the `CloneDyn` trait by cloning the iterator. + /// It then iterates over the cloned iterator and prints each element. + pub fn use_iter< 'a >( iter : Box< dyn IterTrait< 'a, &'a i32 > + 'a > ) + { + // Clone would not be available if CloneDyn is not implemented for the iterator. + // And being an object-safe trait, it can't implement Clone. + // Nevertheless, thanks to CloneDyn, the object is clonable. + // + // This line demonstrates cloning the iterator and iterating over the cloned iterator. + // Without `CloneDyn`, you would need to collect the iterator into a container, allocating memory on the heap. + iter.clone().for_each( | e | println!( "{e}" ) ); + + // Iterate over the original iterator and print each element. + iter.for_each( | e | println!( "{e}" ) ); + } + + // Create a vector of integers. + let data = vec![ 1, 2, 3 ]; + // Get an iterator over the vector. + let iter = get_iter( Some( &data ) ); + // Use the iterator to print its elements. + use_iter( iter ); + # } ``` - +
+If you use multithreading or asynchronous paradigms implement trait `Clone` also for `Send` and `Sync` + +```rust, ignore + +#[ allow( non_local_definitions ) ] +impl< 'c, T > Clone for Box< dyn IterTrait< 'c, T > + 'c > +{ + #[ inline ] + fn clone( &self ) -> Self + { + clone_dyn::clone_into_box( &**self ) + } +} + +#[ allow( non_local_definitions ) ] +impl< 'c, T > Clone for Box< dyn IterTrait< 'c, T > + Send + 'c > +{ + #[ inline ] + fn clone( &self ) -> Self + { + clone_dyn::clone_into_box( &**self ) + } +} + +#[ allow( non_local_definitions ) ] +impl< 'c, T > Clone for Box< dyn IterTrait< 'c, T > + Sync + 'c > +{ + #[ inline ] + fn clone( &self ) -> Self + { + clone_dyn::clone_into_box( &**self ) + } +} + +#[ allow( non_local_definitions ) ] +impl< 'c, T > Clone for Box< dyn IterTrait< 'c, T > + Send + Sync + 'c > +{ + #[ inline ] + fn clone( &self ) -> Self + { + clone_dyn::clone_into_box( &**self ) + } +} + +``` + +
+ +
+ +Try out `cargo run --example clone_dyn_trivial`. +
+[See code](./examples/clone_dyn_trivial.rs). ### To add to your project diff --git a/module/core/clone_dyn/examples/clone_dyn_trivial.rs b/module/core/clone_dyn/examples/clone_dyn_trivial.rs index 980bb02488..cd67d1cbea 100644 --- a/module/core/clone_dyn/examples/clone_dyn_trivial.rs +++ b/module/core/clone_dyn/examples/clone_dyn_trivial.rs @@ -1,24 +1,143 @@ +//! +//! ## Basic use-case +//! //! Demonstrates the usage of `clone_dyn` to enable cloning for trait objects. //! //! By default, Rust does not support cloning for trait objects due to the `Clone` trait //! requiring compile-time knowledge of the type's size. The `clone_dyn` crate addresses //! this limitation through procedural macros, allowing for cloning collections of trait objects. +//! +//! ##### Overview +//! +//! This example shows how to use the `clone_dyn` crate to enable cloning for trait objects, +//! specifically for iterators. It defines a custom trait, `IterTrait`, that encapsulates +//! an iterator with specific characteristics and demonstrates how to use `CloneDyn` to +//! overcome the object safety constraints of the `Clone` trait. +//! +//! ##### The `IterTrait` Trait +//! +//! The `IterTrait` trait is designed to represent iterators that yield references to items (`&'a T`). +//! These iterators must also implement the `ExactSizeIterator` and `DoubleEndedIterator` traits. +//! Additionally, the iterator must implement the `CloneDyn` trait, which allows cloning of trait objects. +//! +//! The trait is implemented for any type that meets the specified requirements. +//! +//! ##### Cloning Trait Objects +//! +//! Rust's type system does not allow trait objects to implement the `Clone` trait directly due to object safety constraints. +//! Specifically, the `Clone` trait requires knowledge of the concrete type at compile time, which is not available for trait objects. +//! +//! The `CloneDyn` trait from the `clone_dyn` crate provides a workaround for this limitation by allowing trait objects to be cloned. +//! Procedural macros generates the necessary code for cloning trait objects, making it possible to clone collections of trait objects. +//! +//! The example demonstrates how to implement `Clone` for boxed `IterTrait` trait objects. +//! +//! ##### `get_iter` Function +//! +//! The `get_iter` function returns a boxed iterator that implements the `IterTrait` trait. +//! If the input is `Some`, it returns an iterator over the vector. +//! If the input is `None`, it returns an empty iterator. +//! +//! It's not possible to use `impl Iterator` here because the code returns iterators of two different types: +//! - `std::slice::Iter` when the input is `Some`. +//! - `std::iter::Empty` when the input is `None`. +//! +//! To handle this, the function returns a trait object ( `Box< dyn IterTrait >` ). +//! However, Rust's `Clone` trait cannot be implemented for trait objects due to object safety constraints. +//! The `CloneDyn` trait addresses this problem by enabling cloning of trait objects. +//! +//! ##### `use_iter` Function +//! +//! The `use_iter` function demonstrates the use of the `CloneDyn` trait by cloning the iterator. +//! It then iterates over the cloned iterator and prints each element. +//! +//! ##### Main Function +//! +//! The main function demonstrates the overall usage by creating a vector, obtaining an iterator, and using the iterator to print elements. +//! -#[ cfg( any( not( feature = "enabled" ), all( feature = "no_std", not( feature = "use_alloc" ) ) ) ) ] +#[ cfg( not( all( feature = "enabled", feature = "clone_dyn_meta" ) ) ) ] fn main() {} - -#[ cfg( all( feature = "enabled", any( not( feature = "no_std" ), feature = "use_alloc" ) ) ) ] +#[ cfg( all( feature = "enabled", feature = "clone_dyn_meta" ) ) ] fn main() { + use clone_dyn::{ clone_dyn, CloneDyn }; - use clone_dyn::clone_dyn; - + /// Trait that encapsulates an iterator with specific characteristics, tailored for your needs. #[ clone_dyn ] - trait Trait1 + pub trait IterTrait< 'a, T > + where + T : 'a, + Self : Iterator< Item = T > + ExactSizeIterator< Item = T > + DoubleEndedIterator, + // Self : CloneDyn, + // There’s no need to explicitly define this bound because the macro will handle it for you. + { + } + + impl< 'a, T, I > IterTrait< 'a, T > for I + where + T : 'a, + Self : Iterator< Item = T > + ExactSizeIterator< Item = T > + DoubleEndedIterator, + Self : CloneDyn, { } - let vec = Vec::< Box< dyn Trait1 > >::new(); - let _vec2 = vec.clone(); /* <- it does not work without `clone_dyn` */ + /// + /// Function to get an iterator over a vector of integers. + /// + /// This function returns a boxed iterator that implements the `IterTrait` trait. + /// If the input is `Some`, it returns an iterator over the vector. + /// If the input is `None`, it returns an empty iterator. + /// + /// Rust's type system does not allow trait objects to implement the `Clone` trait directly due to object safety constraints. + /// Specifically, the `Clone` trait requires knowledge of the concrete type at compile time, which is not available for trait objects. + /// + /// In this example, we need to return an iterator that can be cloned. Since we are returning a trait object ( `Box< dyn IterTrait >` ), + /// we cannot directly implement `Clone` for this trait object. This is where the `CloneDyn` trait from the `clone_dyn` crate comes in handy. + /// + /// The `CloneDyn` trait provides a workaround for this limitation by allowing trait objects to be cloned. + /// It uses procedural macros to generate the necessary code for cloning trait objects, making it possible to clone collections of trait objects. + /// + /// It's not possible to use `impl Iterator` here because the code returns iterators of two different types: + /// - `std::slice::Iter` when the input is `Some`. + /// - `std::iter::Empty` when the input is `None`. + /// + /// To handle this, the function returns a trait object (`Box`). + /// However, Rust's `Clone` trait cannot be implemented for trait objects due to object safety constraints. + /// The `CloneDyn` trait addresses this problem by enabling cloning of trait objects. + + pub fn get_iter< 'a >( src : Option< &'a Vec< i32 > > ) -> Box< dyn IterTrait< 'a, &'a i32 > + 'a > + { + match &src + { + Some( src ) => Box::new( src.iter() ), + _ => Box::new( core::iter::empty() ), + } + } + + /// Function to use an iterator and print its elements. + /// + /// This function demonstrates the use of the `CloneDyn` trait by cloning the iterator. + /// It then iterates over the cloned iterator and prints each element. + pub fn use_iter< 'a >( iter : Box< dyn IterTrait< 'a, &'a i32 > + 'a > ) + { + // Clone would not be available if CloneDyn is not implemented for the iterator. + // And being an object-safe trait, it can't implement Clone. + // Nevertheless, thanks to CloneDyn, the object is clonable. + // + // This line demonstrates cloning the iterator and iterating over the cloned iterator. + // Without `CloneDyn`, you would need to collect the iterator into a container, allocating memory on the heap. + iter.clone().for_each( | e | println!( "{e}" ) ); + + // Iterate over the original iterator and print each element. + iter.for_each( | e | println!( "{e}" ) ); + } + + // Create a vector of integers. + let data = vec![ 1, 2, 3 ]; + // Get an iterator over the vector. + let iter = get_iter( Some( &data ) ); + // Use the iterator to print its elements. + use_iter( iter ); } diff --git a/module/core/clone_dyn/src/lib.rs b/module/core/clone_dyn/src/lib.rs index 54e6f3ef40..194a45c1c8 100644 --- a/module/core/clone_dyn/src/lib.rs +++ b/module/core/clone_dyn/src/lib.rs @@ -1,105 +1,83 @@ -#![ cfg_attr( feature = "no_std", no_std ) ] +#![ no_std ] #![ 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/clone_dyn/latest/clone_dyn/" ) ] #![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/", "Readme.md" ) ) ] -#[ allow( unused_extern_crates ) ] -#[ cfg( all( feature = "no_std", feature = "use_alloc" ) ) ] -extern crate alloc; - /// Namespace with dependencies. #[ cfg( feature = "enabled" ) ] pub mod dependency { + #[ cfg( feature = "clone_dyn_meta" ) ] pub use ::clone_dyn_meta; + #[ cfg( feature = "clone_dyn_types" ) ] + pub use ::clone_dyn_types; } /// Internal namespace. -#[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] #[ cfg( feature = "enabled" ) ] pub( crate ) mod private { - - #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] - extern crate alloc; - #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] - #[ allow( unused_imports ) ] - use alloc::boxed::Box; - #[ cfg( all( feature = "use_std", not( feature = "use_alloc" ) ) ) ] - use std::boxed::Box; - - /// Clone boxed dyn. - /// - /// Not intended to be used directly. - #[ inline ] - pub fn _clone_boxed< T >( t : &T ) -> Box< T > - where - T : ?Sized, - { - // Explanation for the use of `unsafe`: - // The `unsafe` block is necessary here because we're performing low-level memory manipulations - // that cannot be checked by the Rust compiler for safety. Specifically, we're manually handling - // raw pointers and converting them to and from `Box< T >`, which is considered unsafe as it - // bypasses Rust's ownership and borrowing rules. This is done to dynamically clone a boxed - // trait object, which doesn't support cloning through the standard `Clone` trait. The operations - // within this block are carefully crafted to ensure memory safety manually, including proper - // allocation and deallocation of heap memory for the clone. - #[ allow( unsafe_code ) ] - unsafe - { - let mut ptr = t as *const T; - let data_ptr = &mut ptr as *mut *const T as *mut *mut (); - *data_ptr = Box::into_raw( Box::new( < &T >::clone( &t ) ) ) as *mut (); - Box::from_raw( ptr as *mut T ) - } - } - } #[ cfg( feature = "enabled" ) ] #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. +/// Own namespace of the module. #[ cfg( feature = "enabled" ) ] -pub mod protected +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } /// Orphan namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; + + #[ doc( inline ) ] + pub use exposed::*; + #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::exposed::*; + #[ cfg( feature = "clone_dyn_types" ) ] + pub use super::dependency::clone_dyn_types::exposed::*; + } /// Exposed namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; } /// Prelude to use essentials: `use my_module::prelude::*`. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; + #[ doc( inline ) ] #[ allow( unused_imports ) ] - #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] + #[ cfg( feature = "clone_dyn_meta" ) ] pub use ::clone_dyn_meta::clone_dyn; + #[ doc( inline ) ] #[ allow( unused_imports ) ] - #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] - pub use super::private::_clone_boxed; + #[ cfg( feature = "clone_dyn_types" ) ] + pub use super::dependency::clone_dyn_types::prelude::*; + } diff --git a/module/core/clone_dyn/tests/inc/basic.rs b/module/core/clone_dyn/tests/inc/basic.rs new file mode 100644 index 0000000000..55e7eee3cd --- /dev/null +++ b/module/core/clone_dyn/tests/inc/basic.rs @@ -0,0 +1,57 @@ + +#[ allow( unused_imports ) ] +use super::*; + +use the_module::clone_dyn; + +#[ clone_dyn ] +trait Trait1 +{ + fn val( &self ) -> i32; +} + +// + +impl Trait1 for i32 +{ + fn val( &self ) -> i32 + { + *self + } +} + +impl Trait1 for i64 +{ + fn val( &self ) -> i32 + { + self.clone().try_into().unwrap() + } +} + +impl Trait1 for String +{ + fn val( &self ) -> i32 + { + self.len().try_into().unwrap() + } +} + +impl< T > Trait1 for &[ T ] +where + T : the_module::CloneDyn, +{ + fn val( &self ) -> i32 + { + self.len().try_into().unwrap() + } +} + +impl Trait1 for &str +{ + fn val( &self ) -> i32 + { + self.len().try_into().unwrap() + } +} + +include!( "./only_test/basic.rs" ); diff --git a/module/core/clone_dyn/tests/inc/basic_manual.rs b/module/core/clone_dyn/tests/inc/basic_manual.rs new file mode 100644 index 0000000000..04ff392acb --- /dev/null +++ b/module/core/clone_dyn/tests/inc/basic_manual.rs @@ -0,0 +1,95 @@ + +#[ allow( unused_imports ) ] +use super::*; + +trait Trait1 +where + Self : the_module::CloneDyn, +{ + fn val( &self ) -> i32; +} + +// + +impl Trait1 for i32 +{ + fn val( &self ) -> i32 + { + *self + } +} + +impl Trait1 for i64 +{ + fn val( &self ) -> i32 + { + self.clone().try_into().unwrap() + } +} + +impl Trait1 for String +{ + fn val( &self ) -> i32 + { + self.len().try_into().unwrap() + } +} + +impl< T > Trait1 for &[ T ] +where + T : the_module::CloneDyn, +{ + fn val( &self ) -> i32 + { + self.len().try_into().unwrap() + } +} + +impl Trait1 for &str +{ + fn val( &self ) -> i32 + { + self.len().try_into().unwrap() + } +} + +// == begin of generated + +#[ allow( non_local_definitions ) ] +impl < 'c > Clone +for Box< dyn Trait1 + 'c > +{ + #[ inline ] + fn clone( &self ) -> Self + { + the_module::clone_into_box( &**self ) + } +} + +#[ allow( non_local_definitions ) ] +impl < 'c > Clone +for Box< dyn Trait1 + Send + 'c > +{ + #[ inline ] + fn clone( &self ) -> Self { the_module::clone_into_box( &**self ) } +} + +#[ allow( non_local_definitions ) ] +impl < 'c > Clone +for Box< dyn Trait1 + Sync + 'c > +{ + #[ inline ] + fn clone( &self ) -> Self { the_module::clone_into_box( &**self ) } +} + +#[ allow( non_local_definitions ) ] +impl < 'c > Clone +for Box< dyn Trait1 + Send + Sync + 'c > +{ + #[ inline ] + fn clone( &self ) -> Self { the_module::clone_into_box( &**self ) } +} + +// == end of generated + +include!( "./only_test/basic.rs" ); diff --git a/module/core/clone_dyn/tests/inc/mod.rs b/module/core/clone_dyn/tests/inc/mod.rs index 99cee0a3c6..fc05ba6236 100644 --- a/module/core/clone_dyn/tests/inc/mod.rs +++ b/module/core/clone_dyn/tests/inc/mod.rs @@ -2,159 +2,9 @@ #[ allow( unused_imports ) ] use super::*; -// - -tests_impls! -{ - - // - - // qqq : organize tests in the same way tests organized for derive_tools - fn manual() - { - - trait Trait1 - { - } - - // - - #[ inline ] - pub fn _clone_boxed< T >( t : &T ) -> Box< T > - where - T : ?Sized, - { - unsafe - { - let mut ptr = t as *const T; - let data_ptr = &mut ptr as *mut *const T as *mut *mut (); - *data_ptr = Box::into_raw( Box::new( t.clone() ) ) as *mut (); - Box::from_raw( ptr as *mut T ) - } - } - - // - - #[ allow( non_local_definitions ) ] - impl < 'c > Clone - for Box< dyn Trait1 + 'c > - { - #[ inline ] - fn clone( &self ) -> Self { _clone_boxed( &**self ) } - } - - #[ allow( non_local_definitions ) ] - impl < 'c > Clone - for Box< dyn Trait1 + Send + 'c > - { - #[ inline ] - fn clone( &self ) -> Self { _clone_boxed( &**self ) } - } - - #[ allow( non_local_definitions ) ] - impl < 'c > Clone - for Box< dyn Trait1 + Sync + 'c > - { - #[ inline ] - fn clone( &self ) -> Self { _clone_boxed( &**self ) } - } - - #[ allow( non_local_definitions ) ] - impl < 'c > Clone - for Box< dyn Trait1 + Send + Sync + 'c > - { - #[ inline ] - fn clone( &self ) -> Self { _clone_boxed( &**self ) } - } - - // - - let vec = Vec::< Box< dyn Trait1 > >::new(); - let vec2 = vec.clone(); - - } - - // - - fn basic() - { - use the_module::clone_dyn; - - #[ clone_dyn ] - trait Trait1 - { - } - - // - - let vec = Vec::< Box< dyn Trait1 > >::new(); - let vec2 = vec.clone(); - - } - - // - - fn prelude() - { - use the_module::prelude::*; - - #[ clone_dyn ] - trait Trait1 - { - } - - // - - let vec = Vec::< Box< dyn Trait1 > >::new(); - let vec2 = vec.clone(); - - } - - // - - fn parametrized() - { - use the_module::clone_dyn; - - #[ clone_dyn ] - trait Trait2< T1 : Copy, T2 : Copy > - where - T2 : Clone + core::fmt::Debug, - { - } - - // - - let vec = Vec::< Box< dyn Trait2< i32, f32 > > >::new(); - let vec2 = vec.clone(); - - } - - // - - fn sample() - { - use the_module::clone_dyn; - - #[ clone_dyn ] - trait Trait1 - { - } - - let vec = Vec::< Box< dyn Trait1 > >::new(); - let vec2 = vec.clone(); /* <- it does not work without `clone_dyn` */ - - } - -} - -// - -tests_index! -{ - manual, - basic, - prelude, - parametrized, - sample, -} +#[ cfg( feature = "clone_dyn_meta" ) ] +pub mod basic_manual; +#[ cfg( feature = "clone_dyn_meta" ) ] + pub mod basic; +#[ cfg( feature = "clone_dyn_meta" ) ] +pub mod parametrized; diff --git a/module/core/clone_dyn/tests/inc/only_test/basic.rs b/module/core/clone_dyn/tests/inc/only_test/basic.rs new file mode 100644 index 0000000000..1ae447ea14 --- /dev/null +++ b/module/core/clone_dyn/tests/inc/only_test/basic.rs @@ -0,0 +1,103 @@ + +#[ test ] +fn clone_into_box() +{ + + // copyable + + let a : i32 = 13; + let b : Box< i32 > = the_module::clone_into_box( &a ); + a_id!( a, *b ); + + // clonable + + let a : String = "abc".to_string(); + let b : Box< String > = the_module::clone_into_box( &a ); + a_id!( a, *b ); + + // str slice + + let a : &str = "abc"; + let b : Box< str > = the_module::clone_into_box( a ); + a_id!( *a, *b ); + + // slice + + let a : &[ i32 ] = &[ 1, 2, 3 ]; + let b : Box< [ i32 ] > = the_module::clone_into_box( a ); + a_id!( *a, *b ); + + // + +} + +#[ test ] +fn clone() +{ + + // copyable + + let a : i32 = 13; + let b : i32 = the_module::clone( &a ); + a_id!( a, b ); + + // clonable + + let a : String = "abc".to_string(); + let b : String = the_module::clone( &a ); + a_id!( a, b ); + + // str slice + + let a : &str = "abc"; + let b : &str = the_module::clone( &a ); + a_id!( a, b ); + + // slice + + let a : &[ i32 ] = &[ 1, 2, 3 ]; + let b : &[ i32 ] = the_module::clone( &a ); + a_id!( a, b ); + + // + +} + +#[ test ] +fn basic() +{ + + // + + let e_i32 : Box< dyn Trait1 > = Box::new( 13 ); + let e_i64 : Box< dyn Trait1 > = Box::new( 14 ); + let e_string : Box< dyn Trait1 > = Box::new( "abc".to_string() ); + let e_str_slice : Box< dyn Trait1 > = Box::new( "abcd" ); + let e_slice : Box< dyn Trait1 > = Box::new( &[ 1i32, 2i32 ] as &[ i32 ] ); + + // + + let vec : Vec< Box< dyn Trait1 > > = vec![ e_i32.clone(), e_i64.clone(), e_string.clone(), e_str_slice.clone(), e_slice.clone() ]; + let vec = vec.iter().map( | e | e.val() ).collect::< Vec< _ > >(); + let vec2 = vec![ 13, 14, 3, 4, 2 ]; + a_id!( vec, vec2 ); + + // + + let vec : Vec< Box< dyn Trait1 > > = vec![ e_i32.clone(), e_i64.clone(), e_string.clone(), e_str_slice.clone(), e_slice.clone() ]; + let vec2 = the_module::clone( &vec ); + let vec = vec.iter().map( | e | e.val() ).collect::< Vec< _ > >(); + let vec2 = vec2.iter().map( | e | e.val() ).collect::< Vec< _ > >(); + a_id!( vec, vec2 ); + + // + + let vec : Vec< Box< dyn Trait1 > > = vec![ e_i32.clone(), e_i64.clone(), e_string.clone(), e_str_slice.clone(), e_slice.clone() ]; + let vec2 = vec.clone(); + let vec = vec.iter().map( | e | e.val() ).collect::< Vec< _ > >(); + let vec2 = vec2.iter().map( | e | e.val() ).collect::< Vec< _ > >(); + a_id!( vec, vec2 ); + + // + +} diff --git a/module/core/clone_dyn/tests/inc/parametrized.rs b/module/core/clone_dyn/tests/inc/parametrized.rs new file mode 100644 index 0000000000..6f7a67a42b --- /dev/null +++ b/module/core/clone_dyn/tests/inc/parametrized.rs @@ -0,0 +1,131 @@ + +#[ allow( unused_imports ) ] +use super::*; +use the_module::prelude::*; + +// + +#[ clone_dyn ] +trait Trait1< T1 : ::core::fmt::Debug, T2 > +where + T2 : ::core::fmt::Debug, + Self : ::core::fmt::Debug, +{ + fn dbg( &self ) -> String + { + format!( "{:?}", self ) + } +} + +// + +// xxx : review +// #[ derive( Debug, Clone ) ] +// struct Struct1< T1, T2 > +// where +// T1 : ::core::fmt::Debug, +// T2 : ::core::fmt::Debug, +// { +// a : T1, +// b : T2, +// } +// +// impl Trait1< i32, char > for Struct1< i32, char > +// { +// fn dbg( &self ) -> String +// { +// format!( "{self:?}( {:?} {:?} )", self.a, self.b ) +// } +// } + +// + +impl Trait1< i32, char > for i32 +{ + fn dbg( &self ) -> String + { + format!( "{:?}", self ) + } +} + +impl Trait1< i32, char > for i64 +{ + fn dbg( &self ) -> String + { + format!( "{:?}", self ) + } +} + +impl Trait1< i32, char > for String +{ + fn dbg( &self ) -> String + { + format!( "{:?}", self ) + } +} + +impl< T > Trait1< i32, char > for &[ T ] +where + T : the_module::CloneDyn, + Self : ::core::fmt::Debug, +{ + fn dbg( &self ) -> String + { + format!( "{:?}", self ) + } +} + +impl Trait1< i32, char > for &str +{ + fn dbg( &self ) -> String + { + format!( "{:?}", self ) + } +} + + +#[ test ] +fn basic() +{ + + // + + let e_i32 : Box< dyn Trait1< i32, char > > = Box::new( 13 ); + let e_i64 : Box< dyn Trait1< i32, char > > = Box::new( 14 ); + let e_string : Box< dyn Trait1< i32, char > > = Box::new( "abc".to_string() ); + let e_str_slice : Box< dyn Trait1< i32, char > > = Box::new( "abcd" ); + let e_slice : Box< dyn Trait1< i32, char > > = Box::new( &[ 1i32, 2i32 ] as &[ i32 ] ); + + // + + let vec : Vec< Box< dyn Trait1< i32, char > > > = vec![ e_i32.clone(), e_i64.clone(), e_string.clone(), e_str_slice.clone(), e_slice.clone() ]; + let vec = vec.iter().map( | e | e.dbg() ).collect::< Vec< _ > >(); + let vec2 = vec! + [ + "13".to_string(), + "14".to_string(), + "\"abc\"".to_string(), + "\"abcd\"".to_string(), + "[1, 2]".to_string(), + ]; + a_id!( vec, vec2 ); + + // + + let vec : Vec< Box< dyn Trait1< i32, char > > > = vec![ e_i32.clone(), e_i64.clone(), e_string.clone(), e_str_slice.clone(), e_slice.clone() ]; + let vec2 = the_module::clone( &vec ); + let vec = vec.iter().map( | e | e.dbg() ).collect::< Vec< _ > >(); + let vec2 = vec2.iter().map( | e | e.dbg() ).collect::< Vec< _ > >(); + a_id!( vec, vec2 ); + + // + + let vec : Vec< Box< dyn Trait1< i32, char > > > = vec![ e_i32.clone(), e_i64.clone(), e_string.clone(), e_str_slice.clone(), e_slice.clone() ]; + let vec2 = vec.clone(); + let vec = vec.iter().map( | e | e.dbg() ).collect::< Vec< _ > >(); + let vec2 = vec2.iter().map( | e | e.dbg() ).collect::< Vec< _ > >(); + a_id!( vec, vec2 ); + + // + +} diff --git a/module/core/clone_dyn/tests/smoke_test.rs b/module/core/clone_dyn/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/core/clone_dyn/tests/smoke_test.rs +++ b/module/core/clone_dyn/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/core/clone_dyn_meta/Cargo.toml b/module/core/clone_dyn_meta/Cargo.toml index 3b371d1629..7f32a82fee 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.18.0" +version = "0.22.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", @@ -23,7 +23,7 @@ workspace = true [package.metadata.docs.rs] features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] + [lib] proc-macro = true @@ -31,10 +31,11 @@ proc-macro = true [features] default = [ "enabled" ] full = [ "enabled" ] -enabled = [ "macro_tools/enabled" ] +enabled = [ "macro_tools/enabled", "former_types/enabled" ] [dependencies] -macro_tools = { workspace = true } +macro_tools = { workspace = true, features = [ "attr", "attr_prop", "ct", "diag", "generic_params", "punctuated", "phantom", "item_struct", "quantifier" ] } # qqq : optimize set of features +former_types = { workspace = true, features = [ "types_component_assign" ] } [dev-dependencies] test_tools = { workspace = true } diff --git a/module/core/clone_dyn_meta/src/derive.rs b/module/core/clone_dyn_meta/src/derive.rs index cb006d1a9e..506244e700 100644 --- a/module/core/clone_dyn_meta/src/derive.rs +++ b/module/core/clone_dyn_meta/src/derive.rs @@ -1,69 +1,184 @@ use macro_tools::prelude::*; -use macro_tools::{ Result, generic_params }; +use macro_tools:: +{ + Result, + AttributePropertyOptionalSingletone, + AttributePropertyComponent, + diag, + generic_params, + ct, +}; +use former_types::{ Assign }; // -pub fn clone_dyn( _attr : proc_macro::TokenStream, item : proc_macro::TokenStream ) -> Result< proc_macro2::TokenStream > +pub fn clone_dyn( attr_input : proc_macro::TokenStream, item_input : proc_macro::TokenStream ) +-> Result< proc_macro2::TokenStream > { - let item_parsed = match syn::parse::< syn::ItemTrait >( item ) + let attrs = syn::parse::< ItemAttributes >( attr_input )?; + let original_input = item_input.clone(); + let mut item_parsed = match syn::parse::< syn::ItemTrait >( item_input ) { Ok( original ) => original, Err( err ) => return Err( err ), }; - let name_ident = &item_parsed.ident; + let has_debug = attrs.debug.value( false ); + let item_name = &item_parsed.ident; + + let ( _generics_with_defaults, generics_impl, generics_ty, generics_where ) + = generic_params::decompose( &item_parsed.generics ); - let generic_params = &item_parsed.generics.params; - let generics_where = &item_parsed.generics.where_clause; - let generics_names : Vec< _ > = generic_params::names( &item_parsed.generics ).collect(); + let extra : macro_tools::GenericsWithWhere = parse_quote! + { + where + Self : clone_dyn::CloneDyn, + }; + item_parsed.generics = generic_params::merge( &item_parsed.generics, &extra.into() ); let result = qt! { #item_parsed #[ allow( non_local_definitions ) ] - impl < 'c, #generic_params > Clone - for Box< dyn #name_ident< #( #generics_names ),* > + 'c > - // where + impl < 'c, #generics_impl > Clone + for Box< dyn #item_name< #generics_ty > + 'c > + where #generics_where { #[ inline ] - fn clone( &self ) -> Self { clone_dyn::_clone_boxed( &**self ) } + fn clone( &self ) -> Self { clone_dyn::clone_into_box( &**self ) } } #[ allow( non_local_definitions ) ] - impl < 'c, #generic_params > Clone - for Box< dyn #name_ident< #( #generics_names ),* > + Send + 'c > - // where + impl < 'c, #generics_impl > Clone + for Box< dyn #item_name< #generics_ty > + Send + 'c > + where #generics_where { #[ inline ] - fn clone( &self ) -> Self { clone_dyn::_clone_boxed( &**self ) } + fn clone( &self ) -> Self { clone_dyn::clone_into_box( &**self ) } } #[ allow( non_local_definitions ) ] - impl < 'c, #generic_params > Clone - for Box< dyn #name_ident< #( #generics_names ),* > + Sync + 'c > - // where + impl < 'c, #generics_impl > Clone + for Box< dyn #item_name< #generics_ty > + Sync + 'c > + where #generics_where { #[ inline ] - fn clone( &self ) -> Self { clone_dyn::_clone_boxed( &**self ) } + fn clone( &self ) -> Self { clone_dyn::clone_into_box( &**self ) } } #[ allow( non_local_definitions ) ] - impl < 'c, #generic_params > Clone - for Box< dyn #name_ident< #( #generics_names ),* > + Send + Sync + 'c > - // where + impl < 'c, #generics_impl > Clone + for Box< dyn #item_name< #generics_ty > + Send + Sync + 'c > + where #generics_where { #[ inline ] - fn clone( &self ) -> Self { clone_dyn::_clone_boxed( &**self ) } + fn clone( &self ) -> Self { clone_dyn::clone_into_box( &**self ) } } }; + if has_debug + { + let about = format!( "macro : CloneDny\ntrait : {item_name}" ); + diag::report_print( about, &original_input, &result ); + } + Ok( result ) } + +// == attributes + +/// Represents the attributes of a struct. Aggregates all its attributes. +#[ derive( Debug, Default ) ] +pub struct ItemAttributes +{ + /// Attribute for customizing generated code. + pub debug : AttributePropertyDebug, +} + +impl syn::parse::Parse for ItemAttributes +{ + fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self > + { + let mut result = Self::default(); + + let error = | ident : &syn::Ident | -> syn::Error + { + let known = ct::concatcp! + ( + "Known properties of attribute `clone_dyn` are : ", + AttributePropertyDebug::KEYWORD, + ".", + ); + syn_err! + ( + ident, + r#"Expects an attribute of format '#[ clone_dyn( {} ) ]' + {known} + But got: '{}' +"#, + AttributePropertyDebug::KEYWORD, + qt!{ #ident } + ) + }; + + while !input.is_empty() + { + let lookahead = input.lookahead1(); + if lookahead.peek( syn::Ident ) + { + let ident : syn::Ident = input.parse()?; + match ident.to_string().as_str() + { + AttributePropertyDebug::KEYWORD => result.assign( AttributePropertyDebug::from( true ) ), + _ => return Err( error( &ident ) ), + } + } + else + { + return Err( lookahead.error() ); + } + + // Optional comma handling + if input.peek( syn::Token![ , ] ) + { + input.parse::< syn::Token![ , ] >()?; + } + } + + Ok( result ) + } +} + +impl< IntoT > Assign< AttributePropertyDebug, IntoT > for ItemAttributes +where + IntoT : Into< AttributePropertyDebug >, +{ + #[ inline( always ) ] + fn assign( &mut self, prop : IntoT ) + { + self.debug = prop.into(); + } +} + +// == attribute properties + +/// Marker type for attribute property to specify whether to provide a generated code as a hint. +#[ derive( Debug, Default, Clone, Copy ) ] +pub struct AttributePropertyDebugMarker; + +impl AttributePropertyComponent for AttributePropertyDebugMarker +{ + const KEYWORD : &'static str = "debug"; +} + +/// Specifies whether to provide a generated code as a hint. +/// Defaults to `false`, which means no debug is provided unless explicitly requested. +pub type AttributePropertyDebug = AttributePropertyOptionalSingletone< AttributePropertyDebugMarker >; diff --git a/module/core/clone_dyn_meta/tests/smoke_test.rs b/module/core/clone_dyn_meta/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/core/clone_dyn_meta/tests/smoke_test.rs +++ b/module/core/clone_dyn_meta/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/core/clone_dyn_types/Cargo.toml b/module/core/clone_dyn_types/Cargo.toml new file mode 100644 index 0000000000..9c5db44b4a --- /dev/null +++ b/module/core/clone_dyn_types/Cargo.toml @@ -0,0 +1,36 @@ +[package] +name = "clone_dyn_types" +version = "0.22.0" +edition = "2021" +authors = [ + "Kostiantyn Wandalen ", +] +license = "MIT" +readme = "Readme.md" +documentation = "https://docs.rs/clone_dyn_types" +repository = "https://github.com/Wandalen/wTools/tree/master/module/core/clone_dyn_types" +homepage = "https://github.com/Wandalen/wTools/tree/master/module/core/clone_dyn_types" +description = """ +Derive to clone dyn structures. +""" +categories = [ "algorithms", "development-tools" ] +keywords = [ "fundamental", "general-purpose" ] + +[lints] +workspace = true + +[package.metadata.docs.rs] +features = [ "full" ] +all-features = false + +[features] + +default = [ "enabled" ] +full = [ "enabled" ] +enabled = [] + +[dependencies] + +[dev-dependencies] +test_tools = { workspace = true } +# inspect_type = { workspace = true, features = [ "full" ] } diff --git a/module/core/clone_dyn_types/License b/module/core/clone_dyn_types/License new file mode 100644 index 0000000000..6d5ef8559f --- /dev/null +++ b/module/core/clone_dyn_types/License @@ -0,0 +1,22 @@ +Copyright Kostiantyn W and Out of the Box Systems (c) 2013-2024 + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/module/core/clone_dyn_types/Readme.md b/module/core/clone_dyn_types/Readme.md new file mode 100644 index 0000000000..12cc1e5f46 --- /dev/null +++ b/module/core/clone_dyn_types/Readme.md @@ -0,0 +1,239 @@ + +# Module :: clone_dyn_types + + [![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) [![rust-status](https://github.com/Wandalen/wTools/actions/workflows/module_clone_dyn_push.yml/badge.svg)](https://github.com/Wandalen/wTools/actions/workflows/module_clone_dyn_push.yml) [![docs.rs](https://img.shields.io/docsrs/clone_dyn_types?color=e3e8f0&logo=docs.rs)](https://docs.rs/clone_dyn_types) [![Open in Gitpod](https://raster.shields.io/static/v1?label=try&message=online&color=eee&logo=gitpod&logoColor=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=module%2Fcore%2Fclone_dyn%2Fexamples%2Fclone_dyn_trivial.rs,RUN_POSTFIX=--example%20clone_dyn_trivial/https://github.com/Wandalen/wTools) [![discord](https://img.shields.io/discord/872391416519737405?color=eee&logo=discord&logoColor=eee&label=ask)](https://discord.gg/m3YfbXpUUY) + + +Derive to clone dyn structures. + +It's types, use `clone_dyn` to avoid bolerplate. + +By default, Rust does not support cloning for trait objects due to the `Clone` trait requiring compile-time knowledge of the type's size. The `clone_dyn` crate addresses this limitation through procedural macros, allowing for cloning collections of trait objects. Prefer to use `clone_dyn` instead of this crate, because `clone_dyn` includes this crate and also provides an attribute macro to generate boilerplate with one line of code. + +## Alternative + +There are few alternatives [dyn-clone](https://github.com/dtolnay/dyn-clone), [dyn-clonable](https://github.com/kardeiz/objekt-clonable). Unlike other options, this solution is more concise and demands less effort to use, all without compromising the quality of the outcome. + +## Basic use-case + +Demonstrates the usage of `clone_dyn` to enable cloning for trait objects. + +By default, Rust does not support cloning for trait objects due to the `Clone` trait +requiring compile-time knowledge of the type's size. The `clone_dyn` crate addresses +this limitation through procedural macros, allowing for cloning collections of trait objects +and crate `clone_dyn_types` contains implementation of all types. + +##### Overview + +This example shows how to use the `clone_dyn` crate to enable cloning for trait objects, +specifically for iterators. It defines a custom trait, `IterTrait`, that encapsulates +an iterator with specific characteristics and demonstrates how to use `CloneDyn` to +overcome the object safety constraints of the `Clone` trait. + +##### The `IterTrait` Trait + +The `IterTrait` trait is designed to represent iterators that yield references to items (`&'a T`). +These iterators must also implement the `ExactSizeIterator` and `DoubleEndedIterator` traits. +Additionally, the iterator must implement the `CloneDyn` trait, which allows cloning of trait objects. + +The trait is implemented for any type that meets the specified requirements. + +##### Cloning Trait Objects + +Rust's type system does not allow trait objects to implement the `Clone` trait directly due to object safety constraints. +Specifically, the `Clone` trait requires knowledge of the concrete type at compile time, which is not available for trait objects. + +The `CloneDyn` trait from the `clone_dyn_types` crate provides a workaround for this limitation by allowing trait objects to be cloned. + +The example demonstrates how to implement `Clone` for boxed `IterTrait` trait objects. + +##### `get_iter` Function + +The `get_iter` function returns a boxed iterator that implements the `IterTrait` trait. +If the input is `Some`, it returns an iterator over the vector. +If the input is `None`, it returns an empty iterator. + +It's not possible to use `impl Iterator` here because the code returns iterators of two different types: +- `std::slice::Iter` when the input is `Some`. +- `std::iter::Empty` when the input is `None`. + +To handle this, the function returns a trait object ( `Box< dyn IterTrait >` ). +However, Rust's `Clone` trait cannot be implemented for trait objects due to object safety constraints. +The `CloneDyn` trait addresses this problem by enabling cloning of trait objects. + +##### `use_iter` Function + +The `use_iter` function demonstrates the use of the `CloneDyn` trait by cloning the iterator. +It then iterates over the cloned iterator and prints each element. + +##### Main Function + +The main function demonstrates the overall usage by creating a vector, obtaining an iterator, and using the iterator to print elements. + +```rust + +#[ cfg( not( feature = "enabled" ) ) ] +fn main() {} +#[ cfg( feature = "enabled" ) ] +fn main() +{ + use clone_dyn_types::CloneDyn; + + /// Trait that encapsulates an iterator with specific characteristics, tailored for your needs. + pub trait IterTrait< 'a, T > + where + T : 'a, + Self : Iterator< Item = T > + ExactSizeIterator< Item = T > + DoubleEndedIterator, + Self : CloneDyn, + { + } + + impl< 'a, T, I > IterTrait< 'a, T > for I + where + T : 'a, + Self : Iterator< Item = T > + ExactSizeIterator< Item = T > + DoubleEndedIterator, + Self : CloneDyn, + { + } + + // Implement `Clone` for boxed `IterTrait` trait objects. + impl< 'c, T > Clone for Box< dyn IterTrait< 'c, T > + 'c > + { + #[ inline ] + fn clone( &self ) -> Self + { + clone_dyn_types::clone_into_box( &**self ) + } + } + + /// + /// Function to get an iterator over a vector of integers. + /// + /// This function returns a boxed iterator that implements the `IterTrait` trait. + /// If the input is `Some`, it returns an iterator over the vector. + /// If the input is `None`, it returns an empty iterator. + /// + /// Rust's type system does not allow trait objects to implement the `Clone` trait directly due to object safety constraints. + /// Specifically, the `Clone` trait requires knowledge of the concrete type at compile time, which is not available for trait objects. + /// + /// In this example, we need to return an iterator that can be cloned. Since we are returning a trait object ( `Box< dyn IterTrait >` ), + /// we cannot directly implement `Clone` for this trait object. This is where the `CloneDyn` trait from the `clone_dyn_types` crate comes in handy. + /// + /// The `CloneDyn` trait provides a workaround for this limitation by allowing trait objects to be cloned. + /// It uses procedural macros to generate the necessary code for cloning trait objects, making it possible to clone collections of trait objects. + /// + /// It's not possible to use `impl Iterator` here because the code returns iterators of two different types: + /// - `std::slice::Iter` when the input is `Some`. + /// - `std::iter::Empty` when the input is `None`. + /// + /// To handle this, the function returns a trait object (`Box`). + /// However, Rust's `Clone` trait cannot be implemented for trait objects due to object safety constraints. + /// The `CloneDyn` trait addresses this problem by enabling cloning of trait objects. + /// + + pub fn get_iter< 'a >( src : Option< &'a Vec< i32 > > ) -> Box< dyn IterTrait< 'a, &'a i32 > + 'a > + { + match &src + { + Some( src ) => Box::new( src.iter() ), + _ => Box::new( core::iter::empty() ), + } + } + + /// Function to use an iterator and print its elements. + /// + /// This function demonstrates the use of the `CloneDyn` trait by cloning the iterator. + /// It then iterates over the cloned iterator and prints each element. + pub fn use_iter< 'a >( iter : Box< dyn IterTrait< 'a, &'a i32 > + 'a > ) + { + // Clone would not be available if CloneDyn is not implemented for the iterator. + // And being an object-safe trait, it can't implement Clone. + // Nevertheless, thanks to CloneDyn, the object is clonable. + // + // This line demonstrates cloning the iterator and iterating over the cloned iterator. + // Without `CloneDyn`, you would need to collect the iterator into a container, allocating memory on the heap. + iter.clone().for_each( | e | println!( "{e}" ) ); + + // Iterate over the original iterator and print each element. + iter.for_each( | e | println!( "{e}" ) ); + } + + // Create a vector of integers. + let data = vec![ 1, 2, 3 ]; + // Get an iterator over the vector. + let iter = get_iter( Some( &data ) ); + // Use the iterator to print its elements. + use_iter( iter ); + +} +``` + +
+If you use multithreading or asynchronous paradigms implement trait `Clone` also for `Send` and `Sync` + +```rust, ignore + +#[ allow( non_local_definitions ) ] +impl< 'c, T > Clone for Box< dyn IterTrait< 'c, T > + 'c > +{ + #[ inline ] + fn clone( &self ) -> Self + { + clone_dyn_types::clone_into_box( &**self ) + } +} + +#[ allow( non_local_definitions ) ] +impl< 'c, T > Clone for Box< dyn IterTrait< 'c, T > + Send + 'c > +{ + #[ inline ] + fn clone( &self ) -> Self + { + clone_dyn_types::clone_into_box( &**self ) + } +} + +#[ allow( non_local_definitions ) ] +impl< 'c, T > Clone for Box< dyn IterTrait< 'c, T > + Sync + 'c > +{ + #[ inline ] + fn clone( &self ) -> Self + { + clone_dyn_types::clone_into_box( &**self ) + } +} + +#[ allow( non_local_definitions ) ] +impl< 'c, T > Clone for Box< dyn IterTrait< 'c, T > + Send + Sync + 'c > +{ + #[ inline ] + fn clone( &self ) -> Self + { + clone_dyn_types::clone_into_box( &**self ) + } +} + +``` + +
+ +
+ +Try out `cargo run --example clone_dyn_types_trivial`. +
+[See code](./examples/clone_dyn_types_trivial.rs). + +## To add to your project + +```sh +cargo add clone_dyn_types +``` + +## Try out from the repository + +```sh +git clone https://github.com/Wandalen/wTools +cd wTools +cd examples/clone_dyn_types_trivial +cargo run +``` diff --git a/module/core/clone_dyn_types/examples/clone_dyn_types_trivial.rs b/module/core/clone_dyn_types/examples/clone_dyn_types_trivial.rs new file mode 100644 index 0000000000..055864e8e5 --- /dev/null +++ b/module/core/clone_dyn_types/examples/clone_dyn_types_trivial.rs @@ -0,0 +1,151 @@ +//! +//! ## Basic use-case +//! +//! Demonstrates the usage of `clone_dyn` to enable cloning for trait objects. +//! +//! By default, Rust does not support cloning for trait objects due to the `Clone` trait +//! requiring compile-time knowledge of the type's size. The `clone_dyn` crate addresses +//! this limitation through procedural macros, allowing for cloning collections of trait objects +//! and crate `clone_dyn_types` contains implementation of all types. +//! +//! ##### Overview +//! +//! This example shows how to use the `clone_dyn` crate to enable cloning for trait objects, +//! specifically for iterators. It defines a custom trait, `IterTrait`, that encapsulates +//! an iterator with specific characteristics and demonstrates how to use `CloneDyn` to +//! overcome the object safety constraints of the `Clone` trait. +//! +//! ##### The `IterTrait` Trait +//! +//! The `IterTrait` trait is designed to represent iterators that yield references to items (`&'a T`). +//! These iterators must also implement the `ExactSizeIterator` and `DoubleEndedIterator` traits. +//! Additionally, the iterator must implement the `CloneDyn` trait, which allows cloning of trait objects. +//! +//! The trait is implemented for any type that meets the specified requirements. +//! +//! ##### Cloning Trait Objects +//! +//! Rust's type system does not allow trait objects to implement the `Clone` trait directly due to object safety constraints. +//! Specifically, the `Clone` trait requires knowledge of the concrete type at compile time, which is not available for trait objects. +//! +//! The `CloneDyn` trait from the `clone_dyn_types` crate provides a workaround for this limitation by allowing trait objects to be cloned. +//! +//! The example demonstrates how to implement `Clone` for boxed `IterTrait` trait objects. +//! +//! ##### `get_iter` Function +//! +//! The `get_iter` function returns a boxed iterator that implements the `IterTrait` trait. +//! If the input is `Some`, it returns an iterator over the vector. +//! If the input is `None`, it returns an empty iterator. +//! +//! It's not possible to use `impl Iterator` here because the code returns iterators of two different types: +//! - `std::slice::Iter` when the input is `Some`. +//! - `std::iter::Empty` when the input is `None`. +//! +//! To handle this, the function returns a trait object ( `Box< dyn IterTrait >` ). +//! However, Rust's `Clone` trait cannot be implemented for trait objects due to object safety constraints. +//! The `CloneDyn` trait addresses this problem by enabling cloning of trait objects. +//! +//! ##### `use_iter` Function +//! +//! The `use_iter` function demonstrates the use of the `CloneDyn` trait by cloning the iterator. +//! It then iterates over the cloned iterator and prints each element. +//! +//! ##### Main Function +//! +//! The main function demonstrates the overall usage by creating a vector, obtaining an iterator, and using the iterator to print elements. +//! + +#[ cfg( not( feature = "enabled" ) ) ] +fn main() {} +#[ cfg( feature = "enabled" ) ] +fn main() +{ + use clone_dyn_types::CloneDyn; + + /// Trait that encapsulates an iterator with specific characteristics, tailored for your needs. + pub trait IterTrait< 'a, T > + where + T : 'a, + Self : Iterator< Item = T > + ExactSizeIterator< Item = T > + DoubleEndedIterator, + Self : CloneDyn, + { + } + + impl< 'a, T, I > IterTrait< 'a, T > for I + where + T : 'a, + Self : Iterator< Item = T > + ExactSizeIterator< Item = T > + DoubleEndedIterator, + Self : CloneDyn, + { + } + + // Implement `Clone` for boxed `IterTrait` trait objects. + #[ allow( non_local_definitions ) ] + impl< 'c, T > Clone for Box< dyn IterTrait< 'c, T > + 'c > + { + #[ inline ] + fn clone( &self ) -> Self + { + clone_dyn_types::clone_into_box( &**self ) + } + } + + /// + /// Function to get an iterator over a vector of integers. + /// + /// This function returns a boxed iterator that implements the `IterTrait` trait. + /// If the input is `Some`, it returns an iterator over the vector. + /// If the input is `None`, it returns an empty iterator. + /// + /// Rust's type system does not allow trait objects to implement the `Clone` trait directly due to object safety constraints. + /// Specifically, the `Clone` trait requires knowledge of the concrete type at compile time, which is not available for trait objects. + /// + /// In this example, we need to return an iterator that can be cloned. Since we are returning a trait object ( `Box< dyn IterTrait >` ), + /// we cannot directly implement `Clone` for this trait object. This is where the `CloneDyn` trait from the `clone_dyn_types` crate comes in handy. + /// + /// The `CloneDyn` trait provides a workaround for this limitation by allowing trait objects to be cloned. + /// + /// It's not possible to use `impl Iterator` here because the code returns iterators of two different types: + /// - `std::slice::Iter` when the input is `Some`. + /// - `std::iter::Empty` when the input is `None`. + /// + /// To handle this, the function returns a trait object (`Box`). + /// However, Rust's `Clone` trait cannot be implemented for trait objects due to object safety constraints. + /// The `CloneDyn` trait addresses this problem by enabling cloning of trait objects. + + pub fn get_iter< 'a >( src : Option< &'a Vec< i32 > > ) -> Box< dyn IterTrait< 'a, &'a i32 > + 'a > + { + match &src + { + Some( src ) => Box::new( src.iter() ), + _ => Box::new( core::iter::empty() ), + } + } + + /// Function to use an iterator and print its elements. + /// + /// This function demonstrates the use of the `CloneDyn` trait by cloning the iterator. + /// It then iterates over the cloned iterator and prints each element. + pub fn use_iter< 'a >( iter : Box< dyn IterTrait< 'a, &'a i32 > + 'a > ) + { + // Clone would not be available if CloneDyn is not implemented for the iterator. + // And being an object-safe trait, it can't implement Clone. + // Nevertheless, thanks to CloneDyn, the object is clonable. + // + // This line demonstrates cloning the iterator and iterating over the cloned iterator. + // Without `CloneDyn`, you would need to collect the iterator into a container, allocating memory on the heap. + iter.clone().for_each( | e | println!( "{e}" ) ); + + // Iterate over the original iterator and print each element. + iter.for_each( | e | println!( "{e}" ) ); + } + + // Create a vector of integers. + let data = vec![ 1, 2, 3 ]; + // Get an iterator over the vector. + let iter = get_iter( Some( &data ) ); + // Use the iterator to print its elements. + use_iter( iter ); + +} diff --git a/module/core/clone_dyn_types/src/lib.rs b/module/core/clone_dyn_types/src/lib.rs new file mode 100644 index 0000000000..179098432a --- /dev/null +++ b/module/core/clone_dyn_types/src/lib.rs @@ -0,0 +1,262 @@ +#![ no_std ] +#![ 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/clone_dyn_types/latest/clone_dyn_types/" ) ] +#![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/", "Readme.md" ) ) ] + +/// Namespace with dependencies. +#[ cfg( feature = "enabled" ) ] +pub mod dependency +{ +} + +/// Internal namespace. +// #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] +#[ cfg( feature = "enabled" ) ] +pub( crate ) mod private +{ + + // xxx : ? + // #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] + extern crate alloc; + // #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] + // #[ allow( unused_imports ) ] + use alloc::boxed::Box; + // #[ cfg( all( feature = "use_std", not( feature = "use_alloc" ) ) ) ] + // use std::boxed::Box; + + /// A trait to upcast a clonable entity and clone it. + /// It's implemented for all entities which can be cloned. + pub trait CloneDyn : Sealed + { + #[ doc( hidden ) ] + fn __clone_dyn( &self, _ : DontCallMe ) -> *mut (); + } + + // clonable + impl< T > CloneDyn for T + where + T : Clone, + { + #[ inline ] + fn __clone_dyn( &self, _ : DontCallMe ) -> *mut () + { + Box::< T >::into_raw( Box::new( self.clone() ) ) as *mut () + } + } + + // slice + impl< T > CloneDyn for [ T ] + where + T : Clone, + { + #[ inline ] + fn __clone_dyn( &self, _ : DontCallMe ) -> *mut () + { + Box::< [ T ] >::into_raw( self.iter().cloned().collect() ) as *mut () + } + } + + // str slice + impl CloneDyn for str + { + #[ inline ] + fn __clone_dyn( &self, _ : DontCallMe ) -> *mut () + { + Box::< str >::into_raw( Box::from( self ) ) as *mut () + } + } + + /// + /// True clone which is applicable not only to clonable entities, but to trait objects implementing CloneDyn. + /// + /// # Example + /// + /// ``` + /// use clone_dyn_types::clone; + /// + /// #[ derive( Clone ) ] + /// struct MyStruct + /// { + /// value : i32, + /// } + /// + /// let original = MyStruct { value : 42 }; + /// let cloned = clone( &original ); + /// + /// assert_eq!( original.value, cloned.value ); + /// ``` + + #[ inline ] + pub fn clone< T >( src : &T ) -> T + where + T : CloneDyn, + { + // # Safety + // + // This function uses an `unsafe` block because it performs low-level memory manipulations. Specifically, it handles + // raw pointers and converts them to and from `Box< T >`. This is necessary to dynamically clone a trait object, which + // does not support cloning through the standard `Clone` trait. The safety of this function depends on the guarantee + // that the `CloneDyn` trait is correctly implemented for the given type `T`, ensuring that `__clone_dyn` returns a + // valid pointer to a cloned instance of `T`. + // + #[ allow( unsafe_code ) ] + unsafe + { + *Box::from_raw( < T as CloneDyn >::__clone_dyn( src, DontCallMe ) as *mut T ) + } + } + + /// + /// Clone boxed dyn. + /// + /// Clones a dynamically sized trait object into a `Box< T >`. + /// + /// # Example + /// + /// ``` + /// use clone_dyn_types::{ CloneDyn, clone_into_box }; + /// + /// #[ derive( Clone ) ] + /// struct MyStruct + /// { + /// value : i32, + /// } + /// + /// trait MyTrait : CloneDyn + /// { + /// fn val( &self ) -> i32; + /// } + /// + /// impl MyTrait for MyStruct + /// { + /// fn val( &self ) -> i32 + /// { + /// self.value + /// } + /// } + /// + /// #[ allow( non_local_definitions ) ] + /// impl < 'c > Clone + /// for Box< dyn MyTrait + 'c > + /// { + /// #[ inline ] + /// fn clone( &self ) -> Self { clone_into_box( &**self ) } + /// } + /// + /// #[ allow( non_local_definitions ) ] + /// impl < 'c > Clone + /// for Box< dyn MyTrait + Send + 'c > + /// { + /// #[ inline ] + /// fn clone( &self ) -> Self { clone_into_box( &**self ) } + /// } + /// + /// #[ allow( non_local_definitions ) ] + /// impl < 'c > Clone + /// for Box< dyn MyTrait + Sync + 'c > + /// { + /// #[ inline ] + /// fn clone( &self ) -> Self { clone_into_box( &**self ) } + /// } + /// + /// #[ allow( non_local_definitions ) ] + /// impl < 'c > Clone + /// for Box< dyn MyTrait + Send + Sync + 'c > + /// { + /// #[ inline ] + /// fn clone( &self ) -> Self { clone_into_box( &**self ) } + /// } + /// + /// let cloned : Box< dyn MyTrait > = clone_into_box( &MyStruct { value : 42 } ); + /// + /// ``` + + #[ inline ] + pub fn clone_into_box< T >( ref_dyn : &T ) -> Box< T > + where + T : ?Sized + CloneDyn, + { + // # Safety + // + // This function uses an `unsafe` block because it performs low-level memory manipulations involving raw pointers. + // The `unsafe` block is necessary here because we're manually handling raw pointers and converting them to and from + // `Box`. This bypasses Rust's ownership and borrowing rules to achieve dynamic cloning of a boxed trait object. + // The safety of this function relies on the correct implementation of the `CloneDyn` trait for the given type `T`. + // Specifically, `__clone_dyn` must return a valid pointer to a cloned instance of `T`. + // + #[ allow( unsafe_code ) ] + unsafe + { + let mut ptr = ref_dyn as *const T; + let data_ptr = &mut ptr as *mut *const T as *mut *mut (); + *data_ptr = < T as CloneDyn >::__clone_dyn( ref_dyn, DontCallMe ); + Box::from_raw( ptr as *mut T ) + } + } + + #[ doc( hidden ) ] + mod sealed + { + #[ doc( hidden ) ] + #[ allow( missing_debug_implementations ) ] + pub struct DontCallMe; + #[ doc( hidden ) ] + pub trait Sealed {} + impl< T : Clone > Sealed for T {} + impl< T : Clone > Sealed for [ T ] {} + impl Sealed for str {} + } + use sealed::*; + +} + +#[ cfg( feature = "enabled" ) ] +#[ doc( inline ) ] +#[ allow( unused_imports ) ] +pub use own::*; + +/// Own namespace of the module. +#[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] +pub mod own +{ + use super::*; + #[ doc( inline ) ] + pub use orphan::*; +} + +/// Orphan namespace of the module. +#[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] +pub mod orphan +{ + use super::*; + #[ doc( inline ) ] + pub use exposed::*; +} + +/// Exposed namespace of the module. +#[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] +pub mod exposed +{ + use super::*; + #[ doc( inline ) ] + pub use prelude::*; +} + +/// Prelude to use essentials: `use my_module::prelude::*`. +#[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] +pub mod prelude +{ + use super::*; + #[ doc( inline ) ] + pub use private:: + { + CloneDyn, + clone_into_box, + clone, + }; +} diff --git a/module/core/clone_dyn_types/tests/inc/mod.rs b/module/core/clone_dyn_types/tests/inc/mod.rs new file mode 100644 index 0000000000..c5bda8ed18 --- /dev/null +++ b/module/core/clone_dyn_types/tests/inc/mod.rs @@ -0,0 +1,15 @@ + +#[ allow( unused_imports ) ] +use super::*; + +#[ path = "../../../clone_dyn/tests/inc" ] +mod tests +{ + #[ allow( unused_imports ) ] + use super::*; + + mod basic_manual; + // mod basic; + // mod parametrized; + +} diff --git a/module/core/clone_dyn_types/tests/smoke_test.rs b/module/core/clone_dyn_types/tests/smoke_test.rs new file mode 100644 index 0000000000..828e9b016b --- /dev/null +++ b/module/core/clone_dyn_types/tests/smoke_test.rs @@ -0,0 +1,14 @@ + + +#[ test ] +fn local_smoke_test() +{ + ::test_tools::smoke_test_for_local_run(); +} + + +#[ test ] +fn published_smoke_test() +{ + ::test_tools::smoke_test_for_published_run(); +} diff --git a/module/core/clone_dyn_types/tests/tests.rs b/module/core/clone_dyn_types/tests/tests.rs new file mode 100644 index 0000000000..e2210e22b4 --- /dev/null +++ b/module/core/clone_dyn_types/tests/tests.rs @@ -0,0 +1,8 @@ + +#[ allow( unused_imports ) ] +use clone_dyn_types as the_module; +#[ allow( unused_imports ) ] +use test_tools::exposed::*; + +#[ cfg( all( feature = "enabled", any( not( feature = "no_std" ), feature = "use_alloc" ) ) ) ] +mod inc; diff --git a/module/core/collection_tools/Cargo.toml b/module/core/collection_tools/Cargo.toml index 65a81d7cde..303edaa2df 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.8.0" +version = "0.11.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", diff --git a/module/core/collection_tools/Readme.md b/module/core/collection_tools/Readme.md index 1fed2e48ad..39073acc98 100644 --- a/module/core/collection_tools/Readme.md +++ b/module/core/collection_tools/Readme.md @@ -75,7 +75,7 @@ When implementing a `no_std` environment with the `use_alloc` feature in your Ru You can do - + ```rust # #[ cfg( feature = "enabled" ) ] # #[ cfg( any( feature = "use_alloc", not( feature = "no_std" ) ) ) ] diff --git a/module/core/collection_tools/examples/collection_tools_trivial.rs b/module/core/collection_tools/examples/collection_tools_trivial.rs index b817a50c84..8a11bb85bf 100644 --- a/module/core/collection_tools/examples/collection_tools_trivial.rs +++ b/module/core/collection_tools/examples/collection_tools_trivial.rs @@ -27,7 +27,7 @@ )))] fn main(){} -// zzz : aaa : rid off `#[ cfg( not( feature = "use_alloc" ) ) ]` -- Rid of by not relying on std +// zzz : aaa : rid of `#[ cfg( not( feature = "use_alloc" ) ) ]` -- Rid of by not relying on std // #[ cfg( not( feature = "use_alloc" ) ) ] #[ cfg( all( feature = "enabled", feature = "collection_constructors" ) ) ] #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] diff --git a/module/core/collection_tools/src/collections.rs b/module/core/collection_tools/src/collections.rs index 090cf82267..71505ac8fa 100644 --- a/module/core/collection_tools/src/collections.rs +++ b/module/core/collection_tools/src/collections.rs @@ -14,19 +14,19 @@ macro_rules! count ); } -/// [BTreeMap] macros +/// [std::collections::BTreeMap] macros pub mod bmap; -/// [BTreeSet] macros +/// [std::collections::BTreeSet] macros pub mod bset; -/// [BinaryHeap] macros +/// [std::collections::BinaryHeap] macros pub mod heap; -/// [HashMap] macros +/// [std::collections::HashMap] macros pub mod hmap; -/// [HashSet] macros +/// [std::collections::HashSet] macros pub mod hset; -/// [LinkedList] macros +/// [std::collections::LinkedList] macros pub mod list; /// [Vec] macros pub mod vec; -/// [VecDeque] macros +/// [std::collections::VecDeque] macros pub mod vecd; diff --git a/module/core/collection_tools/src/lib.rs b/module/core/collection_tools/src/lib.rs index 6171c0e365..3dd0258b00 100644 --- a/module/core/collection_tools/src/lib.rs +++ b/module/core/collection_tools/src/lib.rs @@ -29,36 +29,39 @@ pub mod dependency #[ doc( inline ) ] #[ allow( unused_imports ) ] #[ cfg( feature = "enabled" ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. +/// Own namespace of the module. #[ cfg( feature = "enabled" ) ] -pub mod protected +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } /// Parented namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; // #[ cfg( feature = "reexports" ) ] #[ cfg( any( feature = "use_alloc", not( feature = "no_std" ) ) ) ] @@ -93,6 +96,8 @@ pub mod exposed /// Prelude to use essentials: `use my_module::prelude::*`. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; } diff --git a/module/core/collection_tools/tests/smoke_test.rs b/module/core/collection_tools/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/core/collection_tools/tests/smoke_test.rs +++ b/module/core/collection_tools/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/core/data_type/Cargo.toml b/module/core/data_type/Cargo.toml index cbb30c67f3..2da324b145 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.7.0" +version = "0.8.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", @@ -34,7 +34,7 @@ default = [ "dt_either", "dt_prelude", "dt_interval", - "dt_collections", + "dt_collection", # "dt_make", # "dt_vectorized_from", # "type_constructor/default", @@ -45,7 +45,7 @@ full = [ "dt_either", "dt_prelude", "dt_interval", - "dt_collections", + "dt_collection", # "dt_make", # "dt_vectorized_from", # "type_constructor/full", @@ -55,9 +55,9 @@ use_alloc = [ "no_std" ] enabled = [] # dt_prelude = [ "collection_tools/reexports" ] -dt_prelude = [] # rid off maybe? +dt_prelude = [] # rid of maybe? dt_interval = [ "interval_adapter/enabled" ] -dt_collections = [ "collection_tools/enabled" ] +dt_collection = [ "collection_tools/enabled" ] dt_either = [ "either" ] # qqq : for Anton : integrate all features of collection_tools into data_type and reuse tests diff --git a/module/core/data_type/Readme.md b/module/core/data_type/Readme.md index 1fccd8d0c7..62c1031498 100644 --- a/module/core/data_type/Readme.md +++ b/module/core/data_type/Readme.md @@ -19,28 +19,12 @@ Macro [types](https://docs.rs/type_constructor/latest/type_constructor/types/mac ```rust -#[ cfg( feature = "type_constructor" ) ] +#[ cfg( feature = "enabled" ) ] { use data_type::prelude::*; - types! - { - pub single MySingle : f32; - pub single SingleWithParametrized : std::sync::Arc< T : Copy >; - pub single SingleWithParameter : < T >; - - pub pair MyPair : f32; - pub pair PairWithParametrized : std::sync::Arc< T1 : Copy >, std::sync::Arc< T2 : Copy >; - pub pair PairWithParameter : < T1, T2 >; + // qqq : xxx : write please - pub pair MyHomoPair : f32; - pub pair HomoPairWithParametrized : std::sync::Arc< T : Copy >; - pub pair HomoPairWithParameter : < T >; - - pub many MyMany : f32; - pub many ManyWithParametrized : std::sync::Arc< T : Copy >; - pub many ManyWithParameter : < T >; - } } ``` diff --git a/module/core/data_type/examples/data_type_trivial.rs b/module/core/data_type/examples/data_type_trivial.rs index d3c8b6b8ab..d5a50f0d81 100644 --- a/module/core/data_type/examples/data_type_trivial.rs +++ b/module/core/data_type/examples/data_type_trivial.rs @@ -1,32 +1,6 @@ -//! In Rust, you often need to wrap a given type into a new one. -//! The role of the orphan rules in particular is basically to prevent you from implementing external traits for external types. -//! To overcome the restriction developer usually wrap the external type into a tuple introducing a new type. -//! Type constructor does exactly that and auto-implement traits From, Into, Deref and few more for the constructed type. -//! -//! Macro [types](https://docs.rs/type_constructor/latest/type_constructor/types/macro.types.html) is responsible for generating code for Single, Pair, Homopair, Many. Each type constructor has its own keyword for that, but Pair and Homopair use the same keyword difference in a number of constituent types. It is possible to define all types at once. +// qqq : xxx : write please + +#[ cfg( feature = "enabled" ) ] fn main() { - #[ cfg( feature = "type_constructor" ) ] - { - use data_type::prelude::*; - - types! - { - pub single MySingle : f32; - pub single SingleWithParametrized : std::sync::Arc< T : Copy >; - pub single SingleWithParameter : < T >; - - pub pair MyPair : f32; - pub pair PairWithParametrized : std::sync::Arc< T1 : Copy >, std::sync::Arc< T2 : Copy >; - pub pair PairWithParameter : < T1, T2 >; - - pub pair MyHomoPair : f32; - pub pair HomoPairWithParametrized : std::sync::Arc< T : Copy >; - pub pair HomoPairWithParameter : < T >; - - pub many MyMany : f32; - pub many ManyWithParametrized : std::sync::Arc< T : Copy >; - pub many ManyWithParameter : < T >; - } - } } diff --git a/module/core/data_type/src/dt.rs b/module/core/data_type/src/dt.rs index 9fb884985f..b720f66635 100644 --- a/module/core/data_type/src/dt.rs +++ b/module/core/data_type/src/dt.rs @@ -5,31 +5,34 @@ pub( crate ) mod private #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } /// Shared with parent namespace of the module +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ cfg( feature = "either" ) ] #[ doc( inline ) ] @@ -54,8 +57,10 @@ pub mod exposed } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; // #[ cfg( feature = "either" ) ] // pub use ::either::*; diff --git a/module/core/data_type/src/lib.rs b/module/core/data_type/src/lib.rs index 2ee15e40a1..b3e29a54ff 100644 --- a/module/core/data_type/src/lib.rs +++ b/module/core/data_type/src/lib.rs @@ -18,7 +18,7 @@ pub mod dependency #[ cfg( feature = "either" ) ] pub use ::either; // #[ cfg( feature = "type_constructor" ) ] - // pub use ::type_constructor; // xxx : rid off + // pub use ::type_constructor; // xxx : rid of #[ cfg( feature = "dt_interval" ) ] pub use ::interval_adapter; #[ cfg( feature = "dt_collection" ) ] @@ -27,34 +27,37 @@ pub mod dependency #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::dt::orphan::*; } /// Shared with parent namespace of the module +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] @@ -73,8 +76,10 @@ pub mod exposed } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] diff --git a/module/core/data_type/tests/inc/mod.rs b/module/core/data_type/tests/inc/mod.rs index ae7aa08f8a..6b003b16c5 100644 --- a/module/core/data_type/tests/inc/mod.rs +++ b/module/core/data_type/tests/inc/mod.rs @@ -9,6 +9,6 @@ mod either_test; // #[ path = "../../../../core/type_constructor/tests/inc/mod.rs" ] // mod type_constructor; -#[ cfg( any( feature = "interval", feature = "dt_interval" ) ) ] +#[ cfg( any( feature = "dt_interval" ) ) ] #[ path = "../../../../core/interval_adapter/tests/inc/mod.rs" ] mod interval_test; diff --git a/module/core/data_type/tests/smoke_test.rs b/module/core/data_type/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/core/data_type/tests/smoke_test.rs +++ b/module/core/data_type/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/core/data_type/tests/tests.rs b/module/core/data_type/tests/tests.rs index 26896b6193..479a7e5268 100644 --- a/module/core/data_type/tests/tests.rs +++ b/module/core/data_type/tests/tests.rs @@ -1,8 +1,4 @@ -// #![ deny( rust_2018_idioms ) ] -// #![ deny( missing_debug_implementations ) ] -// #![ deny( missing_docs ) ] - -// #![ feature( trace_macros ) ] +#![ cfg_attr( feature = "no_std", no_std ) ] #[ allow( unused_imports ) ] use data_type as the_module; diff --git a/module/core/derive_tools/Cargo.toml b/module/core/derive_tools/Cargo.toml index 3f2b08fe4b..4cd1f0d639 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.24.0" +version = "0.26.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", @@ -17,13 +17,16 @@ A collection of derive macros designed to enhance STD. categories = [ "algorithms", "development-tools" ] keywords = [ "fundamental", "general-purpose" ] + [lints] workspace = true + [package.metadata.docs.rs] features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] + + [features] @@ -55,6 +58,7 @@ default = [ "derive_is_variant", "derive_unwrap", # "derive_convert_case", + "derive_into", "derive_display", "derive_from_str", @@ -69,6 +73,8 @@ default = [ "derive_inner_from", "derive_new", + "derive_phantom", + # "use_std", ] @@ -114,10 +120,12 @@ full = [ "derive_inner_from", "derive_new", + "derive_phantom", + # "use_std", ] no_std = [] -use_alloc = [ "no_std", "clone_dyn/use_alloc" ] +use_alloc = [ "no_std" ] enabled = [ "derive_tools_meta/enabled" ] # nightly = [ "derive_more/nightly" ] @@ -143,14 +151,14 @@ derive_error = [ "derive_more", "derive_more/std", "derive_more/error" ] # derive_from = [ "derive_tools_meta/derive_from" ] # derive_reflect = [ "derive_tools_meta/derive_reflect" ] -derive_index = [ "derive_more", "derive_more/std", "derive_more/index" ] -derive_index_mut = [ "derive_more", "derive_more/std", "derive_more/index_mut" ] +# derive_index = [ "derive_more", "derive_more/std", "derive_more/index" ] +# derive_index_mut = [ "derive_more", "derive_more/std", "derive_more/index_mut" ] # derive_inner_from = [ "derive_more", "derive_more/into" ] derive_into_iterator = [ "derive_more", "derive_more/std", "derive_more/into_iterator" ] # derive_iterator = [ "derive_more", "derive_more/iterator" ] +derive_into = [ "derive_more", "derive_more/into" ] derive_mul_assign = [ "derive_more", "derive_more/std", "derive_more/mul_assign" ] derive_mul = [ "derive_more", "derive_more/std", "derive_more/mul" ] -derive_not = [ "derive_more", "derive_more/std", "derive_more/not" ] derive_sum = [ "derive_more", "derive_more/std", "derive_more/sum" ] derive_try_into = [ "derive_more", "derive_more/std", "derive_more/try_into" ] derive_is_variant = [ "derive_more", "derive_more/is_variant" ] @@ -163,7 +171,7 @@ derive_from_str = [ "parse-display", "parse-display/std", "parse-display/regex" derive_strum = [ "strum/std", "strum/derive", "strum/strum_macros" ] strum_phf = [ "strum/std", "strum/phf", "strum/strum_macros" ] -# zzz : review features +# zzz : qqq : review features derive_clone_dyn = [ "clone_dyn/enabled" ] # derive_clone_dyn_use_std = [ "derive_clone_dyn", "clone_dyn/use_std" ] @@ -171,11 +179,18 @@ derive_clone_dyn = [ "clone_dyn/enabled" ] # derive_clone_dyn_use_alloc = [ "derive_clone_dyn", "clone_dyn/use_alloc" ] derive_from = [ "derive_tools_meta/derive_from" ] +derive_index = [ "derive_tools_meta/derive_index" ] +derive_index_mut = [ "derive_tools_meta/derive_index_mut" ] derive_inner_from = [ "derive_tools_meta/derive_inner_from" ] derive_new = [ "derive_tools_meta/derive_new" ] +derive_not = [ "derive_tools_meta/derive_not" ] + +derive_phantom = [ "derive_tools_meta/derive_phantom" ] + parse_display = [ "parse-display" ] + [dependencies] ## external @@ -186,9 +201,10 @@ parse-display = { version = "~0.8.2", optional = true, default-features = false ## internal -derive_tools_meta = { workspace = true, features = [] } -variadic_from = { workspace = true, features = [] } -clone_dyn = { workspace = true, features = [] } +derive_tools_meta = { workspace = true, optional = true, features = [] } +variadic_from = { workspace = true, optional = true, features = [] } +clone_dyn = { workspace = true, optional = true, features = [ "clone_dyn_types", "clone_dyn_meta" ] } + [dev-dependencies] test_tools = { workspace = true } diff --git a/module/core/derive_tools/build.rs b/module/core/derive_tools/build.rs index bfce7f82f0..4830e0b7f8 100644 --- a/module/core/derive_tools/build.rs +++ b/module/core/derive_tools/build.rs @@ -21,9 +21,13 @@ fn main() feature = "derive_deref", feature = "derive_deref_mut", feature = "derive_from", + feature = "derive_index", + feature = "derive_index_mut", feature = "derive_inner_from", feature = "derive_variadic_from", - feature = "derive_reflect" + feature = "derive_not", + feature = "derive_reflect", + feature = "derive_phantom" ) }, any_derive : @@ -35,9 +39,13 @@ fn main() feature = "derive_deref", feature = "derive_deref_mut", feature = "derive_from", + feature = "derive_index", + feature = "derive_index_mut", feature = "derive_inner_from", feature = "derive_variadic_from", - feature = "derive_reflect" + feature = "derive_not", + feature = "derive_reflect", + feature = "derive_phantom" ) }, } diff --git a/module/core/derive_tools/src/lib.rs b/module/core/derive_tools/src/lib.rs index d99c9c9455..7c3ddfdecf 100644 --- a/module/core/derive_tools/src/lib.rs +++ b/module/core/derive_tools/src/lib.rs @@ -43,22 +43,16 @@ mod derive_more pub use ::derive_more::Constructor; #[ cfg( feature = "derive_error" ) ] pub use ::derive_more::Error; - #[ cfg( feature = "derive_index_mut" ) ] - pub use ::derive_more::IndexMut; - #[ cfg( feature = "derive_index" ) ] - pub use ::derive_more::Index; #[ cfg( feature = "derive_into" ) ] pub use ::derive_more::Into; - #[ cfg( feature = "derive_iterator" ) ] - pub use ::derive_more::Iterator; + // #[ cfg( feature = "derive_iterator" ) ] + // pub use ::derive_more::Iterator; #[ cfg( feature = "derive_into_iterator" ) ] pub use ::derive_more::IntoIterator; #[ cfg( feature = "derive_mul" ) ] pub use ::derive_more::{ Mul, Div }; #[ cfg( feature = "derive_mul_assign" ) ] pub use ::derive_more::{ MulAssign, DivAssign }; - #[ cfg( feature = "derive_not" ) ] - pub use ::derive_more::Not; #[ cfg( feature = "derive_sum" ) ] pub use ::derive_more::Sum; #[ cfg( feature = "derive_try_into" ) ] @@ -76,17 +70,24 @@ mod derive_more #[ cfg( any( feature = "derive_variadic_from", feature = "type_variadic_from" ) ) ] pub use variadic_from as variadic; -// #[ cfg( feature = "derive_reflect" ) ] -// pub mod reflect; - -// use derive_tools_meta::Deref; -// use derive_tools_meta::VariadicFrom; - /// Namespace with dependencies. +#[ allow( unused_imports ) ] #[ cfg( feature = "enabled" ) ] pub mod dependency { + + #[ doc( inline ) ] + pub use ::derive_tools_meta; + + #[ doc( inline ) ] + #[ cfg( feature = "derive_clone_dyn" ) ] + pub use ::clone_dyn::{ self, dependency::* }; + + #[ doc( inline ) ] + #[ cfg( any( feature = "derive_variadic_from", feature = "type_variadic_from" ) ) ] + pub use ::variadic_from::{ self, dependency::* }; + #[ doc( inline ) ] #[ cfg( feature = "derive_more" ) ] pub use ::derive_more; @@ -96,180 +97,86 @@ pub mod dependency #[ doc( inline ) ] #[ cfg( feature = "parse_display" ) ] pub use ::parse_display; - #[ doc( inline ) ] - #[ cfg( feature = "clone_dyn" ) ] - pub use ::clone_dyn; - #[ doc( inline ) ] - #[ cfg( feature = "clone_dyn" ) ] - pub use ::clone_dyn::dependency::*; - #[ doc( inline ) ] - #[ cfg( any_derive ) ] - pub use ::derive_tools_meta; - #[ doc( inline ) ] - #[ cfg( any( feature = "derive_variadic_from", feature = "type_variadic_from" ) ) ] - pub use ::variadic_from; + } #[ doc( inline ) ] #[ cfg( feature = "enabled" ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. +/// Own namespace of the module. #[ cfg( feature = "enabled" ) ] -pub mod protected +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; #[ cfg( feature = "derive_clone_dyn" ) ] #[ doc( inline ) ] - #[ allow( unused_imports ) ] pub use ::clone_dyn::orphan::*; - // #[ doc( inline ) ] - // #[ allow( unused_imports ) ] - // pub use super::wtools::orphan::*; - // #[ cfg( feature = "derive_reflect" ) ] - // #[ doc( inline ) ] - // #[ allow( unused_imports ) ] - // pub use super::reflect::orphan::*; } /// Orphan namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ cfg( all( feature = "derive_more" ) ) ] #[ doc( inline ) ] - #[ allow( unused_imports ) ] pub use super::derive_more::*; #[ cfg( feature = "derive_strum" ) ] #[ doc( inline ) ] - #[ allow( unused_imports ) ] pub use ::strum::*; #[ cfg( any( feature = "derive_variadic_from", feature = "type_variadic_from" ) ) ] #[ doc( inline ) ] pub use ::variadic_from::exposed::*; - // #[ cfg( all( feature = "derive_more", feature = "derive_add" ) ) ] - // #[ doc( inline ) ] - // #[ allow( unused_imports ) ] - // pub use ::derive_more::Add; - - // #[ allow( ambiguous_glob_reexports ) ] - // #[ cfg( feature = "derive_more" ) ] - // #[ doc( inline ) ] - // #[ allow( unused_imports ) ] - // pub use ::derive_more:: - // { - // Add, - // AddAssign, - // AsMut, - // AsRef, - // Binary, - // BitAnd, - // BitAndAssign, - // BitOr, - // BitOrAssign, - // BitXor, - // BitXorAssign, - // Constructor, - // Debug, - // Deref, - // DerefMut, - // Display, - // Div, - // DivAssign, - // Error, - // From, - // FromStr, - // Index, - // IndexMut, - // Into, - // IntoIterator, - // IsVariant, - // LowerExp, - // LowerHex, - // Mul, - // MulAssign, - // Neg, - // Not, - // Octal, - // Pointer, - // Product, - // Rem, - // RemAssign, - // Shl, - // ShlAssign, - // Shr, - // ShrAssign, - // Sub, - // SubAssign, - // Sum, - // TryFrom, - // TryInto, - // TryUnwrap, - // Unwrap, - // UpperExp, - // UpperHex, - // }; - #[ cfg( feature = "derive_strum" ) ] #[ doc( inline ) ] - #[ allow( unused_imports ) ] pub use ::strum::*; #[ cfg( feature = "derive_display" ) ] #[ doc( inline ) ] - #[ allow( unused_imports ) ] pub use ::parse_display::Display; #[ cfg( feature = "derive_from_str" ) ] #[ doc( inline ) ] - #[ allow( unused_imports ) ] pub use ::parse_display::FromStr; #[ cfg( feature = "derive_clone_dyn" ) ] #[ doc( inline ) ] - #[ allow( unused_imports ) ] pub use ::clone_dyn::exposed::*; - // #[ doc( inline ) ] - // #[ allow( unused_imports ) ] - // pub use super::wtools::exposed::*; - - // #[ cfg( feature = "derive_reflect" ) ] - // #[ doc( inline ) ] - // #[ allow( unused_imports ) ] - // pub use super::reflect::exposed::*; + #[ cfg( feature = "derive_clone_dyn" ) ] + #[ doc( inline ) ] + pub use ::clone_dyn; - // #[ cfg( any_derive ) ] #[ doc( inline ) ] - #[ allow( unused_imports ) ] pub use ::derive_tools_meta::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] #[ cfg( feature = "derive_from" ) ] pub use ::derive_tools_meta::From; #[ doc( inline ) ] - #[ allow( unused_imports ) ] #[ cfg( feature = "derive_inner_from" ) ] pub use ::derive_tools_meta::InnerFrom; @@ -277,37 +184,20 @@ pub mod exposed /// Prelude to use essentials: `use my_module::prelude::*`. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ cfg( feature = "derive_clone_dyn" ) ] #[ doc( inline ) ] - #[ allow( unused_imports ) ] pub use ::clone_dyn; #[ cfg( feature = "derive_clone_dyn" ) ] #[ doc( inline ) ] - #[ allow( unused_imports ) ] pub use ::clone_dyn::prelude::*; - // it should already be in predlue of clone_dyn - // #[ cfg( feature = "derive_clone_dyn" ) ] - // #[ doc( inline ) ] - // #[ allow( unused_imports ) ] - // pub use ::clone_dyn::clone_dyn; - #[ cfg( any( feature = "derive_variadic_from", feature = "type_variadic_from" ) ) ] #[ doc( inline ) ] pub use ::variadic_from::prelude::*; - // #[ cfg( feature = "derive_reflect" ) ] - // #[ doc( inline ) ] - // #[ allow( unused_imports ) ] - // pub use super::reflect::prelude::*; - - // #[ doc( inline ) ] - // #[ allow( unused_imports ) ] - // pub use super::wtools::prelude::*; - // #[ doc( no_inline ) ] - // pub use super::wtools; - } diff --git a/module/core/derive_tools/tests/inc/basic_test.rs b/module/core/derive_tools/tests/inc/basic_test.rs index b02ae25e19..a2410b9232 100644 --- a/module/core/derive_tools/tests/inc/basic_test.rs +++ b/module/core/derive_tools/tests/inc/basic_test.rs @@ -66,12 +66,6 @@ tests_impls! let exp = ( 1, 3 ); a_id!( got, exp ); - // let src = Struct1 { a : 1, b : 3 }; - // let got : [ i32 ; 2 ] = src.into(); - // let exp = ( 1, 3 ); - // a_id!( got, exp ); - /* zzz : make it working */ - let src = Struct1 { a : 1, b : 3 }; let got = format!( "{}", src ); let exp = "1-3"; diff --git a/module/core/derive_tools/tests/inc/deref_manual_test.rs b/module/core/derive_tools/tests/inc/deref/basic_manual_test.rs similarity index 95% rename from module/core/derive_tools/tests/inc/deref_manual_test.rs rename to module/core/derive_tools/tests/inc/deref/basic_manual_test.rs index 3ad2c5c1b4..f8bea6f288 100644 --- a/module/core/derive_tools/tests/inc/deref_manual_test.rs +++ b/module/core/derive_tools/tests/inc/deref/basic_manual_test.rs @@ -31,4 +31,4 @@ where 'a : 'b, T : AsRef< U > } } -include!( "./only_test/deref.rs" ); +include!( "./only_test/basic.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_test.rs b/module/core/derive_tools/tests/inc/deref/basic_test.rs similarity index 92% rename from module/core/derive_tools/tests/inc/deref_test.rs rename to module/core/derive_tools/tests/inc/deref/basic_test.rs index df445ac9b4..b5d1621ae8 100644 --- a/module/core/derive_tools/tests/inc/deref_test.rs +++ b/module/core/derive_tools/tests/inc/deref/basic_test.rs @@ -12,4 +12,4 @@ where 'a : 'b, T : AsRef< U >; -include!( "./only_test/deref.rs" ); +include!( "./only_test/basic.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/bounds_inlined.rs b/module/core/derive_tools/tests/inc/deref/bounds_inlined.rs index 8d31b2d56d..99b7190e46 100644 --- a/module/core/derive_tools/tests/inc/deref/bounds_inlined.rs +++ b/module/core/derive_tools/tests/inc/deref/bounds_inlined.rs @@ -7,4 +7,4 @@ use derive_tools::Deref; #[ derive( Deref ) ] struct BoundsInlined< T : ToString, U : Debug >( T, U ); -include!( "./only_tests/bounds_inlined.rs" ); +include!( "./only_test/bounds_inlined.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/bounds_inlined_manual.rs b/module/core/derive_tools/tests/inc/deref/bounds_inlined_manual.rs index a6e4306512..efca73bd13 100644 --- a/module/core/derive_tools/tests/inc/deref/bounds_inlined_manual.rs +++ b/module/core/derive_tools/tests/inc/deref/bounds_inlined_manual.rs @@ -14,4 +14,4 @@ impl< T : ToString, U : Debug > Deref for BoundsInlined< T, U > } } -include!( "./only_tests/bounds_inlined.rs" ); +include!( "./only_test/bounds_inlined.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/bounds_mixed.rs b/module/core/derive_tools/tests/inc/deref/bounds_mixed.rs index b539d8a862..441193a2ee 100644 --- a/module/core/derive_tools/tests/inc/deref/bounds_mixed.rs +++ b/module/core/derive_tools/tests/inc/deref/bounds_mixed.rs @@ -9,4 +9,4 @@ struct BoundsMixed< T : ToString, U >( T, U ) where U : Debug; -include!( "./only_tests/bounds_mixed.rs" ); +include!( "./only_test/bounds_mixed.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/bounds_mixed_manual.rs b/module/core/derive_tools/tests/inc/deref/bounds_mixed_manual.rs index fbd3ae91e5..98c4830781 100644 --- a/module/core/derive_tools/tests/inc/deref/bounds_mixed_manual.rs +++ b/module/core/derive_tools/tests/inc/deref/bounds_mixed_manual.rs @@ -18,4 +18,4 @@ where } } -include!( "./only_tests/bounds_mixed.rs" ); +include!( "./only_test/bounds_mixed.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/bounds_where.rs b/module/core/derive_tools/tests/inc/deref/bounds_where.rs index 9fb1a3f08a..e9f38ace7e 100644 --- a/module/core/derive_tools/tests/inc/deref/bounds_where.rs +++ b/module/core/derive_tools/tests/inc/deref/bounds_where.rs @@ -11,4 +11,4 @@ where T : ToString, for< 'a > U : Trait< 'a >; -include!( "./only_tests/bounds_where.rs" ); +include!( "./only_test/bounds_where.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/bounds_where_manual.rs b/module/core/derive_tools/tests/inc/deref/bounds_where_manual.rs index 0b440a2c94..18afda143a 100644 --- a/module/core/derive_tools/tests/inc/deref/bounds_where_manual.rs +++ b/module/core/derive_tools/tests/inc/deref/bounds_where_manual.rs @@ -21,4 +21,4 @@ where } } -include!( "./only_tests/bounds_where.rs" ); +include!( "./only_test/bounds_where.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/enum_named.rs b/module/core/derive_tools/tests/inc/deref/enum_named.rs index 98f87a8797..8f0356878d 100644 --- a/module/core/derive_tools/tests/inc/deref/enum_named.rs +++ b/module/core/derive_tools/tests/inc/deref/enum_named.rs @@ -9,4 +9,4 @@ enum EnumNamed B { a : String, b : i32 }, } -include!( "./only_tests/enum_named.rs" ); +include!( "./only_test/enum_named.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/enum_named_empty.rs b/module/core/derive_tools/tests/inc/deref/enum_named_empty.rs index 22a7c2f8ad..526bbe4b60 100644 --- a/module/core/derive_tools/tests/inc/deref/enum_named_empty.rs +++ b/module/core/derive_tools/tests/inc/deref/enum_named_empty.rs @@ -9,4 +9,4 @@ enum EnumNamedEmpty B {}, } -include!( "./only_tests/enum_named_empty.rs" ); +include!( "./only_test/enum_named_empty.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/enum_named_empty_manual.rs b/module/core/derive_tools/tests/inc/deref/enum_named_empty_manual.rs index 533dc78b0e..8e3bd73806 100644 --- a/module/core/derive_tools/tests/inc/deref/enum_named_empty_manual.rs +++ b/module/core/derive_tools/tests/inc/deref/enum_named_empty_manual.rs @@ -3,7 +3,7 @@ use core::ops::Deref; #[ allow( dead_code) ] enum EnumNamedEmpty { - A {}, + A {}, B {}, } @@ -16,4 +16,4 @@ impl Deref for EnumNamedEmpty } } -include!( "./only_tests/enum_named_empty.rs" ); +include!( "./only_test/enum_named_empty.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/enum_named_manual.rs b/module/core/derive_tools/tests/inc/deref/enum_named_manual.rs index 238192d0b3..9027655111 100644 --- a/module/core/derive_tools/tests/inc/deref/enum_named_manual.rs +++ b/module/core/derive_tools/tests/inc/deref/enum_named_manual.rs @@ -19,4 +19,4 @@ impl Deref for EnumNamed } } -include!( "./only_tests/enum_named.rs" ); +include!( "./only_test/enum_named.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/enum_tuple.rs b/module/core/derive_tools/tests/inc/deref/enum_tuple.rs index 2c6701331b..816cbbddf1 100644 --- a/module/core/derive_tools/tests/inc/deref/enum_tuple.rs +++ b/module/core/derive_tools/tests/inc/deref/enum_tuple.rs @@ -9,4 +9,4 @@ enum EnumTuple B( String, i32 ), } -include!( "./only_tests/enum_tuple.rs" ); +include!( "./only_test/enum_tuple.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/enum_tuple_empty.rs b/module/core/derive_tools/tests/inc/deref/enum_tuple_empty.rs index df423d9893..a05a748911 100644 --- a/module/core/derive_tools/tests/inc/deref/enum_tuple_empty.rs +++ b/module/core/derive_tools/tests/inc/deref/enum_tuple_empty.rs @@ -9,4 +9,4 @@ enum EnumTupleEmpty B(), } -include!( "./only_tests/enum_tuple_empty.rs" ); +include!( "./only_test/enum_tuple_empty.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/enum_tuple_empty_manual.rs b/module/core/derive_tools/tests/inc/deref/enum_tuple_empty_manual.rs index df54d3101e..e390de4ea3 100644 --- a/module/core/derive_tools/tests/inc/deref/enum_tuple_empty_manual.rs +++ b/module/core/derive_tools/tests/inc/deref/enum_tuple_empty_manual.rs @@ -16,4 +16,4 @@ impl Deref for EnumTupleEmpty } } -include!( "./only_tests/enum_tuple_empty.rs" ); +include!( "./only_test/enum_tuple_empty.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/enum_tuple_manual.rs b/module/core/derive_tools/tests/inc/deref/enum_tuple_manual.rs index efd16f833a..4e716956f1 100644 --- a/module/core/derive_tools/tests/inc/deref/enum_tuple_manual.rs +++ b/module/core/derive_tools/tests/inc/deref/enum_tuple_manual.rs @@ -19,4 +19,4 @@ impl Deref for EnumTuple } } -include!( "./only_tests/enum_tuple.rs" ); +include!( "./only_test/enum_tuple.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/enum_unit.rs b/module/core/derive_tools/tests/inc/deref/enum_unit.rs index 3ef2b204ce..0635a277b6 100644 --- a/module/core/derive_tools/tests/inc/deref/enum_unit.rs +++ b/module/core/derive_tools/tests/inc/deref/enum_unit.rs @@ -9,4 +9,4 @@ enum EnumUnit B, } -include!( "./only_tests/enum_unit.rs" ); +include!( "./only_test/enum_unit.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/enum_unit_manual.rs b/module/core/derive_tools/tests/inc/deref/enum_unit_manual.rs index 1cc6fdc94b..55b874c1c5 100644 --- a/module/core/derive_tools/tests/inc/deref/enum_unit_manual.rs +++ b/module/core/derive_tools/tests/inc/deref/enum_unit_manual.rs @@ -16,4 +16,4 @@ impl Deref for EnumUnit } } -include!( "./only_tests/enum_unit.rs" ); +include!( "./only_test/enum_unit.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/generics_constants.rs b/module/core/derive_tools/tests/inc/deref/generics_constants.rs index f4198931f3..d6cfd619eb 100644 --- a/module/core/derive_tools/tests/inc/deref/generics_constants.rs +++ b/module/core/derive_tools/tests/inc/deref/generics_constants.rs @@ -5,4 +5,4 @@ use derive_tools::Deref; #[ derive( Deref ) ] struct GenericsConstants< const N : usize >( i32 ); -include!( "./only_tests/generics_constants.rs" ); +include!( "./only_test/generics_constants.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/generics_constants_default.rs b/module/core/derive_tools/tests/inc/deref/generics_constants_default.rs index b5b03688dc..a3cac37db9 100644 --- a/module/core/derive_tools/tests/inc/deref/generics_constants_default.rs +++ b/module/core/derive_tools/tests/inc/deref/generics_constants_default.rs @@ -5,4 +5,4 @@ use derive_tools::Deref; #[ derive( Deref ) ] struct GenericsConstantsDefault< const N : usize = 0 >( i32 ); -include!( "./only_tests/generics_constants_default.rs" ); +include!( "./only_test/generics_constants_default.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/generics_constants_default_manual.rs b/module/core/derive_tools/tests/inc/deref/generics_constants_default_manual.rs index b56469fe34..cd0f435138 100644 --- a/module/core/derive_tools/tests/inc/deref/generics_constants_default_manual.rs +++ b/module/core/derive_tools/tests/inc/deref/generics_constants_default_manual.rs @@ -12,4 +12,4 @@ impl< const N : usize > Deref for GenericsConstantsDefault< N > } } -include!( "./only_tests/generics_constants_default.rs" ); +include!( "./only_test/generics_constants_default.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/generics_constants_manual.rs b/module/core/derive_tools/tests/inc/deref/generics_constants_manual.rs index fcc6b6da76..c7bc212fe5 100644 --- a/module/core/derive_tools/tests/inc/deref/generics_constants_manual.rs +++ b/module/core/derive_tools/tests/inc/deref/generics_constants_manual.rs @@ -12,4 +12,4 @@ impl< const N : usize > Deref for GenericsConstants< N > } } -include!( "./only_tests/generics_constants.rs" ); +include!( "./only_test/generics_constants.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/generics_lifetimes.rs b/module/core/derive_tools/tests/inc/deref/generics_lifetimes.rs index a308db8fee..37c3a3218d 100644 --- a/module/core/derive_tools/tests/inc/deref/generics_lifetimes.rs +++ b/module/core/derive_tools/tests/inc/deref/generics_lifetimes.rs @@ -5,4 +5,4 @@ use derive_tools::Deref; #[ derive( Deref ) ] struct GenericsLifetimes< 'a >( &'a i32 ); -include!( "./only_tests/generics_lifetimes.rs" ); +include!( "./only_test/generics_lifetimes.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/generics_lifetimes_manual.rs b/module/core/derive_tools/tests/inc/deref/generics_lifetimes_manual.rs index 57f647c9ff..557ef83a23 100644 --- a/module/core/derive_tools/tests/inc/deref/generics_lifetimes_manual.rs +++ b/module/core/derive_tools/tests/inc/deref/generics_lifetimes_manual.rs @@ -12,4 +12,4 @@ impl< 'a > Deref for GenericsLifetimes< 'a > } } -include!( "./only_tests/generics_lifetimes.rs" ); +include!( "./only_test/generics_lifetimes.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/generics_types.rs b/module/core/derive_tools/tests/inc/deref/generics_types.rs index d6acb22702..301a9e82bc 100644 --- a/module/core/derive_tools/tests/inc/deref/generics_types.rs +++ b/module/core/derive_tools/tests/inc/deref/generics_types.rs @@ -5,4 +5,4 @@ use derive_tools::Deref; #[ derive( Deref ) ] struct GenericsTypes< T >( T ); -include!( "./only_tests/generics_types.rs" ); +include!( "./only_test/generics_types.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/generics_types_default.rs b/module/core/derive_tools/tests/inc/deref/generics_types_default.rs index f89f5d9430..a87144b54c 100644 --- a/module/core/derive_tools/tests/inc/deref/generics_types_default.rs +++ b/module/core/derive_tools/tests/inc/deref/generics_types_default.rs @@ -5,4 +5,4 @@ use derive_tools::Deref; #[ derive ( Deref ) ] struct GenericsTypesDefault< T = i32 >( T ); -include!( "./only_tests/generics_types_default.rs" ); +include!( "./only_test/generics_types_default.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/generics_types_default_manual.rs b/module/core/derive_tools/tests/inc/deref/generics_types_default_manual.rs index 773061023c..5e0f0f1e81 100644 --- a/module/core/derive_tools/tests/inc/deref/generics_types_default_manual.rs +++ b/module/core/derive_tools/tests/inc/deref/generics_types_default_manual.rs @@ -12,4 +12,4 @@ impl< T > Deref for GenericsTypesDefault< T > } } -include!( "./only_tests/generics_types_default.rs" ); +include!( "./only_test/generics_types_default.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/generics_types_manual.rs b/module/core/derive_tools/tests/inc/deref/generics_types_manual.rs index 8b9ab74909..bce6949e12 100644 --- a/module/core/derive_tools/tests/inc/deref/generics_types_manual.rs +++ b/module/core/derive_tools/tests/inc/deref/generics_types_manual.rs @@ -12,4 +12,4 @@ impl< T > Deref for GenericsTypes< T > } } -include!( "./only_tests/generics_types.rs" ); +include!( "./only_test/generics_types.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/name_collisions.rs b/module/core/derive_tools/tests/inc/deref/name_collisions.rs index 3a0fe2a74f..995aec56d6 100644 --- a/module/core/derive_tools/tests/inc/deref/name_collisions.rs +++ b/module/core/derive_tools/tests/inc/deref/name_collisions.rs @@ -20,4 +20,4 @@ struct NameCollisions b : String, } -include!( "./only_tests/name_collisions.rs" ); +include!( "./only_test/name_collisions.rs" ); diff --git a/module/core/derive_tools/tests/inc/only_test/deref.rs b/module/core/derive_tools/tests/inc/deref/only_test/basic.rs similarity index 100% rename from module/core/derive_tools/tests/inc/only_test/deref.rs rename to module/core/derive_tools/tests/inc/deref/only_test/basic.rs diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/bounds_inlined.rs b/module/core/derive_tools/tests/inc/deref/only_test/bounds_inlined.rs similarity index 100% rename from module/core/derive_tools/tests/inc/deref/only_tests/bounds_inlined.rs rename to module/core/derive_tools/tests/inc/deref/only_test/bounds_inlined.rs diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/bounds_mixed.rs b/module/core/derive_tools/tests/inc/deref/only_test/bounds_mixed.rs similarity index 100% rename from module/core/derive_tools/tests/inc/deref/only_tests/bounds_mixed.rs rename to module/core/derive_tools/tests/inc/deref/only_test/bounds_mixed.rs diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/bounds_where.rs b/module/core/derive_tools/tests/inc/deref/only_test/bounds_where.rs similarity index 100% rename from module/core/derive_tools/tests/inc/deref/only_tests/bounds_where.rs rename to module/core/derive_tools/tests/inc/deref/only_test/bounds_where.rs diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/enum_named.rs b/module/core/derive_tools/tests/inc/deref/only_test/enum_named.rs similarity index 100% rename from module/core/derive_tools/tests/inc/deref/only_tests/enum_named.rs rename to module/core/derive_tools/tests/inc/deref/only_test/enum_named.rs diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/enum_named_empty.rs b/module/core/derive_tools/tests/inc/deref/only_test/enum_named_empty.rs similarity index 100% rename from module/core/derive_tools/tests/inc/deref/only_tests/enum_named_empty.rs rename to module/core/derive_tools/tests/inc/deref/only_test/enum_named_empty.rs diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/enum_tuple.rs b/module/core/derive_tools/tests/inc/deref/only_test/enum_tuple.rs similarity index 100% rename from module/core/derive_tools/tests/inc/deref/only_tests/enum_tuple.rs rename to module/core/derive_tools/tests/inc/deref/only_test/enum_tuple.rs diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/enum_tuple_empty.rs b/module/core/derive_tools/tests/inc/deref/only_test/enum_tuple_empty.rs similarity index 100% rename from module/core/derive_tools/tests/inc/deref/only_tests/enum_tuple_empty.rs rename to module/core/derive_tools/tests/inc/deref/only_test/enum_tuple_empty.rs diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/enum_unit.rs b/module/core/derive_tools/tests/inc/deref/only_test/enum_unit.rs similarity index 100% rename from module/core/derive_tools/tests/inc/deref/only_tests/enum_unit.rs rename to module/core/derive_tools/tests/inc/deref/only_test/enum_unit.rs diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/generics_constants.rs b/module/core/derive_tools/tests/inc/deref/only_test/generics_constants.rs similarity index 100% rename from module/core/derive_tools/tests/inc/deref/only_tests/generics_constants.rs rename to module/core/derive_tools/tests/inc/deref/only_test/generics_constants.rs diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/generics_constants_default.rs b/module/core/derive_tools/tests/inc/deref/only_test/generics_constants_default.rs similarity index 100% rename from module/core/derive_tools/tests/inc/deref/only_tests/generics_constants_default.rs rename to module/core/derive_tools/tests/inc/deref/only_test/generics_constants_default.rs diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/generics_lifetimes.rs b/module/core/derive_tools/tests/inc/deref/only_test/generics_lifetimes.rs similarity index 100% rename from module/core/derive_tools/tests/inc/deref/only_tests/generics_lifetimes.rs rename to module/core/derive_tools/tests/inc/deref/only_test/generics_lifetimes.rs diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/generics_types.rs b/module/core/derive_tools/tests/inc/deref/only_test/generics_types.rs similarity index 100% rename from module/core/derive_tools/tests/inc/deref/only_tests/generics_types.rs rename to module/core/derive_tools/tests/inc/deref/only_test/generics_types.rs diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/generics_types_default.rs b/module/core/derive_tools/tests/inc/deref/only_test/generics_types_default.rs similarity index 100% rename from module/core/derive_tools/tests/inc/deref/only_tests/generics_types_default.rs rename to module/core/derive_tools/tests/inc/deref/only_test/generics_types_default.rs diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/name_collisions.rs b/module/core/derive_tools/tests/inc/deref/only_test/name_collisions.rs similarity index 100% rename from module/core/derive_tools/tests/inc/deref/only_tests/name_collisions.rs rename to module/core/derive_tools/tests/inc/deref/only_test/name_collisions.rs diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/struct_named.rs b/module/core/derive_tools/tests/inc/deref/only_test/struct_named.rs similarity index 100% rename from module/core/derive_tools/tests/inc/deref/only_tests/struct_named.rs rename to module/core/derive_tools/tests/inc/deref/only_test/struct_named.rs diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/struct_named_empty.rs b/module/core/derive_tools/tests/inc/deref/only_test/struct_named_empty.rs similarity index 100% rename from module/core/derive_tools/tests/inc/deref/only_tests/struct_named_empty.rs rename to module/core/derive_tools/tests/inc/deref/only_test/struct_named_empty.rs diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/struct_tuple.rs b/module/core/derive_tools/tests/inc/deref/only_test/struct_tuple.rs similarity index 100% rename from module/core/derive_tools/tests/inc/deref/only_tests/struct_tuple.rs rename to module/core/derive_tools/tests/inc/deref/only_test/struct_tuple.rs diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/struct_tuple_empty.rs b/module/core/derive_tools/tests/inc/deref/only_test/struct_tuple_empty.rs similarity index 100% rename from module/core/derive_tools/tests/inc/deref/only_tests/struct_tuple_empty.rs rename to module/core/derive_tools/tests/inc/deref/only_test/struct_tuple_empty.rs diff --git a/module/core/derive_tools/tests/inc/deref/only_tests/struct_unit.rs b/module/core/derive_tools/tests/inc/deref/only_test/struct_unit.rs similarity index 100% rename from module/core/derive_tools/tests/inc/deref/only_tests/struct_unit.rs rename to module/core/derive_tools/tests/inc/deref/only_test/struct_unit.rs diff --git a/module/core/derive_tools/tests/inc/deref/struct_named.rs b/module/core/derive_tools/tests/inc/deref/struct_named.rs index 470670a206..0d9356a409 100644 --- a/module/core/derive_tools/tests/inc/deref/struct_named.rs +++ b/module/core/derive_tools/tests/inc/deref/struct_named.rs @@ -9,4 +9,4 @@ struct StructNamed b : i32, } -include!( "./only_tests/struct_named.rs" ); +include!( "./only_test/struct_named.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/struct_named_empty.rs b/module/core/derive_tools/tests/inc/deref/struct_named_empty.rs index ebe217835d..da9f348550 100644 --- a/module/core/derive_tools/tests/inc/deref/struct_named_empty.rs +++ b/module/core/derive_tools/tests/inc/deref/struct_named_empty.rs @@ -5,4 +5,4 @@ use derive_tools::Deref; #[ derive( Deref ) ] struct StructNamedEmpty{} -include!( "./only_tests/struct_named_empty.rs" ); +include!( "./only_test/struct_named_empty.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/struct_named_empty_manual.rs b/module/core/derive_tools/tests/inc/deref/struct_named_empty_manual.rs index efd92be335..d0aa1502ce 100644 --- a/module/core/derive_tools/tests/inc/deref/struct_named_empty_manual.rs +++ b/module/core/derive_tools/tests/inc/deref/struct_named_empty_manual.rs @@ -12,4 +12,4 @@ impl Deref for StructNamedEmpty } } -include!( "./only_tests/struct_named_empty.rs" ); +include!( "./only_test/struct_named_empty.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/struct_named_manual.rs b/module/core/derive_tools/tests/inc/deref/struct_named_manual.rs index 88e31246e6..a508a73cb2 100644 --- a/module/core/derive_tools/tests/inc/deref/struct_named_manual.rs +++ b/module/core/derive_tools/tests/inc/deref/struct_named_manual.rs @@ -16,4 +16,4 @@ impl Deref for StructNamed } } -include!( "./only_tests/struct_named.rs" ); +include!( "./only_test/struct_named.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/struct_tuple.rs b/module/core/derive_tools/tests/inc/deref/struct_tuple.rs index 29c4b3c4ff..07555ba421 100644 --- a/module/core/derive_tools/tests/inc/deref/struct_tuple.rs +++ b/module/core/derive_tools/tests/inc/deref/struct_tuple.rs @@ -5,4 +5,4 @@ use derive_tools::Deref; #[ derive ( Deref ) ] struct StructTuple( String, i32 ); -include!( "./only_tests/struct_tuple.rs" ); +include!( "./only_test/struct_tuple.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/struct_tuple_empty.rs b/module/core/derive_tools/tests/inc/deref/struct_tuple_empty.rs index 57e2ea7257..4dc0b8826d 100644 --- a/module/core/derive_tools/tests/inc/deref/struct_tuple_empty.rs +++ b/module/core/derive_tools/tests/inc/deref/struct_tuple_empty.rs @@ -5,4 +5,4 @@ use derive_tools::Deref; #[ derive ( Deref ) ] struct StructTupleEmpty(); -include!( "./only_tests/struct_tuple_empty.rs" ); +include!( "./only_test/struct_tuple_empty.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/struct_tuple_empty_manual.rs b/module/core/derive_tools/tests/inc/deref/struct_tuple_empty_manual.rs index b239eccd44..49e58ac4d7 100644 --- a/module/core/derive_tools/tests/inc/deref/struct_tuple_empty_manual.rs +++ b/module/core/derive_tools/tests/inc/deref/struct_tuple_empty_manual.rs @@ -12,4 +12,4 @@ impl Deref for StructTupleEmpty } } -include!( "./only_tests/struct_tuple_empty.rs" ); +include!( "./only_test/struct_tuple_empty.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/struct_tuple_manual.rs b/module/core/derive_tools/tests/inc/deref/struct_tuple_manual.rs index 7a97225d3b..27de8dc468 100644 --- a/module/core/derive_tools/tests/inc/deref/struct_tuple_manual.rs +++ b/module/core/derive_tools/tests/inc/deref/struct_tuple_manual.rs @@ -12,4 +12,4 @@ impl Deref for StructTuple } } -include!( "./only_tests/struct_tuple.rs" ); +include!( "./only_test/struct_tuple.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/struct_unit.rs b/module/core/derive_tools/tests/inc/deref/struct_unit.rs index 30c742a68e..fbef89b933 100644 --- a/module/core/derive_tools/tests/inc/deref/struct_unit.rs +++ b/module/core/derive_tools/tests/inc/deref/struct_unit.rs @@ -5,4 +5,4 @@ use derive_tools::Deref; #[ derive ( Deref ) ] struct StructUnit; -include!( "./only_tests/struct_unit.rs" ); +include!( "./only_test/struct_unit.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref/struct_unit_manual.rs b/module/core/derive_tools/tests/inc/deref/struct_unit_manual.rs index c43a711d50..a89b73ce19 100644 --- a/module/core/derive_tools/tests/inc/deref/struct_unit_manual.rs +++ b/module/core/derive_tools/tests/inc/deref/struct_unit_manual.rs @@ -12,4 +12,4 @@ impl Deref for StructUnit } } -include!( "./only_tests/struct_unit.rs" ); +include!( "./only_test/struct_unit.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut_manual_test.rs b/module/core/derive_tools/tests/inc/deref_mut/basic_manual_test.rs similarity index 96% rename from module/core/derive_tools/tests/inc/deref_mut_manual_test.rs rename to module/core/derive_tools/tests/inc/deref_mut/basic_manual_test.rs index a5541fbc52..bca3746f67 100644 --- a/module/core/derive_tools/tests/inc/deref_mut_manual_test.rs +++ b/module/core/derive_tools/tests/inc/deref_mut/basic_manual_test.rs @@ -50,4 +50,4 @@ where 'a : 'b, T : AsRef< U > } } -include!( "./only_test/deref_mut.rs" ); +include!( "./only_test/basic.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut_test.rs b/module/core/derive_tools/tests/inc/deref_mut/basic_test.rs similarity index 92% rename from module/core/derive_tools/tests/inc/deref_mut_test.rs rename to module/core/derive_tools/tests/inc/deref_mut/basic_test.rs index aae9db0775..4ba677e7b0 100644 --- a/module/core/derive_tools/tests/inc/deref_mut_test.rs +++ b/module/core/derive_tools/tests/inc/deref_mut/basic_test.rs @@ -12,4 +12,4 @@ where 'a : 'b, T : AsRef< U >; -include!( "./only_test/deref_mut.rs" ); +include!( "./only_test/basic.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/bounds_inlined.rs b/module/core/derive_tools/tests/inc/deref_mut/bounds_inlined.rs index ebb9fe65b6..41d9156c0d 100644 --- a/module/core/derive_tools/tests/inc/deref_mut/bounds_inlined.rs +++ b/module/core/derive_tools/tests/inc/deref_mut/bounds_inlined.rs @@ -1,10 +1,19 @@ use core::fmt::Debug; -use core::ops::{ Deref }; -use derive_tools::{ Deref, DerefMut }; +use core::ops::Deref; +use derive_tools::DerefMut; #[ allow( dead_code ) ] -#[ derive( Deref, DerefMut ) ] +#[ derive( DerefMut ) ] struct BoundsInlined< T : ToString, U : Debug >( T, U ); -include!( "./only_tests/bounds_inlined.rs" ); +impl< T : ToString, U : Debug > Deref for BoundsInlined< T, U > +{ + type Target = T; + fn deref( &self ) -> &Self::Target + { + &self.0 + } +} + +include!( "./only_test/bounds_inlined.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/bounds_inlined_manual.rs b/module/core/derive_tools/tests/inc/deref_mut/bounds_inlined_manual.rs index 84051196bf..856447a7a3 100644 --- a/module/core/derive_tools/tests/inc/deref_mut/bounds_inlined_manual.rs +++ b/module/core/derive_tools/tests/inc/deref_mut/bounds_inlined_manual.rs @@ -21,4 +21,4 @@ impl< T : ToString, U : Debug > DerefMut for BoundsInlined< T, U > } } -include!( "./only_tests/bounds_inlined.rs" ); +include!( "./only_test/bounds_inlined.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/bounds_mixed.rs b/module/core/derive_tools/tests/inc/deref_mut/bounds_mixed.rs index 5b8d13196f..d4e07fa448 100644 --- a/module/core/derive_tools/tests/inc/deref_mut/bounds_mixed.rs +++ b/module/core/derive_tools/tests/inc/deref_mut/bounds_mixed.rs @@ -1,12 +1,23 @@ use core::fmt::Debug; -use core::ops::{ Deref }; -use derive_tools::{ Deref, DerefMut }; +use core::ops::Deref; +use derive_tools::DerefMut; #[ allow( dead_code ) ] -#[ derive( Deref, DerefMut ) ] +#[ derive( DerefMut ) ] struct BoundsMixed< T : ToString, U >( T, U ) where U : Debug; -include!( "./only_tests/bounds_mixed.rs" ); +impl< T : ToString, U > Deref for BoundsMixed< T, U > +where + U : Debug, +{ + type Target = T; + fn deref( &self ) -> &Self::Target + { + &self.0 + } +} + +include!( "./only_test/bounds_mixed.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/bounds_mixed_manual.rs b/module/core/derive_tools/tests/inc/deref_mut/bounds_mixed_manual.rs index 4bbfa33c21..23ef9fcb11 100644 --- a/module/core/derive_tools/tests/inc/deref_mut/bounds_mixed_manual.rs +++ b/module/core/derive_tools/tests/inc/deref_mut/bounds_mixed_manual.rs @@ -28,4 +28,4 @@ where } -include!( "./only_tests/bounds_mixed.rs" ); +include!( "./only_test/bounds_mixed.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/bounds_where.rs b/module/core/derive_tools/tests/inc/deref_mut/bounds_where.rs index 25a61c35d1..a32d38da89 100644 --- a/module/core/derive_tools/tests/inc/deref_mut/bounds_where.rs +++ b/module/core/derive_tools/tests/inc/deref_mut/bounds_where.rs @@ -1,14 +1,26 @@ trait Trait<'a> {} impl<'a> Trait<'a> for i32 {} -use core::ops::{ Deref }; -use derive_tools::{ Deref, DerefMut }; +use core::ops::Deref; +use derive_tools::DerefMut; #[ allow( dead_code ) ] -#[ derive( Deref, DerefMut ) ] +#[ derive( DerefMut ) ] struct BoundsWhere< T, U >( T, U ) where T : ToString, for< 'a > U : Trait< 'a >; -include!( "./only_tests/bounds_where.rs" ); +impl< T, U > Deref for BoundsWhere< T, U > +where + T : ToString, + for< 'a > U : Trait< 'a > +{ + type Target = T; + fn deref( &self ) -> &Self::Target + { + &self.0 + } +} + +include!( "./only_test/bounds_where.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/bounds_where_manual.rs b/module/core/derive_tools/tests/inc/deref_mut/bounds_where_manual.rs index 3a61604a87..7d984c999f 100644 --- a/module/core/derive_tools/tests/inc/deref_mut/bounds_where_manual.rs +++ b/module/core/derive_tools/tests/inc/deref_mut/bounds_where_manual.rs @@ -31,4 +31,4 @@ where } } -include!( "./only_tests/bounds_where.rs" ); +include!( "./only_test/bounds_where.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/enum_named.rs b/module/core/derive_tools/tests/inc/deref_mut/enum_named.rs index f6ced02179..deb903dc7f 100644 --- a/module/core/derive_tools/tests/inc/deref_mut/enum_named.rs +++ b/module/core/derive_tools/tests/inc/deref_mut/enum_named.rs @@ -1,12 +1,24 @@ -use core::ops::{ Deref }; -use derive_tools::{ Deref, DerefMut }; +use core::ops::Deref; +use derive_tools::DerefMut; #[ allow( dead_code) ] -#[ derive( Deref, DerefMut ) ] +#[ derive( DerefMut ) ] enum EnumNamed { A { a : String, b : i32 }, B { a : String, b : i32 }, } -include!( "./only_tests/enum_named.rs" ); +impl Deref for EnumNamed +{ + type Target = String; + fn deref( &self ) -> &Self::Target + { + match self + { + Self::A { a : v, ..} | Self::B { a : v, .. } => v + } + } +} + +include!( "./only_test/enum_named.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/enum_named_manual.rs b/module/core/derive_tools/tests/inc/deref_mut/enum_named_manual.rs index 096c52cf20..5128c63693 100644 --- a/module/core/derive_tools/tests/inc/deref_mut/enum_named_manual.rs +++ b/module/core/derive_tools/tests/inc/deref_mut/enum_named_manual.rs @@ -29,4 +29,4 @@ impl DerefMut for EnumNamed } } -include!( "./only_tests/enum_named.rs" ); +include!( "./only_test/enum_named.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/enum_tuple.rs b/module/core/derive_tools/tests/inc/deref_mut/enum_tuple.rs index 8957e47e25..b76756b220 100644 --- a/module/core/derive_tools/tests/inc/deref_mut/enum_tuple.rs +++ b/module/core/derive_tools/tests/inc/deref_mut/enum_tuple.rs @@ -1,12 +1,24 @@ -use core::ops::{ Deref }; -use derive_tools::{ Deref, DerefMut }; +use core::ops::Deref; +use derive_tools::DerefMut; #[ allow( dead_code) ] -#[ derive( Deref, DerefMut ) ] +#[ derive( DerefMut ) ] enum EnumTuple { A( String, i32 ), B( String, i32 ), } -include!( "./only_tests/enum_tuple.rs" ); +impl Deref for EnumTuple +{ + type Target = String; + fn deref( &self ) -> &Self::Target + { + match self + { + Self::A( v, .. ) | Self::B( v, .. ) => v + } + } +} + +include!( "./only_test/enum_tuple.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/enum_tuple_manual.rs b/module/core/derive_tools/tests/inc/deref_mut/enum_tuple_manual.rs index c04408ef45..71decb8809 100644 --- a/module/core/derive_tools/tests/inc/deref_mut/enum_tuple_manual.rs +++ b/module/core/derive_tools/tests/inc/deref_mut/enum_tuple_manual.rs @@ -29,4 +29,4 @@ impl DerefMut for EnumTuple } } -include!( "./only_tests/enum_tuple.rs" ); +include!( "./only_test/enum_tuple.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/generics_constants.rs b/module/core/derive_tools/tests/inc/deref_mut/generics_constants.rs index 33ff0ff89f..3f44441d80 100644 --- a/module/core/derive_tools/tests/inc/deref_mut/generics_constants.rs +++ b/module/core/derive_tools/tests/inc/deref_mut/generics_constants.rs @@ -1,8 +1,17 @@ -use core::ops::{ Deref }; -use derive_tools::{ Deref, DerefMut }; +use core::ops::Deref; +use derive_tools::{ DerefMut }; #[ allow( dead_code ) ] -#[ derive( Deref, DerefMut ) ] +#[ derive( DerefMut ) ] struct GenericsConstants< const N : usize >( i32 ); -include!( "./only_tests/generics_constants.rs" ); +impl< const N : usize > Deref for GenericsConstants< N > +{ + type Target = i32; + fn deref( &self ) -> &Self::Target + { + &self.0 + } +} + +include!( "./only_test/generics_constants.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/generics_constants_default.rs b/module/core/derive_tools/tests/inc/deref_mut/generics_constants_default.rs index a5591f7569..c38a01b33c 100644 --- a/module/core/derive_tools/tests/inc/deref_mut/generics_constants_default.rs +++ b/module/core/derive_tools/tests/inc/deref_mut/generics_constants_default.rs @@ -1,8 +1,17 @@ -use core::ops::{ Deref }; -use derive_tools::{ Deref, DerefMut }; +use core::ops::Deref; +use derive_tools::DerefMut; #[ allow( dead_code ) ] -#[ derive( Deref, DerefMut ) ] +#[ derive( DerefMut ) ] struct GenericsConstantsDefault< const N : usize = 0 >( i32 ); -include!( "./only_tests/generics_constants_default.rs" ); +impl< const N : usize > Deref for GenericsConstantsDefault< N > +{ + type Target = i32; + fn deref( &self ) -> &Self::Target + { + &self.0 + } +} + +include!( "./only_test/generics_constants_default.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/generics_constants_default_manual.rs b/module/core/derive_tools/tests/inc/deref_mut/generics_constants_default_manual.rs index 6348347253..e0e4495eab 100644 --- a/module/core/derive_tools/tests/inc/deref_mut/generics_constants_default_manual.rs +++ b/module/core/derive_tools/tests/inc/deref_mut/generics_constants_default_manual.rs @@ -19,4 +19,4 @@ impl< const N : usize > DerefMut for GenericsConstantsDefault< N > } } -include!( "./only_tests/generics_constants_default.rs" ); +include!( "./only_test/generics_constants_default.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/generics_constants_manual.rs b/module/core/derive_tools/tests/inc/deref_mut/generics_constants_manual.rs index efe320d565..0578607114 100644 --- a/module/core/derive_tools/tests/inc/deref_mut/generics_constants_manual.rs +++ b/module/core/derive_tools/tests/inc/deref_mut/generics_constants_manual.rs @@ -19,4 +19,4 @@ impl< const N : usize > DerefMut for GenericsConstants< N > } } -include!( "./only_tests/generics_constants.rs" ); +include!( "./only_test/generics_constants.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/generics_lifetimes.rs b/module/core/derive_tools/tests/inc/deref_mut/generics_lifetimes.rs index 3a3ff17bdd..7adb83cc3c 100644 --- a/module/core/derive_tools/tests/inc/deref_mut/generics_lifetimes.rs +++ b/module/core/derive_tools/tests/inc/deref_mut/generics_lifetimes.rs @@ -1,8 +1,17 @@ -use core::ops::{ Deref }; -use derive_tools::{ Deref, DerefMut }; +use core::ops::Deref; +use derive_tools::DerefMut; #[ allow( dead_code ) ] -#[ derive( Deref, DerefMut ) ] +#[ derive( DerefMut ) ] struct GenericsLifetimes< 'a >( &'a i32 ); -include!( "./only_tests/generics_lifetimes.rs" ); +impl< 'a > Deref for GenericsLifetimes< 'a > +{ + type Target = &'a i32; + fn deref( &self ) -> &Self::Target + { + &self.0 + } +} + +include!( "./only_test/generics_lifetimes.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/generics_lifetimes_manual.rs b/module/core/derive_tools/tests/inc/deref_mut/generics_lifetimes_manual.rs index 7d16d699c9..2d9d86a08f 100644 --- a/module/core/derive_tools/tests/inc/deref_mut/generics_lifetimes_manual.rs +++ b/module/core/derive_tools/tests/inc/deref_mut/generics_lifetimes_manual.rs @@ -19,4 +19,4 @@ impl< 'a > DerefMut for GenericsLifetimes< 'a > } } -include!( "./only_tests/generics_lifetimes.rs" ); +include!( "./only_test/generics_lifetimes.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/generics_types.rs b/module/core/derive_tools/tests/inc/deref_mut/generics_types.rs index dc64f4ec43..09ea883225 100644 --- a/module/core/derive_tools/tests/inc/deref_mut/generics_types.rs +++ b/module/core/derive_tools/tests/inc/deref_mut/generics_types.rs @@ -1,8 +1,17 @@ -use core::ops::{ Deref }; -use derive_tools::{ Deref, DerefMut }; +use core::ops::Deref; +use derive_tools::DerefMut; #[ allow( dead_code ) ] -#[ derive( Deref, DerefMut ) ] +#[ derive( DerefMut ) ] struct GenericsTypes< T >( T ); -include!( "./only_tests/generics_types.rs" ); +impl< T > Deref for GenericsTypes< T > +{ + type Target = T; + fn deref( &self ) -> &Self::Target + { + &self.0 + } +} + +include!( "./only_test/generics_types.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/generics_types_default.rs b/module/core/derive_tools/tests/inc/deref_mut/generics_types_default.rs index 8680954981..66e49bbf99 100644 --- a/module/core/derive_tools/tests/inc/deref_mut/generics_types_default.rs +++ b/module/core/derive_tools/tests/inc/deref_mut/generics_types_default.rs @@ -1,8 +1,17 @@ -use core::ops::{ Deref }; -use derive_tools::{ Deref, DerefMut }; +use core::ops::Deref; +use derive_tools::DerefMut; #[ allow( dead_code ) ] -#[ derive ( Deref, DerefMut ) ] +#[ derive ( DerefMut ) ] struct GenericsTypesDefault< T = i32 >( T ); -include!( "./only_tests/generics_types_default.rs" ); +impl< T > Deref for GenericsTypesDefault< T > +{ + type Target = T; + fn deref( &self ) -> &Self::Target + { + &self.0 + } +} + +include!( "./only_test/generics_types_default.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/generics_types_default_manual.rs b/module/core/derive_tools/tests/inc/deref_mut/generics_types_default_manual.rs index 00b41e2ece..6f638b4535 100644 --- a/module/core/derive_tools/tests/inc/deref_mut/generics_types_default_manual.rs +++ b/module/core/derive_tools/tests/inc/deref_mut/generics_types_default_manual.rs @@ -19,4 +19,4 @@ impl< T > DerefMut for GenericsTypesDefault< T > } } -include!( "./only_tests/generics_types_default.rs" ); +include!( "./only_test/generics_types_default.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/generics_types_manual.rs b/module/core/derive_tools/tests/inc/deref_mut/generics_types_manual.rs index 2bdeb3183f..a015cdda72 100644 --- a/module/core/derive_tools/tests/inc/deref_mut/generics_types_manual.rs +++ b/module/core/derive_tools/tests/inc/deref_mut/generics_types_manual.rs @@ -19,4 +19,4 @@ impl< T > DerefMut for GenericsTypes< T > } } -include!( "./only_tests/generics_types.rs" ); +include!( "./only_test/generics_types.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/name_collisions.rs b/module/core/derive_tools/tests/inc/deref_mut/name_collisions.rs index 66f82b0fb1..449d9bca19 100644 --- a/module/core/derive_tools/tests/inc/deref_mut/name_collisions.rs +++ b/module/core/derive_tools/tests/inc/deref_mut/name_collisions.rs @@ -2,7 +2,7 @@ #![ allow( unused_imports ) ] use ::core::ops::Deref; -use derive_tools::{ Deref, DerefMut }; +use derive_tools::{ DerefMut }; pub mod core {} pub mod std {} @@ -13,11 +13,20 @@ pub mod FromPair {} pub mod FromBin {} #[ allow( dead_code ) ] -#[ derive( Deref, DerefMut ) ] +#[ derive( DerefMut ) ] struct NameCollisions { a : i32, b : String, } -include!( "./only_tests/name_collisions.rs" ); +impl Deref for NameCollisions +{ + type Target = i32; + fn deref( &self ) -> &Self::Target + { + &self.a + } +} + +include!( "./only_test/name_collisions.rs" ); diff --git a/module/core/derive_tools/tests/inc/only_test/deref_mut.rs b/module/core/derive_tools/tests/inc/deref_mut/only_test/basic.rs similarity index 100% rename from module/core/derive_tools/tests/inc/only_test/deref_mut.rs rename to module/core/derive_tools/tests/inc/deref_mut/only_test/basic.rs diff --git a/module/core/derive_tools/tests/inc/deref_mut/only_tests/bounds_inlined.rs b/module/core/derive_tools/tests/inc/deref_mut/only_test/bounds_inlined.rs similarity index 100% rename from module/core/derive_tools/tests/inc/deref_mut/only_tests/bounds_inlined.rs rename to module/core/derive_tools/tests/inc/deref_mut/only_test/bounds_inlined.rs diff --git a/module/core/derive_tools/tests/inc/deref_mut/only_tests/bounds_mixed.rs b/module/core/derive_tools/tests/inc/deref_mut/only_test/bounds_mixed.rs similarity index 100% rename from module/core/derive_tools/tests/inc/deref_mut/only_tests/bounds_mixed.rs rename to module/core/derive_tools/tests/inc/deref_mut/only_test/bounds_mixed.rs diff --git a/module/core/derive_tools/tests/inc/deref_mut/only_tests/bounds_where.rs b/module/core/derive_tools/tests/inc/deref_mut/only_test/bounds_where.rs similarity index 100% rename from module/core/derive_tools/tests/inc/deref_mut/only_tests/bounds_where.rs rename to module/core/derive_tools/tests/inc/deref_mut/only_test/bounds_where.rs diff --git a/module/core/derive_tools/tests/inc/deref_mut/only_tests/enum_named.rs b/module/core/derive_tools/tests/inc/deref_mut/only_test/enum_named.rs similarity index 100% rename from module/core/derive_tools/tests/inc/deref_mut/only_tests/enum_named.rs rename to module/core/derive_tools/tests/inc/deref_mut/only_test/enum_named.rs diff --git a/module/core/derive_tools/tests/inc/deref_mut/only_tests/enum_tuple.rs b/module/core/derive_tools/tests/inc/deref_mut/only_test/enum_tuple.rs similarity index 100% rename from module/core/derive_tools/tests/inc/deref_mut/only_tests/enum_tuple.rs rename to module/core/derive_tools/tests/inc/deref_mut/only_test/enum_tuple.rs diff --git a/module/core/derive_tools/tests/inc/deref_mut/only_tests/generics_constants.rs b/module/core/derive_tools/tests/inc/deref_mut/only_test/generics_constants.rs similarity index 100% rename from module/core/derive_tools/tests/inc/deref_mut/only_tests/generics_constants.rs rename to module/core/derive_tools/tests/inc/deref_mut/only_test/generics_constants.rs diff --git a/module/core/derive_tools/tests/inc/deref_mut/only_tests/generics_constants_default.rs b/module/core/derive_tools/tests/inc/deref_mut/only_test/generics_constants_default.rs similarity index 100% rename from module/core/derive_tools/tests/inc/deref_mut/only_tests/generics_constants_default.rs rename to module/core/derive_tools/tests/inc/deref_mut/only_test/generics_constants_default.rs diff --git a/module/core/derive_tools/tests/inc/deref_mut/only_tests/generics_lifetimes.rs b/module/core/derive_tools/tests/inc/deref_mut/only_test/generics_lifetimes.rs similarity index 100% rename from module/core/derive_tools/tests/inc/deref_mut/only_tests/generics_lifetimes.rs rename to module/core/derive_tools/tests/inc/deref_mut/only_test/generics_lifetimes.rs diff --git a/module/core/derive_tools/tests/inc/deref_mut/only_tests/generics_types.rs b/module/core/derive_tools/tests/inc/deref_mut/only_test/generics_types.rs similarity index 100% rename from module/core/derive_tools/tests/inc/deref_mut/only_tests/generics_types.rs rename to module/core/derive_tools/tests/inc/deref_mut/only_test/generics_types.rs diff --git a/module/core/derive_tools/tests/inc/deref_mut/only_tests/generics_types_default.rs b/module/core/derive_tools/tests/inc/deref_mut/only_test/generics_types_default.rs similarity index 100% rename from module/core/derive_tools/tests/inc/deref_mut/only_tests/generics_types_default.rs rename to module/core/derive_tools/tests/inc/deref_mut/only_test/generics_types_default.rs diff --git a/module/core/derive_tools/tests/inc/deref_mut/only_tests/name_collisions.rs b/module/core/derive_tools/tests/inc/deref_mut/only_test/name_collisions.rs similarity index 100% rename from module/core/derive_tools/tests/inc/deref_mut/only_tests/name_collisions.rs rename to module/core/derive_tools/tests/inc/deref_mut/only_test/name_collisions.rs diff --git a/module/core/derive_tools/tests/inc/deref_mut/only_tests/struct_named.rs b/module/core/derive_tools/tests/inc/deref_mut/only_test/struct_named.rs similarity index 100% rename from module/core/derive_tools/tests/inc/deref_mut/only_tests/struct_named.rs rename to module/core/derive_tools/tests/inc/deref_mut/only_test/struct_named.rs diff --git a/module/core/derive_tools/tests/inc/deref_mut/only_tests/struct_tuple.rs b/module/core/derive_tools/tests/inc/deref_mut/only_test/struct_tuple.rs similarity index 100% rename from module/core/derive_tools/tests/inc/deref_mut/only_tests/struct_tuple.rs rename to module/core/derive_tools/tests/inc/deref_mut/only_test/struct_tuple.rs diff --git a/module/core/derive_tools/tests/inc/deref_mut/struct_named.rs b/module/core/derive_tools/tests/inc/deref_mut/struct_named.rs index 4cf35f59df..6edd933c33 100644 --- a/module/core/derive_tools/tests/inc/deref_mut/struct_named.rs +++ b/module/core/derive_tools/tests/inc/deref_mut/struct_named.rs @@ -1,12 +1,21 @@ -use core::ops::{ Deref }; -use derive_tools::{ Deref, DerefMut }; +use core::ops::Deref; +use derive_tools::DerefMut; #[ allow( dead_code ) ] -#[ derive( Deref, DerefMut ) ] +#[ derive( DerefMut ) ] struct StructNamed { a : String, b : i32, } -include!( "./only_tests/struct_named.rs" ); +impl Deref for StructNamed +{ + type Target = String; + fn deref( &self ) -> &Self::Target + { + &self.a + } +} + +include!( "./only_test/struct_named.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/struct_named_manual.rs b/module/core/derive_tools/tests/inc/deref_mut/struct_named_manual.rs index 24cff7f14a..cac020e425 100644 --- a/module/core/derive_tools/tests/inc/deref_mut/struct_named_manual.rs +++ b/module/core/derive_tools/tests/inc/deref_mut/struct_named_manual.rs @@ -23,4 +23,4 @@ impl DerefMut for StructNamed } } -include!( "./only_tests/struct_named.rs" ); +include!( "./only_test/struct_named.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/struct_tuple.rs b/module/core/derive_tools/tests/inc/deref_mut/struct_tuple.rs index 5d5d439859..657b799050 100644 --- a/module/core/derive_tools/tests/inc/deref_mut/struct_tuple.rs +++ b/module/core/derive_tools/tests/inc/deref_mut/struct_tuple.rs @@ -1,8 +1,17 @@ -use core::ops::{ Deref }; -use derive_tools::{ Deref, DerefMut }; +use core::ops::Deref; +use derive_tools::DerefMut; #[ allow( dead_code ) ] -#[ derive ( Deref, DerefMut ) ] +#[ derive ( DerefMut ) ] struct StructTuple( String, i32 ); -include!( "./only_tests/struct_tuple.rs" ); +impl Deref for StructTuple +{ + type Target = String; + fn deref( &self ) -> &Self::Target + { + &self.0 + } +} + +include!( "./only_test/struct_tuple.rs" ); diff --git a/module/core/derive_tools/tests/inc/deref_mut/struct_tuple_manual.rs b/module/core/derive_tools/tests/inc/deref_mut/struct_tuple_manual.rs index de82ac329c..4212b878b1 100644 --- a/module/core/derive_tools/tests/inc/deref_mut/struct_tuple_manual.rs +++ b/module/core/derive_tools/tests/inc/deref_mut/struct_tuple_manual.rs @@ -19,4 +19,4 @@ impl DerefMut for StructTuple } } -include!( "./only_tests/struct_tuple.rs" ); +include!( "./only_test/struct_tuple.rs" ); diff --git a/module/core/derive_tools/tests/inc/from/manual_test.rs b/module/core/derive_tools/tests/inc/from/basic_manual_test.rs similarity index 100% rename from module/core/derive_tools/tests/inc/from/manual_test.rs rename to module/core/derive_tools/tests/inc/from/basic_manual_test.rs diff --git a/module/core/derive_tools/tests/inc/from/test.rs b/module/core/derive_tools/tests/inc/from/basic_test.rs similarity index 100% rename from module/core/derive_tools/tests/inc/from/test.rs rename to module/core/derive_tools/tests/inc/from/basic_test.rs diff --git a/module/core/derive_tools/tests/inc/from/multiple_named_manual_test.rs b/module/core/derive_tools/tests/inc/from/multiple_named_manual_test.rs index 02b756b5f5..ff1a641cbf 100644 --- a/module/core/derive_tools/tests/inc/from/multiple_named_manual_test.rs +++ b/module/core/derive_tools/tests/inc/from/multiple_named_manual_test.rs @@ -3,8 +3,8 @@ use super::*; #[ derive( Debug, PartialEq, Eq ) ] struct StructNamedFields { - a: i32, - b: bool, + a : i32, + b : bool, } impl From< ( i32, bool ) > for StructNamedFields @@ -12,7 +12,7 @@ impl From< ( i32, bool ) > for StructNamedFields #[ inline( always ) ] fn from( src : ( i32, bool ) ) -> Self { - Self{ a: src.0, b: src.1 } + Self{ a : src.0, b : src.1 } } } diff --git a/module/core/derive_tools/tests/inc/from/multiple_named_test.rs b/module/core/derive_tools/tests/inc/from/multiple_named_test.rs index ddb088c624..dbb2c6c4dc 100644 --- a/module/core/derive_tools/tests/inc/from/multiple_named_test.rs +++ b/module/core/derive_tools/tests/inc/from/multiple_named_test.rs @@ -3,8 +3,8 @@ use super::*; #[ derive( Debug, PartialEq, Eq, the_module::From ) ] struct StructNamedFields { - a: i32, - b: bool, + a : i32, + b : bool, } include!( "./only_test/multiple_named.rs" ); diff --git a/module/core/derive_tools/tests/inc/from/multiple_manual_test.rs b/module/core/derive_tools/tests/inc/from/multiple_unnamed_manual_test.rs similarity index 84% rename from module/core/derive_tools/tests/inc/from/multiple_manual_test.rs rename to module/core/derive_tools/tests/inc/from/multiple_unnamed_manual_test.rs index b44fc6b651..8f3feba833 100644 --- a/module/core/derive_tools/tests/inc/from/multiple_manual_test.rs +++ b/module/core/derive_tools/tests/inc/from/multiple_unnamed_manual_test.rs @@ -12,4 +12,4 @@ impl From< ( i32, bool ) > for StructWithManyFields } } -include!( "./only_test/multiple.rs" ); +include!( "./only_test/multiple_unnamed.rs" ); diff --git a/module/core/derive_tools/tests/inc/from/multiple_test.rs b/module/core/derive_tools/tests/inc/from/multiple_unnamed_test.rs similarity index 70% rename from module/core/derive_tools/tests/inc/from/multiple_test.rs rename to module/core/derive_tools/tests/inc/from/multiple_unnamed_test.rs index 925cd66ca0..f4757f1a1a 100644 --- a/module/core/derive_tools/tests/inc/from/multiple_test.rs +++ b/module/core/derive_tools/tests/inc/from/multiple_unnamed_test.rs @@ -3,4 +3,4 @@ use super::*; #[ derive( Debug, PartialEq, Eq, the_module::From ) ] struct StructWithManyFields( i32, bool ); -include!( "./only_test/multiple.rs" ); +include!( "./only_test/multiple_unnamed.rs" ); diff --git a/module/core/derive_tools/tests/inc/from/named_manual_test.rs b/module/core/derive_tools/tests/inc/from/named_manual_test.rs index 6118d32e69..cc3b47f4c5 100644 --- a/module/core/derive_tools/tests/inc/from/named_manual_test.rs +++ b/module/core/derive_tools/tests/inc/from/named_manual_test.rs @@ -3,7 +3,7 @@ use super::*; #[ derive( Debug, PartialEq, Eq ) ] struct MyStruct { - a: i32, + a : i32, } impl From< i32 > for MyStruct @@ -11,7 +11,7 @@ impl From< i32 > for MyStruct #[ inline( always ) ] fn from( src : i32 ) -> Self { - Self{ a: src } + Self{ a : src } } } diff --git a/module/core/derive_tools/tests/inc/from/only_test/basic.rs b/module/core/derive_tools/tests/inc/from/only_test/basic.rs index f7f591e3c0..edd9526697 100644 --- a/module/core/derive_tools/tests/inc/from/only_test/basic.rs +++ b/module/core/derive_tools/tests/inc/from/only_test/basic.rs @@ -31,3 +31,5 @@ fn from_test() // a_id!( *got, exp ); } + +// xxx \ No newline at end of file diff --git a/module/core/derive_tools/tests/inc/from/only_test/multiple.rs b/module/core/derive_tools/tests/inc/from/only_test/multiple_unnamed.rs similarity index 100% rename from module/core/derive_tools/tests/inc/from/only_test/multiple.rs rename to module/core/derive_tools/tests/inc/from/only_test/multiple_unnamed.rs diff --git a/module/core/derive_tools/tests/inc/from/variants_collisions.rs b/module/core/derive_tools/tests/inc/from/variants_collisions.rs index aefa3be96f..7b858a6b8c 100644 --- a/module/core/derive_tools/tests/inc/from/variants_collisions.rs +++ b/module/core/derive_tools/tests/inc/from/variants_collisions.rs @@ -10,6 +10,8 @@ pub mod FromString {} pub mod FromPair {} pub mod FromBin {} +// qqq : add collision tests for 4 outher branches + #[ derive( Debug, PartialEq, the_module::From ) ] // #[ debug ] pub enum GetData diff --git a/module/core/derive_tools/tests/inc/index/compiletime/enum.rs b/module/core/derive_tools/tests/inc/index/compiletime/enum.rs new file mode 100644 index 0000000000..543ebde1f0 --- /dev/null +++ b/module/core/derive_tools/tests/inc/index/compiletime/enum.rs @@ -0,0 +1,13 @@ +use derive_tools::Index; + +#[ derive( Index ) ] +enum Enum< T > +{ + Nothing, + #[ index ] + IndexVector( Vec< T > ) +} + +fn main() +{ +} diff --git a/module/core/derive_tools/tests/inc/index/compiletime/enum.stderr b/module/core/derive_tools/tests/inc/index/compiletime/enum.stderr new file mode 100644 index 0000000000..fd33fec0c1 --- /dev/null +++ b/module/core/derive_tools/tests/inc/index/compiletime/enum.stderr @@ -0,0 +1,7 @@ +error: proc-macro derive panicked + --> tests/inc/index/compiletime/enum.rs:3:12 + | +3 | #[ derive( Index ) ] + | ^^^^^ + | + = help: message: not implemented: Index not implemented for Enum diff --git a/module/core/derive_tools/tests/inc/index/compiletime/struct.rs b/module/core/derive_tools/tests/inc/index/compiletime/struct.rs new file mode 100644 index 0000000000..df10669a10 --- /dev/null +++ b/module/core/derive_tools/tests/inc/index/compiletime/struct.rs @@ -0,0 +1,14 @@ +use derive_tools::Index; + +#[ derive( Index ) ] +struct StructMultipleNamed< T > +{ + #[ index ] + a : Vec< T >, + #[ index ] + b : Vec< T >, +} + +fn main() +{ +} diff --git a/module/core/derive_tools/tests/inc/index/compiletime/struct.stderr b/module/core/derive_tools/tests/inc/index/compiletime/struct.stderr new file mode 100644 index 0000000000..2410de4629 --- /dev/null +++ b/module/core/derive_tools/tests/inc/index/compiletime/struct.stderr @@ -0,0 +1,8 @@ +error: Only one field can include #[ index ] derive macro + --> tests/inc/index/compiletime/struct.rs:6:3 + | +6 | / #[ index ] +7 | | a : Vec< T >, +8 | | #[ index ] +9 | | b : Vec< T >, + | |_______________^ diff --git a/module/core/derive_tools/tests/inc/index/compiletime/struct_named_empty.rs b/module/core/derive_tools/tests/inc/index/compiletime/struct_named_empty.rs new file mode 100644 index 0000000000..ec15e88da3 --- /dev/null +++ b/module/core/derive_tools/tests/inc/index/compiletime/struct_named_empty.rs @@ -0,0 +1,10 @@ +use derive_tools::Index; + +#[ derive( Index ) ] +struct EmptyStruct +{ +} + +fn main() +{ +} diff --git a/module/core/derive_tools/tests/inc/index/compiletime/struct_named_empty.stderr b/module/core/derive_tools/tests/inc/index/compiletime/struct_named_empty.stderr new file mode 100644 index 0000000000..fc7bc03403 --- /dev/null +++ b/module/core/derive_tools/tests/inc/index/compiletime/struct_named_empty.stderr @@ -0,0 +1,7 @@ +error: proc-macro derive panicked + --> tests/inc/index/compiletime/struct_named_empty.rs:3:12 + | +3 | #[ derive( Index ) ] + | ^^^^^ + | + = help: message: not implemented: Index not implemented for Unit diff --git a/module/core/derive_tools/tests/inc/index/compiletime/struct_unit.rs b/module/core/derive_tools/tests/inc/index/compiletime/struct_unit.rs new file mode 100644 index 0000000000..84375aef65 --- /dev/null +++ b/module/core/derive_tools/tests/inc/index/compiletime/struct_unit.rs @@ -0,0 +1,9 @@ +use derive_tools::Index; + +#[ derive( Index ) ] +struct StructUnit; + +fn main() +{ + +} diff --git a/module/core/derive_tools/tests/inc/index/compiletime/struct_unit.stderr b/module/core/derive_tools/tests/inc/index/compiletime/struct_unit.stderr new file mode 100644 index 0000000000..644279835a --- /dev/null +++ b/module/core/derive_tools/tests/inc/index/compiletime/struct_unit.stderr @@ -0,0 +1,7 @@ +error: proc-macro derive panicked + --> tests/inc/index/compiletime/struct_unit.rs:3:12 + | +3 | #[ derive( Index ) ] + | ^^^^^ + | + = help: message: not implemented: Index not implemented for Unit diff --git a/module/core/derive_tools/tests/inc/index/only_test/struct_multiple_named.rs b/module/core/derive_tools/tests/inc/index/only_test/struct_multiple_named.rs new file mode 100644 index 0000000000..50ea4f671a --- /dev/null +++ b/module/core/derive_tools/tests/inc/index/only_test/struct_multiple_named.rs @@ -0,0 +1,14 @@ +#[ test ] +fn index() +{ + let x = StructMultipleNamed + { + a : vec![ 12, 22 ], + b : vec![ 33, 55 ] + }; + let v = vec![ 33, 55 ]; + let exp = ( v[ 0 ], v[ 1 ] ); + let got = ( x[ 0 ], x[ 1 ] ); + + assert_eq!( got, exp ); +} diff --git a/module/core/derive_tools/tests/inc/index/only_test/struct_multiple_tuple.rs b/module/core/derive_tools/tests/inc/index/only_test/struct_multiple_tuple.rs new file mode 100644 index 0000000000..18dc0a71e1 --- /dev/null +++ b/module/core/derive_tools/tests/inc/index/only_test/struct_multiple_tuple.rs @@ -0,0 +1,8 @@ +#[ test ] +fn index() +{ + let x = StructMultipleTuple( false, vec![ 2, 44, 81 ] ); + let exp = ( 2, 44 ); + let got = ( x[ 0 ], x[ 1 ] ); + assert_eq!( got, exp ); +} diff --git a/module/core/derive_tools/tests/inc/index/only_test/struct_named.rs b/module/core/derive_tools/tests/inc/index/only_test/struct_named.rs new file mode 100644 index 0000000000..2d17264939 --- /dev/null +++ b/module/core/derive_tools/tests/inc/index/only_test/struct_named.rs @@ -0,0 +1,13 @@ +#[ test ] +fn index() +{ + let x = StructNamed + { + a : vec![ false, true ] + }; + let v = vec![ false, true ]; + let exp = ( v[ 0 ], v[ 1 ] ); + let got = ( x[ 0 ], x[ 1 ] ); + + assert_eq!( got, exp ); +} diff --git a/module/core/derive_tools/tests/inc/index/only_test/struct_tuple.rs b/module/core/derive_tools/tests/inc/index/only_test/struct_tuple.rs new file mode 100644 index 0000000000..ef3d479590 --- /dev/null +++ b/module/core/derive_tools/tests/inc/index/only_test/struct_tuple.rs @@ -0,0 +1,9 @@ +#[ test ] +fn index() +{ + let x = StructTuple( vec![ 2, 44, 81 ] ); + let exp = ( 2, 44 ); + let got = ( x[ 0 ], x[ 1 ] ); + + assert_eq!( got, exp ); +} diff --git a/module/core/derive_tools/tests/inc/index/struct_collisions.rs b/module/core/derive_tools/tests/inc/index/struct_collisions.rs new file mode 100644 index 0000000000..5d000f096c --- /dev/null +++ b/module/core/derive_tools/tests/inc/index/struct_collisions.rs @@ -0,0 +1,23 @@ +#![ allow( non_snake_case ) ] +#![ allow( unused_imports ) ] +use super::*; + +pub mod core {} +pub mod std {} +pub mod marker {} + +pub mod a {} +pub mod b {} + +#[ derive( the_module::Index, the_module::From ) ] +#[ allow( dead_code ) ] +struct StructMultipleNamed< T > +{ + #[ from ( on ) ] + a : Vec< T >, + #[ index ] + b : Vec< T >, +} + +include!( "./only_test/struct_multiple_named.rs" ); + diff --git a/module/core/derive_tools/tests/inc/index/struct_multiple_named_field.rs b/module/core/derive_tools/tests/inc/index/struct_multiple_named_field.rs new file mode 100644 index 0000000000..a99e72a7b5 --- /dev/null +++ b/module/core/derive_tools/tests/inc/index/struct_multiple_named_field.rs @@ -0,0 +1,14 @@ +#![ allow( dead_code ) ] +#[ allow( unused_imports ) ] +use super::*; + +#[ derive( the_module::Index ) ] +struct StructMultipleNamed< T > +{ + a : Vec< T >, + #[ index ] + b : Vec< T >, +} + +include!( "./only_test/struct_multiple_named.rs" ); + diff --git a/module/core/derive_tools/tests/inc/index/struct_multiple_named_item.rs b/module/core/derive_tools/tests/inc/index/struct_multiple_named_item.rs new file mode 100644 index 0000000000..e2751673f8 --- /dev/null +++ b/module/core/derive_tools/tests/inc/index/struct_multiple_named_item.rs @@ -0,0 +1,13 @@ +#![ allow( dead_code ) ] +#[ allow( unused_imports ) ] +use super::*; + +#[ derive( the_module::Index ) ] +#[ index ( name = b ) ] +struct StructMultipleNamed< T > +{ + a : Vec< T >, + b : Vec< T >, +} + +include!( "./only_test/struct_multiple_named.rs" ); diff --git a/module/core/derive_tools/tests/inc/index/struct_multiple_named_manual.rs b/module/core/derive_tools/tests/inc/index/struct_multiple_named_manual.rs new file mode 100644 index 0000000000..ff3d26f7e2 --- /dev/null +++ b/module/core/derive_tools/tests/inc/index/struct_multiple_named_manual.rs @@ -0,0 +1,20 @@ +use core::ops::Index; + +#[ allow( dead_code ) ] +struct StructMultipleNamed< T > +{ + a : Vec< T >, + b : Vec< T >, +} + +impl< T > Index< usize > for StructMultipleNamed< T > +{ + type Output = T; + + fn index( &self, index : usize ) -> &Self::Output + { + &self.b[ index ] + } +} + +include!( "./only_test/struct_multiple_named.rs" ); diff --git a/module/core/derive_tools/tests/inc/index/struct_multiple_tuple.rs b/module/core/derive_tools/tests/inc/index/struct_multiple_tuple.rs new file mode 100644 index 0000000000..1228949d1f --- /dev/null +++ b/module/core/derive_tools/tests/inc/index/struct_multiple_tuple.rs @@ -0,0 +1,13 @@ +#![ allow( dead_code ) ] +#[ allow( unused_imports ) ] +use super::*; + +#[ derive( the_module::Index ) ] +struct StructMultipleTuple< T > +( + bool, + #[ index ] + Vec< T >, +); + +include!( "./only_test/struct_multiple_tuple.rs" ); diff --git a/module/core/derive_tools/tests/inc/index/struct_multiple_tuple_manual.rs b/module/core/derive_tools/tests/inc/index/struct_multiple_tuple_manual.rs new file mode 100644 index 0000000000..12a58b2ae6 --- /dev/null +++ b/module/core/derive_tools/tests/inc/index/struct_multiple_tuple_manual.rs @@ -0,0 +1,16 @@ +use core::ops::Index; + +#[ allow( dead_code) ] +struct StructMultipleTuple< T >( bool, Vec< T > ); + +impl< T > Index< usize > for StructMultipleTuple< T > +{ + type Output = T; + + fn index( &self, index : usize ) -> &Self::Output + { + &self.1[ index ] + } +} + +include!( "./only_test/struct_multiple_tuple.rs" ); diff --git a/module/core/derive_tools/tests/inc/index/struct_named.rs b/module/core/derive_tools/tests/inc/index/struct_named.rs new file mode 100644 index 0000000000..ca5b884595 --- /dev/null +++ b/module/core/derive_tools/tests/inc/index/struct_named.rs @@ -0,0 +1,12 @@ +#![ allow( dead_code ) ] +#[ allow( unused_imports ) ] +use super::*; + +#[ derive( the_module::Index ) ] +struct StructNamed< T > +{ + #[ index ] + a : Vec< T >, +} + +include!( "./only_test/struct_named.rs" ); diff --git a/module/core/derive_tools/tests/inc/index/struct_named_manual.rs b/module/core/derive_tools/tests/inc/index/struct_named_manual.rs new file mode 100644 index 0000000000..e66ce4131d --- /dev/null +++ b/module/core/derive_tools/tests/inc/index/struct_named_manual.rs @@ -0,0 +1,19 @@ +use core::ops::Index; + +#[ allow( dead_code ) ] +struct StructNamed< T > +{ + a : Vec< T > +} + +impl< T > Index< usize > for StructNamed< T > +{ + type Output = T; + + fn index( &self, index : usize ) -> &Self::Output + { + &self.a[ index ] + } +} + +include!( "./only_test/struct_named.rs" ); diff --git a/module/core/derive_tools/tests/inc/index/struct_tuple.rs b/module/core/derive_tools/tests/inc/index/struct_tuple.rs new file mode 100644 index 0000000000..97728a8753 --- /dev/null +++ b/module/core/derive_tools/tests/inc/index/struct_tuple.rs @@ -0,0 +1,11 @@ +use super::*; + +#[ allow( dead_code ) ] +#[ derive( the_module::Index ) ] +struct StructTuple< T > +( + #[ index ] + Vec< T > +); + +include!( "./only_test/struct_tuple.rs" ); diff --git a/module/core/derive_tools/tests/inc/index/struct_tuple_manual.rs b/module/core/derive_tools/tests/inc/index/struct_tuple_manual.rs new file mode 100644 index 0000000000..14582ff909 --- /dev/null +++ b/module/core/derive_tools/tests/inc/index/struct_tuple_manual.rs @@ -0,0 +1,16 @@ +use core::ops::Index; + +#[ allow( dead_code) ] +struct StructTuple< T >( Vec< T > ); + +impl< T > Index< usize > for StructTuple< T > +{ + type Output = T; + + fn index( &self, index : usize ) -> &Self::Output + { + &self.0[ index ] + } +} + +include!( "./only_test/struct_tuple.rs" ); diff --git a/module/core/derive_tools/tests/inc/index_mut/compiletime/enum.rs b/module/core/derive_tools/tests/inc/index_mut/compiletime/enum.rs new file mode 100644 index 0000000000..29357cf2a3 --- /dev/null +++ b/module/core/derive_tools/tests/inc/index_mut/compiletime/enum.rs @@ -0,0 +1,13 @@ +use derive_tools::IndexMut; + +#[ derive( IndexMut ) ] +enum Enum< T > +{ + Nothing, + #[ index ] + IndexVector( Vec< T > ) +} + +fn main() +{ +} diff --git a/module/core/derive_tools/tests/inc/index_mut/compiletime/enum.stderr b/module/core/derive_tools/tests/inc/index_mut/compiletime/enum.stderr new file mode 100644 index 0000000000..47952cbcbe --- /dev/null +++ b/module/core/derive_tools/tests/inc/index_mut/compiletime/enum.stderr @@ -0,0 +1,7 @@ +error: proc-macro derive panicked + --> tests/inc/index_mut/compiletime/enum.rs:3:12 + | +3 | #[ derive( IndexMut ) ] + | ^^^^^^^^ + | + = help: message: not implemented: IndexMut not implemented for Enum diff --git a/module/core/derive_tools/tests/inc/index_mut/compiletime/struct.rs b/module/core/derive_tools/tests/inc/index_mut/compiletime/struct.rs new file mode 100644 index 0000000000..119c1ec1ba --- /dev/null +++ b/module/core/derive_tools/tests/inc/index_mut/compiletime/struct.rs @@ -0,0 +1,14 @@ +use derive_tools::IndexMut; + +#[ derive( IndexMut ) ] +struct StructMultipleNamed< T > +{ + #[ index ] + a : Vec< T >, + #[ index ] + b : Vec< T >, +} + +fn main() +{ +} diff --git a/module/core/derive_tools/tests/inc/index_mut/compiletime/struct.stderr b/module/core/derive_tools/tests/inc/index_mut/compiletime/struct.stderr new file mode 100644 index 0000000000..ebe09c13f9 --- /dev/null +++ b/module/core/derive_tools/tests/inc/index_mut/compiletime/struct.stderr @@ -0,0 +1,8 @@ +error: Only one field can include #[ index ] derive macro + --> tests/inc/index_mut/compiletime/struct.rs:6:3 + | +6 | / #[ index ] +7 | | a : Vec< T >, +8 | | #[ index ] +9 | | b : Vec< T >, + | |_______________^ diff --git a/module/core/derive_tools/tests/inc/index_mut/compiletime/struct_named_empty.rs b/module/core/derive_tools/tests/inc/index_mut/compiletime/struct_named_empty.rs new file mode 100644 index 0000000000..898f8f3dfa --- /dev/null +++ b/module/core/derive_tools/tests/inc/index_mut/compiletime/struct_named_empty.rs @@ -0,0 +1,10 @@ +use derive_tools::IndexMut; + +#[ derive( IndexMut ) ] +struct EmptyStruct +{ +} + +fn main() +{ +} diff --git a/module/core/derive_tools/tests/inc/index_mut/compiletime/struct_named_empty.stderr b/module/core/derive_tools/tests/inc/index_mut/compiletime/struct_named_empty.stderr new file mode 100644 index 0000000000..08eabad5aa --- /dev/null +++ b/module/core/derive_tools/tests/inc/index_mut/compiletime/struct_named_empty.stderr @@ -0,0 +1,7 @@ +error: proc-macro derive panicked + --> tests/inc/index_mut/compiletime/struct_named_empty.rs:3:12 + | +3 | #[ derive( IndexMut ) ] + | ^^^^^^^^ + | + = help: message: not implemented: IndexMut not implemented for Unit diff --git a/module/core/derive_tools/tests/inc/index_mut/compiletime/struct_unit.rs b/module/core/derive_tools/tests/inc/index_mut/compiletime/struct_unit.rs new file mode 100644 index 0000000000..ce59c37b15 --- /dev/null +++ b/module/core/derive_tools/tests/inc/index_mut/compiletime/struct_unit.rs @@ -0,0 +1,9 @@ +use derive_tools::IndexMut; + +#[ derive( IndexMut ) ] +struct StructUnit; + +fn main() +{ + +} diff --git a/module/core/derive_tools/tests/inc/index_mut/compiletime/struct_unit.stderr b/module/core/derive_tools/tests/inc/index_mut/compiletime/struct_unit.stderr new file mode 100644 index 0000000000..2497827a4e --- /dev/null +++ b/module/core/derive_tools/tests/inc/index_mut/compiletime/struct_unit.stderr @@ -0,0 +1,7 @@ +error: proc-macro derive panicked + --> tests/inc/index_mut/compiletime/struct_unit.rs:3:12 + | +3 | #[ derive( IndexMut ) ] + | ^^^^^^^^ + | + = help: message: not implemented: IndexMut not implemented for Unit diff --git a/module/core/derive_tools/tests/inc/index_mut/only_test/struct_multiple_named.rs b/module/core/derive_tools/tests/inc/index_mut/only_test/struct_multiple_named.rs new file mode 100644 index 0000000000..0d79398809 --- /dev/null +++ b/module/core/derive_tools/tests/inc/index_mut/only_test/struct_multiple_named.rs @@ -0,0 +1,20 @@ +#[ test ] +fn index_mut() +{ + let mut x = StructMultipleNamed + { + a : vec![ 4, 17 ], + b : vec![ 33, 55 ] + }; + + x[ 0 ] = 5; + x[ 1 ] = 18; + let v = vec![ 5, 18 ]; + + let exp = ( v[ 0 ], v[ 1 ] ); + let got = ( x[ 0 ], x[ 1 ] ); + + assert_eq!( got, exp ); +} + + diff --git a/module/core/derive_tools/tests/inc/index_mut/only_test/struct_multiple_tuple.rs b/module/core/derive_tools/tests/inc/index_mut/only_test/struct_multiple_tuple.rs new file mode 100644 index 0000000000..115e50ad7e --- /dev/null +++ b/module/core/derive_tools/tests/inc/index_mut/only_test/struct_multiple_tuple.rs @@ -0,0 +1,14 @@ +#[ test ] +fn index_mut() +{ + let mut x = StructMultipleTuple( false, vec![ 2, 44, 81 ] ); + + x[ 0 ] = 18; + x[ 1 ] = 99; + + let exp = ( 18, 99 ); + let got = ( x[ 0 ], x[ 1 ] ); + + assert_eq!( got, exp ); +} + diff --git a/module/core/derive_tools/tests/inc/index_mut/only_test/struct_named.rs b/module/core/derive_tools/tests/inc/index_mut/only_test/struct_named.rs new file mode 100644 index 0000000000..c2e20f82fe --- /dev/null +++ b/module/core/derive_tools/tests/inc/index_mut/only_test/struct_named.rs @@ -0,0 +1,18 @@ +#[ test ] +fn index_mut() +{ + let mut x = StructNamed + { + a : vec![ 4, 17 ] + }; + + x[ 0 ] = 5; + x[ 1 ] = 18; + let v = vec![ 5, 18 ]; + + let exp = ( v[ 0 ], v[ 1 ] ); + let got = ( x[ 0 ], x[ 1 ] ); + + assert_eq!( got, exp ); +} + diff --git a/module/core/derive_tools/tests/inc/index_mut/only_test/struct_tuple.rs b/module/core/derive_tools/tests/inc/index_mut/only_test/struct_tuple.rs new file mode 100644 index 0000000000..e120e9ffbe --- /dev/null +++ b/module/core/derive_tools/tests/inc/index_mut/only_test/struct_tuple.rs @@ -0,0 +1,14 @@ +#[ test ] +fn index_mut() +{ + let mut x = StructTuple( vec![ 2, 44, 81 ] ); + + x[ 0 ] = 18; + x[ 1 ] = 99; + + let exp = ( 18, 99 ); + let got = ( x[ 0 ], x[ 1 ] ); + + assert_eq!( got, exp ); +} + diff --git a/module/core/derive_tools/tests/inc/index_mut/struct_collisions.rs b/module/core/derive_tools/tests/inc/index_mut/struct_collisions.rs new file mode 100644 index 0000000000..26349c9cf5 --- /dev/null +++ b/module/core/derive_tools/tests/inc/index_mut/struct_collisions.rs @@ -0,0 +1,22 @@ + +#![ allow( non_snake_case ) ] +#![ allow( unused_imports ) ] +use super::*; + +pub mod core {} +pub mod std {} +pub mod marker {} + +pub mod a {} +pub mod b {} + +#[ derive( the_module::IndexMut ) ] +#[ allow( dead_code ) ] +struct StructMultipleNamed< T > +{ + a : Vec< T >, + #[ index ] + b : Vec< T >, +} + +include!( "./only_test/struct_multiple_named.rs" ); diff --git a/module/core/derive_tools/tests/inc/index_mut/struct_multiple_named_field.rs b/module/core/derive_tools/tests/inc/index_mut/struct_multiple_named_field.rs new file mode 100644 index 0000000000..4ba00b6f89 --- /dev/null +++ b/module/core/derive_tools/tests/inc/index_mut/struct_multiple_named_field.rs @@ -0,0 +1,14 @@ +#![ allow( dead_code ) ] +#[ allow( unused_imports ) ] +use super::*; + +#[ derive( the_module::IndexMut ) ] +struct StructMultipleNamed< T > +{ + a : Vec< T >, + #[ index ] + b : Vec< T >, +} + +include!( "./only_test/struct_multiple_named.rs" ); + diff --git a/module/core/derive_tools/tests/inc/index_mut/struct_multiple_named_item.rs b/module/core/derive_tools/tests/inc/index_mut/struct_multiple_named_item.rs new file mode 100644 index 0000000000..4620c59687 --- /dev/null +++ b/module/core/derive_tools/tests/inc/index_mut/struct_multiple_named_item.rs @@ -0,0 +1,15 @@ +#![ allow( dead_code ) ] +#[ allow( unused_imports ) ] +use super::*; + +#[ derive( the_module::IndexMut ) ] +#[ index( name = b ) ] +struct StructMultipleNamed< T > +{ + a : Vec< T >, + b : Vec< T >, +} + +include!( "./only_test/struct_multiple_named.rs" ); + + diff --git a/module/core/derive_tools/tests/inc/index_mut/struct_multiple_named_manual.rs b/module/core/derive_tools/tests/inc/index_mut/struct_multiple_named_manual.rs new file mode 100644 index 0000000000..1d8830a6da --- /dev/null +++ b/module/core/derive_tools/tests/inc/index_mut/struct_multiple_named_manual.rs @@ -0,0 +1,30 @@ +use core::ops::{ Index, IndexMut }; + +#[ allow( dead_code ) ] +struct StructMultipleNamed< T > +{ + a : Vec< T >, + b : Vec< T >, +} + +impl< T > Index< usize > for StructMultipleNamed< T > +{ + type Output = T; + + fn index( &self, index : usize ) -> &Self::Output + { + &self.b[ index ] + } +} + +impl< T > IndexMut< usize > for StructMultipleNamed< T > +{ + fn index_mut( &mut self, index : usize ) -> &mut Self::Output + { + &mut self.b[ index ] + } +} + + +include!( "./only_test/struct_multiple_named.rs" ); + diff --git a/module/core/derive_tools/tests/inc/index_mut/struct_multiple_tuple.rs b/module/core/derive_tools/tests/inc/index_mut/struct_multiple_tuple.rs new file mode 100644 index 0000000000..41c9a21877 --- /dev/null +++ b/module/core/derive_tools/tests/inc/index_mut/struct_multiple_tuple.rs @@ -0,0 +1,15 @@ +#![ allow( dead_code ) ] +#[ allow( unused_imports ) ] +use super::*; + + +#[ derive( the_module::IndexMut ) ] +struct StructMultipleTuple< T > +( + bool, + #[ index ] + Vec< T > +); + +include!( "./only_test/struct_multiple_tuple.rs" ); + diff --git a/module/core/derive_tools/tests/inc/index_mut/struct_multiple_tuple_manual.rs b/module/core/derive_tools/tests/inc/index_mut/struct_multiple_tuple_manual.rs new file mode 100644 index 0000000000..66ffeb906f --- /dev/null +++ b/module/core/derive_tools/tests/inc/index_mut/struct_multiple_tuple_manual.rs @@ -0,0 +1,27 @@ +use core::ops::{ Index, IndexMut }; + +#[ allow( dead_code ) ] +struct StructMultipleTuple< T >( bool, Vec< T > ); + +impl< T > Index< usize > for StructMultipleTuple< T > +{ + type Output = T; + + fn index( &self, index : usize ) -> &Self::Output + { + &self.1[ index ] + } +} + +impl< T > IndexMut< usize > for StructMultipleTuple< T > +{ + fn index_mut( &mut self, index : usize ) -> &mut Self::Output + { + &mut self.1[ index ] + } +} + + +include!( "./only_test/struct_multiple_tuple.rs" ); + + diff --git a/module/core/derive_tools/tests/inc/index_mut/struct_named.rs b/module/core/derive_tools/tests/inc/index_mut/struct_named.rs new file mode 100644 index 0000000000..162547488a --- /dev/null +++ b/module/core/derive_tools/tests/inc/index_mut/struct_named.rs @@ -0,0 +1,12 @@ +#![ allow( dead_code ) ] +#[ allow( unused_imports ) ] +use super::*; + +#[ derive( the_module::IndexMut ) ] +struct StructNamed< T > +{ + #[ index ] + a : Vec< T >, +} + +include!( "./only_test/struct_named.rs" ); diff --git a/module/core/derive_tools/tests/inc/index_mut/struct_named_manual.rs b/module/core/derive_tools/tests/inc/index_mut/struct_named_manual.rs new file mode 100644 index 0000000000..2c8c3bebc4 --- /dev/null +++ b/module/core/derive_tools/tests/inc/index_mut/struct_named_manual.rs @@ -0,0 +1,28 @@ +use core::ops::{ Index, IndexMut }; + +#[ allow( dead_code ) ] +struct StructNamed< T > +{ + a : Vec< T > +} + +impl< T > Index< usize > for StructNamed< T > +{ + type Output = T; + + fn index( &self, index : usize ) -> &Self::Output + { + &self.a[ index ] + } +} + +impl< T > IndexMut< usize > for StructNamed< T > +{ + fn index_mut( &mut self, index : usize ) -> &mut Self::Output + { + &mut self.a[ index ] + } +} + + +include!( "./only_test/struct_named.rs" ); diff --git a/module/core/derive_tools/tests/inc/index_mut/struct_tuple.rs b/module/core/derive_tools/tests/inc/index_mut/struct_tuple.rs new file mode 100644 index 0000000000..f252344d58 --- /dev/null +++ b/module/core/derive_tools/tests/inc/index_mut/struct_tuple.rs @@ -0,0 +1,12 @@ +#![ allow( dead_code ) ] +#[ allow( unused_imports ) ] +use super::*; + +#[ derive( the_module::IndexMut ) ] +struct StructTuple< T > +( + #[ index ] + Vec< T > +); + +include!( "./only_test/struct_tuple.rs" ); diff --git a/module/core/derive_tools/tests/inc/index_mut/struct_tuple_manual.rs b/module/core/derive_tools/tests/inc/index_mut/struct_tuple_manual.rs new file mode 100644 index 0000000000..be299f90c6 --- /dev/null +++ b/module/core/derive_tools/tests/inc/index_mut/struct_tuple_manual.rs @@ -0,0 +1,26 @@ +use core::ops::{ Index, IndexMut }; + +#[ allow( dead_code ) ] +struct StructTuple< T >( Vec< T > ); + +impl< T > Index< usize > for StructTuple< T > +{ + type Output = T; + + fn index( &self, index : usize ) -> &Self::Output + { + &self.0[ index ] + } +} + +impl< T > IndexMut< usize > for StructTuple< T > +{ + fn index_mut( &mut self, index : usize ) -> &mut Self::Output + { + &mut self.0[ index ] + } +} + + +include!( "./only_test/struct_tuple.rs" ); + diff --git a/module/core/derive_tools/tests/inc/inner_from/manual_test.rs b/module/core/derive_tools/tests/inc/inner_from/basic_manual_test.rs similarity index 100% rename from module/core/derive_tools/tests/inc/inner_from/manual_test.rs rename to module/core/derive_tools/tests/inc/inner_from/basic_manual_test.rs diff --git a/module/core/derive_tools/tests/inc/inner_from/test.rs b/module/core/derive_tools/tests/inc/inner_from/basic_test.rs similarity index 100% rename from module/core/derive_tools/tests/inc/inner_from/test.rs rename to module/core/derive_tools/tests/inc/inner_from/basic_test.rs diff --git a/module/core/derive_tools/tests/inc/inner_from/multiple_named_manual_test.rs b/module/core/derive_tools/tests/inc/inner_from/multiple_named_manual_test.rs index 0a934e454f..915d9061be 100644 --- a/module/core/derive_tools/tests/inc/inner_from/multiple_named_manual_test.rs +++ b/module/core/derive_tools/tests/inc/inner_from/multiple_named_manual_test.rs @@ -3,8 +3,8 @@ use super::*; #[ derive( Debug, PartialEq, Eq ) ] struct StructNamedFields { - a: i32, - b: bool, + a : i32, + b : bool, } impl From< StructNamedFields > for ( i32, bool ) diff --git a/module/core/derive_tools/tests/inc/inner_from/multiple_named_test.rs b/module/core/derive_tools/tests/inc/inner_from/multiple_named_test.rs index 6177841adf..a26eb047ea 100644 --- a/module/core/derive_tools/tests/inc/inner_from/multiple_named_test.rs +++ b/module/core/derive_tools/tests/inc/inner_from/multiple_named_test.rs @@ -3,8 +3,8 @@ use super::*; #[ derive( Debug, PartialEq, Eq, the_module::InnerFrom ) ] struct StructNamedFields { - a: i32, - b: bool, + a : i32, + b : bool, } include!( "./only_test/multiple_named.rs" ); diff --git a/module/core/derive_tools/tests/inc/inner_from/multiple_manual_test.rs b/module/core/derive_tools/tests/inc/inner_from/multiple_unnamed_manual_test.rs similarity index 100% rename from module/core/derive_tools/tests/inc/inner_from/multiple_manual_test.rs rename to module/core/derive_tools/tests/inc/inner_from/multiple_unnamed_manual_test.rs diff --git a/module/core/derive_tools/tests/inc/inner_from/multiple_test.rs b/module/core/derive_tools/tests/inc/inner_from/multiple_unnamed_test.rs similarity index 100% rename from module/core/derive_tools/tests/inc/inner_from/multiple_test.rs rename to module/core/derive_tools/tests/inc/inner_from/multiple_unnamed_test.rs diff --git a/module/core/derive_tools/tests/inc/inner_from/named_manual_test.rs b/module/core/derive_tools/tests/inc/inner_from/named_manual_test.rs index 4d7805644d..f8a3976094 100644 --- a/module/core/derive_tools/tests/inc/inner_from/named_manual_test.rs +++ b/module/core/derive_tools/tests/inc/inner_from/named_manual_test.rs @@ -3,7 +3,7 @@ use super::*; #[ derive( Debug, PartialEq, Eq ) ] struct MyStruct { - a: i32, + a : i32, } impl From< MyStruct > for i32 diff --git a/module/core/derive_tools/tests/inc/inner_from/named_test.rs b/module/core/derive_tools/tests/inc/inner_from/named_test.rs index 2f6d3ccccc..1d686dd38c 100644 --- a/module/core/derive_tools/tests/inc/inner_from/named_test.rs +++ b/module/core/derive_tools/tests/inc/inner_from/named_test.rs @@ -3,7 +3,7 @@ use super::*; #[ derive( Debug, PartialEq, Eq, the_module::InnerFrom ) ] struct MyStruct { - a: i32, + a : i32, } include!( "./only_test/named.rs" ); diff --git a/module/core/derive_tools/tests/inc/inner_from/only_test/multiple_named.rs b/module/core/derive_tools/tests/inc/inner_from/only_test/multiple_named.rs index 05b9a66e9d..0d38366da1 100644 --- a/module/core/derive_tools/tests/inc/inner_from/only_test/multiple_named.rs +++ b/module/core/derive_tools/tests/inc/inner_from/only_test/multiple_named.rs @@ -1,7 +1,7 @@ #[ test ] fn from_named() { - let got : ( i32, bool ) = StructNamedFields{ a: 10, b: true }.into(); + let got : ( i32, bool ) = StructNamedFields{ a : 10, b : true }.into(); let exp = ( 10 , true ); a_id!( got, exp ); } diff --git a/module/core/derive_tools/tests/inc/inner_from/only_test/named.rs b/module/core/derive_tools/tests/inc/inner_from/only_test/named.rs index a733f46367..72ada9af15 100644 --- a/module/core/derive_tools/tests/inc/inner_from/only_test/named.rs +++ b/module/core/derive_tools/tests/inc/inner_from/only_test/named.rs @@ -1,7 +1,7 @@ #[ test ] -fn inner_from_named() +fn inner_from_named() { - let got : i32 = MyStruct{ a: 10 }.into(); + let got : i32 = MyStruct{ a : 10 }.into(); let exp = 10; a_id!( got, exp ); } diff --git a/module/core/derive_tools/tests/inc/mod.rs b/module/core/derive_tools/tests/inc/mod.rs index 518d8757d4..2c2c57ddc1 100644 --- a/module/core/derive_tools/tests/inc/mod.rs +++ b/module/core/derive_tools/tests/inc/mod.rs @@ -3,7 +3,7 @@ use super::*; // = import tests of clone_dyn #[ cfg( feature = "derive_clone_dyn" ) ] -#[ path = "../../../../core/clone_dyn/tests/inc/mod.rs" ] +#[ path = "../../../../../module/core/clone_dyn/tests/inc/mod.rs" ] mod clone_dyn_test; // = import tests of variadic_from @@ -17,15 +17,19 @@ mod variadic_from_test; mod all_manual_test; #[ cfg ( - all - ( - feature = "derive_as_mut", - feature = "derive_as_ref", - feature = "derive_deref", - feature = "derive_deref_mut", - feature = "derive_from", - feature = "derive_inner_from", - ) + all + ( + feature = "derive_as_mut", + feature = "derive_as_ref", + feature = "derive_deref", + feature = "derive_deref_mut", + feature = "derive_from", + feature = "derive_index", + feature = "derive_index_mut", + feature = "derive_inner_from", + feature = "derive_not", + feature = "derive_phantom" + ) )] mod all_test; @@ -48,6 +52,11 @@ mod deref_tests // + mod basic_test; + mod basic_manual_test; + + // + mod struct_unit; mod struct_unit_manual; mod struct_tuple; @@ -108,6 +117,11 @@ mod deref_mut_tests // + mod basic_test; + mod basic_manual_test; + + // + mod struct_tuple; mod struct_tuple_manual; mod struct_named; @@ -147,53 +161,267 @@ mod deref_mut_tests mod name_collisions; } +#[ cfg( feature = "derive_new" ) ] +#[ path = "new" ] +mod new_tests +{ + #[ allow( unused_imports ) ] + use super::*; + + // qqq : for each branch add generic test + + // + + mod basic_manual_test; + mod basic_test; + mod unit_manual_test; + mod unit_test; + mod named_manual_test; + mod named_test; + mod multiple_named_manual_test; + mod multiple_named_test; + mod multiple_unnamed_manual_test; + // mod multiple_unnamed_test; + // xxx : continue + + // + +} + #[ cfg( feature = "derive_from" ) ] #[ path = "from" ] -mod from +mod from_tests { - #[ allow( unused_imports ) ] - use super::*; - - mod named_test; - mod named_manual_test; - - mod manual_test; - mod multiple_named_manual_test; - mod multiple_manual_test; - mod unit_manual_test; - mod test; - mod multiple_named_test; - mod unit_test; - mod multiple_test; - - mod variants_manual; - mod variants_derive; - - mod variants_duplicates_all_off; - mod variants_duplicates_some_off; - mod variants_duplicates_some_off_default_off; - - mod variants_generics; - mod variants_generics_where; - mod variants_collisions; + #[ allow( unused_imports ) ] + use super::*; + + // qqq : for each branch add generic test + + // + + mod basic_test; + mod basic_manual_test; + + // + + mod named_test; + mod named_manual_test; + + mod multiple_named_manual_test; + mod multiple_unnamed_manual_test; + mod unit_manual_test; + mod multiple_named_test; + mod unit_test; + mod multiple_unnamed_test; + + mod variants_manual; + mod variants_derive; + + mod variants_duplicates_all_off; + mod variants_duplicates_some_off; + mod variants_duplicates_some_off_default_off; + + mod variants_generics; + mod variants_generics_where; + mod variants_collisions; +} + +#[ cfg( feature = "derive_not" ) ] +#[ path = "not" ] +mod not_tests +{ + #[ allow( unused_imports ) ] + use super::*; + + mod struct_named; + mod struct_named_manual; + mod struct_named_empty; + mod struct_named_empty_manual; + mod struct_tuple; + mod struct_tuple_manual; + mod struct_tuple_empty; + mod struct_tuple_empty_manual; + mod struct_unit; + mod struct_unit_manual; + mod named_reference_field; + mod named_reference_field_manual; + mod named_mut_reference_field; + mod named_mut_reference_field_manual; + mod tuple_reference_field; + mod tuple_reference_field_manual; + mod tuple_mut_reference_field; + mod tuple_mut_reference_field_manual; + mod bounds_inlined; + mod bounds_inlined_manual; + mod bounds_mixed; + mod bounds_mixed_manual; + mod bounds_where; + mod bounds_where_manual; + mod with_custom_type; + mod name_collisions; + mod named_default_off; + mod named_default_off_manual; + mod named_default_off_reference_on; + mod named_default_off_reference_on_manual; + mod named_default_off_some_on; + mod named_default_off_some_on_manual; + mod named_default_on_mut_reference_off; + mod named_default_on_mut_reference_off_manual; + mod named_default_on_some_off; + mod named_default_on_some_off_manual; + mod tuple_default_off; + mod tuple_default_off_manual; + mod tuple_default_off_reference_on; + mod tuple_default_off_reference_on_manual; + mod tuple_default_off_some_on; + mod tuple_default_off_some_on_manual; + mod tuple_default_on_mut_reference_off; + mod tuple_default_on_mut_reference_off_manual; + mod tuple_default_on_some_off; + mod tuple_default_on_some_off_manual; } #[ cfg( feature = "derive_inner_from" ) ] #[ path = "inner_from" ] mod inner_from_tests { - #[ allow( unused_imports ) ] - use super::*; - - mod manual_test; - mod named_manual_test; - mod multiple_named_manual_test; - mod multiple_manual_test; - mod unit_manual_test; - mod test; - mod named_test; - mod multiple_named_test; - mod unit_test; - mod multiple_test; + #[ allow( unused_imports ) ] + use super::*; + + // + + mod basic_test; + mod basic_manual_test; + + // + + mod unit_test; + mod named_manual_test; + mod multiple_named_manual_test; + mod unit_manual_test; + mod named_test; + mod multiple_named_test; + mod multiple_unnamed_manual_test; + mod multiple_unnamed_test; + +} + +#[ cfg( feature = "derive_phantom" ) ] +#[ path = "phantom" ] +mod phantom_tests +{ + #[ allow( unused_imports ) ] + use super::*; + + mod struct_named; + mod struct_named_manual; + mod struct_named_empty; + mod struct_named_empty_manual; + mod struct_tuple; + mod struct_tuple_manual; + mod struct_tuple_empty; + mod struct_tuple_empty_manual; + mod struct_unit_to_tuple; + mod struct_unit_to_tuple_manual; + mod bounds_inlined; + mod bounds_inlined_manual; + mod bounds_mixed; + mod bounds_mixed_manual; + mod bounds_where; + mod bounds_where_manual; + mod name_collisions; + mod covariant_type; + mod covariant_type_manual; + mod contravariant_type; + mod contravariant_type_manual; + mod send_sync_type; + mod send_sync_type_manual; + + only_for_terminal_module! + { + #[ test_tools::nightly ] + #[ test ] + fn phantom_trybuild() + { + + println!( "current_dir : {:?}", std::env::current_dir().unwrap() ); + let t = test_tools::compiletime::TestCases::new(); + + t.compile_fail( "tests/inc/phantom/compiletime/enum.rs" ); + t.compile_fail( "tests/inc/phantom/compiletime/invariant_type.rs" ); + } + } +} + +#[ cfg( feature = "derive_index" ) ] +#[ path = "index" ] +mod index_tests +{ + #[ allow( unused_imports ) ] + use super::*; + + mod struct_named; + mod struct_multiple_named_field; + mod struct_multiple_named_item; + mod struct_named_manual; + mod struct_multiple_named_manual; + mod struct_tuple; + mod struct_multiple_tuple; + mod struct_tuple_manual; + mod struct_multiple_tuple_manual; + mod struct_collisions; + + only_for_terminal_module! + { + #[ test_tools::nightly ] + #[ test ] + fn index_trybuild() + { + + println!( "current_dir : {:?}", std::env::current_dir().unwrap() ); + let t = test_tools::compiletime::TestCases::new(); + + t.compile_fail( "tests/inc/index/compiletime/struct.rs" ); + t.compile_fail( "tests/inc/index/compiletime/struct_unit.rs" ); + t.compile_fail( "tests/inc/index/compiletime/struct_named_empty.rs" ); + t.compile_fail( "tests/inc/index/compiletime/enum.rs" ); + } + } } + +#[ cfg( feature = "derive_index_mut" ) ] +#[ path = "index_mut" ] +mod index_mut_tests +{ + #[ allow( unused_imports ) ] + use super::*; + mod struct_named; + mod struct_multiple_named_field; + mod struct_multiple_named_item; + mod struct_named_manual; + mod struct_multiple_named_manual; + mod struct_tuple; + mod struct_multiple_tuple; + mod struct_tuple_manual; + mod struct_multiple_tuple_manual; + mod struct_collisions; + + only_for_terminal_module! + { + #[ test_tools::nightly ] + #[ test ] + fn index_mut_trybuild() + { + + println!( "current_dir : {:?}", std::env::current_dir().unwrap() ); + let t = test_tools::compiletime::TestCases::new(); + + t.compile_fail( "tests/inc/index_mut/compiletime/struct.rs" ); + t.compile_fail( "tests/inc/index_mut/compiletime/struct_unit.rs" ); + t.compile_fail( "tests/inc/index_mut/compiletime/struct_named_empty.rs" ); + t.compile_fail( "tests/inc/index_mut/compiletime/enum.rs" ); + } + } +} + diff --git a/module/core/derive_tools/tests/inc/new/basic_manual_test.rs b/module/core/derive_tools/tests/inc/new/basic_manual_test.rs new file mode 100644 index 0000000000..993956eefa --- /dev/null +++ b/module/core/derive_tools/tests/inc/new/basic_manual_test.rs @@ -0,0 +1,15 @@ +use super::*; + +#[ derive( Debug, Clone, Copy, PartialEq ) ] +pub struct IsTransparent( bool ); + +impl IsTransparent +{ + #[ inline( always ) ] + fn new( src : bool ) -> Self + { + Self( src ) + } +} + +include!( "./only_test/basic.rs" ); diff --git a/module/core/derive_tools/tests/inc/new/basic_test.rs b/module/core/derive_tools/tests/inc/new/basic_test.rs new file mode 100644 index 0000000000..6cea8c5a49 --- /dev/null +++ b/module/core/derive_tools/tests/inc/new/basic_test.rs @@ -0,0 +1,6 @@ +use super::*; + +#[ derive( Debug, Clone, Copy, PartialEq, the_module::New ) ] +pub struct IsTransparent( bool ); + +include!( "./only_test/basic.rs" ); diff --git a/module/core/derive_tools/tests/inc/new/multiple_named_manual_test.rs b/module/core/derive_tools/tests/inc/new/multiple_named_manual_test.rs new file mode 100644 index 0000000000..839456b1a0 --- /dev/null +++ b/module/core/derive_tools/tests/inc/new/multiple_named_manual_test.rs @@ -0,0 +1,19 @@ +use super::*; + +#[ derive( Debug, PartialEq, Eq ) ] +struct StructNamedFields +{ + a : i32, + b : bool, +} + +impl StructNamedFields +{ + #[ inline( always ) ] + fn new( a : i32, b : bool ) -> Self + { + Self{ a, b } + } +} + +include!( "./only_test/multiple_named.rs" ); diff --git a/module/core/derive_tools/tests/inc/new/multiple_named_test.rs b/module/core/derive_tools/tests/inc/new/multiple_named_test.rs new file mode 100644 index 0000000000..c3988146df --- /dev/null +++ b/module/core/derive_tools/tests/inc/new/multiple_named_test.rs @@ -0,0 +1,11 @@ +use super::*; + +#[ derive( Debug, PartialEq, Eq, the_module::New ) ] +// #[ debug ] +struct StructNamedFields +{ + a : i32, + b : bool, +} + +include!( "./only_test/multiple_named.rs" ); diff --git a/module/core/derive_tools/tests/inc/new/multiple_unnamed_manual_test.rs b/module/core/derive_tools/tests/inc/new/multiple_unnamed_manual_test.rs new file mode 100644 index 0000000000..08ee277851 --- /dev/null +++ b/module/core/derive_tools/tests/inc/new/multiple_unnamed_manual_test.rs @@ -0,0 +1,15 @@ +use super::*; + +#[ derive( Debug, PartialEq, Eq ) ] +struct StructWithManyFields( i32, bool ); + +impl StructWithManyFields +{ + #[ inline( always ) ] + fn new( src1 : i32, src2 : bool ) -> Self + { + Self( src1, src2 ) + } +} + +include!( "./only_test/multiple_unnamed.rs" ); diff --git a/module/core/derive_tools/tests/inc/new/multiple_unnamed_test.rs b/module/core/derive_tools/tests/inc/new/multiple_unnamed_test.rs new file mode 100644 index 0000000000..6a8f882287 --- /dev/null +++ b/module/core/derive_tools/tests/inc/new/multiple_unnamed_test.rs @@ -0,0 +1,6 @@ +use super::*; + +#[ derive( Debug, PartialEq, Eq, the_module::New ) ] +struct StructWithManyFields( i32, bool ); + +include!( "./only_test/multiple_unnamed.rs" ); diff --git a/module/core/derive_tools/tests/inc/new/named_manual_test.rs b/module/core/derive_tools/tests/inc/new/named_manual_test.rs new file mode 100644 index 0000000000..679afeec66 --- /dev/null +++ b/module/core/derive_tools/tests/inc/new/named_manual_test.rs @@ -0,0 +1,18 @@ +use super::*; + +#[ derive( Debug, PartialEq, Eq ) ] +struct MyStruct +{ + a : i32, +} + +impl MyStruct +{ + #[ inline( always ) ] + fn new( src : i32 ) -> Self + { + Self{ a : src } + } +} + +include!( "./only_test/named.rs" ); diff --git a/module/core/derive_tools/tests/inc/new/named_test.rs b/module/core/derive_tools/tests/inc/new/named_test.rs new file mode 100644 index 0000000000..1df964f76f --- /dev/null +++ b/module/core/derive_tools/tests/inc/new/named_test.rs @@ -0,0 +1,9 @@ +use super::*; + +#[ derive( Debug, PartialEq, Eq, the_module::New ) ] +struct MyStruct +{ + a : i32, +} + +include!( "./only_test/named.rs" ); diff --git a/module/core/derive_tools/tests/inc/new/only_test/basic.rs b/module/core/derive_tools/tests/inc/new/only_test/basic.rs new file mode 100644 index 0000000000..7dadc915f2 --- /dev/null +++ b/module/core/derive_tools/tests/inc/new/only_test/basic.rs @@ -0,0 +1,13 @@ + +#[ test ] +fn from_test() +{ + + let got = IsTransparent::new( true ); + let exp = IsTransparent( true ); + a_id!( got, exp ); + let got = IsTransparent::new( false ); + let exp = IsTransparent( false ); + a_id!( got, exp ); + +} diff --git a/module/core/derive_tools/tests/inc/new/only_test/multiple_named.rs b/module/core/derive_tools/tests/inc/new/only_test/multiple_named.rs new file mode 100644 index 0000000000..eebdbba992 --- /dev/null +++ b/module/core/derive_tools/tests/inc/new/only_test/multiple_named.rs @@ -0,0 +1,7 @@ +#[ test ] +fn from_named() +{ + let got : StructNamedFields = StructNamedFields::new( 10, true ); + let exp = StructNamedFields{ a : 10 , b : true }; + a_id!( got, exp ); +} diff --git a/module/core/derive_tools/tests/inc/new/only_test/multiple_unnamed.rs b/module/core/derive_tools/tests/inc/new/only_test/multiple_unnamed.rs new file mode 100644 index 0000000000..94abf3c133 --- /dev/null +++ b/module/core/derive_tools/tests/inc/new/only_test/multiple_unnamed.rs @@ -0,0 +1,7 @@ +#[ test ] +fn from_named() +{ + let got : StructWithManyFields = StructWithManyFields::new( 10, true ); + let exp = StructWithManyFields( 10 , true ); + a_id!( got, exp ); +} diff --git a/module/core/derive_tools/tests/inc/new/only_test/named.rs b/module/core/derive_tools/tests/inc/new/only_test/named.rs new file mode 100644 index 0000000000..b654961735 --- /dev/null +++ b/module/core/derive_tools/tests/inc/new/only_test/named.rs @@ -0,0 +1,7 @@ +#[ test ] +fn from_named() +{ + let got : MyStruct = MyStruct::new( 13 ); + let exp = MyStruct { a : 13 }; + a_id!( got, exp ); +} diff --git a/module/core/derive_tools/tests/inc/new/only_test/unit.rs b/module/core/derive_tools/tests/inc/new/only_test/unit.rs new file mode 100644 index 0000000000..279908a05d --- /dev/null +++ b/module/core/derive_tools/tests/inc/new/only_test/unit.rs @@ -0,0 +1,7 @@ +#[ test ] +fn from_named() +{ + let got : UnitStruct = UnitStruct::new(); + let exp = UnitStruct; + a_id!( got, exp ); +} diff --git a/module/core/derive_tools/tests/inc/new/unit_manual_test.rs b/module/core/derive_tools/tests/inc/new/unit_manual_test.rs new file mode 100644 index 0000000000..d5fc60e6c5 --- /dev/null +++ b/module/core/derive_tools/tests/inc/new/unit_manual_test.rs @@ -0,0 +1,15 @@ +use super::*; + +#[ derive( Debug, Clone, Copy, PartialEq ) ] +struct UnitStruct; + +impl UnitStruct +{ + #[ inline( always ) ] + fn new() -> Self + { + Self + } +} + +include!( "./only_test/unit.rs" ); diff --git a/module/core/derive_tools/tests/inc/new/unit_test.rs b/module/core/derive_tools/tests/inc/new/unit_test.rs new file mode 100644 index 0000000000..606df185d8 --- /dev/null +++ b/module/core/derive_tools/tests/inc/new/unit_test.rs @@ -0,0 +1,6 @@ +use super::*; + +#[ derive( Debug, Clone, Copy, PartialEq, the_module::New ) ] +struct UnitStruct; + +include!( "./only_test/unit.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/bounds_inlined.rs b/module/core/derive_tools/tests/inc/not/bounds_inlined.rs new file mode 100644 index 0000000000..537bcc5e87 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/bounds_inlined.rs @@ -0,0 +1,13 @@ +use std::fmt::Debug; +use core::ops::Not; +use super::*; + +#[ allow( dead_code ) ] +#[ derive( the_module::Not ) ] +struct BoundsInlined< T : ToString + Not< Output = T >, U : Debug + Not< Output = U > > +{ + a : T, + b : U, +} + +include!( "./only_test/bounds_inlined.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/bounds_inlined_manual.rs b/module/core/derive_tools/tests/inc/not/bounds_inlined_manual.rs new file mode 100644 index 0000000000..12e39a3546 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/bounds_inlined_manual.rs @@ -0,0 +1,21 @@ +use std::fmt::Debug; +use core::ops::Not; + +#[ allow( dead_code ) ] +struct BoundsInlined< T : ToString + Not< Output = T >, U : Debug + Not< Output = U > > +{ + a: T, + b: U, +} + +impl< T : ToString + Not< Output = T >, U : Debug + Not< Output = U > > Not for BoundsInlined< T, U > +{ + type Output = Self; + + fn not( self ) -> Self::Output + { + Self { a : !self.a, b : !self.b } + } +} + +include!( "./only_test/bounds_inlined.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/bounds_mixed.rs b/module/core/derive_tools/tests/inc/not/bounds_mixed.rs new file mode 100644 index 0000000000..e3dc55fe26 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/bounds_mixed.rs @@ -0,0 +1,15 @@ +use std::fmt::Debug; +use core::ops::Not; +use super::*; + +#[ allow( dead_code ) ] +#[ derive( the_module::Not ) ] +struct BoundsMixed< T : ToString + Not< Output = T >, U > +where + U : Debug + Not< Output = U >, +{ + a: T, + b: U, +} + +include!( "./only_test/bounds_mixed.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/bounds_mixed_manual.rs b/module/core/derive_tools/tests/inc/not/bounds_mixed_manual.rs new file mode 100644 index 0000000000..6d80545bae --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/bounds_mixed_manual.rs @@ -0,0 +1,25 @@ +use std::fmt::Debug; +use core::ops::Not; + +#[ allow( dead_code ) ] +struct BoundsMixed< T : ToString + Not< Output = T >, U > +where + U : Debug + Not< Output = U >, +{ + a : T, + b : U, +} + +impl< T : ToString + Not< Output = T >, U > Not for BoundsMixed< T, U > +where + U : Debug + Not< Output = U >, +{ + type Output = Self; + + fn not( self ) -> Self::Output + { + Self { a : !self.a, b : !self.b } + } +} + +include!( "./only_test/bounds_mixed.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/bounds_where.rs b/module/core/derive_tools/tests/inc/not/bounds_where.rs new file mode 100644 index 0000000000..176dd5a76c --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/bounds_where.rs @@ -0,0 +1,16 @@ +use std::fmt::Debug; +use core::ops::Not; +use super::*; + +#[ allow( dead_code ) ] +#[ derive( the_module::Not ) ] +struct BoundsWhere< T, U > +where + T : ToString + Not< Output = T >, + U : Debug + Not< Output = U >, +{ + a : T, + b : U, +} + +include!( "./only_test/bounds_where.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/bounds_where_manual.rs b/module/core/derive_tools/tests/inc/not/bounds_where_manual.rs new file mode 100644 index 0000000000..7a5db59cba --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/bounds_where_manual.rs @@ -0,0 +1,27 @@ +use std::fmt::Debug; +use core::ops::Not; + +#[ allow( dead_code ) ] +struct BoundsWhere< T, U > + where + T: ToString + Not< Output = T >, + U: Debug + Not< Output = U >, +{ + a : T, + b : U, +} + +impl< T, U > Not for BoundsWhere< T, U > +where + T : ToString + Not< Output = T >, + U : Debug + Not< Output = U >, +{ + type Output = Self; + + fn not( self ) -> Self::Output + { + Self { a : !self.a, b : !self.b } + } +} + +include!( "./only_test/bounds_where.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/name_collisions.rs b/module/core/derive_tools/tests/inc/not/name_collisions.rs new file mode 100644 index 0000000000..bfa809dba4 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/name_collisions.rs @@ -0,0 +1,14 @@ +use super::*; + +pub mod core {} +pub mod std {} + +#[ allow( dead_code ) ] +#[ derive( the_module::Not ) ] +struct NameCollisions +{ + a : bool, + b : u8, +} + +include!( "./only_test/name_collisions.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/named_default_off.rs b/module/core/derive_tools/tests/inc/not/named_default_off.rs new file mode 100644 index 0000000000..5acf40b84f --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/named_default_off.rs @@ -0,0 +1,12 @@ +use super::*; + +#[ allow( dead_code ) ] +#[ derive( the_module::Not ) ] +#[ not( off ) ] +struct NamedDefaultOff +{ + a : bool, + b : u8, +} + +include!( "only_test/named_default_off.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/named_default_off_manual.rs b/module/core/derive_tools/tests/inc/not/named_default_off_manual.rs new file mode 100644 index 0000000000..d97b6498cb --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/named_default_off_manual.rs @@ -0,0 +1,20 @@ +use core::ops::Not; + +#[ allow( dead_code ) ] +struct NamedDefaultOff +{ + a : bool, + b : u8, +} + +impl Not for NamedDefaultOff +{ + type Output = Self; + + fn not( self ) -> Self::Output + { + Self { a : self.a, b : self.b } + } +} + +include!( "only_test/named_default_off.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/named_default_off_reference_on.rs b/module/core/derive_tools/tests/inc/not/named_default_off_reference_on.rs new file mode 100644 index 0000000000..c79b3f83e5 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/named_default_off_reference_on.rs @@ -0,0 +1,13 @@ +use super::*; + +#[ allow( dead_code ) ] +#[ derive( the_module::Not ) ] +#[ not( off ) ] +struct NamedDefaultOffReferenceOn< 'a > +{ + #[ not( on ) ] + a : &'a bool, + b : u8, +} + +include!( "only_test/named_default_off_reference_on.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/named_default_off_reference_on_manual.rs b/module/core/derive_tools/tests/inc/not/named_default_off_reference_on_manual.rs new file mode 100644 index 0000000000..99907f1f74 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/named_default_off_reference_on_manual.rs @@ -0,0 +1,20 @@ +use core::ops::Not; + +#[ allow( dead_code ) ] +struct NamedDefaultOffReferenceOn< 'a > +{ + a : &'a bool, + b : u8, +} + +impl< 'a > Not for NamedDefaultOffReferenceOn< 'a > +{ + type Output = Self; + + fn not(self) -> Self::Output + { + Self { a: self.a, b : self.b } + } +} + +include!( "only_test/named_default_off_reference_on.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/named_default_off_some_on.rs b/module/core/derive_tools/tests/inc/not/named_default_off_some_on.rs new file mode 100644 index 0000000000..2a150122aa --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/named_default_off_some_on.rs @@ -0,0 +1,13 @@ +use super::*; + +#[ allow( dead_code ) ] +#[ derive( the_module::Not ) ] +#[ not( off )] +struct NamedDefaultOffSomeOn +{ + a : bool, + #[ not( on ) ] + b : u8, +} + +include!( "only_test/named_default_off_some_on.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/named_default_off_some_on_manual.rs b/module/core/derive_tools/tests/inc/not/named_default_off_some_on_manual.rs new file mode 100644 index 0000000000..c636795720 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/named_default_off_some_on_manual.rs @@ -0,0 +1,20 @@ +use core::ops::Not; + +#[ allow( dead_code ) ] +struct NamedDefaultOffSomeOn +{ + a : bool, + b : u8, +} + +impl Not for NamedDefaultOffSomeOn +{ + type Output = Self; + + fn not( self ) -> Self::Output + { + Self { a: self.a, b: !self.b } + } +} + +include!( "only_test/named_default_off_some_on.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/named_default_on_mut_reference_off.rs b/module/core/derive_tools/tests/inc/not/named_default_on_mut_reference_off.rs new file mode 100644 index 0000000000..f162ec5ee0 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/named_default_on_mut_reference_off.rs @@ -0,0 +1,12 @@ +use super::*; + +#[ allow( dead_code ) ] +#[ derive( the_module::Not ) ] +struct NamedDefaultOnMutReferenceOff< 'a > +{ + #[ not( off ) ] + a : &'a bool, + b : u8, +} + +include!( "only_test/named_default_on_mut_reference_off.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/named_default_on_mut_reference_off_manual.rs b/module/core/derive_tools/tests/inc/not/named_default_on_mut_reference_off_manual.rs new file mode 100644 index 0000000000..4048629fa0 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/named_default_on_mut_reference_off_manual.rs @@ -0,0 +1,20 @@ +use core::ops::Not; + +#[ allow( dead_code ) ] +struct NamedDefaultOnMutReferenceOff< 'a > +{ + a : &'a bool, + b : u8, +} + +impl< 'a > Not for NamedDefaultOnMutReferenceOff< 'a > +{ + type Output = Self; + + fn not(self) -> Self::Output + { + Self { a :self.a, b : !self.b } + } +} + +include!( "only_test/named_default_on_mut_reference_off.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/named_default_on_some_off.rs b/module/core/derive_tools/tests/inc/not/named_default_on_some_off.rs new file mode 100644 index 0000000000..2b82009ead --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/named_default_on_some_off.rs @@ -0,0 +1,12 @@ +use super::*; + +#[ allow( dead_code ) ] +#[ derive( the_module::Not ) ] +struct NamedDefaultOnSomeOff +{ + a : bool, + #[ not( off ) ] + b : u8, +} + +include!( "only_test/named_default_on_some_off.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/named_default_on_some_off_manual.rs b/module/core/derive_tools/tests/inc/not/named_default_on_some_off_manual.rs new file mode 100644 index 0000000000..15de7868e5 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/named_default_on_some_off_manual.rs @@ -0,0 +1,20 @@ +use core::ops::Not; + +#[ allow( dead_code ) ] +struct NamedDefaultOnSomeOff +{ + a : bool, + b : u8, +} + +impl Not for NamedDefaultOnSomeOff +{ + type Output = Self; + + fn not( self ) -> Self::Output + { + Self { a: !self.a, b: self.b } + } +} + +include!( "only_test/named_default_on_some_off.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/named_mut_reference_field.rs b/module/core/derive_tools/tests/inc/not/named_mut_reference_field.rs new file mode 100644 index 0000000000..66634ce9e0 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/named_mut_reference_field.rs @@ -0,0 +1,11 @@ +use super::*; + +#[ allow( dead_code ) ] +#[ derive( the_module::Not ) ] +struct NamedMutReferenceField< 'a > +{ + a : &'a mut bool, + b : u8, +} + +include!( "only_test/named_mut_reference_field.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/named_mut_reference_field_manual.rs b/module/core/derive_tools/tests/inc/not/named_mut_reference_field_manual.rs new file mode 100644 index 0000000000..96e71b66e4 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/named_mut_reference_field_manual.rs @@ -0,0 +1,21 @@ +use core::ops::Not; + +#[ allow( dead_code ) ] +struct NamedMutReferenceField< 'a > +{ + a : &'a mut bool, + b : u8, +} + +impl< 'a > Not for NamedMutReferenceField< 'a > +{ + type Output = Self; + + fn not( self ) -> Self::Output + { + *self.a = !*self.a; + Self { a : self.a, b : !self.b } + } +} + +include!( "only_test/named_mut_reference_field.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/named_reference_field.rs b/module/core/derive_tools/tests/inc/not/named_reference_field.rs new file mode 100644 index 0000000000..df4e480a9e --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/named_reference_field.rs @@ -0,0 +1,11 @@ +use super::*; + +#[ allow( dead_code ) ] +#[ derive( the_module::Not ) ] +struct NamedReferenceField< 'a > +{ + a : &'a bool, + b : u8, +} + +include!( "only_test/named_reference_field.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/named_reference_field_manual.rs b/module/core/derive_tools/tests/inc/not/named_reference_field_manual.rs new file mode 100644 index 0000000000..ee2d1d8e7a --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/named_reference_field_manual.rs @@ -0,0 +1,20 @@ +use core::ops::Not; + +#[ allow( dead_code ) ] +struct NamedReferenceField< 'a > +{ + a : &'a bool, + b : u8, +} + +impl< 'a > Not for NamedReferenceField< 'a > +{ + type Output = Self; + + fn not( self ) -> Self::Output + { + Self { a : self.a, b : !self.b } + } +} + +include!( "only_test/named_reference_field.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/only_test/bounds_inlined.rs b/module/core/derive_tools/tests/inc/not/only_test/bounds_inlined.rs new file mode 100644 index 0000000000..e3fa56a9b2 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/only_test/bounds_inlined.rs @@ -0,0 +1,10 @@ +#[ test ] +fn not() +{ + let mut x = BoundsInlined::< bool, u8 > { a : true, b : 0 }; + + x = !x; + + assert_eq!( x.a, false ); + assert_eq!( x.b, 255 ); +} diff --git a/module/core/derive_tools/tests/inc/not/only_test/bounds_mixed.rs b/module/core/derive_tools/tests/inc/not/only_test/bounds_mixed.rs new file mode 100644 index 0000000000..03a5d21a18 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/only_test/bounds_mixed.rs @@ -0,0 +1,10 @@ +#[ test ] +fn not() +{ + let mut x = BoundsMixed::< bool, u8 > { a : true, b : 0 }; + + x = !x; + + assert_eq!( x.a, false ); + assert_eq!( x.b, 255 ); +} diff --git a/module/core/derive_tools/tests/inc/not/only_test/bounds_where.rs b/module/core/derive_tools/tests/inc/not/only_test/bounds_where.rs new file mode 100644 index 0000000000..557fc920f4 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/only_test/bounds_where.rs @@ -0,0 +1,10 @@ +#[ test ] +fn not() +{ + let mut x = BoundsWhere::< bool, u8 > { a : true, b : 0 }; + + x = !x; + + assert_eq!( x.a, false ); + assert_eq!( x.b, 255 ); +} diff --git a/module/core/derive_tools/tests/inc/not/only_test/name_collisions.rs b/module/core/derive_tools/tests/inc/not/only_test/name_collisions.rs new file mode 100644 index 0000000000..dee5d55f1b --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/only_test/name_collisions.rs @@ -0,0 +1,10 @@ +#[ test ] +fn not() +{ + let mut x = NameCollisions { a : true, b : 0 }; + + x = !x; + + assert_eq!( x.a, false ); + assert_eq!( x.b, 255 ); +} diff --git a/module/core/derive_tools/tests/inc/not/only_test/named_default_off.rs b/module/core/derive_tools/tests/inc/not/only_test/named_default_off.rs new file mode 100644 index 0000000000..f40c36b58d --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/only_test/named_default_off.rs @@ -0,0 +1,10 @@ +#[ test ] +fn not() +{ + let mut x = NamedDefaultOff { a : true, b: 0 }; + + x = !x; + + assert_eq!( x.a, true ); + assert_eq!( x.b, 0 ); +} diff --git a/module/core/derive_tools/tests/inc/not/only_test/named_default_off_reference_on.rs b/module/core/derive_tools/tests/inc/not/only_test/named_default_off_reference_on.rs new file mode 100644 index 0000000000..6b1fcbf859 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/only_test/named_default_off_reference_on.rs @@ -0,0 +1,11 @@ +#[ test ] +fn not() +{ + let value = true; + let mut x = NamedDefaultOffReferenceOn { a : &value, b : 0 }; + + x = !x; + + assert_eq!( *x.a, true ); + assert_eq!( x.b, 0 ); +} diff --git a/module/core/derive_tools/tests/inc/not/only_test/named_default_off_some_on.rs b/module/core/derive_tools/tests/inc/not/only_test/named_default_off_some_on.rs new file mode 100644 index 0000000000..86c31c29bf --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/only_test/named_default_off_some_on.rs @@ -0,0 +1,10 @@ +#[ test ] +fn not() +{ + let mut x = NamedDefaultOffSomeOn { a : true, b: 0 }; + + x = !x; + + assert_eq!( x.a, true ); + assert_eq!( x.b, 255 ); +} diff --git a/module/core/derive_tools/tests/inc/not/only_test/named_default_on_mut_reference_off.rs b/module/core/derive_tools/tests/inc/not/only_test/named_default_on_mut_reference_off.rs new file mode 100644 index 0000000000..cbcfd9384d --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/only_test/named_default_on_mut_reference_off.rs @@ -0,0 +1,11 @@ +#[ test ] +fn not() +{ + let mut value = true; + let mut x = NamedDefaultOnMutReferenceOff { a : &mut value, b : 0 }; + + x = !x; + + assert_eq!( *x.a, true ); + assert_eq!( x.b, 255 ); +} \ No newline at end of file diff --git a/module/core/derive_tools/tests/inc/not/only_test/named_default_on_some_off.rs b/module/core/derive_tools/tests/inc/not/only_test/named_default_on_some_off.rs new file mode 100644 index 0000000000..aaee7182ba --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/only_test/named_default_on_some_off.rs @@ -0,0 +1,10 @@ +#[ test ] +fn not() +{ + let mut x = NamedDefaultOnSomeOff { a : true, b: 0 }; + + x = !x; + + assert_eq!( x.a, false ); + assert_eq!( x.b, 0 ); +} diff --git a/module/core/derive_tools/tests/inc/not/only_test/named_mut_reference_field.rs b/module/core/derive_tools/tests/inc/not/only_test/named_mut_reference_field.rs new file mode 100644 index 0000000000..a853a3862b --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/only_test/named_mut_reference_field.rs @@ -0,0 +1,11 @@ +#[ test ] +fn not() +{ + let mut value = true; + let mut x = NamedMutReferenceField { a : &mut value, b : 0 }; + + x = !x; + + assert_eq!( *x.a, false ); + assert_eq!( x.b, 255 ); +} diff --git a/module/core/derive_tools/tests/inc/not/only_test/named_reference_field.rs b/module/core/derive_tools/tests/inc/not/only_test/named_reference_field.rs new file mode 100644 index 0000000000..88aa4c2664 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/only_test/named_reference_field.rs @@ -0,0 +1,11 @@ +#[ test ] +fn not() +{ + let value = true; + let mut x = NamedReferenceField { a : &value, b : 0 }; + + x = !x; + + assert_eq!( *x.a, true ); + assert_eq!( x.b, 255 ); +} diff --git a/module/core/derive_tools/tests/inc/not/only_test/struct_named.rs b/module/core/derive_tools/tests/inc/not/only_test/struct_named.rs new file mode 100644 index 0000000000..254e92baf7 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/only_test/struct_named.rs @@ -0,0 +1,10 @@ +#[ test ] +fn not() +{ + let mut x = StructNamed { a : true, b: 0 }; + + x = !x; + + assert_eq!( x.a, false ); + assert_eq!( x.b, 255 ); +} diff --git a/module/core/derive_tools/tests/inc/not/only_test/struct_named_empty.rs b/module/core/derive_tools/tests/inc/not/only_test/struct_named_empty.rs new file mode 100644 index 0000000000..743360a472 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/only_test/struct_named_empty.rs @@ -0,0 +1,6 @@ +#[ test ] +fn not() +{ + let mut _x = StructNamedEmpty { }; + _x = !_x; +} diff --git a/module/core/derive_tools/tests/inc/not/only_test/struct_tuple.rs b/module/core/derive_tools/tests/inc/not/only_test/struct_tuple.rs new file mode 100644 index 0000000000..d98601539b --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/only_test/struct_tuple.rs @@ -0,0 +1,10 @@ +#[ test ] +fn not() +{ + let mut x = StructTuple( true, 0 ); + + x = !x; + + assert_eq!( x.0, false ); + assert_eq!( x.1, 255 ); +} diff --git a/module/core/derive_tools/tests/inc/not/only_test/struct_tuple_empty.rs b/module/core/derive_tools/tests/inc/not/only_test/struct_tuple_empty.rs new file mode 100644 index 0000000000..ac6277690f --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/only_test/struct_tuple_empty.rs @@ -0,0 +1,6 @@ +#[ test ] +fn not() +{ + let mut _x = StructTupleEmpty(); + _x = !_x; +} diff --git a/module/core/derive_tools/tests/inc/not/only_test/struct_unit.rs b/module/core/derive_tools/tests/inc/not/only_test/struct_unit.rs new file mode 100644 index 0000000000..a2039827ad --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/only_test/struct_unit.rs @@ -0,0 +1,6 @@ +#[ test ] +fn not() +{ + let mut _x = StructUnit; + _x = !_x; +} diff --git a/module/core/derive_tools/tests/inc/not/only_test/tuple_default_off.rs b/module/core/derive_tools/tests/inc/not/only_test/tuple_default_off.rs new file mode 100644 index 0000000000..68618c3c66 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/only_test/tuple_default_off.rs @@ -0,0 +1,10 @@ +#[ test ] +fn not() +{ + let mut x = TupleDefaultOff( true, 0 ); + + x = !x; + + assert_eq!( x.0, true ); + assert_eq!( x.1, 0 ); +} diff --git a/module/core/derive_tools/tests/inc/not/only_test/tuple_default_off_reference_on.rs b/module/core/derive_tools/tests/inc/not/only_test/tuple_default_off_reference_on.rs new file mode 100644 index 0000000000..b9a9a5bbc5 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/only_test/tuple_default_off_reference_on.rs @@ -0,0 +1,11 @@ +#[ test ] +fn not() +{ + let value = true; + let mut x = TupleDefaultOffReferenceOn( &value, 0 ); + + x = !x; + + assert_eq!( *x.0, true ); + assert_eq!( x.1, 0 ); +} diff --git a/module/core/derive_tools/tests/inc/not/only_test/tuple_default_off_some_on.rs b/module/core/derive_tools/tests/inc/not/only_test/tuple_default_off_some_on.rs new file mode 100644 index 0000000000..3efd00ac9c --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/only_test/tuple_default_off_some_on.rs @@ -0,0 +1,10 @@ +#[ test ] +fn not() +{ + let mut x = TupleDefaultOffSomeOn( true, 0 ); + + x = !x; + + assert_eq!( x.0, true ); + assert_eq!( x.1, 255 ); +} diff --git a/module/core/derive_tools/tests/inc/not/only_test/tuple_default_on_mut_reference_off.rs b/module/core/derive_tools/tests/inc/not/only_test/tuple_default_on_mut_reference_off.rs new file mode 100644 index 0000000000..3fd3127d09 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/only_test/tuple_default_on_mut_reference_off.rs @@ -0,0 +1,11 @@ +#[ test ] +fn not() +{ + let mut value = true; + let mut x = TupleDefaultOnMutReferenceOff( &mut value, 0 ); + + x = !x; + + assert_eq!( *x.0, true ); + assert_eq!( x.1, 255 ); +} \ No newline at end of file diff --git a/module/core/derive_tools/tests/inc/not/only_test/tuple_default_on_some_off.rs b/module/core/derive_tools/tests/inc/not/only_test/tuple_default_on_some_off.rs new file mode 100644 index 0000000000..a59656d08e --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/only_test/tuple_default_on_some_off.rs @@ -0,0 +1,10 @@ +#[ test ] +fn not() +{ + let mut x = TupleDefaultOnSomeOff( true, 0 ); + + x = !x; + + assert_eq!( x.0, false ); + assert_eq!( x.1, 0 ); +} diff --git a/module/core/derive_tools/tests/inc/not/only_test/tuple_mut_reference_field.rs b/module/core/derive_tools/tests/inc/not/only_test/tuple_mut_reference_field.rs new file mode 100644 index 0000000000..23af2221ec --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/only_test/tuple_mut_reference_field.rs @@ -0,0 +1,11 @@ +#[ test ] +fn not() +{ + let mut value = true; + let mut x = TupleMutReferenceField( &mut value, 0 ); + + x = !x; + + assert_eq!( *x.0, false ); + assert_eq!( x.1, 255 ); +} diff --git a/module/core/derive_tools/tests/inc/not/only_test/tuple_reference_field.rs b/module/core/derive_tools/tests/inc/not/only_test/tuple_reference_field.rs new file mode 100644 index 0000000000..4813f3db44 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/only_test/tuple_reference_field.rs @@ -0,0 +1,11 @@ +#[ test ] +fn not() +{ + let value = true; + let mut x = TupleReferenceField( &value, 0 ); + + x = !x; + + assert_eq!( *x.0, true ); + assert_eq!( x.1, 255 ); +} diff --git a/module/core/derive_tools/tests/inc/not/only_test/with_custom_type.rs b/module/core/derive_tools/tests/inc/not/only_test/with_custom_type.rs new file mode 100644 index 0000000000..07ea74eb19 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/only_test/with_custom_type.rs @@ -0,0 +1,10 @@ +#[ test ] +fn not() +{ + let mut x = WithCustomType { custom_type : CustomType { a : true, b: 0 } }; + + x = !x; + + assert_eq!(x.custom_type.a, false); + assert_eq!(x.custom_type.b, 255); +} diff --git a/module/core/derive_tools/tests/inc/not/struct_named.rs b/module/core/derive_tools/tests/inc/not/struct_named.rs new file mode 100644 index 0000000000..af52a0f372 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/struct_named.rs @@ -0,0 +1,11 @@ +use super::*; + +#[ allow( dead_code ) ] +#[ derive( the_module::Not ) ] +struct StructNamed +{ + a : bool, + b : u8, +} + +include!( "./only_test/struct_named.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/struct_named_empty.rs b/module/core/derive_tools/tests/inc/not/struct_named_empty.rs new file mode 100644 index 0000000000..7f8eeb6302 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/struct_named_empty.rs @@ -0,0 +1,7 @@ +use super::*; + +#[ allow( dead_code ) ] +#[ derive( the_module::Not ) ] +struct StructNamedEmpty{} + +include!( "./only_test/struct_named_empty.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/struct_named_empty_manual.rs b/module/core/derive_tools/tests/inc/not/struct_named_empty_manual.rs new file mode 100644 index 0000000000..79b6407789 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/struct_named_empty_manual.rs @@ -0,0 +1,15 @@ +use core::ops::Not; + +#[ allow( dead_code ) ] +struct StructNamedEmpty{} + +impl Not for StructNamedEmpty +{ + type Output = Self; + + fn not( self ) -> Self::Output { + StructNamedEmpty {} + } +} + +include!( "./only_test/struct_named_empty.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/struct_named_manual.rs b/module/core/derive_tools/tests/inc/not/struct_named_manual.rs new file mode 100644 index 0000000000..9f999df07e --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/struct_named_manual.rs @@ -0,0 +1,20 @@ +use core::ops::Not; + +#[ allow( dead_code ) ] +struct StructNamed +{ + a : bool, + b : u8, +} + +impl Not for StructNamed +{ + type Output = Self; + + fn not( self ) -> Self::Output + { + Self { a : !self.a, b : !self.b } + } +} + +include!( "./only_test/struct_named.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/struct_tuple.rs b/module/core/derive_tools/tests/inc/not/struct_tuple.rs new file mode 100644 index 0000000000..61acd98688 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/struct_tuple.rs @@ -0,0 +1,7 @@ +use super::*; + +#[ allow( dead_code ) ] +#[ derive( the_module::Not ) ] +struct StructTuple( bool, u8 ); + +include!( "./only_test/struct_tuple.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/struct_tuple_empty.rs b/module/core/derive_tools/tests/inc/not/struct_tuple_empty.rs new file mode 100644 index 0000000000..38fcfa7c31 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/struct_tuple_empty.rs @@ -0,0 +1,7 @@ +use super::*; + +#[ allow( dead_code ) ] +#[ derive( the_module::Not ) ] +struct StructTupleEmpty(); + +include!( "./only_test/struct_tuple_empty.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/struct_tuple_empty_manual.rs b/module/core/derive_tools/tests/inc/not/struct_tuple_empty_manual.rs new file mode 100644 index 0000000000..f1f426d14c --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/struct_tuple_empty_manual.rs @@ -0,0 +1,16 @@ +use core::ops::Not; + +#[ allow( dead_code ) ] +struct StructTupleEmpty(); + +impl Not for StructTupleEmpty +{ + type Output = Self; + + fn not( self ) -> Self::Output + { + Self() + } +} + +include!( "./only_test/struct_tuple_empty.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/struct_tuple_manual.rs b/module/core/derive_tools/tests/inc/not/struct_tuple_manual.rs new file mode 100644 index 0000000000..607dae63fe --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/struct_tuple_manual.rs @@ -0,0 +1,16 @@ +use core::ops::Not; + +#[ allow( dead_code ) ] +struct StructTuple( bool, u8 ); + +impl Not for StructTuple +{ + type Output = Self; + + fn not( self ) -> Self::Output + { + Self( !self.0, !self.1 ) + } +} + +include!( "./only_test/struct_tuple.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/struct_unit.rs b/module/core/derive_tools/tests/inc/not/struct_unit.rs new file mode 100644 index 0000000000..6d2af63c6d --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/struct_unit.rs @@ -0,0 +1,7 @@ +use super::*; + +#[ allow( dead_code ) ] +#[ derive( the_module::Not ) ] +struct StructUnit; + +include!( "./only_test/struct_unit.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/struct_unit_manual.rs b/module/core/derive_tools/tests/inc/not/struct_unit_manual.rs new file mode 100644 index 0000000000..3f77e12ea2 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/struct_unit_manual.rs @@ -0,0 +1,15 @@ +use core::ops::Not; + +struct StructUnit; + +impl Not for StructUnit +{ + type Output = Self; + + fn not( self ) -> Self::Output + { + Self {} + } +} + +include!( "./only_test/struct_unit.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/tuple_default_off.rs b/module/core/derive_tools/tests/inc/not/tuple_default_off.rs new file mode 100644 index 0000000000..1665e09fc9 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/tuple_default_off.rs @@ -0,0 +1,8 @@ +use super::*; + +#[ allow( dead_code ) ] +#[ derive( the_module::Not ) ] +#[ not( off ) ] +struct TupleDefaultOff( bool, u8 ); + +include!( "only_test/tuple_default_off.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/tuple_default_off_manual.rs b/module/core/derive_tools/tests/inc/not/tuple_default_off_manual.rs new file mode 100644 index 0000000000..77db4fb218 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/tuple_default_off_manual.rs @@ -0,0 +1,16 @@ +use core::ops::Not; + +#[ allow( dead_code ) ] +struct TupleDefaultOff( bool, u8 ); + +impl Not for TupleDefaultOff +{ + type Output = Self; + + fn not( self ) -> Self::Output + { + Self( self.0, self.1 ) + } +} + +include!( "only_test/tuple_default_off.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/tuple_default_off_reference_on.rs b/module/core/derive_tools/tests/inc/not/tuple_default_off_reference_on.rs new file mode 100644 index 0000000000..b88ba83057 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/tuple_default_off_reference_on.rs @@ -0,0 +1,8 @@ +use super::*; + +#[ allow( dead_code ) ] +#[ derive( the_module::Not ) ] +#[ not( off ) ] +struct TupleDefaultOffReferenceOn< 'a >( #[ not( on ) ] &'a bool, u8 ); + +include!( "./only_test/tuple_default_off_reference_on.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/tuple_default_off_reference_on_manual.rs b/module/core/derive_tools/tests/inc/not/tuple_default_off_reference_on_manual.rs new file mode 100644 index 0000000000..d6d11c694c --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/tuple_default_off_reference_on_manual.rs @@ -0,0 +1,16 @@ +use core::ops::Not; + +#[ allow( dead_code ) ] +struct TupleDefaultOffReferenceOn< 'a >( &'a bool, u8 ); + +impl< 'a > Not for TupleDefaultOffReferenceOn< 'a > +{ + type Output = Self; + + fn not(self) -> Self::Output + { + Self( self.0, self.1 ) + } +} + +include!( "./only_test/tuple_default_off_reference_on.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/tuple_default_off_some_on.rs b/module/core/derive_tools/tests/inc/not/tuple_default_off_some_on.rs new file mode 100644 index 0000000000..c5b7e620ab --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/tuple_default_off_some_on.rs @@ -0,0 +1,8 @@ +use super::*; + +#[ allow( dead_code ) ] +#[ derive( the_module::Not ) ] +#[ not( off ) ] +struct TupleDefaultOffSomeOn( bool, #[ not( on ) ] u8 ); + +include!( "only_test/tuple_default_off_some_on.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/tuple_default_off_some_on_manual.rs b/module/core/derive_tools/tests/inc/not/tuple_default_off_some_on_manual.rs new file mode 100644 index 0000000000..0f8ba8ea43 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/tuple_default_off_some_on_manual.rs @@ -0,0 +1,16 @@ +use core::ops::Not; + +#[ allow( dead_code ) ] +struct TupleDefaultOffSomeOn( bool, u8 ); + +impl Not for TupleDefaultOffSomeOn +{ + type Output = Self; + + fn not( self ) -> Self::Output + { + Self( self.0, !self.1 ) + } +} + +include!( "only_test/tuple_default_off_some_on.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/tuple_default_on_mut_reference_off.rs b/module/core/derive_tools/tests/inc/not/tuple_default_on_mut_reference_off.rs new file mode 100644 index 0000000000..3c62587799 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/tuple_default_on_mut_reference_off.rs @@ -0,0 +1,7 @@ +use super::*; + +#[ allow( dead_code ) ] +#[ derive( the_module::Not ) ] +struct TupleDefaultOnMutReferenceOff< 'a >( #[ not( off ) ] &'a bool, u8); + +include!( "only_test/tuple_default_on_mut_reference_off.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/tuple_default_on_mut_reference_off_manual.rs b/module/core/derive_tools/tests/inc/not/tuple_default_on_mut_reference_off_manual.rs new file mode 100644 index 0000000000..95eb3d036a --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/tuple_default_on_mut_reference_off_manual.rs @@ -0,0 +1,16 @@ +use core::ops::Not; + +#[ allow( dead_code ) ] +struct TupleDefaultOnMutReferenceOff< 'a >( &'a bool, u8 ); + +impl< 'a > Not for TupleDefaultOnMutReferenceOff< 'a > +{ + type Output = Self; + + fn not(self) -> Self::Output + { + Self( self.0, !self.1 ) + } +} + +include!( "only_test/tuple_default_on_mut_reference_off.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/tuple_default_on_some_off.rs b/module/core/derive_tools/tests/inc/not/tuple_default_on_some_off.rs new file mode 100644 index 0000000000..14204b4c36 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/tuple_default_on_some_off.rs @@ -0,0 +1,7 @@ +use super::*; + +#[ allow( dead_code ) ] +#[ derive( the_module::Not ) ] +struct TupleDefaultOnSomeOff( bool, #[ not( off ) ] u8); + +include!( "only_test/tuple_default_on_some_off.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/tuple_default_on_some_off_manual.rs b/module/core/derive_tools/tests/inc/not/tuple_default_on_some_off_manual.rs new file mode 100644 index 0000000000..04e5d59bc7 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/tuple_default_on_some_off_manual.rs @@ -0,0 +1,16 @@ +use core::ops::Not; + +#[ allow( dead_code ) ] +struct TupleDefaultOnSomeOff( bool, u8 ); + +impl Not for TupleDefaultOnSomeOff +{ + type Output = Self; + + fn not( self ) -> Self::Output + { + Self( !self.0, self.1 ) + } +} + +include!( "only_test/tuple_default_on_some_off.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/tuple_mut_reference_field.rs b/module/core/derive_tools/tests/inc/not/tuple_mut_reference_field.rs new file mode 100644 index 0000000000..6a23e74fc1 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/tuple_mut_reference_field.rs @@ -0,0 +1,7 @@ +use super::*; + +#[ allow( dead_code ) ] +#[ derive( the_module::Not ) ] +struct TupleMutReferenceField< 'a >( &'a mut bool, u8 ); + +include!( "./only_test/tuple_mut_reference_field.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/tuple_mut_reference_field_manual.rs b/module/core/derive_tools/tests/inc/not/tuple_mut_reference_field_manual.rs new file mode 100644 index 0000000000..6975f2ab21 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/tuple_mut_reference_field_manual.rs @@ -0,0 +1,17 @@ +use core::ops::Not; + +#[ allow( dead_code ) ] +struct TupleMutReferenceField< 'a >( &'a mut bool, u8 ); + +impl< 'a > Not for TupleMutReferenceField< 'a > +{ + type Output = Self; + + fn not( self ) -> Self::Output + { + *self.0 = !*self.0; + Self( self.0, !self.1 ) + } +} + +include!( "./only_test/tuple_mut_reference_field.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/tuple_reference_field.rs b/module/core/derive_tools/tests/inc/not/tuple_reference_field.rs new file mode 100644 index 0000000000..b3f26b65bb --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/tuple_reference_field.rs @@ -0,0 +1,7 @@ +use super::*; + +#[ allow( dead_code ) ] +#[ derive( the_module::Not ) ] +struct TupleReferenceField< 'a >( &'a bool, u8 ); + +include!( "./only_test/tuple_reference_field.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/tuple_reference_field_manual.rs b/module/core/derive_tools/tests/inc/not/tuple_reference_field_manual.rs new file mode 100644 index 0000000000..c2fe1670d1 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/tuple_reference_field_manual.rs @@ -0,0 +1,16 @@ +use core::ops::Not; + +#[ allow( dead_code ) ] +struct TupleReferenceField< 'a >( &'a bool, u8 ); + +impl< 'a > Not for TupleReferenceField< 'a > +{ + type Output = Self; + + fn not( self ) -> Self::Output + { + Self( self.0, !self.1 ) + } +} + +include!( "./only_test/tuple_reference_field.rs" ); diff --git a/module/core/derive_tools/tests/inc/not/with_custom_type.rs b/module/core/derive_tools/tests/inc/not/with_custom_type.rs new file mode 100644 index 0000000000..618d406528 --- /dev/null +++ b/module/core/derive_tools/tests/inc/not/with_custom_type.rs @@ -0,0 +1,28 @@ +use core::ops::Not; +use super::*; + +#[ allow( dead_code ) ] +struct CustomType +{ + a : bool, + b : u8, +} + +impl Not for CustomType +{ + type Output = Self; + + fn not( self ) -> Self::Output + { + Self { a : !self.a, b : !self.b } + } +} + +#[ allow( dead_code ) ] +#[ derive( the_module::Not ) ] +struct WithCustomType +{ + custom_type : CustomType, +} + +include!( "./only_test/with_custom_type.rs" ); diff --git a/module/core/derive_tools/tests/inc/phantom/bounds_inlined.rs b/module/core/derive_tools/tests/inc/phantom/bounds_inlined.rs new file mode 100644 index 0000000000..cfcb0969b2 --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/bounds_inlined.rs @@ -0,0 +1,8 @@ +use std::fmt::Debug; +use super::*; + +#[ allow( dead_code ) ] +#[ the_module::phantom ] +struct BoundsInlined< T: ToString, U: Debug > {} + +include!( "./only_test/bounds_inlined.rs" ); \ No newline at end of file diff --git a/module/core/derive_tools/tests/inc/phantom/bounds_inlined_manual.rs b/module/core/derive_tools/tests/inc/phantom/bounds_inlined_manual.rs new file mode 100644 index 0000000000..01fd788326 --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/bounds_inlined_manual.rs @@ -0,0 +1,13 @@ +use std:: +{ + fmt::Debug, + marker::PhantomData, +}; + +#[ allow( dead_code ) ] +struct BoundsInlined< T: ToString, U: Debug > +{ + _phantom: PhantomData< ( T, U ) >, +} + +include!( "./only_test/bounds_inlined.rs" ); \ No newline at end of file diff --git a/module/core/derive_tools/tests/inc/phantom/bounds_mixed.rs b/module/core/derive_tools/tests/inc/phantom/bounds_mixed.rs new file mode 100644 index 0000000000..3d0b390d19 --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/bounds_mixed.rs @@ -0,0 +1,11 @@ +use std::fmt::Debug; +use super::*; + +#[ allow( dead_code ) ] +#[ the_module::phantom ] +struct BoundsMixed< T: ToString, U > +where + U: Debug, +{} + +include!( "./only_test/bounds_mixed.rs" ); \ No newline at end of file diff --git a/module/core/derive_tools/tests/inc/phantom/bounds_mixed_manual.rs b/module/core/derive_tools/tests/inc/phantom/bounds_mixed_manual.rs new file mode 100644 index 0000000000..2c1ad041dd --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/bounds_mixed_manual.rs @@ -0,0 +1,15 @@ +use std:: +{ + fmt::Debug, + marker::PhantomData, +}; + +#[ allow( dead_code ) ] +struct BoundsMixed< T: ToString, U > +where + U: Debug, +{ + _phantom: PhantomData< ( T, U ) >, +} + +include!( "./only_test/bounds_mixed.rs" ); \ No newline at end of file diff --git a/module/core/derive_tools/tests/inc/phantom/bounds_where.rs b/module/core/derive_tools/tests/inc/phantom/bounds_where.rs new file mode 100644 index 0000000000..b7e7d73dd9 --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/bounds_where.rs @@ -0,0 +1,12 @@ +use std::fmt::Debug; +use super::*; + +#[ allow( dead_code ) ] +#[ the_module::phantom ] +struct BoundsWhere< T, U > +where + T: ToString, + U: Debug, +{} + +include!( "./only_test/bounds_where.rs" ); \ No newline at end of file diff --git a/module/core/derive_tools/tests/inc/phantom/bounds_where_manual.rs b/module/core/derive_tools/tests/inc/phantom/bounds_where_manual.rs new file mode 100644 index 0000000000..89e248dc60 --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/bounds_where_manual.rs @@ -0,0 +1,16 @@ +use std:: +{ + fmt::Debug, + marker::PhantomData, +}; + +#[ allow( dead_code ) ] +struct BoundsWhere< T, U > + where + T: ToString, + U: Debug, +{ + _phantom: PhantomData< ( T, U ) > +} + +include!( "./only_test/bounds_where.rs" ); diff --git a/module/core/derive_tools/tests/inc/phantom/compiletime/enum.rs b/module/core/derive_tools/tests/inc/phantom/compiletime/enum.rs new file mode 100644 index 0000000000..f3aea8bc03 --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/compiletime/enum.rs @@ -0,0 +1,13 @@ +use derive_tools::phantom; + +#[ phantom ] +enum Enum< T > +{ + A, + B, + C( T ), +} + +fn main() +{ +} \ No newline at end of file diff --git a/module/core/derive_tools/tests/inc/phantom/compiletime/enum.stderr b/module/core/derive_tools/tests/inc/phantom/compiletime/enum.stderr new file mode 100644 index 0000000000..0a3888237c --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/compiletime/enum.stderr @@ -0,0 +1,5 @@ +error: expected `struct` + --> tests/inc/phantom/compiletime/enum.rs:4:1 + | +4 | enum Enum< T > + | ^^^^ diff --git a/module/core/derive_tools/tests/inc/phantom/compiletime/invariant_type.rs b/module/core/derive_tools/tests/inc/phantom/compiletime/invariant_type.rs new file mode 100644 index 0000000000..feea6184c6 --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/compiletime/invariant_type.rs @@ -0,0 +1,18 @@ +use derive_tools::phantom; + +#[ phantom ] +struct InvariantType< T > +{ + a: T, +} + +fn assert_invariant< 'a >( x: InvariantType< *mut &'static str > ) -> InvariantType< *mut &'a str > +{ + x +} + +fn main() +{ + let x: InvariantType< *mut &'static str > = InvariantType { a: &mut "boo", _phantom: Default::default() }; + let _: InvariantType< *mut &str > = assert_invariant( x ); +} \ No newline at end of file diff --git a/module/core/derive_tools/tests/inc/phantom/compiletime/invariant_type.stderr b/module/core/derive_tools/tests/inc/phantom/compiletime/invariant_type.stderr new file mode 100644 index 0000000000..5945c78a60 --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/compiletime/invariant_type.stderr @@ -0,0 +1,12 @@ +error: lifetime may not live long enough + --> tests/inc/phantom/compiletime/invariant_type.rs:11:3 + | +9 | fn assert_invariant< 'a >( x: InvariantType< *mut &'static str > ) -> InvariantType< *mut &'a str > + | -- lifetime `'a` defined here +10 | { +11 | x + | ^ returning this value requires that `'a` must outlive `'static` + | + = note: requirement occurs because of a mutable pointer to `&str` + = note: mutable pointers are invariant over their type parameter + = help: see for more information about variance diff --git a/module/core/derive_tools/tests/inc/phantom/contravariant_type.rs b/module/core/derive_tools/tests/inc/phantom/contravariant_type.rs new file mode 100644 index 0000000000..35e1d46946 --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/contravariant_type.rs @@ -0,0 +1,10 @@ +use super::*; + +#[ allow( dead_code ) ] +#[ the_module::phantom ] +struct ContravariantType< T > +{ + a: T, +} + +include!( "./only_test/contravariant_type.rs" ); \ No newline at end of file diff --git a/module/core/derive_tools/tests/inc/phantom/contravariant_type_manual.rs b/module/core/derive_tools/tests/inc/phantom/contravariant_type_manual.rs new file mode 100644 index 0000000000..30ad26d10b --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/contravariant_type_manual.rs @@ -0,0 +1,10 @@ +use std::marker::PhantomData; + +#[ allow( dead_code ) ] +struct ContravariantType< T > +{ + a: T, + _phantom: PhantomData< T >, +} + +include!( "./only_test/contravariant_type.rs" ); \ No newline at end of file diff --git a/module/core/derive_tools/tests/inc/phantom/covariant_type.rs b/module/core/derive_tools/tests/inc/phantom/covariant_type.rs new file mode 100644 index 0000000000..bdcd40d573 --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/covariant_type.rs @@ -0,0 +1,10 @@ +use super::*; + +#[ allow( dead_code ) ] +#[ the_module::phantom ] +struct CovariantType< T > +{ + a: T, +} + +include!( "./only_test/covariant_type.rs" ); \ No newline at end of file diff --git a/module/core/derive_tools/tests/inc/phantom/covariant_type_manual.rs b/module/core/derive_tools/tests/inc/phantom/covariant_type_manual.rs new file mode 100644 index 0000000000..ce4484519e --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/covariant_type_manual.rs @@ -0,0 +1,10 @@ +use std::marker::PhantomData; + +#[ allow( dead_code ) ] +struct CovariantType< T > +{ + a: T, + _phantom: PhantomData< T >, +} + +include!( "./only_test/covariant_type.rs" ); \ No newline at end of file diff --git a/module/core/derive_tools/tests/inc/phantom/name_collisions.rs b/module/core/derive_tools/tests/inc/phantom/name_collisions.rs new file mode 100644 index 0000000000..1686b4c1da --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/name_collisions.rs @@ -0,0 +1,15 @@ +use super::*; + +pub mod std {} +pub mod core {} +pub mod marker {} + +#[ allow( dead_code ) ] +#[ the_module::phantom ] +struct NameCollisions< T > +{ + a : String, + b : i32, +} + +include!( "./only_test/name_collisions.rs" ); \ No newline at end of file diff --git a/module/core/derive_tools/tests/inc/phantom/only_test/bounds_inlined.rs b/module/core/derive_tools/tests/inc/phantom/only_test/bounds_inlined.rs new file mode 100644 index 0000000000..c0320bc28f --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/only_test/bounds_inlined.rs @@ -0,0 +1,5 @@ +#[ test ] +fn phantom() +{ + let _ = BoundsInlined::< String, i32 > { _phantom: Default::default() }; +} \ No newline at end of file diff --git a/module/core/derive_tools/tests/inc/phantom/only_test/bounds_mixed.rs b/module/core/derive_tools/tests/inc/phantom/only_test/bounds_mixed.rs new file mode 100644 index 0000000000..773c57967d --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/only_test/bounds_mixed.rs @@ -0,0 +1,5 @@ +#[ test ] +fn phantom() +{ + let _ = BoundsMixed::< String, i32 > { _phantom: Default::default() }; +} \ No newline at end of file diff --git a/module/core/derive_tools/tests/inc/phantom/only_test/bounds_where.rs b/module/core/derive_tools/tests/inc/phantom/only_test/bounds_where.rs new file mode 100644 index 0000000000..3bf24a6d6c --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/only_test/bounds_where.rs @@ -0,0 +1,5 @@ +#[ test ] +fn phantom() +{ + let _ = BoundsWhere::< String, i32 > { _phantom: Default::default() }; +} \ No newline at end of file diff --git a/module/core/derive_tools/tests/inc/phantom/only_test/contravariant_type.rs b/module/core/derive_tools/tests/inc/phantom/only_test/contravariant_type.rs new file mode 100644 index 0000000000..f30c2a57e8 --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/only_test/contravariant_type.rs @@ -0,0 +1,18 @@ +fn assert_contravariant( x: ContravariantType< &dyn Fn( &'static str ) -> String > ) -> String +{ + ( x.a )( "test" ) +} + +#[test] +fn contravariant() +{ + let x_fn: &dyn for< 'a > Fn( &'a str ) -> String = &| s: &str | + { + format!( "x_fn: {s}" ) + }; + + let x: ContravariantType< &dyn for< 'a > Fn( &'a str ) -> String > = ContravariantType { a: x_fn, _phantom: Default::default() }; + let value = assert_contravariant(x); + + assert_eq!( value, String::from( "x_fn: test" ) ); +} diff --git a/module/core/derive_tools/tests/inc/phantom/only_test/covariant_type.rs b/module/core/derive_tools/tests/inc/phantom/only_test/covariant_type.rs new file mode 100644 index 0000000000..75e02a1255 --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/only_test/covariant_type.rs @@ -0,0 +1,12 @@ +fn assert_covariant< 'a >( x: CovariantType< &'static str > ) -> CovariantType< &'a str > +{ + x +} + +#[ test ] +fn covariant() +{ + let x: CovariantType< &'static str > = CovariantType { a: "boo", _phantom: Default::default(), }; + let y: CovariantType< &str > = assert_covariant( x ); + assert_eq!( y.a, "boo" ); +} diff --git a/module/core/derive_tools/tests/inc/phantom/only_test/name_collisions.rs b/module/core/derive_tools/tests/inc/phantom/only_test/name_collisions.rs new file mode 100644 index 0000000000..29badc6387 --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/only_test/name_collisions.rs @@ -0,0 +1,5 @@ +#[ test ] +fn phantom() +{ + let _ = NameCollisions::< bool > { a : "boo".into(), b : 3, _phantom: Default::default() }; +} \ No newline at end of file diff --git a/module/core/derive_tools/tests/inc/phantom/only_test/send_sync_type.rs b/module/core/derive_tools/tests/inc/phantom/only_test/send_sync_type.rs new file mode 100644 index 0000000000..8276f07094 --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/only_test/send_sync_type.rs @@ -0,0 +1,9 @@ +fn assert_send_sync< T: Send + Sync >( _x: SendSyncType< T > ) +{} + +#[ test ] +fn phantom() +{ + let x: SendSyncType::< bool > = SendSyncType { a: true, _phantom: Default::default() }; + assert_send_sync( x ); +} \ No newline at end of file diff --git a/module/core/derive_tools/tests/inc/phantom/only_test/struct_named.rs b/module/core/derive_tools/tests/inc/phantom/only_test/struct_named.rs new file mode 100644 index 0000000000..d29423246f --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/only_test/struct_named.rs @@ -0,0 +1,5 @@ +#[ test ] +fn phantom() +{ + let _ = StructNamed::< bool > { a : "boo".into(), b : 3, _phantom: Default::default() }; +} \ No newline at end of file diff --git a/module/core/derive_tools/tests/inc/phantom/only_test/struct_named_empty.rs b/module/core/derive_tools/tests/inc/phantom/only_test/struct_named_empty.rs new file mode 100644 index 0000000000..8b7da9540a --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/only_test/struct_named_empty.rs @@ -0,0 +1,5 @@ +#[ test ] +fn phantom() +{ + let _ = StructNamedEmpty::< bool > { _phantom: Default::default() }; +} \ No newline at end of file diff --git a/module/core/derive_tools/tests/inc/phantom/only_test/struct_tuple.rs b/module/core/derive_tools/tests/inc/phantom/only_test/struct_tuple.rs new file mode 100644 index 0000000000..a54f6e6636 --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/only_test/struct_tuple.rs @@ -0,0 +1,5 @@ +#[ test ] +fn phantom() +{ + let _ = StructTuple::< bool >( "boo".into(), 3, Default::default() ); +} diff --git a/module/core/derive_tools/tests/inc/phantom/only_test/struct_tuple_empty.rs b/module/core/derive_tools/tests/inc/phantom/only_test/struct_tuple_empty.rs new file mode 100644 index 0000000000..865d3dc08e --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/only_test/struct_tuple_empty.rs @@ -0,0 +1,5 @@ +#[ test ] +fn phantom() +{ + let _ = StructTupleEmpty::< bool >( Default::default() ); +} \ No newline at end of file diff --git a/module/core/derive_tools/tests/inc/phantom/only_test/struct_unit_to_tuple.rs b/module/core/derive_tools/tests/inc/phantom/only_test/struct_unit_to_tuple.rs new file mode 100644 index 0000000000..abaa38b628 --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/only_test/struct_unit_to_tuple.rs @@ -0,0 +1,5 @@ +#[ test ] +fn phantom() +{ + let _ = StructUnit::< bool >( Default::default() ); +} \ No newline at end of file diff --git a/module/core/derive_tools/tests/inc/phantom/send_sync_type.rs b/module/core/derive_tools/tests/inc/phantom/send_sync_type.rs new file mode 100644 index 0000000000..f50f2044f3 --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/send_sync_type.rs @@ -0,0 +1,10 @@ +use super::*; + +#[ allow( dead_code ) ] +#[ the_module::phantom ] +struct SendSyncType< T > +{ + a: T, +} + +include!( "./only_test/send_sync_type.rs" ); \ No newline at end of file diff --git a/module/core/derive_tools/tests/inc/phantom/send_sync_type_manual.rs b/module/core/derive_tools/tests/inc/phantom/send_sync_type_manual.rs new file mode 100644 index 0000000000..0917d7db34 --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/send_sync_type_manual.rs @@ -0,0 +1,10 @@ +use std::marker::PhantomData; + +#[ allow( dead_code ) ] +struct SendSyncType< T > +{ + a: T, + _phantom: PhantomData< T >, +} + +include!( "./only_test/send_sync_type.rs" ); \ No newline at end of file diff --git a/module/core/derive_tools/tests/inc/phantom/struct_named.rs b/module/core/derive_tools/tests/inc/phantom/struct_named.rs new file mode 100644 index 0000000000..51ba45b723 --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/struct_named.rs @@ -0,0 +1,11 @@ +use super::*; + +#[ allow( dead_code ) ] +#[ the_module::phantom ] +struct StructNamed< T > +{ + a : String, + b : i32, +} + +include!( "./only_test/struct_named.rs" ); \ No newline at end of file diff --git a/module/core/derive_tools/tests/inc/phantom/struct_named_empty.rs b/module/core/derive_tools/tests/inc/phantom/struct_named_empty.rs new file mode 100644 index 0000000000..aed495af34 --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/struct_named_empty.rs @@ -0,0 +1,7 @@ +use super::*; + +#[ allow( dead_code ) ] +#[ the_module::phantom ] +struct StructNamedEmpty< T > {} + +include!( "./only_test/struct_named_empty.rs" ); \ No newline at end of file diff --git a/module/core/derive_tools/tests/inc/phantom/struct_named_empty_manual.rs b/module/core/derive_tools/tests/inc/phantom/struct_named_empty_manual.rs new file mode 100644 index 0000000000..e1929105e7 --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/struct_named_empty_manual.rs @@ -0,0 +1,9 @@ +use std::marker::PhantomData; + +#[ allow( dead_code ) ] +struct StructNamedEmpty< T > +{ + _phantom : PhantomData< T >, +} + +include!( "./only_test/struct_named_empty.rs" ); \ No newline at end of file diff --git a/module/core/derive_tools/tests/inc/phantom/struct_named_manual.rs b/module/core/derive_tools/tests/inc/phantom/struct_named_manual.rs new file mode 100644 index 0000000000..b98e75c0cc --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/struct_named_manual.rs @@ -0,0 +1,11 @@ +use std::marker::PhantomData; + +#[ allow( dead_code ) ] +struct StructNamed< T > +{ + a : String, + b : i32, + _phantom : PhantomData< T >, +} + +include!( "./only_test/struct_named.rs" ); \ No newline at end of file diff --git a/module/core/derive_tools/tests/inc/phantom/struct_tuple.rs b/module/core/derive_tools/tests/inc/phantom/struct_tuple.rs new file mode 100644 index 0000000000..d19af977f8 --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/struct_tuple.rs @@ -0,0 +1,7 @@ +use super::*; + +#[ allow( dead_code ) ] +#[ the_module::phantom ] +struct StructTuple< T >( String, i32 ); + +include!( "./only_test/struct_tuple.rs" ); \ No newline at end of file diff --git a/module/core/derive_tools/tests/inc/phantom/struct_tuple_empty.rs b/module/core/derive_tools/tests/inc/phantom/struct_tuple_empty.rs new file mode 100644 index 0000000000..272672ccf5 --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/struct_tuple_empty.rs @@ -0,0 +1,7 @@ +use super::*; + +#[ allow( dead_code ) ] +#[ the_module::phantom ] +struct StructTupleEmpty< T >(); + +include!( "./only_test/struct_tuple_empty.rs" ); \ No newline at end of file diff --git a/module/core/derive_tools/tests/inc/phantom/struct_tuple_empty_manual.rs b/module/core/derive_tools/tests/inc/phantom/struct_tuple_empty_manual.rs new file mode 100644 index 0000000000..4ebbe05a7b --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/struct_tuple_empty_manual.rs @@ -0,0 +1,6 @@ +use std::marker::PhantomData; + +#[ allow( dead_code ) ] +struct StructTupleEmpty< T >( PhantomData< T > ); + +include!( "./only_test/struct_tuple_empty.rs" ); \ No newline at end of file diff --git a/module/core/derive_tools/tests/inc/phantom/struct_tuple_manual.rs b/module/core/derive_tools/tests/inc/phantom/struct_tuple_manual.rs new file mode 100644 index 0000000000..35ea17b962 --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/struct_tuple_manual.rs @@ -0,0 +1,6 @@ +use std::marker::PhantomData; + +#[ allow( dead_code ) ] +struct StructTuple< T >( String, i32, PhantomData< T > ); + +include!( "./only_test/struct_tuple.rs" ); \ No newline at end of file diff --git a/module/core/derive_tools/tests/inc/phantom/struct_unit_to_tuple.rs b/module/core/derive_tools/tests/inc/phantom/struct_unit_to_tuple.rs new file mode 100644 index 0000000000..52e79926a6 --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/struct_unit_to_tuple.rs @@ -0,0 +1,7 @@ +use super::*; + +#[ allow( dead_code ) ] +#[ the_module::phantom ] +struct StructUnit< T >; + +include!( "./only_test/struct_unit_to_tuple.rs" ); \ No newline at end of file diff --git a/module/core/derive_tools/tests/inc/phantom/struct_unit_to_tuple_manual.rs b/module/core/derive_tools/tests/inc/phantom/struct_unit_to_tuple_manual.rs new file mode 100644 index 0000000000..a4b093e7cf --- /dev/null +++ b/module/core/derive_tools/tests/inc/phantom/struct_unit_to_tuple_manual.rs @@ -0,0 +1,6 @@ +use std::marker::PhantomData; + +#[ allow( dead_code ) ] +struct StructUnit< T >( PhantomData< T > ); + +include!( "./only_test/struct_unit_to_tuple.rs" ); \ No newline at end of file diff --git a/module/core/derive_tools/tests/smoke_test.rs b/module/core/derive_tools/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/core/derive_tools/tests/smoke_test.rs +++ b/module/core/derive_tools/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/core/derive_tools/tests/tests.rs b/module/core/derive_tools/tests/tests.rs index 766eadcfe7..6af3bbd6f0 100644 --- a/module/core/derive_tools/tests/tests.rs +++ b/module/core/derive_tools/tests/tests.rs @@ -1,4 +1,6 @@ +include!( "../../../../module/step/meta/src/module/terminal.rs" ); + #[ allow( unused_imports ) ] use derive_tools as the_module; #[ allow( unused_imports ) ] @@ -6,4 +8,3 @@ use test_tools::exposed::*; #[ cfg( feature = "enabled" ) ] mod inc; - diff --git a/module/core/derive_tools_meta/Cargo.toml b/module/core/derive_tools_meta/Cargo.toml index eade555900..9b1e39c9ee 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.23.0" +version = "0.25.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", @@ -24,8 +24,6 @@ workspace = true features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] - [lib] proc-macro = true @@ -36,10 +34,14 @@ default = [ "derive_deref", "derive_from", "derive_new", + "derive_index", + "derive_index_mut", "derive_inner_from", "derive_as_ref", "derive_as_mut", "derive_variadic_from", + "derive_not", + "derive_phantom" ] full = [ "enabled", @@ -47,10 +49,14 @@ full = [ "derive_deref", "derive_from", "derive_new", + "derive_index", + "derive_index_mut", "derive_inner_from", "derive_as_ref", "derive_as_mut", "derive_variadic_from", + "derive_not", + "derive_phantom" ] enabled = [ "macro_tools/enabled", "iter_tools/enabled", "former_types/enabled" ] @@ -60,15 +66,19 @@ derive_deref = [] derive_deref_mut = [] derive_from = [] derive_new = [] +derive_index = [] +derive_index_mut = [] derive_inner_from = [] -derive_variadic_from = [] +derive_variadic_from = [ "iter_tools/iter_ext" ] +derive_not = [] +derive_phantom = [] [dependencies] -# xxx : qqq : optimize features set -macro_tools = { workspace = true, features = [ "full" ] } -iter_tools = { workspace = true, features = [ "full" ] } +# zzz : qqq : optimize features set +macro_tools = { workspace = true, features = [ "attr", "attr_prop", "container_kind", "ct", "diag", "generic_args", "typ", "derive", "generic_params", "name", "phantom", "struct_like", "quantifier" ] } +# zzz : qqq : optimize features set +iter_tools = { workspace = true, features = [ "iter_trait" ] } former_types = { workspace = true, features = [ "types_component_assign" ] } -const_format = { version = "0.2.32" } [dev-dependencies] test_tools = { workspace = true } diff --git a/module/core/derive_tools_meta/src/derive.rs b/module/core/derive_tools_meta/src/derive.rs index 5008fe2fab..5a10f790af 100644 --- a/module/core/derive_tools_meta/src/derive.rs +++ b/module/core/derive_tools_meta/src/derive.rs @@ -5,7 +5,7 @@ #[ allow( unused_imports ) ] use macro_tools::prelude::*; -// pub use macro_tools::{ Result, Many }; +#[ allow( unused_imports ) ] pub use iter_tools as iter; #[ cfg( feature = "derive_as_mut" ) ] @@ -18,11 +18,17 @@ pub mod deref; pub mod deref_mut; #[ cfg( feature = "derive_from" ) ] pub mod from; +#[ cfg( feature = "derive_index" ) ] +pub mod index; +#[ cfg( feature = "derive_index_mut" ) ] +pub mod index_mut; #[ cfg( feature = "derive_inner_from" ) ] pub mod inner_from; #[ cfg( feature = "derive_new" ) ] pub mod new; #[ cfg( feature = "derive_variadic_from" ) ] pub mod variadic_from; -#[ cfg( feature = "derive_reflect" ) ] -pub mod reflect; +#[ cfg( feature = "derive_not" ) ] +pub mod not; +#[ cfg( feature = "derive_phantom" ) ] +pub mod phantom; diff --git a/module/core/derive_tools_meta/src/derive/deref_mut.rs b/module/core/derive_tools_meta/src/derive/deref_mut.rs index 46d7a273f6..28e01c9e8f 100644 --- a/module/core/derive_tools_meta/src/derive/deref_mut.rs +++ b/module/core/derive_tools_meta/src/derive/deref_mut.rs @@ -99,9 +99,18 @@ fn generate_struct /// /// ## Input /// ```rust -/// # use derive_tools_meta::{ Deref, DerefMut }; -/// #[ derive( Deref, DerefMut ) ] +/// # use derive_tools_meta::DerefMut; +/// #[ derive( DerefMut ) ] /// pub struct Struct( i32, Vec< String > ); +/// +/// impl ::core::ops::Deref for Struct +/// { +/// type Target = i32; +/// fn deref( &self ) -> &Self::Target +/// { +/// &self.0 +/// } +/// } /// ``` /// /// ## Output @@ -162,13 +171,22 @@ fn generate_struct_tuple_fields /// /// ## Input /// ```rust -/// # use derive_tools_meta::{ Deref, DerefMut }; -/// #[ derive( Deref, DerefMut ) ] +/// # use derive_tools_meta::DerefMut; +/// #[ derive( DerefMut ) ] /// pub struct Struct /// { /// a : i32, /// b : Vec< String >, /// } +/// +/// impl ::core::ops::Deref for Struct +/// { +/// type Target = i32; +/// fn deref( &self ) -> &Self::Target +/// { +/// &self.a +/// } +/// } /// ``` /// /// ## Output @@ -289,14 +307,26 @@ fn generate_enum /// /// ## Input /// ```rust -/// # use derive_tools_meta::{ Deref, DerefMut }; -/// #[ derive( Deref, DerefMut ) ] +/// # use derive_tools_meta::DerefMut; +/// #[ derive( DerefMut ) ] /// pub enum E /// { /// A ( i32, Vec< String > ), /// B ( i32, Vec< String > ), /// C ( i32, Vec< String > ), /// } +/// +/// impl ::core::ops::Deref for E +/// { +/// type Target = i32; +/// fn deref( &self ) -> &Self::Target +/// { +/// match self +/// { +/// E::A( v, .. ) | E::B( v, .. ) | E::C( v, .. ) => v, +/// } +/// } +/// } /// ``` /// /// ## Output @@ -372,14 +402,26 @@ fn generate_enum_tuple_variants /// /// ## Input /// ```rust -/// # use derive_tools_meta::{ Deref, DerefMut }; -/// #[ derive( Deref, DerefMut ) ] +/// # use derive_tools_meta::DerefMut; +/// #[ derive( DerefMut ) ] /// pub enum E /// { /// A { a : i32, b : Vec< String > }, /// B { a : i32, b : Vec< String > }, /// C { a : i32, b : Vec< String > }, /// } +/// +/// impl ::core::ops::Deref for E +/// { +/// type Target = i32; +/// fn deref( &self ) -> &Self::Target +/// { +/// match self +/// { +/// E::A { a : v, .. } | E::B { a : v, .. } | E::C { a : v, .. } => v, +/// } +/// } +/// } /// ``` /// /// ## Output diff --git a/module/core/derive_tools_meta/src/derive/from.rs b/module/core/derive_tools_meta/src/derive/from.rs index 65334d453d..585df90183 100644 --- a/module/core/derive_tools_meta/src/derive/from.rs +++ b/module/core/derive_tools_meta/src/derive/from.rs @@ -262,7 +262,7 @@ fn generate_single_field_named /// #[ derive( From ) ] /// pub struct IsTransparent( bool ); /// ``` -/// +/// /// ## Output /// ```rust /// pub struct IsTransparent( bool ); @@ -348,22 +348,21 @@ fn generate_multiple_fields_named< 'a > generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, generics_where: &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, - field_names : Box< dyn macro_tools::IterTrait< 'a, &'a syn::Ident > + '_ >, + field_names : impl macro_tools::IterTrait< 'a, &'a syn::Ident >, field_types : impl macro_tools::IterTrait< 'a, &'a syn::Type >, ) -> proc_macro2::TokenStream { - let params : Vec< proc_macro2::TokenStream > = field_names + let params = field_names .enumerate() .map(| ( index, field_name ) | { let index = index.to_string().parse::< proc_macro2::TokenStream >().unwrap(); qt! { #field_name : src.#index } - }) - .collect(); + }); - let field_types : Vec< _ > = field_types.collect(); + let field_types2 = field_types.clone(); qt! { impl< #generics_impl > From< (# ( #field_types ),* ) > for #item_name< #generics_ty > @@ -372,16 +371,15 @@ fn generate_multiple_fields_named< 'a > { #[ inline( always ) ] // fn from( src : (i32, bool) ) -> Self - fn from( src : ( #( #field_types ),* ) ) -> Self + fn from( src : ( #( #field_types2 ),* ) ) -> Self { - #item_name { #(#params),* } + #item_name { #( #params ),* } } } } } -// qqq : document, add example of generated code -- done /// Generates `From` implementation for tuple structs with multiple fields /// /// # Example @@ -417,13 +415,12 @@ fn generate_multiple_fields< 'a > -> proc_macro2::TokenStream { - let params : Vec< proc_macro2::TokenStream > = ( 0..field_types.len() ) + let params = ( 0..field_types.len() ) .map( | index | { let index = index.to_string().parse::< proc_macro2::TokenStream >().unwrap(); qt!( src.#index ) - }) - .collect(); + }); let field_types : Vec< _ > = field_types.collect(); @@ -541,4 +538,4 @@ field : {variant_name}"#, } ) -} \ No newline at end of file +} diff --git a/module/core/derive_tools_meta/src/derive/from/field_attributes.rs b/module/core/derive_tools_meta/src/derive/from/field_attributes.rs index 8ff1e9f56f..5aeb72bd56 100644 --- a/module/core/derive_tools_meta/src/derive/from/field_attributes.rs +++ b/module/core/derive_tools_meta/src/derive/from/field_attributes.rs @@ -1,6 +1,7 @@ use super::*; use macro_tools:: { + ct, Result, AttributeComponent, AttributePropertyComponent, @@ -30,7 +31,7 @@ impl FieldAttributes let error = | attr : &syn::Attribute | -> syn::Error { - let known_attributes = const_format::concatcp! + let known_attributes = ct::concatcp! ( "Known attirbutes are : ", "debug", @@ -166,7 +167,7 @@ impl syn::parse::Parse for FieldAttributeConfig let error = | ident : &syn::Ident | -> syn::Error { - let known = const_format::concatcp! + let known = ct::concatcp! ( "Known entries of attribute ", FieldAttributeConfig::KEYWORD, " are : ", AttributePropertyDebug::KEYWORD, diff --git a/module/core/derive_tools_meta/src/derive/from/item_attributes.rs b/module/core/derive_tools_meta/src/derive/from/item_attributes.rs index 78cc32f2d4..f60b4fbbe4 100644 --- a/module/core/derive_tools_meta/src/derive/from/item_attributes.rs +++ b/module/core/derive_tools_meta/src/derive/from/item_attributes.rs @@ -1,6 +1,7 @@ use super::*; use macro_tools:: { + ct, Result, AttributeComponent, }; @@ -28,7 +29,7 @@ impl ItemAttributes let error = | attr : &syn::Attribute | -> syn::Error { - let known_attributes = const_format::concatcp! + let known_attributes = ct::concatcp! ( "Known attirbutes are : ", "debug", @@ -151,7 +152,7 @@ impl syn::parse::Parse for ItemAttributeConfig let error = | ident : &syn::Ident | -> syn::Error { - let known = const_format::concatcp! + let known = ct::concatcp! ( "Known entries of attribute ", ItemAttributeConfig::KEYWORD, " are : ", EnabledMarker::KEYWORD_ON, diff --git a/module/core/derive_tools_meta/src/derive/index.rs b/module/core/derive_tools_meta/src/derive/index.rs new file mode 100644 index 0000000000..f9841e0d6a --- /dev/null +++ b/module/core/derive_tools_meta/src/derive/index.rs @@ -0,0 +1,350 @@ +use super::*; +use macro_tools:: +{ + attr, + diag, + generic_params, + struct_like::StructLike, + Result +}; + +#[ path = "index/item_attributes.rs" ] +mod item_attributes; +use item_attributes::*; +#[ path = "index/field_attributes.rs" ] +mod field_attributes; +use field_attributes::*; + + +pub fn index( input : proc_macro::TokenStream ) -> Result< proc_macro2::TokenStream > +{ + let original_input = input.clone(); + let parsed = syn::parse::< StructLike >( input )?; + let has_debug = attr::has_debug( parsed.attrs().iter() )?; + let item_name = &parsed.ident(); + + let item_attrs = ItemAttributes::from_attrs( parsed.attrs().iter() )?; + + let ( _generics_with_defaults, generics_impl, generics_ty, generics_where ) + = generic_params::decompose( &parsed.generics() ); + + let result = match parsed + { + StructLike::Struct( ref item ) => + generate_struct + ( + item_name, + &item_attrs, + &generics_impl, + &generics_ty, + &generics_where, + &item.fields, + + ), + StructLike::Enum( _ ) => + unimplemented!( "Index not implemented for Enum" ), + StructLike::Unit( _ ) => + unimplemented!( "Index not implemented for Unit" ), + }?; + + if has_debug + { + let about = format!( "derive : Not\nstructure : {item_name}" ); + diag::report_print( about, &original_input, &result ); + } + + Ok( result ) +} + +/// An aggregator function to generate `Index` implementation for tuple and named structs +fn generate_struct +( + item_name : &syn::Ident, + item_attrs : &ItemAttributes, + generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_where : &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, + fields : &syn::Fields, +) +-> Result< proc_macro2::TokenStream > +{ + + match fields + { + syn::Fields::Named( fields ) => + generate_struct_named_fields + ( + item_name, + &item_attrs, + generics_impl, + generics_ty, + generics_where, + fields + ), + + syn::Fields::Unnamed( fields ) => + generate_struct_tuple_fields + ( + item_name, + generics_impl, + generics_ty, + generics_where, + fields + ), + + syn::Fields::Unit => + unimplemented!( "Index not implemented for Unit" ), + } +} + +/// Generates `Index` implementation for named structs +/// +/// # Example +/// +/// ## Input +/// # use derive_tools_meta::Index; +/// #[ derive( Index ) ] +/// pub struct IsTransparent +/// { +/// #[ index ] +/// value : Vec< u8 >, +/// } +/// +/// ## Output +/// ```rust +/// pub struct IsTransparent +/// { +/// value : Vec< u8 >, +/// } +/// #[ automatically_derived ] +/// impl ::core::ops::Index< usize > for IsTransparent +/// { +/// type Output = u8; +/// #[ inline( always ) ] +/// fn index( &self, index : usize ) -> &Self::Output +/// { +/// &self.value[ index ] +/// } +/// } +/// ``` +/// +fn generate_struct_named_fields +( + item_name : &syn::Ident, + item_attrs : &ItemAttributes, + generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_where : &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, + fields : &syn::FieldsNamed, +) +-> Result< proc_macro2::TokenStream > +{ + + let fields = fields.named.clone(); + let attr_name = &item_attrs.index.name.clone().internal(); + + let field_attrs: Vec< &syn::Field > = fields + .iter() + .filter + ( + | field | + { + FieldAttributes::from_attrs( field.attrs.iter() ).map_or + ( + false, + | attrs | attrs.index.value( false ) + ) + } + ) + .collect(); + + + let generated = if let Some( attr_name ) = attr_name + { + Ok + ( + qt! + { + &self.#attr_name[ index ] + } + ) + } + else + { + match field_attrs.len() + { + 0 | 1 => + { + let field_name = + match field_attrs + .first() + .copied() + .or_else + ( + || fields.first() + ) + { + Some( field ) => + field.ident.as_ref().unwrap(), + None => + unimplemented!( "IndexMut not implemented for Unit" ), + }; + + Ok + ( + qt! + { + &self.#field_name[ index ] + } + ) + } + _ => + Err + ( + syn::Error::new_spanned + ( + &fields, + "Only one field can include #[ index ] derive macro" + ) + ), + } + }?; + + Ok + ( + qt! + { + #[ automatically_derived ] + impl< #generics_impl > ::core::ops::Index< usize > for #item_name< #generics_ty > + where + #generics_where + { + type Output = T; + #[ inline( always ) ] + fn index( &self, index : usize ) -> &Self::Output + { + #generated + } + } + } + ) +} + +/// Generates `Index` implementation for tuple structs +/// +/// # Example +/// +/// ## Input +/// # use derive_tools_meta::Index; +/// #[ derive( Index ) ] +/// pub struct IsTransparent +/// ( +/// #[ index ] +/// Vec< u8 > +/// ); +/// +/// ## Output +/// ```rust +/// pub struct IsTransparent +/// ( +/// Vec< u8 > +/// ); +/// #[ automatically_derived ] +/// impl ::core::ops::Index< usize > for IsTransparent +/// { +/// type Output = u8; +/// #[ inline( always ) ] +/// fn index( &self, index : usize ) -> &Self::Output +/// { +/// &self.0[ index ] +/// } +/// } +/// ``` +/// +fn generate_struct_tuple_fields +( + item_name : &syn::Ident, + generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_where : &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, + fields : &syn::FieldsUnnamed, +) +-> Result< proc_macro2::TokenStream > +{ + let fields = fields.unnamed.clone(); + let non_empty_attrs : Vec< &syn::Field > = fields + .iter() + .filter( | field | !field.attrs.is_empty() ) + .collect(); + + let generated = match non_empty_attrs.len() + { + 0 => + { + Ok + ( + qt! + { + &self.0[ index ] + } + ) + }, + 1 => + fields + .iter() + .enumerate() + .map + ( + | ( i, field ) | + { + let i = syn::Index::from( i ); + if !field.attrs.is_empty() + { + Ok + ( + qt! + { + &self.#i[ index ] + } + ) + } + else + { + Ok + ( + qt!{ } + ) + } + } + ).collect(), + _ => + Err + ( + syn::Error::new_spanned + ( + &fields, + "Only one field can include #[ index ] derive macro" + ) + ), + }?; + + Ok + ( + qt! + { + #[ automatically_derived ] + impl< #generics_impl > ::core::ops::Index< usize > for #item_name< #generics_ty > + where + #generics_where + { + type Output = T; + #[ inline( always ) ] + fn index( &self, index : usize ) -> &Self::Output + { + #generated + } + } + } + ) +} + diff --git a/module/core/derive_tools_meta/src/derive/index/field_attributes.rs b/module/core/derive_tools_meta/src/derive/index/field_attributes.rs new file mode 100644 index 0000000000..f21e170305 --- /dev/null +++ b/module/core/derive_tools_meta/src/derive/index/field_attributes.rs @@ -0,0 +1,99 @@ +use macro_tools:: +{ + ct, + syn_err, + syn, + qt, + Result, + AttributePropertyComponent, + AttributePropertyOptionalSingletone, + Assign, +}; + +/// +/// Attributes of a field / variant +/// + +/// Represents the attributes of a struct. Aggregates all its attributes. +#[ derive( Debug, Default ) ] +pub struct FieldAttributes +{ + /// Specifies whether we should generate Index implementation for the field. + pub index : AttributePropertyIndex, +} + +impl FieldAttributes +{ + /// Constructs a `ItemAttributes` instance from an iterator of attributes. + /// + /// This function parses the provided attributes and assigns them to the + /// appropriate fields in the `ItemAttributes` struct. + pub fn from_attrs< 'a >( attrs : impl Iterator< Item = & 'a syn::Attribute > ) -> Result< Self > + { + let mut result = Self::default(); + + // Closure to generate an error message for unknown attributes. + let error = | attr : & syn::Attribute | -> syn::Error + { + let known_attributes = ct::concatcp! + ( + "Known attributes are : ", + ", ", AttributePropertyIndex::KEYWORD, + ".", + ); + syn_err! + ( + attr, + "Expects an attribute of format '#[ attribute ]'\n {known_attributes}\n But got: '{}'", + qt! { #attr } + ) + }; + + for attr in attrs + { + let key_ident = attr.path().get_ident().ok_or_else( || error( attr ) )?; + let key_str = format!( "{}", key_ident ); + + match key_str.as_ref() + { + AttributePropertyIndex::KEYWORD => result.assign( AttributePropertyIndex::from( true ) ), + _ => {}, + // _ => return Err( error( attr ) ), + } + } + + Ok( result ) + } +} + +impl< IntoT > Assign< AttributePropertyIndex, IntoT > for FieldAttributes +where + IntoT : Into< AttributePropertyIndex >, +{ + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + self.index.assign( component.into() ); + } +} + + +// == Attribute properties + +/// Marker type for attribute property to indicate whether a index code should be generated. +/// Defaults to `false`, meaning no index code is generated unless explicitly requested. +#[ derive( Debug, Default, Clone, Copy ) ] +pub struct AttributePropertyIndexMarker; + +impl AttributePropertyComponent for AttributePropertyIndexMarker +{ + const KEYWORD : & 'static str = "index"; +} + +/// Indicates whether a index code should be generated. +/// Defaults to `false`, meaning no index code is generated unless explicitly requested. +pub type AttributePropertyIndex = AttributePropertyOptionalSingletone< AttributePropertyIndexMarker >; + +// == + + diff --git a/module/core/derive_tools_meta/src/derive/index/item_attributes.rs b/module/core/derive_tools_meta/src/derive/index/item_attributes.rs new file mode 100644 index 0000000000..33a056e248 --- /dev/null +++ b/module/core/derive_tools_meta/src/derive/index/item_attributes.rs @@ -0,0 +1,233 @@ +use super::*; +use macro_tools:: +{ + ct, + Result, + AttributeComponent, + AttributePropertyComponent, + AttributePropertyOptionalSyn, + AttributePropertyOptionalSingletone, +}; + +/// Represents the attributes of a struct. Aggregates all its attributes. +#[ derive( Debug, Default ) ] +pub struct ItemAttributes +{ + /// Attribute for customizing generated code. + pub index : ItemAttributeIndex, + /// Specifies whether to provide a generated code as a hint. + /// Defaults to `false`, which means no code is printed unless explicitly requested. + pub debug : AttributePropertyDebug, +} + +#[ derive( Debug, Default ) ] +pub struct ItemAttributeIndex +{ + /// Specifies what specific named field must implement Index. + pub name : AttributePropertyName, +} + +impl ItemAttributes +{ + /// Constructs a `ItemAttributes` instance from an iterator of attributes. + /// + /// This function parses the provided attributes and assigns them to the + /// appropriate fields in the `ItemAttributes` struct. + pub fn from_attrs< 'a >( attrs : impl Iterator< Item = & 'a syn::Attribute > ) -> Result< Self > + { + let mut result = Self::default(); + + // Closure to generate an error message for unknown attributes. + let error = | attr : & syn::Attribute | -> syn::Error + { + let known_attributes = ct::concatcp! + ( + "Known attributes are: ", + "debug", + ", ", ItemAttributeIndex::KEYWORD, + "." + ); + syn_err! + ( + attr, + "Expects an attribute of format '#[ attribute ]'\n {known_attributes}\n But got: '{}'", + qt! { #attr } + ) + }; + + for attr in attrs + { + let key_ident = attr.path().get_ident().ok_or_else( || error( attr ) )?; + let key_str = format!( "{}", key_ident ); + match key_str.as_ref() + { + ItemAttributeIndex::KEYWORD => result.assign( ItemAttributeIndex::from_meta( attr )? ), + "debug" => {}, + _ => {}, + // _ => return Err( error( attr ) ), + } + } + + Ok( result ) + } +} + +impl AttributeComponent for ItemAttributeIndex +{ + const KEYWORD : &'static str = "index"; + + fn from_meta( attr : &syn::Attribute ) -> Result< Self > + { + match attr.meta + { + syn::Meta::List( ref meta_list ) => + { + return syn::parse2::< ItemAttributeIndex >( meta_list.tokens.clone() ); + }, + syn::Meta::Path( ref _path ) => + { + return Ok( Default::default() ) + }, + _ => return_syn_err!( attr, "Expects an attribute of format `#[ from( on ) ]`. \nGot: {}", qt!{ #attr } ), + } + } + +} + + +impl< IntoT > Assign< ItemAttributeIndex, IntoT > for ItemAttributes +where + IntoT : Into< ItemAttributeIndex >, +{ + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + self.index.assign( component.into() ); + } +} + + + +impl< IntoT > Assign< AttributePropertyDebug, IntoT > for ItemAttributes +where + IntoT : Into< AttributePropertyDebug >, +{ + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + self.debug = component.into(); + } +} + + +impl< IntoT > Assign< ItemAttributeIndex, IntoT > for ItemAttributeIndex +where + IntoT : Into< ItemAttributeIndex >, +{ + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + let component = component.into(); + self.name.assign( component.name ); + } +} + +impl< IntoT > Assign< AttributePropertyName, IntoT > for ItemAttributeIndex +where + IntoT : Into< AttributePropertyName >, +{ + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + self.name = component.into(); + } +} + + +impl syn::parse::Parse for ItemAttributeIndex +{ + fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self > + { + let mut result = Self::default(); + + let error = | ident : &syn::Ident | -> syn::Error + { + let known = ct::concatcp! + ( + "Known entries of attribute ", ItemAttributeIndex::KEYWORD, " are : ", + AttributePropertyName::KEYWORD, + ".", + ); + syn_err! + ( + ident, + r#"Expects an attribute of format '#[ from( off ) ]' + {known} + But got: '{}' +"#, + qt!{ #ident } + ) + }; + + while !input.is_empty() + { + let lookahead = input.lookahead1(); + if lookahead.peek( syn::Ident ) + { + let ident : syn::Ident = input.parse()?; + match ident.to_string().as_str() + { + AttributePropertyName::KEYWORD => result.assign( AttributePropertyName::parse( input )? ), + _ => return Err( error( &ident ) ), + } + } + else + { + return Err( lookahead.error() ); + } + + // Optional comma handling + if input.peek( syn::Token![ , ] ) + { + input.parse::< syn::Token![ , ] >()?; + } + } + + Ok( result ) + } +} + + +// == Attribute properties + +/// Marker type for attribute property of optional identifier that names the setter. It is parsed from inputs +/// like `name = field_name`. +#[ derive( Debug, Default, Clone, Copy ) ] +pub struct NameMarker; + +impl AttributePropertyComponent for NameMarker +{ + const KEYWORD : &'static str = "name"; +} + +/// An optional identifier that names the setter. It is parsed from inputs +/// like `name = field_name`. +pub type AttributePropertyName = AttributePropertyOptionalSyn< syn::Ident, NameMarker >; + +// = + +/// Marker type for attribute property to specify whether to provide a generated code as a hint. +/// Defaults to `false`, which means no debug is provided unless explicitly requested. +#[ derive( Debug, Default, Clone, Copy ) ] +pub struct AttributePropertyDebugMarker; + +impl AttributePropertyComponent for AttributePropertyDebugMarker +{ + const KEYWORD : &'static str = "debug"; +} + +/// Specifies whether to provide a generated code as a hint. +/// Defaults to `false`, which means no debug is provided unless explicitly requested. +pub type AttributePropertyDebug = AttributePropertyOptionalSingletone< AttributePropertyDebugMarker >; + +// == diff --git a/module/core/derive_tools_meta/src/derive/index_mut.rs b/module/core/derive_tools_meta/src/derive/index_mut.rs new file mode 100644 index 0000000000..fc72715eea --- /dev/null +++ b/module/core/derive_tools_meta/src/derive/index_mut.rs @@ -0,0 +1,362 @@ +use super::*; +use macro_tools:: +{ + attr, + diag, + generic_params, + struct_like::StructLike, + Result +}; + +#[ path = "index/item_attributes.rs" ] +mod item_attributes; +use item_attributes::*; +#[ path = "index/field_attributes.rs" ] +mod field_attributes; +use field_attributes::*; + + +pub fn index_mut( input : proc_macro::TokenStream ) -> Result< proc_macro2::TokenStream > +{ + let original_input = input.clone(); + let parsed = syn::parse::< StructLike >( input )?; + let has_debug = attr::has_debug( parsed.attrs().iter() )?; + let item_name = &parsed.ident(); + + let item_attrs = ItemAttributes::from_attrs( parsed.attrs().iter() )?; + + let ( _generics_with_defaults, generics_impl, generics_ty, generics_where ) + = generic_params::decompose( &parsed.generics() ); + + let result = match parsed + { + StructLike::Struct( ref item ) => + generate_struct + ( + item_name, + &item_attrs, + &generics_impl, + &generics_ty, + &generics_where, + &item.fields, + + ), + StructLike::Enum( _ ) => + unimplemented!( "IndexMut not implemented for Enum" ), + StructLike::Unit( _ ) => + unimplemented!( "IndexMut not implemented for Unit" ), + }?; + + if has_debug + { + let about = format!( "derive : Not\nstructure : {item_name}" ); + diag::report_print( about, &original_input, &result ); + } + + Ok( result ) +} + +/// An aggregator function to generate `IndexMut` implementation for tuple and named structs +fn generate_struct +( + item_name : &syn::Ident, + item_attrs : &ItemAttributes, + generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_where : &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, + fields : &syn::Fields, +) +-> Result< proc_macro2::TokenStream > +{ + + match fields + { + syn::Fields::Named( fields ) => + generate_struct_named_fields + ( + item_name, + &item_attrs, + generics_impl, + generics_ty, + generics_where, + fields + ), + + syn::Fields::Unnamed( fields ) => + generate_struct_tuple_fields + ( + item_name, + generics_impl, + generics_ty, + generics_where, + fields + ), + + syn::Fields::Unit => + unimplemented!( "IndexMut not implemented for Unit" ), + } +} + + +fn generate_struct_named_fields +( + item_name : &syn::Ident, + item_attrs : &ItemAttributes, + generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_where : &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, + fields : &syn::FieldsNamed, +) +-> Result< proc_macro2::TokenStream > +{ + + let fields = fields.named.clone(); + let attr_name = &item_attrs.index.name.clone().internal(); + + let field_attrs: Vec< &syn::Field > = fields + .iter() + .filter + ( + | field | + { + FieldAttributes::from_attrs( field.attrs.iter() ).map_or + ( + false, + | attrs | attrs.index.value( false ) + ) + } + ) + .collect(); + + let generate = | is_mut : bool | + -> Result< proc_macro2::TokenStream > + { + if let Some( attr_name ) = attr_name + { + Ok + ( + if is_mut + { + qt! + { + &mut self.#attr_name[ index ] + } + } + else + { + qt! + { + &self.#attr_name[ index ] + } + } + ) + } + else + { + match field_attrs.len() + { + 0 | 1 => + { + let field_name = + match field_attrs + .first() + .cloned() + .or_else + ( + || fields.first() + ) + { + Some( field ) => + field.ident.as_ref().unwrap(), + None => + unimplemented!( "IndexMut not implemented for Unit" ), + }; + + Ok + ( + if is_mut + { + qt! + { + &mut self.#field_name[ index ] + } + } + else + { + qt! + { + &self.#field_name[ index ] + } + } + ) + } + _ => + Err + ( + syn::Error::new_spanned + ( + &fields, + "Only one field can include #[ index ] derive macro", + ) + ), + } + } + }; + + + let generated_index = generate( false )?; + let generated_index_mut = generate( true )?; + + Ok + ( + qt! + { + #[ automatically_derived ] + impl< #generics_impl > ::core::ops::Index< usize > for #item_name< #generics_ty > + where + #generics_where + { + type Output = T; + #[ inline( always ) ] + fn index( &self, index : usize ) -> &Self::Output + { + #generated_index + } + } + + #[ automatically_derived ] + impl< #generics_impl > ::core::ops::IndexMut< usize > for #item_name< #generics_ty > + where + #generics_where + { + #[ inline( always ) ] + fn index_mut( &mut self, index : usize ) -> &mut Self::Output + { + #generated_index_mut + } + } + } + ) +} + +fn generate_struct_tuple_fields +( + item_name : &syn::Ident, + generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, + generics_where : &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, + fields : &syn::FieldsUnnamed, +) +-> Result< proc_macro2::TokenStream > +{ + let fields = fields.unnamed.clone(); + let non_empty_attrs : Vec< &syn::Field > = fields + .iter() + .filter( | field | !field.attrs.is_empty() ) + .collect(); + + + let generate = | is_mut : bool | + -> Result< proc_macro2::TokenStream > + { + match non_empty_attrs.len() + { + 0 => + { + Ok + ( + if is_mut + { + qt! + { + &mut self.0[ index ] + } + } + else + { + qt! + { + &self.0[ index ] + } + } + ) + }, + 1 => fields + .iter() + .enumerate() + .map + ( + | ( i, field ) | + { + let i = syn::Index::from( i ); + if !field.attrs.is_empty() + { + Ok + ( + if is_mut + { + qt!{&mut self.#i[ index ]} + } + else + { + qt!{&self.#i[ index ] } + } + ) + } + else + { + Ok + ( + qt!{ } + ) + } + } + ).collect(), + _ => + Err + ( + syn::Error::new_spanned + ( + &fields, + "Only one field can include #[ index ] derive macro" + ) + ), + } + }; + + + + let generated = generate( false )?; + let generated_mut = generate( true )?; + + Ok + ( + qt! + { + #[ automatically_derived ] + impl< #generics_impl > ::core::ops::Index< usize > for #item_name< #generics_ty > + where + #generics_where + { + type Output = T; + #[ inline( always ) ] + fn index( &self, index : usize ) -> &Self::Output + { + #generated + } + } + + #[ automatically_derived ] + impl< #generics_impl > ::core::ops::IndexMut< usize > for #item_name< #generics_ty > + where + #generics_where + { + #[ inline( always ) ] + fn index_mut( &mut self, index : usize ) -> &mut Self::Output + { + #generated_mut + } + } + } + ) +} diff --git a/module/core/derive_tools_meta/src/derive/inner_from.rs b/module/core/derive_tools_meta/src/derive/inner_from.rs index 427f447087..ef871671c1 100644 --- a/module/core/derive_tools_meta/src/derive/inner_from.rs +++ b/module/core/derive_tools_meta/src/derive/inner_from.rs @@ -228,6 +228,7 @@ fn from_impl_multiple_fields< 'a > /// /// ## Output /// ```rust +/// use std::convert::From; /// pub struct Struct; /// #[ allow( non_local_definitions ) ] /// #[ allow( clippy::unused_imports ) ] diff --git a/module/core/derive_tools_meta/src/derive/new.rs b/module/core/derive_tools_meta/src/derive/new.rs index 4bfb0761bb..2f0341c159 100644 --- a/module/core/derive_tools_meta/src/derive/new.rs +++ b/module/core/derive_tools_meta/src/derive/new.rs @@ -18,7 +18,7 @@ use item_attributes::*; // -// xxx : qqq : implement +// zzz : qqq : implement pub fn new( input : proc_macro::TokenStream ) -> Result< proc_macro2::TokenStream > { // use macro_tools::quote::ToTokens; @@ -126,7 +126,7 @@ pub fn new( input : proc_macro::TokenStream ) -> Result< proc_macro2::TokenStrea Ok( result ) } -// xxx : qqq : implement +// zzz : qqq : implement // qqq : document, add example of generated code fn generate_unit ( @@ -153,7 +153,7 @@ fn generate_unit } } -// xxx : qqq : implement +// zzz : qqq : implement // qqq : document, add example of generated code fn generate_single_field_named ( @@ -178,14 +178,14 @@ fn generate_single_field_named // fn new( src : i32 ) -> Self fn new( src : #field_type ) -> Self { - // Self { a: src } + // Self { a : src } Self { #field_name: src } } } } } -// xxx : qqq : implement +// zzz : qqq : implement // qqq : document, add example of generated code fn generate_single_field ( @@ -217,7 +217,7 @@ fn generate_single_field } } -// xxx : qqq : implement +// zzz : qqq : implement // qqq : document, add example of generated code fn generate_multiple_fields_named< 'a > ( @@ -225,22 +225,21 @@ fn generate_multiple_fields_named< 'a > generics_impl : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, generics_ty : &syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >, generics_where: &syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >, - field_names : Box< dyn macro_tools::IterTrait< 'a, &'a syn::Ident > + '_ >, + field_names : impl macro_tools::IterTrait< 'a, &'a syn::Ident >, field_types : impl macro_tools::IterTrait< 'a, &'a syn::Type >, ) -> proc_macro2::TokenStream { - let params : Vec< proc_macro2::TokenStream > = field_names + let val_type = field_names + .clone() + .zip( field_types ) .enumerate() - .map(| ( index, field_name ) | + .map(| ( _index, ( field_name, field_type ) ) | { - let index = index.to_string().parse::< proc_macro2::TokenStream >().unwrap(); - qt! { #field_name : src.#index } - }) - .collect(); + qt! { #field_name : #field_type } + }); - let field_types : Vec< _ > = field_types.collect(); qt! { // impl StructNamedFields @@ -250,17 +249,17 @@ fn generate_multiple_fields_named< 'a > { #[ inline( always ) ] // fn new( src : ( i32, bool ) ) -> Self - fn new( src : ( #( #field_types ),* ) ) -> Self + fn new( #( #val_type ),* ) -> Self { // StructNamedFields{ a : src.0, b : src.1 } - #item_name { #(#params),* } + #item_name { #( #field_names ),* } } } } } -// xxx : qqq : implement +// zzz : qqq : implement // qqq : document, add example of generated code fn generate_multiple_fields< 'a > ( @@ -273,15 +272,12 @@ fn generate_multiple_fields< 'a > -> proc_macro2::TokenStream { - let params : Vec< proc_macro2::TokenStream > = ( 0..field_types.len() ) + let params = ( 0..field_types.len() ) .map( | index | { let index = index.to_string().parse::< proc_macro2::TokenStream >().unwrap(); qt!( src.#index ) - }) - .collect(); - - let field_types : Vec< _ > = field_types.collect(); + }); qt! { @@ -301,7 +297,7 @@ fn generate_multiple_fields< 'a > } } -// xxx : qqq : implement +// zzz : qqq : implement // qqq : document, add example of generated code fn variant_generate ( diff --git a/module/core/derive_tools_meta/src/derive/not.rs b/module/core/derive_tools_meta/src/derive/not.rs new file mode 100644 index 0000000000..83a9055bc6 --- /dev/null +++ b/module/core/derive_tools_meta/src/derive/not.rs @@ -0,0 +1,200 @@ +use super::*; +use macro_tools:: +{ + attr, + diag, + generic_params, + item_struct, + Result, + syn::ItemStruct, +}; + +mod field_attributes; +use field_attributes::*; +mod item_attributes; +use item_attributes::*; +use iter_tools::IterTrait; + +/// Generates [Not](core::ops::Not) trait implementation for input struct. +pub fn not( input : proc_macro::TokenStream ) -> Result< proc_macro2::TokenStream > +{ + let original_input = input.clone(); + let parsed = syn::parse::< ItemStruct >( input )?; + let has_debug = attr::has_debug( parsed.attrs.iter() )?; + let item_attrs = ItemAttributes::from_attrs( parsed.attrs.iter() )?; + let item_name = &parsed.ident; + + let ( _generics_with_defaults, generics_impl, generics_ty, generics_where ) + = generic_params::decompose( &parsed.generics ); + + let field_attrs = parsed.fields.iter().map( | field | &field.attrs ); + let field_types = item_struct::field_types( &parsed ); + let field_names = item_struct::field_names( &parsed ); + + let body = match ( field_types.len(), field_names ) + { + ( 0, _ ) => generate_for_unit(), + ( _, Some( field_names ) ) => generate_for_named( field_attrs, field_types, field_names, &item_attrs )?, + ( _, None ) => generate_for_tuple( field_attrs, field_types, &item_attrs )?, + }; + + let result = qt! + { + impl< #generics_impl > ::core::ops::Not for #item_name< #generics_ty > + where + #generics_where + { + type Output = Self; + + fn not( self ) -> Self::Output + { + #body + } + } + }; + + if has_debug + { + let about = format!( "derive : Not\nstructure : {item_name}" ); + diag::report_print( about, &original_input, &result ); + } + + Ok( result ) +} + +fn generate_for_unit() -> proc_macro2::TokenStream +{ + qt! { Self {} } +} + +fn generate_for_named< 'a > +( + field_attributes: impl IterTrait< 'a, &'a Vec< syn::Attribute > >, + field_types : impl macro_tools::IterTrait< 'a, &'a syn::Type >, + field_names : impl macro_tools::IterTrait< 'a, &'a syn::Ident >, + item_attrs : &ItemAttributes, +) +-> Result< proc_macro2::TokenStream > +{ + let fields_enabled = field_attributes + .map( | attrs| FieldAttributes::from_attrs( attrs.iter() ) ) + .collect::< Result< Vec< _ > > >()? + .into_iter() + .map( | fa | fa.config.enabled.value( item_attrs.config.enabled.value( item_attrs.config.enabled.value( true ) ) ) ); + + let ( mut_ref_transformations, values ): ( Vec< proc_macro2::TokenStream >, Vec< proc_macro2::TokenStream > ) = + field_types + .clone() + .zip( field_names ) + .zip( fields_enabled ) + .map( | ( ( field_type, field_name ), is_enabled ) | + { + match field_type + { + syn::Type::Reference( reference ) => + { + ( + // If the field is a mutable reference, then change it value by reference + if reference.mutability.is_some() + { + qt! { *self.#field_name = !*self.#field_name; } + } + else + { + qt! {} + }, + qt! { #field_name: self.#field_name } + ) + } + _ => + { + ( + qt!{}, + if is_enabled + { + qt! { #field_name: !self.#field_name } + } + else + { + qt! { #field_name: self.#field_name } + } + ) + } + } + }) + .unzip(); + + Ok( + qt! + { + #(#mut_ref_transformations)* + Self { #(#values),* } + } + ) +} + +fn generate_for_tuple< 'a > +( + field_attributes: impl IterTrait< 'a, &'a Vec >, + field_types : impl macro_tools::IterTrait< 'a, &'a syn::Type >, + item_attrs : &ItemAttributes, +) +-> Result +{ + let fields_enabled = field_attributes + .map( | attrs| FieldAttributes::from_attrs( attrs.iter() ) ) + .collect::< Result< Vec< _ > > >()? + .into_iter() + .map( | fa | fa.config.enabled.value( item_attrs.config.enabled.value( item_attrs.config.enabled.value( true ) ) ) ); + + let ( mut_ref_transformations, values ): (Vec< proc_macro2::TokenStream >, Vec< proc_macro2::TokenStream > ) = + field_types + .clone() + .enumerate() + .zip( fields_enabled ) + .map( | ( ( index, field_type ), is_enabled ) | + { + let index = syn::Index::from( index ); + match field_type + { + syn::Type::Reference( reference ) => + { + ( + // If the field is a mutable reference, then change it value by reference + if reference.mutability.is_some() + { + qt! { *self.#index = !*self.#index; } + } + else + { + qt! {} + }, + qt! { self.#index } + ) + } + _ => + { + ( + qt!{}, + if is_enabled + { + qt! { !self.#index } + } + else + { + qt! { self.#index } + } + ) + } + } + }) + .unzip(); + + Ok( + qt! + { + #(#mut_ref_transformations)* + Self ( #(#values),* ) + } + ) +} diff --git a/module/core/derive_tools_meta/src/derive/not/field_attributes.rs b/module/core/derive_tools_meta/src/derive/not/field_attributes.rs new file mode 100644 index 0000000000..76381550a2 --- /dev/null +++ b/module/core/derive_tools_meta/src/derive/not/field_attributes.rs @@ -0,0 +1,203 @@ +use super::*; +use macro_tools:: +{ + ct, + Result, + AttributeComponent, + AttributePropertyOptionalSingletone, +}; + +use former_types::Assign; + +/// +/// Attributes of a field. +/// + +/// Represents the attributes of a struct. Aggregates all its attributes. +#[ derive( Debug, Default ) ] +pub struct FieldAttributes +{ + /// Attribute for customizing generated code. + pub config : FieldAttributeConfig, +} + +impl FieldAttributes +{ + pub fn from_attrs< 'a >( attrs : impl Iterator< Item = &'a syn::Attribute > ) -> Result< Self > + { + let mut result = Self::default(); + + let error = | attr : &syn::Attribute | -> syn::Error + { + let known_attributes = ct::concatcp! + ( + "Known attributes are : ", + FieldAttributeConfig::KEYWORD, + ".", + ); + syn_err! + ( + attr, + "Expects an attribute of format '#[ attribute( key1 = val1, key2 = val2 ) ]'\n {known_attributes}\n But got: '{}'", + qt!{ #attr } + ) + }; + + for attr in attrs + { + + let key_ident = attr.path().get_ident().ok_or_else( || error( attr ) )?; + let key_str = format!( "{}", key_ident ); + + match key_str.as_ref() + { + FieldAttributeConfig::KEYWORD => result.assign( FieldAttributeConfig::from_meta( attr )? ), + _ => {}, + } + } + + Ok( result ) + } +} + +/// +/// Attribute to hold parameters of handling for a specific field. +/// For example to avoid [Not](core::ops::Not) handling for it use `#[ not( off ) ]` +/// +#[ derive( Debug, Default ) ] +pub struct FieldAttributeConfig +{ + /// Specifies whether we should handle the field. + /// Can be altered using `on` and `off` attributes + pub enabled : AttributePropertyEnabled, +} + +impl AttributeComponent for FieldAttributeConfig +{ + const KEYWORD : &'static str = "not"; + + fn from_meta( attr : &syn::Attribute ) -> Result< Self > + { + match attr.meta + { + syn::Meta::List( ref meta_list ) => + { + return syn::parse2::< FieldAttributeConfig >( meta_list.tokens.clone() ); + }, + syn::Meta::Path( ref _path ) => + { + return Ok( Default::default() ) + }, + _ => return_syn_err!( attr, "Expects an attribute of format `#[ not( off ) ]`. \nGot: {}", qt!{ #attr } ), + } + } +} + +impl< IntoT > Assign< FieldAttributeConfig, IntoT > for FieldAttributes +where + IntoT : Into< FieldAttributeConfig >, +{ + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + self.config.assign( component.into() ); + } +} + +impl< IntoT > Assign< FieldAttributeConfig, IntoT > for FieldAttributeConfig +where + IntoT : Into< FieldAttributeConfig >, +{ + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + let component = component.into(); + self.enabled.assign( component.enabled ); + } +} + +impl< IntoT > Assign< AttributePropertyEnabled, IntoT > for FieldAttributeConfig +where + IntoT : Into< AttributePropertyEnabled >, +{ + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + self.enabled = component.into(); + } +} + +impl syn::parse::Parse for FieldAttributeConfig +{ + fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self > + { + let mut result = Self::default(); + + let error = | ident : &syn::Ident | -> syn::Error + { + let known = ct::concatcp! + ( + "Known entries of attribute ", FieldAttributeConfig::KEYWORD, " are : ", + EnabledMarker::KEYWORD_ON, + ", ", EnabledMarker::KEYWORD_OFF, + ".", + ); + syn_err! + ( + ident, + r#"Expects an attribute of format '#[ not( off ) ]' + {known} + But got: '{}' +"#, + qt!{ #ident } + ) + }; + + while !input.is_empty() + { + let lookahead = input.lookahead1(); + if lookahead.peek( syn::Ident ) + { + let ident : syn::Ident = input.parse()?; + match ident.to_string().as_str() + { + EnabledMarker::KEYWORD_ON => result.assign( AttributePropertyEnabled::from( true ) ), + EnabledMarker::KEYWORD_OFF => result.assign( AttributePropertyEnabled::from( false ) ), + _ => return Err( error( &ident ) ), + } + } + else + { + return Err( lookahead.error() ); + } + + // Optional comma handling + if input.peek( syn::Token![ , ] ) + { + input.parse::< syn::Token![ , ] >()?; + } + } + + Ok( result ) + } +} + +// == attribute properties + +/// Marker type for attribute property to indicates whether [Not](core::ops::Not) implementation should handle the field. +#[ derive( Debug, Default, Clone, Copy ) ] +pub struct EnabledMarker; + +impl EnabledMarker +{ + /// Keywords for parsing this attribute property. + pub const KEYWORD_OFF : &'static str = "off"; + /// Keywords for parsing this attribute property. + pub const KEYWORD_ON : &'static str = "on"; +} + +/// Specifies whether [Not](core::ops::Not) whether to handle the field or not. +/// Can be altered using `on` and `off` attributes. But default it's `on`. +pub type AttributePropertyEnabled = AttributePropertyOptionalSingletone< EnabledMarker >; + +// = diff --git a/module/core/derive_tools_meta/src/derive/not/item_attributes.rs b/module/core/derive_tools_meta/src/derive/not/item_attributes.rs new file mode 100644 index 0000000000..92ef350ff5 --- /dev/null +++ b/module/core/derive_tools_meta/src/derive/not/item_attributes.rs @@ -0,0 +1,187 @@ +use super::*; +use macro_tools:: +{ + ct, + Result, + AttributeComponent, +}; + +use former_types::Assign; + +/// +/// Attributes of the whole item. +/// + +/// Represents the attributes of a struct. Aggregates all its attributes. +#[ derive( Debug, Default ) ] +pub struct ItemAttributes +{ + /// Attribute for customizing generated code. + pub config : ItemAttributeConfig, +} + +impl ItemAttributes +{ + pub fn from_attrs< 'a >( attrs : impl Iterator< Item = &'a syn::Attribute > ) -> Result< Self > + { + let mut result = Self::default(); + + let error = | attr : &syn::Attribute | -> syn::Error + { + let known_attributes = ct::concatcp! + ( + "Known attributes are : ", + ItemAttributeConfig::KEYWORD, + ".", + ); + syn_err! + ( + attr, + "Expects an attribute of format '#[ attribute( key1 = val1, key2 = val2 ) ]'\n {known_attributes}\n But got: '{}'", + qt!{ #attr } + ) + }; + + for attr in attrs + { + + let key_ident = attr.path().get_ident().ok_or_else( || error( attr ) )?; + let key_str = format!( "{}", key_ident ); + + match key_str.as_ref() + { + ItemAttributeConfig::KEYWORD => result.assign( ItemAttributeConfig::from_meta( attr )? ), + _ => {}, + } + } + + Ok( result ) + } +} + +/// +/// Attribute to hold parameters of forming for a specific field. +/// For example to avoid [Not](core::ops::Not) handling for it use `#[ not( off ) ]` +/// +#[ derive( Debug, Default ) ] +pub struct ItemAttributeConfig +{ + /// Specifies whether [Not](core::ops::Not) fields should be handled by default. + /// Can be altered using `on` and `off` attributes. But default it's `on`. + /// `#[ not( on ) ]` - [Not](core::ops::Not) is generated unless `off` for the field is explicitly specified. + /// `#[ not( off ) ]` - [Not](core::ops::Not) is not generated unless `on` for the field is explicitly specified. + pub enabled : AttributePropertyEnabled, +} + +impl AttributeComponent for ItemAttributeConfig +{ + const KEYWORD : &'static str = "not"; + + fn from_meta( attr : &syn::Attribute ) -> Result< Self > + { + match attr.meta + { + syn::Meta::List( ref meta_list ) => + { + return syn::parse2::< ItemAttributeConfig >( meta_list.tokens.clone() ); + }, + syn::Meta::Path( ref _path ) => + { + return Ok( Default::default() ) + }, + _ => return_syn_err!( attr, "Expects an attribute of format `#[ not( off ) ]`. \nGot: {}", qt!{ #attr } ), + } + } + +} + +impl< IntoT > Assign< ItemAttributeConfig, IntoT > for ItemAttributes +where + IntoT : Into< ItemAttributeConfig >, +{ + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + self.config.assign( component.into() ); + } +} + +impl< IntoT > Assign< ItemAttributeConfig, IntoT > for ItemAttributeConfig +where + IntoT : Into< ItemAttributeConfig >, +{ + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + let component = component.into(); + self.enabled.assign( component.enabled ); + } +} + +impl< IntoT > Assign< AttributePropertyEnabled, IntoT > for ItemAttributeConfig +where + IntoT : Into< AttributePropertyEnabled >, +{ + #[ inline( always ) ] + fn assign( &mut self, component : IntoT ) + { + self.enabled = component.into(); + } +} + +impl syn::parse::Parse for ItemAttributeConfig +{ + fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self > + { + let mut result = Self::default(); + + let error = | ident : &syn::Ident | -> syn::Error + { + let known = ct::concatcp! + ( + "Known entries of attribute ", ItemAttributeConfig::KEYWORD, " are : ", + EnabledMarker::KEYWORD_ON, + ", ", EnabledMarker::KEYWORD_OFF, + ".", + ); + syn_err! + ( + ident, + r#"Expects an attribute of format '#[ not( off ) ]' + {known} + But got: '{}' +"#, + qt!{ #ident } + ) + }; + + while !input.is_empty() + { + let lookahead = input.lookahead1(); + if lookahead.peek( syn::Ident ) + { + let ident : syn::Ident = input.parse()?; + match ident.to_string().as_str() + { + EnabledMarker::KEYWORD_ON => result.assign( AttributePropertyEnabled::from( true ) ), + EnabledMarker::KEYWORD_OFF => result.assign( AttributePropertyEnabled::from( false ) ), + _ => return Err( error( &ident ) ), + } + } + else + { + return Err( lookahead.error() ); + } + + // Optional comma handling + if input.peek( syn::Token![ , ] ) + { + input.parse::< syn::Token![ , ] >()?; + } + } + + Ok( result ) + } +} + +// == diff --git a/module/core/derive_tools_meta/src/derive/phantom.rs b/module/core/derive_tools_meta/src/derive/phantom.rs new file mode 100644 index 0000000000..23f2671125 --- /dev/null +++ b/module/core/derive_tools_meta/src/derive/phantom.rs @@ -0,0 +1,122 @@ +use super::*; +use former_types::Assign; +use macro_tools:: +{ + ct, + diag, + Result, + phantom::add_to_item, + quote::ToTokens, + syn::ItemStruct, + AttributePropertyComponent, + AttributePropertyOptionalSingletone +}; + +pub fn phantom( _attr : proc_macro::TokenStream, input : proc_macro::TokenStream ) -> Result< proc_macro2::TokenStream > +{ + let attrs = syn::parse::< ItemAttributes >( _attr )?; + let original_input = input.clone(); + let item_parsed = syn::parse::< ItemStruct >( input )?; + + let has_debug = attrs.debug.value( false ); + let item_name = &item_parsed.ident; + let result = add_to_item( &item_parsed ).to_token_stream(); + + if has_debug + { + let about = format!( "derive : PhantomData\nstructure : {item_name}" ); + diag::report_print( about, &original_input, &result ); + } + + Ok( result ) +} + +// == attributes + +/// Represents the attributes of a struct. Aggregates all its attributes. +#[ derive( Debug, Default ) ] +pub struct ItemAttributes +{ + /// Attribute for customizing generated code. + pub debug : AttributePropertyDebug, +} + +impl syn::parse::Parse for ItemAttributes +{ + fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self > + { + let mut result = Self::default(); + + let error = | ident : &syn::Ident | -> syn::Error + { + let known = ct::concatcp! + ( + "Known properties of attribute `phantom` are : ", + AttributePropertyDebug::KEYWORD, + ".", + ); + syn_err! + ( + ident, + r#"Expects an attribute of format '#[ phantom( {} ) ]' + {known} + But got: '{}' +"#, + AttributePropertyDebug::KEYWORD, + qt!{ #ident } + ) + }; + + while !input.is_empty() + { + let lookahead = input.lookahead1(); + if lookahead.peek( syn::Ident ) + { + let ident : syn::Ident = input.parse()?; + match ident.to_string().as_str() + { + AttributePropertyDebug::KEYWORD => result.assign( AttributePropertyDebug::from( true ) ), + _ => return Err( error( &ident ) ), + } + } + else + { + return Err( lookahead.error() ); + } + + // Optional comma handling + if input.peek( syn::Token![ , ] ) + { + input.parse::< syn::Token![ , ] >()?; + } + } + + Ok( result ) + } +} + +impl< IntoT > Assign< AttributePropertyDebug, IntoT > for ItemAttributes + where + IntoT : Into< AttributePropertyDebug >, +{ + #[ inline( always ) ] + fn assign( &mut self, prop : IntoT ) + { + self.debug = prop.into(); + } +} + +// == attribute properties + +/// Marker type for attribute property to specify whether to provide a generated code as a hint. +#[ derive( Debug, Default, Clone, Copy ) ] +pub struct AttributePropertyDebugMarker; + +impl AttributePropertyComponent for AttributePropertyDebugMarker +{ + const KEYWORD : &'static str = "debug"; +} + +/// Specifies whether to provide a generated code as a hint. +/// Defaults to `false`, which means no debug is provided unless explicitly requested. +pub type AttributePropertyDebug = AttributePropertyOptionalSingletone< AttributePropertyDebugMarker >; diff --git a/module/core/derive_tools_meta/src/lib.rs b/module/core/derive_tools_meta/src/lib.rs index b2ea174a1f..2b323bbdc0 100644 --- a/module/core/derive_tools_meta/src/lib.rs +++ b/module/core/derive_tools_meta/src/lib.rs @@ -13,8 +13,13 @@ feature = "derive_deref", feature = "derive_deref_mut", feature = "derive_from", + feature = "derive_index", + feature = "derive_index_mut", feature = "derive_inner_from", + feature = "derive_new", feature = "derive_variadic_from", + feature = "derive_not", + feature = "derive_phantom" ) )] #[ cfg( feature = "enabled" ) ] @@ -28,8 +33,13 @@ mod derive; // feature = "derive_deref", // feature = "derive_deref_mut", // feature = "derive_from", +// feature = "derive_index", +// feature = "derive_index_mut", // feature = "derive_inner_from", +// feature = "derive_new", // feature = "derive_variadic_from", +// feature = "derive_not", +// feature = "derive_phantom" // ) // )] // #[ cfg( feature = "enabled" ) ] @@ -77,7 +87,7 @@ mod derive; From, attributes ( - debug, // struct + debug, // item from, // field ) )] @@ -132,7 +142,7 @@ pub fn from( input : proc_macro::TokenStream ) -> proc_macro::TokenStream New, attributes ( - debug, // struct + debug, // item new, // field ) )] @@ -282,16 +292,26 @@ pub fn deref( input : proc_macro::TokenStream ) -> proc_macro::TokenStream /// Write this /// /// ```rust -/// # use derive_tools_meta::*; -/// #[ derive( Deref, DerefMut ) ] +/// # use derive_tools_meta::DerefMut; +/// #[ derive( DerefMut ) ] /// pub struct IsTransparent( bool ); +/// +/// impl ::core::ops::Deref for IsTransparent +/// { +/// type Target = bool; +/// #[ inline( always ) ] +/// fn deref( &self ) -> &Self::Target +/// { +/// &self.0 +/// } +/// } /// ``` /// /// Instead of this /// /// ```rust /// pub struct IsTransparent( bool ); -/// impl core::ops::Deref for IsTransparent +/// impl ::core::ops::Deref for IsTransparent /// { /// type Target = bool; /// #[ inline( always ) ] @@ -300,7 +320,7 @@ pub fn deref( input : proc_macro::TokenStream ) -> proc_macro::TokenStream /// &self.0 /// } /// } -/// impl core::ops::DerefMut for IsTransparent +/// impl ::core::ops::DerefMut for IsTransparent /// { /// #[ inline( always ) ] /// fn deref_mut( &mut self ) -> &mut Self::Target @@ -473,8 +493,8 @@ pub fn as_mut( input : proc_macro::TokenStream ) -> proc_macro::TokenStream /// /// dbg!( exp ); /// //> MyStruct { -/// //> a: 13, -/// //> b: 14, +/// //> a : 13, +/// //> b : 14, /// //> } /// } /// ``` @@ -487,10 +507,10 @@ pub fn as_mut( input : proc_macro::TokenStream ) -> proc_macro::TokenStream /// #[ derive( Debug, PartialEq, Default, VariadicFrom ) ] /// // Use `#[ debug ]` to expand and debug generate code. /// // #[ debug ] -/// struct MyStruct +/// item MyStruct /// { -/// a: i32, -/// b: i32, +/// a : i32, +/// b : i32, /// } /// ``` /// @@ -507,3 +527,243 @@ pub fn derive_variadic_from( input : proc_macro::TokenStream ) -> proc_macro::To Err( err ) => err.to_compile_error().into(), } } + +/// Provides an automatic [Not](core::ops::Not) trait implementation for struct. +/// +/// This macro simplifies the creation of a logical negation or complement operation +/// for structs that encapsulate values which support the `!` operator. +/// +/// ## Example Usage +/// +/// Instead of manually implementing [Not](core::ops::Not) for [IsActive]: +/// +/// ```rust +/// use core::ops::Not; +/// +/// pub struct IsActive( bool ); +/// +/// impl Not for IsActive +/// { +/// type Output = IsActive; +/// +/// fn not(self) -> Self::Output +/// { +/// IsActive(!self.0) +/// } +/// } +/// ``` +/// +/// Use `#[ derive( Not ) ]` to automatically generate the implementation: +/// +/// ```rust +/// # use derive_tools_meta::*; +/// #[ derive( Not ) ] +/// pub struct IsActive( bool ); +/// ``` +/// +/// The macro automatically implements the [not](core::ops::Not::not) method, reducing boilerplate code and potential errors. +/// +#[ cfg( feature = "enabled" ) ] +#[ cfg( feature = "derive_not" ) ] +#[ proc_macro_derive +( + Not, + attributes + ( + debug, // item + not, // field + ) +)] +pub fn derive_not( input : proc_macro::TokenStream ) -> proc_macro::TokenStream +{ + let result = derive::not::not( input ); + match result + { + Ok( stream ) => stream.into(), + Err( err ) => err.to_compile_error().into(), + } +} + +/// +/// Provides an automatic `PhantomData` field for a struct based on its generic types. +/// +/// This macro simplifies the addition of a `PhantomData` field to a struct +/// to indicate that the struct logically owns instances of the generic types, +/// even though it does not store them. +/// +/// ## Example Usage +/// +/// Instead of manually adding `PhantomData` to `MyStruct`: +/// +/// ```rust +/// use std::marker::PhantomData; +/// +/// pub struct MyStruct +/// { +/// data: i32, +/// _phantom: PhantomData, +/// } +/// ``` +/// +/// Use `#[ phantom ]` to automatically generate the `PhantomData` field: +/// +/// ```rust +/// use derive_tools_meta::*; +/// +/// #[ phantom ] +/// pub struct MyStruct< T > +/// { +/// data: i32, +/// } +/// ``` +/// +/// The macro facilitates the addition of the `PhantomData` field without additional boilerplate code. +/// + +#[ cfg( feature = "enabled" ) ] +#[ cfg ( feature = "derive_phantom" ) ] +#[ proc_macro_attribute ] +pub fn phantom( _attr: proc_macro::TokenStream, input : proc_macro::TokenStream ) -> proc_macro::TokenStream +{ + let result = derive::phantom::phantom( _attr, input ); + match result + { + Ok( stream ) => stream.into(), + Err( err ) => err.to_compile_error().into(), + } +} + +/// +/// Provides an automatic [Index](core::ops::Index) trait implementation when-ever it's possible. +/// +/// This macro simplifies the indexing syntax of struct type. +/// +/// ## Example Usage +// +/// Instead of manually implementing `Index< T >` for `IsTransparent`: +/// +/// ```rust +/// use core::ops::Index; +/// +/// pub struct IsTransparent< T > +/// { +/// a : Vec< T >, +/// } +/// +/// impl< T > Index< usize > for IsTransparent< T > +/// { +/// type Output = T; +/// +/// #[ inline( always ) ] +/// fn index( &self, index : usize ) -> &Self::Output +/// { +/// &self.a[ index ] +/// } +/// } +/// ``` +/// +/// Use `#[ index ]` to automatically generate the implementation: +/// +/// ```rust +/// use derive_tools_meta::*; +/// +/// #[ derive( Index ) ] +/// pub struct IsTransparent< T > +/// { +/// #[ index ] +/// a : Vec< T > +/// }; +/// ``` +/// + +#[ cfg( feature = "enabled" ) ] +#[ cfg( feature = "derive_index" ) ] +#[ proc_macro_derive +( + Index, + attributes + ( + debug, // item + index, // field + ) +)] +pub fn derive_index( input : proc_macro::TokenStream ) -> proc_macro::TokenStream +{ + let result = derive::index::index( input ); + match result + { + Ok( stream ) => stream.into(), + Err( err ) => err.to_compile_error().into(), + } +} + +/// +/// Provides an automatic [IndexMut](core::ops::IndexMut) trait implementation when-ever it's possible. +/// +/// This macro simplifies the indexing syntax of struct type. +/// +/// ## Example Usage +// +/// Instead of manually implementing `IndexMut< T >` for `IsTransparent`: +/// +/// ```rust +/// use core::ops::{ Index, IndexMut }; +/// pub struct IsTransparent< T > +/// { +/// a : Vec< T >, +/// } +/// +/// impl< T > Index< usize > for IsTransparent< T > +/// { +/// type Output = T; +/// +/// #[ inline( always ) ] +/// fn index( &self, index : usize ) -> &Self::Output +/// { +/// &self.a[ index ] +/// } +/// } +/// +/// impl< T > IndexMut< usize > for IsTransparent< T > +/// { +/// fn index_mut( &mut self, index : usize ) -> &mut Self::Output +/// { +/// &mut self.a[ index ] +/// } +/// } +/// ``` +/// +/// Use `#[ index ]` on field or `#[ index( name = field_name )]` on named items to automatically generate the implementation: +/// +/// ```rust +/// use derive_tools_meta::*; +/// #[derive( IndexMut )] +/// pub struct IsTransparent< T > +/// { +/// #[ index ] +/// a : Vec< T > +/// }; +/// ``` +/// + +#[ cfg( feature = "enabled" ) ] +#[ cfg( feature = "derive_index_mut" ) ] +#[ proc_macro_derive +( + IndexMut, + attributes + ( + debug, // item + index, // field + ) +)] +pub fn derive_index_mut( input : proc_macro::TokenStream ) -> proc_macro::TokenStream +{ + let result = derive::index_mut::index_mut( input ); + match result + { + Ok( stream ) => stream.into(), + Err( err ) => err.to_compile_error().into(), + } +} + diff --git a/module/core/diagnostics_tools/Cargo.toml b/module/core/diagnostics_tools/Cargo.toml index 5053a7402c..c2b7d7e994 100644 --- a/module/core/diagnostics_tools/Cargo.toml +++ b/module/core/diagnostics_tools/Cargo.toml @@ -24,7 +24,7 @@ workspace = true features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] + [features] default = [ diff --git a/module/core/diagnostics_tools/src/diag/cta.rs b/module/core/diagnostics_tools/src/diag/cta.rs index 60fc685938..05f44abc81 100644 --- a/module/core/diagnostics_tools/src/diag/cta.rs +++ b/module/core/diagnostics_tools/src/diag/cta.rs @@ -46,38 +46,42 @@ pub( crate ) mod private #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { cta_true, }; diff --git a/module/core/diagnostics_tools/src/diag/layout.rs b/module/core/diagnostics_tools/src/diag/layout.rs index 174ed9bc0e..e09acb646b 100644 --- a/module/core/diagnostics_tools/src/diag/layout.rs +++ b/module/core/diagnostics_tools/src/diag/layout.rs @@ -84,41 +84,45 @@ pub( crate ) mod private pub use cta_mem_same_size; } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ cfg( feature = "diagnostics_compiletime_assertions" ) ] #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { cta_type_same_size, cta_type_same_align, diff --git a/module/core/diagnostics_tools/src/diag/mod.rs b/module/core/diagnostics_tools/src/diag/mod.rs index 821b020beb..ab548ef796 100644 --- a/module/core/diagnostics_tools/src/diag/mod.rs +++ b/module/core/diagnostics_tools/src/diag/mod.rs @@ -15,14 +15,15 @@ pub mod layout; #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; #[ cfg( feature = "diagnostics_runtime_assertions" ) ] #[ doc( inline ) ] #[ allow( unused_imports ) ] @@ -38,19 +39,21 @@ pub mod protected } /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ cfg( feature = "diagnostics_runtime_assertions" ) ] #[ doc( inline ) ] #[ allow( unused_imports ) ] @@ -66,8 +69,10 @@ pub mod exposed } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ cfg( feature = "diagnostics_runtime_assertions" ) ] #[ doc( inline ) ] #[ allow( unused_imports ) ] diff --git a/module/core/diagnostics_tools/src/diag/rta.rs b/module/core/diagnostics_tools/src/diag/rta.rs index 38b9b5a0f3..70af251d51 100644 --- a/module/core/diagnostics_tools/src/diag/rta.rs +++ b/module/core/diagnostics_tools/src/diag/rta.rs @@ -221,43 +221,47 @@ pub( crate ) mod private #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; + #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private::a_id as assert_eq; + pub use private::a_id as assert_eq; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private::a_not_id as assert_ne; + pub use private::a_not_id as assert_ne; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; // #[ doc( inline ) ] // #[ allow( unused_imports ) ] @@ -268,14 +272,13 @@ pub mod prelude #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::private::a_id; + pub use private::a_id; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::private::a_not_id; + pub use private::a_not_id; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { a_true, a_false, diff --git a/module/core/diagnostics_tools/src/lib.rs b/module/core/diagnostics_tools/src/lib.rs index cce36f97b7..a3415c710e 100644 --- a/module/core/diagnostics_tools/src/lib.rs +++ b/module/core/diagnostics_tools/src/lib.rs @@ -20,15 +20,16 @@ pub mod dependency #[ doc( inline ) ] #[ allow( unused_imports ) ] #[ cfg( feature = "enabled" ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. +/// Own namespace of the module. #[ cfg( feature = "enabled" ) ] -pub mod protected +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::diag::orphan::*; @@ -36,20 +37,22 @@ pub mod protected /// Orphan namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::diag::exposed::*; @@ -57,8 +60,10 @@ pub mod exposed /// Prelude to use essentials: `use my_module::prelude::*`. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::diag::prelude::*; diff --git a/module/core/diagnostics_tools/tests/smoke_test.rs b/module/core/diagnostics_tools/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/core/diagnostics_tools/tests/smoke_test.rs +++ b/module/core/diagnostics_tools/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/core/error_tools/Cargo.toml b/module/core/error_tools/Cargo.toml index 1ef5cccee8..f2f4537001 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.14.0" +version = "0.15.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", @@ -25,27 +25,25 @@ workspace = true features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] + # = features [features] default = [ "enabled", - "error_for_lib", - "error_for_app", + "error_typed", + "error_untyped", ] full = [ - "enabled", - "error_for_lib", - "error_for_app", + "default", ] no_std = [] use_alloc = [ "no_std" ] enabled = [] -error_for_lib = [ "thiserror" ] -error_for_app = [ "anyhow" ] +error_typed = [ "thiserror" ] +error_untyped = [ "anyhow" ] # = entry diff --git a/module/core/error_tools/Readme.md b/module/core/error_tools/Readme.md index cf2613a5ba..727ed9d8b7 100644 --- a/module/core/error_tools/Readme.md +++ b/module/core/error_tools/Readme.md @@ -25,7 +25,7 @@ fn main() } #[ cfg( feature = "enabled" ) ] -fn f1() -> error_tools::Result< () > +fn f1() -> error_tools::untyped::Result< () > { let _read = std::fs::read_to_string( "Cargo.toml" )?; Err( error_tools::BasicError::new( "Some error" ).into() ) diff --git a/module/core/error_tools/examples/error_tools_trivial.rs b/module/core/error_tools/examples/error_tools_trivial.rs index f20df26c12..cc6fc29f24 100644 --- a/module/core/error_tools/examples/error_tools_trivial.rs +++ b/module/core/error_tools/examples/error_tools_trivial.rs @@ -14,7 +14,7 @@ fn main() } #[ cfg( not( feature = "no_std" ) ) ] -fn f1() -> error_tools::Result< () > +fn f1() -> error_tools::untyped::Result< () > { let _read = std::fs::read_to_string( "Cargo.toml" )?; Err( error_tools::BasicError::new( "Some error" ).into() ) diff --git a/module/core/error_tools/src/assert.rs b/module/core/error_tools/src/assert.rs index 0fe7bcf1f6..dd604822b6 100644 --- a/module/core/error_tools/src/assert.rs +++ b/module/core/error_tools/src/assert.rs @@ -114,39 +114,44 @@ pub( crate ) mod private pub use debug_assert_not_identical; } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Shared with parent namespace of the module +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { - pub use super::private::debug_assert_id; - pub use super::private::debug_assert_identical; - pub use super::private::debug_assert_ni; - pub use super::private::debug_assert_not_identical; + use super::*; + pub use private::debug_assert_id; + pub use private::debug_assert_identical; + pub use private::debug_assert_ni; + pub use private::debug_assert_not_identical; } diff --git a/module/core/error_tools/src/error.rs b/module/core/error_tools/src/error.rs index 0b8fa734ba..142d9c2ce9 100644 --- a/module/core/error_tools/src/error.rs +++ b/module/core/error_tools/src/error.rs @@ -1,7 +1,100 @@ /// Internal namespace. pub( crate ) mod private { - pub use std::error::Error as ErrorInterface; + pub use std::error::Error as ErrorTrait; + + /// This trait allows adding extra context or information to an error, creating a tuple of the additional + /// context and the original error. This is particularly useful for error handling when you want to include + /// more details in the error without losing the original error value. + /// + /// The `ErrWith` trait provides methods to wrap an error with additional context, either by using a closure + /// that generates the context or by directly providing the context. + /// + /// ``` + pub trait ErrWith< ReportErr, ReportOk, E > + { + /// Takes a closure `f` that returns a value of type `ReportErr`, and uses it to wrap an error of type `(ReportErr, E)` + /// in the context of a `Result` of type `ReportOk`. + /// + /// This method allows you to add additional context to an error by providing a closure that generates the context. + /// + /// # Arguments + /// + /// * `f` - A closure that returns the additional context of type `ReportErr`. + /// + /// # Returns + /// + /// A `Result` of type `ReportOk` if the original result is `Ok`, or a tuple `(ReportErr, E)` containing the additional + /// context and the original error if the original result is `Err`. + /// + /// # Example + /// + /// ```rust + /// use error_tools::ErrWith; + /// let result : Result< (), std::io::Error > = Err( std::io::Error::new( std::io::ErrorKind::Other, "an error occurred" ) ); + /// let result_with_context : Result< (), ( &str, std::io::Error ) > = result.err_with( || "additional context" ); + /// ``` + fn err_with< F >( self, f : F ) -> std::result::Result< ReportOk, ( ReportErr, E ) > + where + F : FnOnce() -> ReportErr; + + /// Takes a reference to a `ReportErr` value and uses it to wrap an error of type `(ReportErr, E)` + /// in the context of a `Result` of type `ReportOk`. + /// + /// This method allows you to add additional context to an error by providing a reference to the context. + /// + /// # Arguments + /// + /// * `report` - A reference to the additional context of type `ReportErr`. + /// + /// # Returns + /// + /// A `Result` of type `ReportOk` if the original result is `Ok`, or a tuple `(ReportErr, E)` containing the additional + /// context and the original error if the original result is `Err`. + /// + /// # Example + /// + /// ```rust + /// use error_tools::ErrWith; + /// let result : Result< (), std::io::Error > = Err( std::io::Error::new( std::io::ErrorKind::Other, "an error occurred" ) ); + /// let report = "additional context"; + /// let result_with_report : Result< (), ( &str, std::io::Error ) > = result.err_with_report( &report ); + /// ``` + fn err_with_report( self, report : &ReportErr ) -> std::result::Result< ReportOk, ( ReportErr, E ) > + where + ReportErr : Clone; + + } + + impl< ReportErr, ReportOk, E, IntoError > ErrWith< ReportErr, ReportOk, E > + for std::result::Result< ReportOk, IntoError > + where + IntoError : Into< E >, + { + + fn err_with< F >( self, f : F ) -> std::result::Result< ReportOk, ( ReportErr, E ) > + where + F : FnOnce() -> ReportErr, + { + self.map_err( | e | ( f(), e.into() ) ) + } + + #[ inline( always ) ] + fn err_with_report( self, report : &ReportErr ) -> std::result::Result< ReportOk, ( ReportErr, E ) > + where + ReportErr : Clone, + Self : Sized, + { + self.map_err( | e | ( report.clone(), e.into() ) ) + } + + } + + /// A type alias for a `Result` that contains an error which is a tuple of a report and an original error. + /// + /// This is useful when you want to report additional information along with an error. The `ResultWithReport` type + /// helps in defining such results more concisely. + pub type ResultWithReport< Report, Error > = Result< Report, ( Report, Error ) >; /// /// Macro to generate an error descriptor. @@ -59,7 +152,8 @@ pub( crate ) mod private } - // xxx : deprecate maybe? + // zzz : review + /// baic implementation of generic BasicError #[ derive( core::fmt::Debug, core::clone::Clone, core::cmp::PartialEq, core::cmp::Eq ) ] @@ -90,7 +184,7 @@ pub( crate ) mod private } } - impl ErrorInterface for BasicError + impl ErrorTrait for BasicError { fn description( &self ) -> &str { @@ -116,37 +210,56 @@ pub( crate ) mod private #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } /// Shared with parent namespace of the module +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; + #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use private:: + { + ErrWith, + ResultWithReport, + }; + + #[ doc( inline ) ] + pub use prelude::*; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { - pub use super::private::err; - pub use super::private::return_err; - pub use super::private::ErrorInterface; - pub use super::private::BasicError; + use super::*; + + #[ doc( inline ) ] + pub use private:: + { + err, + return_err, + ErrorTrait, + BasicError, + }; + } diff --git a/module/core/error_tools/src/lib.rs b/module/core/error_tools/src/lib.rs index b672032358..30a25af03b 100644 --- a/module/core/error_tools/src/lib.rs +++ b/module/core/error_tools/src/lib.rs @@ -14,92 +14,137 @@ pub mod assert; pub mod error; /// Namespace with dependencies. - #[ cfg( feature = "enabled" ) ] pub mod dependency { #[ doc( inline ) ] #[ allow( unused_imports ) ] - #[ cfg( feature = "error_for_lib" ) ] + #[ cfg( feature = "error_typed" ) ] pub use ::thiserror; #[ doc( inline ) ] #[ allow( unused_imports ) ] - #[ cfg( feature = "error_for_app" ) ] + #[ cfg( feature = "error_untyped" ) ] pub use ::anyhow; } #[ cfg( feature = "enabled" ) ] -/// Exceptions handling mechanism for libs. -pub mod for_lib -{ - #[ doc( inline ) ] - #[ allow( unused_imports ) ] - #[ cfg( feature = "error_for_lib" ) ] - pub use ::thiserror::*; -} +#[ cfg( feature = "error_typed" ) ] +/// Typed exceptions handling mechanism. +pub mod typed; #[ cfg( feature = "enabled" ) ] -// qqq : cover by simple test /* aaa : Dmytro : added trivial test routine `basic` */ -/// Exceptions handling mechanism for apps. -pub mod for_app -{ - #[ doc( inline ) ] - #[ allow( unused_imports ) ] - #[ cfg( feature = "error_for_app" ) ] - pub use ::anyhow::*; -} +#[ cfg( feature = "error_untyped" ) ] +/// Untyped exceptions handling mechanism. +pub mod untyped; #[ cfg( feature = "enabled" ) ] #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. +/// Own namespace of the module. #[ cfg( feature = "enabled" ) ] -pub mod protected +#[ allow( unused_imports ) ] +pub mod own { + use super::*; + #[ allow( unused_imports ) ] + use super::*; + + #[ doc( inline ) ] + #[ allow( unused_imports ) ] + pub use assert::orphan::*; + + #[ cfg( not( feature = "no_std" ) ) ] #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use error::orphan::*; + + #[ cfg( feature = "error_untyped" ) ] + #[ doc( inline ) ] + #[ allow( unused_imports ) ] + pub use untyped::orphan::*; + + #[ cfg( feature = "error_typed" ) ] + #[ doc( inline ) ] + #[ allow( unused_imports ) ] + pub use typed::orphan::*; + } /// Shared with parent namespace of the module #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; - - #[ cfg( feature = "error_for_app" ) ] - pub use super::for_app::Result; + pub use exposed::*; } /// Exposed namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; + #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; + #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::assert::exposed::*; + pub use assert::exposed::*; #[ cfg( not( feature = "no_std" ) ) ] #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::error::exposed::*; + pub use error::exposed::*; + + #[ cfg( feature = "error_untyped" ) ] + #[ doc( inline ) ] + #[ allow( unused_imports ) ] + pub use untyped::exposed::*; + + #[ cfg( feature = "error_typed" ) ] + #[ doc( inline ) ] + #[ allow( unused_imports ) ] + pub use typed::exposed::*; } /// Prelude to use essentials: `use my_module::prelude::*`. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; + #[ allow( unused_imports ) ] + use super::*; + + #[ doc( inline ) ] + #[ allow( unused_imports ) ] + pub use assert::prelude::*; + + #[ cfg( not( feature = "no_std" ) ) ] + #[ doc( inline ) ] + #[ allow( unused_imports ) ] + pub use error::prelude::*; + + #[ cfg( feature = "error_untyped" ) ] + #[ doc( inline ) ] + #[ allow( unused_imports ) ] + pub use untyped::prelude::*; + + #[ cfg( feature = "error_typed" ) ] + #[ doc( inline ) ] + #[ allow( unused_imports ) ] + pub use typed::prelude::*; + } diff --git a/module/core/error_tools/src/result.rs b/module/core/error_tools/src/result.rs index 55717118bc..c95cb517ec 100644 --- a/module/core/error_tools/src/result.rs +++ b/module/core/error_tools/src/result.rs @@ -7,24 +7,24 @@ // pub type Result< T, E = BasicError > = std::result::Result< T, E >; // } // -// /// Protected namespace of the module. -// pub mod protected +// /// Own namespace of the module. +// pub mod own // { // #[ doc( inline ) ] // #[ allow( unused_imports ) ] -// pub use super::orphan::*; +// pub use orphan::*; // } // // #[ doc( inline ) ] // #[ allow( unused_imports ) ] -// pub use protected::*; +// pub use own::*; // // /// Shared with parent namespace of the module // pub mod orphan // { // #[ doc( inline ) ] // #[ allow( unused_imports ) ] -// pub use super::exposed::*; +// pub use exposed::*; // } // // /// Exposed namespace of the module. @@ -32,12 +32,12 @@ // { // #[ doc( inline ) ] // #[ allow( unused_imports ) ] -// pub use super::prelude::*; +// pub use prelude::*; // } // // /// Prelude to use essentials: `use my_module::prelude::*`. // pub mod prelude // { -// pub use super::private::Result; +// pub use private::Result; // } // diff --git a/module/core/error_tools/src/typed.rs b/module/core/error_tools/src/typed.rs new file mode 100644 index 0000000000..f3c5dd6330 --- /dev/null +++ b/module/core/error_tools/src/typed.rs @@ -0,0 +1,61 @@ +/// Internal namespace. +pub( crate ) mod private +{ + +} + +#[ doc( inline ) ] +#[ allow( unused_imports ) ] +pub use own::*; + +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own +{ + use super::*; + #[ doc( inline ) ] + pub use orphan::*; +} + +/// Shared with parent namespace of the module +#[ allow( unused_imports ) ] +pub mod orphan +{ + use super::*; + pub use super::super::typed; + pub use super::super::typed as for_lib; + + #[ doc( inline ) ] + pub use exposed::*; + + #[ doc( inline ) ] + #[ allow( unused_imports ) ] + pub use ::thiserror:: + { + Error, + }; + +} + +/// Exposed namespace of the module. +#[ allow( unused_imports ) ] +pub mod exposed +{ + use super::*; + + #[ doc( inline ) ] + pub use prelude::*; + +} + +/// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] +pub mod prelude +{ + use super::*; + + #[ doc( inline ) ] + #[ allow( unused_imports ) ] + pub use thiserror; + +} \ No newline at end of file diff --git a/module/core/error_tools/src/untyped.rs b/module/core/error_tools/src/untyped.rs new file mode 100644 index 0000000000..c6ca66c08d --- /dev/null +++ b/module/core/error_tools/src/untyped.rs @@ -0,0 +1,68 @@ +/// Internal namespace. +pub( crate ) mod private +{ + +} + +#[ doc( inline ) ] +#[ allow( unused_imports ) ] +pub use own::*; + +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own +{ + use super::*; + #[ doc( inline ) ] + pub use orphan::*; + + #[ doc( inline ) ] + pub use ::anyhow:: + { + Chain, + Context, + Error, + Ok, + Result, + }; + +} + +/// Shared with parent namespace of the module +#[ allow( unused_imports ) ] +pub mod orphan +{ + use super::*; + pub use super::super::untyped; + pub use super::super::untyped as for_app; + + #[ doc( inline ) ] + pub use exposed::*; + + #[ doc( inline ) ] + pub use ::anyhow:: + { + format_err, + ensure, + bail, + }; + +} + +/// Exposed namespace of the module. +#[ allow( unused_imports ) ] +pub mod exposed +{ + use super::*; + + #[ doc( inline ) ] + pub use prelude::*; + +} + +/// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] +pub mod prelude +{ + use super::*; +} \ No newline at end of file diff --git a/module/core/error_tools/tests/inc/basic_test.rs b/module/core/error_tools/tests/inc/basic_test.rs index 2cdd891518..61462b17f9 100644 --- a/module/core/error_tools/tests/inc/basic_test.rs +++ b/module/core/error_tools/tests/inc/basic_test.rs @@ -38,7 +38,7 @@ tests_impls! fn use1() { - use std::error::Error as ErrorInterface; + use std::error::Error as ErrorTrait; use the_module::BasicError as Error; // test.case( "basic" ); @@ -54,7 +54,7 @@ tests_impls! fn use2() { - use the_module::{ BasicError, ErrorInterface }; + use the_module::{ BasicError, ErrorTrait }; // test.case( "basic" ); @@ -98,7 +98,7 @@ tests_impls! fn sample() { #[ cfg( not( feature = "no_std" ) ) ] - fn f1() -> the_module::Result< () > + fn f1() -> the_module::untyped::Result< () > { let _read = std::fs::read_to_string( "Cargo.toml" )?; Err( the_module::BasicError::new( "Some error" ).into() ) diff --git a/module/core/error_tools/tests/inc/err_with_test.rs b/module/core/error_tools/tests/inc/err_with_test.rs new file mode 100644 index 0000000000..7b3a65516f --- /dev/null +++ b/module/core/error_tools/tests/inc/err_with_test.rs @@ -0,0 +1,31 @@ +#![ allow( unused_imports ) ] +use super::*; + +#[ test ] +fn err_with() +{ + + use the_module::ErrWith; + let result : Result< (), std::io::Error > = Err( std::io::Error::new( std::io::ErrorKind::Other, "an error occurred" ) ); + let got : Result< (), ( &str, std::io::Error ) > = result.err_with( || "additional context" ); + let exp : Result< (), ( &str, std::io::Error ) > = Err( ( "additional context", std::io::Error::new( std::io::ErrorKind::Other, "an error occurred" ) ) ); + assert_eq!( got.as_ref().unwrap_err().0, exp.as_ref().unwrap_err().0 ); + assert!( got.is_err() ); + +} + +// + +#[ test ] +fn err_with_report() +{ + + use error_tools::ErrWith; + let result : Result< (), std::io::Error > = Err( std::io::Error::new( std::io::ErrorKind::Other, "an error occurred" ) ); + let report = "additional context"; + let got : Result< (), ( &str, std::io::Error ) > = result.err_with_report( &report ); + let exp : Result< (), ( &str, std::io::Error ) > = Err( ( "additional context", std::io::Error::new( std::io::ErrorKind::Other, "an error occurred" ) ) ); + assert_eq!( got.as_ref().unwrap_err().0, exp.as_ref().unwrap_err().0 ); + assert!( got.is_err() ); + +} diff --git a/module/core/error_tools/tests/inc/mod.rs b/module/core/error_tools/tests/inc/mod.rs index 6d99a71ca5..256c6e20bd 100644 --- a/module/core/error_tools/tests/inc/mod.rs +++ b/module/core/error_tools/tests/inc/mod.rs @@ -1,6 +1,8 @@ #[ allow( unused_imports ) ] use super::*; -mod basic_test; -mod for_app_test; mod assert_test; +mod basic_test; +#[ cfg( not( feature = "no_std" ) ) ] +mod err_with_test; +mod untyped_test; diff --git a/module/core/error_tools/tests/inc/for_app_test.rs b/module/core/error_tools/tests/inc/untyped_test.rs similarity index 55% rename from module/core/error_tools/tests/inc/for_app_test.rs rename to module/core/error_tools/tests/inc/untyped_test.rs index e2eb7601f6..f1db8e77a9 100644 --- a/module/core/error_tools/tests/inc/for_app_test.rs +++ b/module/core/error_tools/tests/inc/untyped_test.rs @@ -3,15 +3,15 @@ use super::*; // -#[ cfg( feature = "error_for_app" ) ] +#[ cfg( feature = "error_untyped" ) ] tests_impls! { fn basic() { // test.case( "from parse usize error" ); - let err = the_module::for_app::anyhow!( "err" ); - a_id!( the_module::for_app::Error::is::< &str >( &err ), true ); + let err = the_module::untyped::format_err!( "err" ); + a_id!( the_module::untyped::Error::is::< &str >( &err ), true ); a_id!( err.is::< &str >(), true ); a_id!( err.to_string(), "err" ); } @@ -19,7 +19,7 @@ tests_impls! // -#[ cfg( feature = "error_for_app" ) ] +#[ cfg( feature = "error_untyped" ) ] tests_index! { basic, diff --git a/module/core/error_tools/tests/smoke_test.rs b/module/core/error_tools/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/core/error_tools/tests/smoke_test.rs +++ b/module/core/error_tools/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/core/error_tools/tests/error_tools_tests.rs b/module/core/error_tools/tests/tests.rs similarity index 100% rename from module/core/error_tools/tests/error_tools_tests.rs rename to module/core/error_tools/tests/tests.rs diff --git a/module/core/for_each/Cargo.toml b/module/core/for_each/Cargo.toml index 4632085ca1..877ccbe184 100644 --- a/module/core/for_each/Cargo.toml +++ b/module/core/for_each/Cargo.toml @@ -24,7 +24,7 @@ workspace = true features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] + # include = [ # "/rust/impl/meta/for_each", # "/Cargo.toml", diff --git a/module/core/for_each/src/lib.rs b/module/core/for_each/src/lib.rs index c12e9a7513..6d658ec0ef 100644 --- a/module/core/for_each/src/lib.rs +++ b/module/core/for_each/src/lib.rs @@ -472,46 +472,51 @@ pub( crate ) mod private #[ cfg( feature = "enabled" ) ] #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. +/// Own namespace of the module. #[ cfg( feature = "enabled" ) ] -pub mod protected +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } /// Orphan namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; } /// Prelude to use essentials: `use my_module::prelude::*`. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::private::for_each; + pub use private::for_each; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::private::braces_unwrap; + pub use private::braces_unwrap; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::private::identity; + pub use private::identity; } diff --git a/module/core/for_each/tests/smoke_test.rs b/module/core/for_each/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/core/for_each/tests/smoke_test.rs +++ b/module/core/for_each/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/core/format_tools/Cargo.toml b/module/core/format_tools/Cargo.toml new file mode 100644 index 0000000000..7bc2112ae8 --- /dev/null +++ b/module/core/format_tools/Cargo.toml @@ -0,0 +1,50 @@ +[package] +name = "format_tools" +version = "0.2.0" +edition = "2021" +authors = [ + "Kostiantyn Wandalen ", +] +license = "MIT" +readme = "Readme.md" +documentation = "https://docs.rs/format_tools" +repository = "https://github.com/Wandalen/wTools/tree/master/module/core/format_tools" +homepage = "https://github.com/Wandalen/wTools/tree/master/module/core/format_tools" +description = """ +Collection of mechanisms for formatting and serialization into string. +""" +categories = [ "algorithms", "development-tools" ] +keywords = [ "fundamental", "general-purpose" ] + +[lints] +workspace = true + +[package.metadata.docs.rs] +features = [ "full" ] +all-features = false + +[features] + +default = [ + "enabled", +] + +full = [ + "enabled", +] +enabled = [ + "reflect_tools/enabled", + # "derive_tools/enabled", + "former/enabled", +] + +[dependencies] +# derive_tools = { workspace = true, features = [ "derive_from", "derive_inner_from" ] } +reflect_tools = { workspace = true, features = [ "reflect_types" ] } +former = { workspace = true, features = [ "derive_former" ] } + +[dev-dependencies] +test_tools = { workspace = true } + +# [build-dependencies] +# cfg_aliases = "0.1.1" diff --git a/module/core/format_tools/License b/module/core/format_tools/License new file mode 100644 index 0000000000..6d5ef8559f --- /dev/null +++ b/module/core/format_tools/License @@ -0,0 +1,22 @@ +Copyright Kostiantyn W and Out of the Box Systems (c) 2013-2024 + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/module/core/format_tools/Readme.md b/module/core/format_tools/Readme.md new file mode 100644 index 0000000000..19543ef6f4 --- /dev/null +++ b/module/core/format_tools/Readme.md @@ -0,0 +1,94 @@ +# Module :: format_tools + + + [![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) [![rust-status](https://github.com/Wandalen/wTools/actions/workflows/module_reflect_tools_push.yml/badge.svg)](https://github.com/Wandalen/wTools/actions/workflows/module_reflect_tools_push.yml) [![docs.rs](https://img.shields.io/docsrs/format_tools?color=e3e8f0&logo=docs.rs)](https://docs.rs/format_tools) [![Open in Gitpod](https://raster.shields.io/static/v1?label=try&message=online&color=eee&logo=gitpod&logoColor=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=module%2Fcore%2Freflect_tools%2Fexamples%2Freflect_tools_trivial.rs,RUN_POSTFIX=--example%20reflect_tools_trivial/https://github.com/Wandalen/wTools) [![discord](https://img.shields.io/discord/872391416519737405?color=eee&logo=discord&logoColor=eee&label=ask)](https://discord.gg/m3YfbXpUUY) + + +Collection of mechanisms for formatting and serialization into string. + +### Basic use-case + + + +Using the `to_string_with_fallback` macro to convert values to strings with a primary and fallback formatting method. + +```rust +fn main() +{ + // Import necessary traits and the macro from the `format_tools` crate. + use core::fmt; + use format_tools:: + { + WithDebug, + WithDisplay, + to_string_with_fallback, + }; + + // 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 + { + 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 + { + write!( f, "This is display" ) + } + } + + // 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 + { + 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 ); + +} +``` + +### To add to your project + +```sh +cargo add format_tools +``` + +### Try out from the repository + +```sh +git clone https://github.com/Wandalen/wTools +cd wTools +cd examples/foramt_tools_trivial +cargo run +``` diff --git a/module/core/format_tools/build.rs b/module/core/format_tools/build.rs new file mode 100644 index 0000000000..f515253266 --- /dev/null +++ b/module/core/format_tools/build.rs @@ -0,0 +1,25 @@ +//! To avoid messing up with long logical expressions in the codebase. + +// use cfg_aliases::cfg_aliases; + +fn main() +{ + // // Setup cfg aliases + // cfg_aliases! + // { + // all_features : + // { + // all + // ( + // feature = "reflect_reflect" + // ) + // }, + // any_feature : + // { + // any + // ( + // feature = "reflect_reflect" + // ) + // }, + // } +} diff --git a/module/core/format_tools/examples/format_tools_trivial.rs b/module/core/format_tools/examples/format_tools_trivial.rs new file mode 100644 index 0000000000..6683ab3f4a --- /dev/null +++ b/module/core/format_tools/examples/format_tools_trivial.rs @@ -0,0 +1,68 @@ +//! +//! Using the `to_string_with_fallback` macro +//! to convert values to strings with a primary and fallback formatting method. +//! + +fn main() +{ + // Import necessary traits and the macro from the `format_tools` crate. + use core::fmt; + use format_tools:: + { + WithDebug, + WithDisplay, + to_string_with_fallback, + }; + + // 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 + { + 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 + { + write!( f, "This is display" ) + } + } + + // 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 + { + 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 ); + +} \ No newline at end of file diff --git a/module/core/format_tools/src/format.rs b/module/core/format_tools/src/format.rs new file mode 100644 index 0000000000..2ba8ca3428 --- /dev/null +++ b/module/core/format_tools/src/format.rs @@ -0,0 +1,346 @@ +//! +//! Collection of mechanisms for formatting and serialization into string. +//! + +/// Internal namespace. +pub( crate ) mod private +{ + + /// Macro to create a field with a key and formatted value. + /// + /// This macro helps to convert a field of a structure into one or another string representation + /// depending on the parameters `how`, `fallback1`, and `fallback2`. Unlike `_field_with_key`, + /// the key is the path of the expression and is deduced from the last part of the expression. + /// For example, for `this.is.field`, the key is `field`. + + #[ macro_export ] + macro_rules! _field_with_key + { + ( + $key : ident, + $src : expr, + $how : ty, + $fallback1 : ty, + $fallback2 : ty + $(,)? + ) + => + {{ + ( + ::core::stringify!( $key ), + $crate::MaybeAs::< '_, str, $how >::from + ( + $crate::to_string_with_fallback!( $how, $fallback1, $fallback2, $src ) + ), + ) + }}; + } + + /// Macro to create a field with optional fallbacks. + /// + /// This macro helps to convert a field of a structure into one or another string representation + /// depending on the parameters `how`, `fallback1`, and `fallback2`. Unlike `_field_with_key`, + /// the key is the path of the expression and is deduced from the last part of the expression. + /// For example, for `this.is.field`, the key is `field`. + + #[ macro_export ] + macro_rules! _field + { + + ( & $path:ident.$( $key:ident )+, $how : ty, $fallback1 : ty, $fallback2 : ty $(,)? ) => + {{ + $crate::_field!( # ( & $path . ) ( $( $key )+ ) ( $how, $fallback1, $fallback2 ) ) + }}; + + ( $path:ident.$( $key:ident )+, $how : ty, $fallback1 : ty, $fallback2 : ty $(,)? ) => + {{ + $crate::_field!( # ( $path . ) ( $( $key )+ ) ( $how, $fallback1, $fallback2 ) ) + }}; + + ( & $key:ident, $how : ty, $fallback1 : ty, $fallback2 : ty $(,)? ) => + {{ + $crate::_field!( # () ( $key ) ( $how, $fallback1, $fallback2 ) ) + }}; + + ( $key:ident, $how : ty, $fallback1 : ty, $fallback2 : ty $(,)? ) => + {{ + $crate::_field!( # () ( $key ) ( $how, $fallback1, $fallback2 ) ) + }}; + + // private + + ( + # + ( $( $prefix:tt )* ) + ( $prekey:ident.$( $field:ident )+ ) + ( $how : ty, $fallback1 : ty, $fallback2 : ty ) + ) + => + {{ + $crate::_field!( # ( $( $prefix )* $prekey . ) ( $( $field )+ ) ( $how, $fallback1, $fallback2 ) ) + }}; + + ( + # + ( $( $prefix:tt )* ) + ( $key:ident ) + ( $how : ty, $fallback1 : ty, $fallback2 : ty ) + ) + => + {{ + $crate::_field!( # # ( $( $prefix )* ) ( $key ) ( $how, $fallback1, $fallback2 ) ) + }}; + + ( + # # + ( $( $prefix:tt )* ) + ( $key:ident ) + ( $how : ty, $fallback1 : ty, $fallback2 : ty ) + ) + => + {{ + $crate::_field_with_key!( $key, $( $prefix )* $key, $how, $fallback1, $fallback2 ) + }}; + + } + + /// Converting representations to a reference on a string slice, + /// but if not possible, to a display string, and if that is also not possible, then to a debug string. + /// + /// Macros for converting fields to different string representations in a prioritized manner: + /// 1. Reference to a string slice. + /// 2. Display string. + /// 3. Debug string with miltiline. + pub mod ref_or_display_or_debug_multiline + { + + /// Macro to create a field with key using reference, display, or debug formatting. + /// + /// This macro attempts to convert the field to a reference to a string slice. + /// If that is not possible, it tries to use the Display trait for conversion. + /// If that also fails, it falls back to using the Debug trait with multiline. + #[ macro_export ] + macro_rules! ref_or_display_or_debug_multiline_field_with_key + { + ( + $key : ident, + $src : expr + $(,)? + ) + => + {{ + $crate::_field_with_key!( $key, $src, $crate::WithRef, $crate::WithDisplay, $crate::WithDebugMultiline ) + }}; + } + + /// Macro to create a field using reference, display, or debug formatting. + /// + /// This macro attempts to convert the field to a reference to a string slice. + /// If that is not possible, it tries to use the Display trait for conversion. + /// If that also fails, it falls back to using the Debug trait with multiline. + #[ macro_export ] + macro_rules! ref_or_display_or_debug_multiline_field + { + ( $( $t:tt )+ ) + => + {{ + $crate::_field!( $( $t )+, $crate::WithRef, $crate::WithDisplay, $crate::WithDebugMultiline ) + }} + } + + pub use ref_or_display_or_debug_multiline_field_with_key as field_with_key; + pub use ref_or_display_or_debug_multiline_field as field; + + } + + /// Converting representations to a reference on a string slice, + /// but if not possible, to a display string, and if that is also not possible, then to a debug string. + /// + /// Macros for converting fields to different string representations in a prioritized manner: + /// 1. Reference to a string slice. + /// 2. Display string. + /// 3. Debug string. + pub mod ref_or_display_or_debug + { + + /// Macro to create a field with key using reference, display, or debug formatting. + /// + /// This macro attempts to convert the field to a reference to a string slice. + /// If that is not possible, it tries to use the Display trait for conversion. + /// If that also fails, it falls back to using the Debug trait. + #[ macro_export ] + macro_rules! ref_or_display_or_debug_field_with_key + { + ( + $key : ident, + $src : expr + $(,)? + ) + => + {{ + $crate::_field_with_key!( $key, $src, $crate::WithRef, $crate::WithDisplay, $crate::WithDebug ) + }}; + } + + /// Macro to create a field using reference, display, or debug formatting. + /// + /// This macro attempts to convert the field to a reference to a string slice. + /// If that is not possible, it tries to use the Display trait for conversion. + /// If that also fails, it falls back to using the Debug trait. + #[ macro_export ] + macro_rules! ref_or_display_or_debug_field + { + ( $( $t:tt )+ ) + => + {{ + $crate::_field!( $( $t )+, $crate::WithRef, $crate::WithDisplay, $crate::WithDebug ) + }} + } + + pub use ref_or_display_or_debug_field_with_key as field_with_key; + pub use ref_or_display_or_debug_field as field; + + } + + /// Converting representations to a reference on a string slice, + /// but if not possible, to a debug string. + /// + /// Macros for converting fields to different string representations in a prioritized manner: + /// 1. Reference to a string slice. + /// 2. Debug string. + /// + pub mod ref_or_debug + { + + /// Macro to create a field with key using reference or debug formatting. + /// + /// This macro attempts to convert the field to a reference to a string slice. + /// If that is not possible, it falls back to using the Debug trait. + #[ macro_export ] + macro_rules! ref_or_debug_field_with_key + { + ( + $key : ident, + $src : expr + $(,)? + ) + => + {{ + $crate::_field_with_key!( $key, $src, $crate::WithRef, $crate::WithDebug, $crate::WithDebug ) + }}; + } + + /// Macro to create a field using reference or debug formatting. + /// + /// This macro attempts to convert the field to a reference to a string slice. + /// If that is not possible, it falls back to using the Debug trait. + #[ macro_export ] + macro_rules! ref_or_debug_field + { + ( $( $t:tt )+ ) + => + {{ + $crate::_field!( $( $t )+, $crate::WithRef, $crate::WithDebug, $crate::WithDebug ) + }} + } + + pub use ref_or_debug_field_with_key as field_with_key; + pub use ref_or_debug_field as field; + + } + +} + +pub mod to_string; +pub mod to_string_with_fallback; +pub mod as_table; +pub mod md_math; +pub mod print; +pub mod string; +pub mod table; + +#[ doc( inline ) ] +#[ allow( unused_imports ) ] +pub use own::*; + +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own +{ + use super::*; + + #[ doc( inline ) ] + pub use super:: + { + to_string::orphan::*, + to_string_with_fallback::orphan::*, + as_table::orphan::*, + md_math::orphan::*, + print::orphan::*, + string::orphan::*, + table::orphan::*, + }; + +} + +/// Orphan namespace of the module. +#[ allow( unused_imports ) ] +pub mod orphan +{ + use super::*; + + #[ doc( inline ) ] + pub use exposed::*; + + #[ doc( inline ) ] + pub use private:: + { + ref_or_display_or_debug, + ref_or_display_or_debug_multiline, + ref_or_debug, + }; + +} + +/// Exposed namespace of the module. +#[ allow( unused_imports ) ] +pub mod exposed +{ + use super::*; + + #[ doc( inline ) ] + pub use reflect_tools::MaybeAs; + + #[ doc( inline ) ] + pub use + { + to_string::exposed::*, + to_string_with_fallback::exposed::*, + as_table::exposed::*, + md_math::exposed::*, + print::exposed::*, + string::exposed::*, + table::exposed::*, + }; + +} + +/// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] +pub mod prelude +{ + use super::*; + + #[ doc( inline ) ] + pub use + { + to_string::prelude::*, + to_string_with_fallback::prelude::*, + as_table::prelude::*, + md_math::prelude::*, + print::prelude::*, + string::prelude::*, + table::prelude::*, + }; + +} diff --git a/module/core/format_tools/src/format/as_table.rs b/module/core/format_tools/src/format/as_table.rs new file mode 100644 index 0000000000..0ade384611 --- /dev/null +++ b/module/core/format_tools/src/format/as_table.rs @@ -0,0 +1,261 @@ +//! +//! Nice print's wrapper. +//! + +/// Internal namespace. +pub( crate ) mod private +{ + + use crate::*; + use core:: + { + ops::{ Deref }, + marker::PhantomData, + fmt, + // cmp::Ordering, + }; + + /// Transparent wrapper for table-like structures. + #[ repr( transparent ) ] + #[ derive( Clone, Copy ) ] + pub struct AsTable< 'table, T, RowKey, Row, CellKey, CellFormat > + ( + &'table T, + ::core::marker::PhantomData< ( &'table (), fn () -> ( RowKey, Row, CellKey, CellFormat ) ) >, + ) + where + Row : Clone + Cells< CellKey, CellFormat >, + CellKey : fmt::Debug + Clone + std::cmp::Eq + std::hash::Hash, + CellFormat : Copy + 'static, + ; + + impl< 'table, T, RowKey, Row, CellKey, CellFormat > + AsTable< 'table, T, RowKey, Row, CellKey, CellFormat > + where + Row : Clone + Cells< CellKey, CellFormat >, + CellKey : fmt::Debug + Clone + std::cmp::Eq + std::hash::Hash, + CellFormat : Copy + 'static, + { + /// Just a constructor. + pub fn new( src : &'table T ) -> Self + { + Self( src, Default::default() ) + } + } + + impl< 'table, T, RowKey, Row, CellKey, CellFormat > AsRef< T > + for AsTable< 'table, T, RowKey, Row, CellKey, CellFormat > + where + Row : Clone + Cells< CellKey, CellFormat >, + CellKey : fmt::Debug + Clone + std::cmp::Eq + std::hash::Hash, + CellFormat : Copy + 'static, + { + fn as_ref( &self ) -> &T + { + &self.0 + } + } + + impl< 'table, T, RowKey, Row, CellKey, CellFormat > Deref + for AsTable< 'table, T, RowKey, Row, CellKey, CellFormat > + where + Row : Clone + Cells< CellKey, CellFormat >, + CellKey : fmt::Debug + Clone + std::cmp::Eq + std::hash::Hash, + CellFormat : Copy + 'static, + { + type Target = T; + + fn deref( &self ) -> &Self::Target + { + &self.0 + } + } + + impl< 'table, T, RowKey, Row, CellKey, CellFormat > From< &'table T > + for AsTable< 'table, T, RowKey, Row, CellKey, CellFormat > + where + Row : Clone + Cells< CellKey, CellFormat >, + CellKey : fmt::Debug + Clone + std::cmp::Eq + std::hash::Hash, + CellFormat : Copy + 'static, + { + fn from( table : &'table T ) -> Self + { + AsTable( table, PhantomData ) + } + } + + impl< 'table, T, RowKey, Row, CellKey, CellFormat > fmt::Debug + for AsTable< 'table, T, RowKey, Row, CellKey, CellFormat > + where + T : fmt::Debug, + Row : Clone + Cells< CellKey, CellFormat >, + CellKey : fmt::Debug + Clone + std::cmp::Eq + std::hash::Hash, + CellFormat : Copy + 'static, + { + fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> fmt::Result + { + f + .debug_struct( "AsTable" ) + .field( "0", &self.0 ) + .finish() + } + } + +// // = +// +// pub struct CellKeyWrap< CellKey > +// where +// CellKey : fmt::Debug + Clone + std::cmp::Eq + std::hash::Hash, +// { +// pub data : CellKey, +// pub index : usize, +// } +// +// impl< CellKey > CellKeyWrap< CellKey > +// where +// CellKey : fmt::Debug + Clone + std::cmp::Eq + std::hash::Hash, +// { +// /// Just a constructor. +// pub fn new( data : CellKey, index : usize ) -> Self +// { +// Self { data, index } +// } +// } +// +// impl< CellKey > Clone for CellKeyWrap< CellKey > +// where +// CellKey : fmt::Debug + Clone + std::cmp::Eq + std::hash::Hash, +// { +// fn clone( &self ) -> Self +// { +// Self::new( self.data.clone(), self.index ) +// } +// } +// +// impl< CellKey > AsRef< CellKey > for CellKeyWrap< CellKey > +// where +// CellKey : fmt::Debug + Clone + std::cmp::Eq + std::hash::Hash, +// { +// fn as_ref( &self ) -> &CellKey +// { +// &self.data +// } +// } +// +// impl< CellKey > Deref for CellKeyWrap< CellKey > +// where +// CellKey : fmt::Debug + Clone + std::cmp::Eq + std::hash::Hash, +// { +// type Target = CellKey; +// fn deref( &self ) -> &CellKey +// { +// &self.data +// } +// } +// +// impl< CellKey > From< ( CellKey, usize ) > +// for CellKeyWrap< CellKey > +// where +// CellKey : fmt::Debug + Clone + std::cmp::Eq + std::hash::Hash, +// { +// fn from( src : ( CellKey, usize ) ) -> Self +// { +// CellKeyWrap::new( src.0, src.1 ) +// } +// } +// +// impl< CellKey > fmt::Debug for CellKeyWrap< CellKey > +// where +// CellKey : fmt::Debug + Clone + std::cmp::Eq + std::hash::Hash, +// { +// fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> fmt::Result +// { +// f.debug_struct( "CellKey" ) +// .field( "data", &self.data ) +// .field( "index", &self.index ) +// .finish() +// } +// } +// +// impl< CellKey > PartialEq for CellKeyWrap< CellKey > +// where +// CellKey : fmt::Debug + Clone + std::cmp::Eq + std::hash::Hash, // xxx : there should be std::cmp::PartialEq, probably +// { +// fn eq( &self, other : &Self ) -> bool +// { +// self.index == other.index +// // self.as_ref() == other.as_ref() +// } +// } +// +// impl< CellKey > Eq for CellKeyWrap< CellKey > +// where +// CellKey : fmt::Debug + Clone + std::cmp::Eq + std::hash::Hash, +// { +// } +// +// impl< CellKey > PartialOrd for CellKeyWrap< CellKey > +// where +// CellKey : fmt::Debug + Clone + std::cmp::Eq + std::hash::Hash, +// { +// fn partial_cmp( &self, other : &Self ) -> Option< Ordering > +// { +// Some( self.index.cmp( &other.index ) ) +// } +// } +// +// impl< CellKey > Ord for CellKeyWrap< CellKey > +// where +// CellKey : fmt::Debug + Clone + std::cmp::Eq + std::hash::Hash, +// { +// fn cmp( &self, other : &Self ) -> Ordering +// { +// self.index.cmp( &other.index ) +// } +// } + +} + +#[ allow( unused_imports ) ] +pub use own::*; + +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own +{ + use super::*; + + #[ doc( inline ) ] + pub use orphan::*; +} + +/// Orphan namespace of the module. +#[ allow( unused_imports ) ] +pub mod orphan +{ + use super::*; + #[ doc( inline ) ] + pub use exposed::*; +} + +/// Exposed namespace of the module. +#[ allow( unused_imports ) ] +pub mod exposed +{ + use super::*; + + #[ doc( inline ) ] + pub use private:: + { + AsTable, + // CellKeyWrap, + }; + +} + +/// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] +pub mod prelude +{ + use super::*; +} diff --git a/module/core/format_tools/src/format/md_math.rs b/module/core/format_tools/src/format/md_math.rs new file mode 100644 index 0000000000..86ae353f8c --- /dev/null +++ b/module/core/format_tools/src/format/md_math.rs @@ -0,0 +1,94 @@ +//! Multidimensional math utilities. +//! +//! Provides functionality for converting multidimensional indices into flat offsets, +//! useful for operations involving multidimensional arrays or grids. + +/// Internal namespace. +pub( crate ) mod private +{ + use core:: + { + ops::{ Add, Mul }, + cmp::PartialOrd, + }; + + /// Trait for converting a multidimensional index into a flat offset. + /// + /// This trait is implemented for 3-dimensional arrays, allowing conversion of a + /// 3D index into a single linear offset. It is useful for mapping coordinates in + /// a 3D space to a flat array. + pub trait MdOffset< T > + { + /// Converts a 3D index into a flat offset. + /// + /// # Arguments + /// + /// - `md_index`: A 3-element array representing the multidimensional index. + /// + /// # Returns + /// + /// A value of type `T` representing the flat offset. + fn md_offset( & self, md_index : [ T ; 3 ] ) -> T; + } + + impl< T > MdOffset< T > for [ T ; 3 ] + where + T : Mul< T, Output = T > + Add< T, Output = T > + PartialOrd + Copy, + { + fn md_offset( & self, md_index : [ T ; 3 ] ) -> T + { + debug_assert!( md_index[ 0 ] < self[ 0 ] ); + debug_assert!( md_index[ 1 ] < self[ 1 ] ); + debug_assert!( md_index[ 2 ] < self[ 2 ] ); + let m1 = self[ 0 ]; + let m2 = m1 * self[ 1 ]; + md_index[ 0 ] + m1 * md_index[ 1 ] + m2 * md_index[ 2 ] + } + } + +} + +#[ allow( unused_imports ) ] +pub use own::*; + +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own +{ + use super::*; + #[ doc( inline ) ] + pub use orphan::*; + + #[ doc( inline ) ] + pub use private:: + { + MdOffset, + }; + +} + +/// Orphan namespace of the module. +#[ allow( unused_imports ) ] +pub mod orphan +{ + use super::*; + #[ doc( inline ) ] + pub use exposed::*; +} + +/// Exposed namespace of the module. +#[ allow( unused_imports ) ] +pub mod exposed +{ + use super::*; + pub use super::super::md_math; + +} + +/// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] +pub mod prelude +{ + use super::*; +} + diff --git a/module/core/format_tools/src/format/print.rs b/module/core/format_tools/src/format/print.rs new file mode 100644 index 0000000000..0813475b70 --- /dev/null +++ b/module/core/format_tools/src/format/print.rs @@ -0,0 +1,512 @@ +//! +//! Nice print. +//! + +/// Internal namespace. +pub( crate ) mod private +{ + + use crate::*; + use std:: + { + borrow::Cow, + collections::HashMap, + }; + use core:: + { + fmt, + }; + use former::Former; + + //= + + /// A struct to configure options for printing data as a table. + /// + /// The `Styles` struct provides customizable delimiters for formatting table data. It allows + /// you to define how table data should be separated and formatted, making it adaptable to + /// various needs. + /// + /// # Fields + /// + /// - `cell_separator`: A `String` that specifies the delimiter used to separate columns + /// within a table. This is the character or string that separates each column. + /// + /// - `row_prefix`: A `String` that specifies the prefix added to each row. This can be + /// used to add a consistent start to each row. + /// + /// - `row_postfix`: A `String` that specifies the postfix added to each row. This can be + /// used to add a consistent end to each row. + /// + /// - `row_postfix`: A `String` that specifies the postfix added to each row. This can be + /// used to add a consistent end to each row. + /// + /// ``` + #[ derive( Debug, Former ) ] + pub struct Styles + { + /// Delimiter for separating table columns. + pub cell_separator : String, + + /// Delimiter for adding prefix to a row. + pub row_prefix : String, + + /// Delimiter for adding postfix to a row. + pub row_postfix : String, + } + + impl Default for Styles + { + fn default() -> Self + { + let cell_separator = " ".to_string(); + let row_prefix = "".to_string(); + let row_postfix = "".to_string(); + Styles { cell_separator, row_prefix, row_postfix } + } + } + + /// Struct for formatting tables. + pub struct Context< 'a > + { + buf : &'a mut dyn fmt::Write, + styles : Styles, + } + + impl< 'a > Context< 'a > + { + /// Just constructr. + pub fn new( buf : &'a mut dyn fmt::Write, styles : Styles ) -> Self + { + Self { buf, styles } + } + } + + impl fmt::Debug for Context< '_ > + { + fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> fmt::Result + { + f + .debug_struct( "Context" ) + .field( "buf", &"dyn fmt::Write" ) + .field( "styles", &self.styles ) + .finish() + } + } + + /// A trait for converting tables to a string representation. + pub trait TableToString< 'a > + { + /// Converts the table to a string representation. + /// + /// # Returns + /// + /// A `String` containing the formatted table. + fn table_to_string( &'a self ) -> String; + } + + impl< 'a, T > TableToString< 'a > for T + where + T : TableFormatter< 'a > + { + fn table_to_string( &'a self ) -> String + { + let mut output = String::new(); + let mut context = Context + { + buf : &mut output, + styles : Styles::default(), + }; + T::fmt( self, &mut context ).expect( "Table formatting failed" ); + output + } + } + + /// A trait for formatting tables. + /// + /// This trait defines a method for formatting tables, allowing implementations + /// to specify how a table should be formatted and displayed. + /// + + pub trait TableFormatter< 'b > + { + /// Formats the table and writes the result to the given formatter. + fn fmt< 'a >( &'b self, f : &mut Context< 'a > ) -> fmt::Result; + } + + /// A trait for formatting tables. + impl< 'a, T, RowKey, Row, CellKey, CellFormat > TableFormatter< 'a > + for AsTable< 'a, T, RowKey, Row, CellKey, CellFormat > + where + Self : TableRows< RowKey, Row, CellKey, CellFormat >, + Self : TableHeader< CellKey >, + Self : TableSize, + Row : Clone + Cells< CellKey, CellFormat >, + CellKey : fmt::Debug + Clone + std::cmp::Eq + std::hash::Hash + 'static, + CellFormat : Copy + 'static, + { + fn fmt( &'a self, f : &mut Context< '_ > ) -> fmt::Result + { + + let mut x = FormatExtract::extract( self ); + // x.extract_slices(); + +// let FormatExtract +// { +// mcells, +// col_order, +// col_descriptors, +// data, +// .. +// } = x; + + let cell_separator = &f.styles.cell_separator; + let row_prefix = &f.styles.row_prefix; + let row_postfix = &f.styles.row_postfix; + + // Write head with proper alignment + if let Some( header ) = self.header() + { + // xxx : rid of vector + let mut formatted_row : Vec< String > = Vec::with_capacity( x.col_order.len() ); + for k in &x.col_order + { + let descriptor = &x.col_descriptors[ &k ]; + let width = descriptor.1; + let cell = descriptor.0.as_ref().unwrap_or( &Cow::Borrowed( "" ) ); + formatted_row.push( format!( "{:^width$}", cell, width = width ) ); + } + writeln!( f.buf, "{}{}{}", row_prefix, formatted_row.join( cell_separator ), row_postfix )?; + } + + // Write rows with proper alignment + for row in &x.data + { + // xxx : rid of vector + let height = row.iter().fold( 1, | acc, ( _k, e ) | acc.max( e.1[ 1 ] ) ); + // println!( "height : {height}" ); + + let mut formatted_row : Vec< String > = Vec::with_capacity( x.col_order.len() ); + for k in &x.col_order + { + let cell = &row[ &k ]; + let descriptor = &x.col_descriptors[ &k ]; + let width = descriptor.1; + println!( "width : {width:?}" ); + formatted_row.push( format!( "{:^width$}", cell.0.as_ref(), width = width ) ); + } + writeln!( f.buf, "{}{}{}", row_prefix, formatted_row.join( cell_separator ), row_postfix )?; + } + + Ok(()) + } + } + + pub struct FormatExtract< 'a, 'b, CellKey > + where + CellKey : fmt::Debug + Clone + std::cmp::Eq + std::hash::Hash + 'static, // xxx + 'a : 'b, + // 'b : 'a, + { + + /// Multidimensional size in number of columns per table and number of rows per table. + pub mcells : [ usize ; 2 ], + + /// Order of columns must be as stable as possible. + pub col_order : Vec< CellKey >, + + // key string, width, index + pub col_descriptors : HashMap< CellKey, ( Option< Cow< 'a, str > >, usize, usize ) >, + + // height + pub row_descriptors : Vec< ( usize, ) >, + + /// Either slices or strings extracted for further processsing. + // key, string, size, + pub data : Vec< HashMap< CellKey, ( Cow< 'a, str >, [ usize ; 2 ] ) > >, + + /// Multidimensional size in number of subrows per row, number of columns per table and number of rows per table. + /// Use it to retrive corresponding slice from multi-matrix of slices. + pub slices_dim : [ usize ; 3 ], + + /// Either slices or strings extracted for further processsing. + pub slices : Vec< &'b str >, + + // Does table have the header. + pub has_header : bool, + + } + + impl< 'a, 'b, CellKey > FormatExtract< 'a, 'b, CellKey > + where + CellKey : fmt::Debug + Clone + std::cmp::Eq + std::hash::Hash + 'static, + 'a : 'b, + // 'b : 'a, + { + + pub fn extract_slices< 'c : 'b >( &'c mut self ) + { + use md_math::MdOffset; + + let mut slices : Vec< &str > = vec![]; + std::mem::swap( &mut self.slices, &mut slices ); + + let col : &( Option< Cow< '_, str > >, usize, usize ) = &self.col_descriptors[ &self.col_order[ 0 ] ]; + slices[ 0 ] = col.0.as_ref().unwrap(); + + let mut irow : isize = -1; + if self.has_header + { + + irow += 1; + for ( icol, k ) in self.col_order.iter().enumerate() + { + let col : &( _, _, _ ) = &self.col_descriptors[ k ]; + let cell = &col.0; + + if let Some( cell ) = cell + { + + string::lines( cell ) + .enumerate() + .for_each( | ( layer, s ) | slices[ [ layer, icol, irow as usize ].md_offset( self.slices_dim ) ] = s ) + ; + + } + + } + + } + + for row_data in self.data.iter() + { + + irow += 1; + let row = &self.row_descriptors[ irow as usize ]; + + for ( icol, k ) in self.col_order.iter().enumerate() + { + let cell = &row_data[ &k ]; + string::lines( cell.0.as_ref() ) + .enumerate() + .for_each( | ( layer, s ) | slices[ [ layer, icol, irow as usize ].md_offset( self.slices_dim ) ] = s ) + ; + } + + } + + std::mem::swap( &mut self.slices, &mut slices ); + } + + pub fn extract< Table, RowKey, Row, CellFormat >( table : &'a Table ) -> Self + where + Table : TableRows< RowKey, Row, CellKey, CellFormat >, + Table : TableHeader< CellKey >, + Table : TableSize, + Row : Clone + Cells< CellKey, CellFormat > + 'a, + CellFormat : Copy + 'static, + { + + let mcells = table.mcells(); + // key string, width, index + let mut col_descriptors : HashMap< CellKey, ( Option< Cow< '_, str > >, usize, usize ) > = HashMap::new(); + // height + let mut row_descriptors : Vec< ( usize, ) > = Vec::with_capacity( mcells[ 1 ] ); + + let mut col_order : Vec< CellKey > = Vec::new(); + let mut has_header = false; + + // process header first + + let mut row_number : isize = -1; + if let Some( header ) = table.header() + { + assert!( header.len() <= usize::MAX, "Header of a table has too many cells" ); + has_header = true; + row_number = 0; + row_descriptors.push( ( 1, ) ); + + for ( key, title ) in header + { + let title_str : Cow< '_, str > = Cow::Owned( format!( "{}", title ) ); + let l = col_descriptors.len(); + let sz = string::size( &title_str ); + + col_descriptors + .entry( key.clone() ) + .and_modify( | col | + { + col.1 = col.1.max( sz[ 1 ] ); + }) + .or_insert_with( || + { + col_order.push( key.clone() ); + ( Some( title_str ), sz[ 1 ], l + 1 ) + }); + + row_descriptors[ row_number as usize ] = ( row_descriptors[ row_number as usize ].0.max( sz[ 0 ] ), ); + debug_assert!( row_descriptors.len() == ( row_number as usize ) + 1 ); + + } + } + + // Collect rows + // key, string, size, + let mut data : Vec< HashMap< CellKey, ( Cow< '_, str >, [ usize ; 2 ] ) > > = Vec::new(); + assert!( table.rows().len() <= usize::MAX, "Table has too many rows" ); + for row in table.rows() + { + assert!( row.cells().len() <= usize::MAX, "Row of a table has too many cells" ); + + row_number += 1; + row_descriptors.push( ( 1, ) ); + + let fields : HashMap< CellKey, ( Cow< '_, str >, [ usize ; 2 ] ) > = row + .cells() + .map + ( + | ( key, cell ) | + { + let r = match cell.0 + { + Some( cell ) => + { + ( key, cell ) + } + None => + { + ( key, Cow::Borrowed( "" ) ) + } + }; + + let sz = string::size( &r.1 ); + let l = col_descriptors.len(); + row_descriptors[ row_number as usize ] = ( row_descriptors[ row_number as usize ].0.max( sz[ 0 ] ), ); + + col_descriptors + .entry( r.0.clone() ) + .and_modify( | col | + { + col.1 = col.1.max( sz[ 1 ] ); + }) + .or_insert_with( || + { + col_order.push( r.0.clone() ); + ( None, sz[ 1 ], l + 1 ) + }); + + return ( r.0, ( r.1, sz ) ); + } + ) + .collect(); + data.push( fields ); + } + + // cook slices multi-matrix + + let mut slices_dim = [ 1, mcells[ 0 ], mcells[ 1 ] + ( if has_header { 1 } else { 0 } ) ]; + slices_dim[ 0 ] = row_descriptors + .iter() + .fold( 0, | acc : usize, e | acc.max( e.0 ) ) + ; + + let slices_len = slices_dim[ 0 ] * slices_dim[ 1 ] * slices_dim[ 2 ]; + let mut slices : Vec< &str > = vec![ "" ; slices_len ]; + + // + + let mut r = Self + { + mcells, + col_order, + col_descriptors, + row_descriptors, + data, + has_header, + slices_dim, + slices, + }; + + r + +// use md_math::MdOffset; +// let mut slices : Vec< &str > = vec![]; +// std::mem::swap( &mut r.slices, &mut slices ); +// +// let col : &( Option< Cow< '_, str > >, usize, usize ) = &r.col_descriptors[ &r.col_order[ 0 ] ]; +// slices[ 0 ] = col.0.as_ref().unwrap(); +// +// let mut irow : isize = -1; +// if r.has_header +// { +// +// irow += 1; +// for ( icol, k ) in r.col_order.iter().enumerate() +// { +// let col : &( _, _, _ ) = &r.col_descriptors[ k ]; +// let cell = &col.0; +// +// if let Some( cell ) = cell +// { +// +// string::lines( cell ) +// .enumerate() +// .for_each( | ( layer, s ) | slices[ [ layer, icol, irow as usize ].md_offset( r.slices_dim ) ] = s ) +// ; +// +// } +// +// } +// +// } +// +// r + } + + } + +} + +#[ allow( unused_imports ) ] +pub use own::*; + +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own +{ + use super::*; + #[ doc( inline ) ] + pub use orphan::*; +} + +/// Orphan namespace of the module. +#[ allow( unused_imports ) ] +pub mod orphan +{ + use super::*; + #[ doc( inline ) ] + pub use exposed::*; +} + +/// Exposed namespace of the module. +#[ allow( unused_imports ) ] +pub mod exposed +{ + use super::*; + + #[ doc( inline ) ] + pub use private:: + { + Styles, + Context, + TableFormatter, + TableToString, + }; + +} + +/// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] +pub mod prelude +{ + use super::*; +} diff --git a/module/core/format_tools/src/format/string.rs b/module/core/format_tools/src/format/string.rs new file mode 100644 index 0000000000..21c750873d --- /dev/null +++ b/module/core/format_tools/src/format/string.rs @@ -0,0 +1,220 @@ +//! +//! String tools. +//! + +// xxx : move to crate string_tools + +/// Internal namespace. +pub( crate ) mod private +{ + + // use crate::*; + + /// Returns the size of the text in `src` as a `[ width, height ]` array. + /// + /// This function calculates the dimensions of the input text, where the width is defined + /// as the length of the longest line, and the height is the total number of lines. It + /// handles various edge cases, including empty strings and strings with trailing newlines, + /// to ensure accurate dimension calculation. + /// + /// # Arguments + /// + /// * `src` - A string slice or any type that can be referenced as a string. This allows + /// for flexibility in passing different string-like types. + /// + /// # Returns + /// + /// A `[usize; 2]` array representing the dimensions of the text: + /// - `width`: The length of the longest line in the text. + /// - `height`: The total number of lines in the text. + /// + /// # Nuances + /// + /// - **Empty Strings**: If the input string is empty, the function returns `[0, 1]` + /// because there is one line with a width of zero. + /// - **Trailing Newlines**: If the input string ends with a newline character, it is + /// treated as having an additional empty line at the end. + /// - **Empty Lines**: Empty lines within the text are counted as lines with a width of zero. + /// + /// # Examples + /// + /// ``` + /// let text = "Hello\nWorld\nThis is a test"; + /// let dimensions = format_tools::string::size( text ); + /// assert_eq!( dimensions, [ 14, 3 ] ); + /// ``` + /// + /// In this example, the function returns `[ 14, 3 ]` because the longest line ( "This is a test" ) + /// has 14 characters, and there are 3 lines in total. + /// + /// ``` + /// let text = ""; + /// let dimensions = format_tools::string::size( text ); + /// assert_eq!( dimensions, [ 0, 1 ] ); + /// ``` + /// + /// Here, the function returns `[0, 1]` because the input is an empty string, which is considered + /// as a single line with zero width. + /// + /// ``` + /// let text = "Line 1\n\nLine 3\n"; + /// let dimensions = format_tools::string::size( text ); + /// assert_eq!( dimensions, [ 6, 4 ] ); + /// ``` + /// + /// In this example, the function returns `[ 6, 4 ]` because the longest line ( "Line 1" or "Line 3" ) + /// has 6 characters, there are 4 lines in total, including the empty line and the trailing newline. + + pub fn size< S : AsRef< str > >( src : S ) -> [ usize ; 2 ] + { + let text = src.as_ref(); + let mut height = 0; + let mut width = 0; + + for line in lines( text ) + { + height += 1; + let line_length = line.chars().count(); + if line_length > width + { + width = line_length; + } + } + + [ width, height ] + } + + /// Returns an iterator over the lines of a string slice. + /// + /// This function provides an iterator that yields each line of the input string slice. + /// It is an enhancement over the standard `str::lines()` method, as it handles trailing + /// newlines by returning an additional empty line if the input string ends with a newline. + /// + /// # Arguments + /// + /// * `src` - A reference to a type that can be converted to a string slice. This allows + /// for flexibility in passing various string-like types. + /// + /// # Returns + /// + /// An iterator of type `Lines` that yields each line as a `&str`. + /// + /// # Examples + /// + /// ``` + /// let text = "Hello\nWorld\n"; + /// let mut lines = format_tools::string::lines( text ); + /// assert_eq!( lines.next(), Some( "Hello" ) ); + /// assert_eq!( lines.next(), Some( "World" ) ); + /// assert_eq!( lines.next(), Some( "" ) ); + /// assert_eq!( lines.next(), None ); + /// ``` + pub fn lines< S : AsRef< str > + ?Sized >( src : & S ) -> Lines< '_ > + { + Lines::new( src.as_ref() ) + } + + /// An iterator over the lines of a string slice. + /// + /// This struct implements the `Iterator` trait, allowing you to iterate over the lines + /// of a string. It enhances the standard `str::Lines` iterator by handling trailing + /// newlines, ensuring that an additional empty line is returned if the input string + /// ends with a newline character. + /// ``` + #[ derive( Debug ) ] + pub struct Lines< 'a > + { + lines : std::str::Lines< 'a >, + has_trailing_newline : bool, + finished : bool, + } + impl< 'a > Lines< 'a > + { + fn new( input : &'a str ) -> Self + { + let has_trailing_newline = input.len() == 0 || input.ends_with( '\n' ); + Lines + { + lines : input.lines(), + has_trailing_newline, + finished : false, + } + } + } + + impl< 'a > Iterator for Lines< 'a > + { + type Item = &'a str; + + fn next( &mut self ) -> Option< Self::Item > + { + if self.finished + { + return None; + } + + match self.lines.next() + { + Some( line ) => Some( line ), + None => + { + if self.has_trailing_newline + { + self.finished = true; + Some( "" ) + } + else + { + None + } + } + } + } + } + +} + +#[ allow( unused_imports ) ] +pub use own::*; + +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own +{ + use super::*; + #[ doc( inline ) ] + pub use orphan::*; + + #[ doc( inline ) ] + pub use private:: + { + size, + lines, + Lines, + }; + +} + +/// Orphan namespace of the module. +#[ allow( unused_imports ) ] +pub mod orphan +{ + use super::*; + #[ doc( inline ) ] + pub use exposed::*; +} + +/// Exposed namespace of the module. +#[ allow( unused_imports ) ] +pub mod exposed +{ + use super::*; + pub use super::super::string; +} + +/// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] +pub mod prelude +{ + use super::*; +} diff --git a/module/core/format_tools/src/format/table.rs b/module/core/format_tools/src/format/table.rs new file mode 100644 index 0000000000..0f2cc5d77b --- /dev/null +++ b/module/core/format_tools/src/format/table.rs @@ -0,0 +1,242 @@ +//! +//! Table interface. +//! + +/// Internal namespace. +pub( crate ) mod private +{ + + use crate::*; + use core:: + { + fmt, + // borrow::Borrow, + }; + use std::borrow::Cow; + use reflect_tools:: + { + IteratorTrait, + Fields, + }; + + // = + + /// A trait for iterating over all cells of a row. + pub trait Cells< CellKey, CellFormat > + where + // Cell : std::borrow::ToOwned + ?Sized, + CellFormat : Copy + 'static, + { + /// Returns an iterator over all cells of the row. + // fn cells( &self ) -> impl IteratorTrait< Item = ( CellKey, MaybeAs< '_, str, CellFormat > ) > + // fn cells< 'a >( &'a self ) -> impl IteratorTrait< Item = ( CellKey, MaybeAs< 'a, str, CellFormat > ) > + fn cells< 'a, 'b >( &'a self ) -> impl IteratorTrait< Item = ( CellKey, MaybeAs< 'b, str, CellFormat > ) > + where + 'a : 'b, + // Cell : 'a, + ; + } + + impl< Row, CellKey, CellFormat > Cells< CellKey, CellFormat > + for Row + where + for< 'b > Row : Fields< CellKey, MaybeAs< 'b, str, CellFormat > >, + CellFormat : Copy + 'static, + for< 'b > MaybeAs< 'b, str, CellFormat > : From< < Row as Fields< CellKey, MaybeAs< 'b, str, CellFormat > > >::Value< 'b > >, + { + + // fn cells( &self ) -> impl IteratorTrait< Item = ( CellKey, MaybeAs< '_, str, CellFormat > ) > + // fn cells< 'a >( &'a self ) -> impl IteratorTrait< Item = ( CellKey, MaybeAs< 'a, str, CellFormat > ) > + fn cells< 'a, 'b >( &'a self ) -> impl IteratorTrait< Item = ( CellKey, MaybeAs< 'b, str, CellFormat > ) > + where + 'a : 'b, + // where + // Cell : 'a, + { + self.fields().map + ( + move | ( key, cell ) | + { + ( key, cell.into() ) + } + ) + } + + } + + // = + + /// A trait for iterating over all rows of a table. + pub trait TableRows< RowKey, Row, CellKey, CellFormat > + where + Row : Clone + Cells< CellKey, CellFormat >, + // Cell : std::borrow::ToOwned + ?Sized, + CellFormat : Copy + 'static, + CellKey : fmt::Debug + Clone + std::cmp::Eq + std::hash::Hash, + { + /// Returns an iterator over all rows of the table. + fn rows< 'a >( &'a self ) -> impl IteratorTrait< Item = &'a Row > + where Row : 'a; + } + + impl< T, RowKey, Row, CellKey, CellFormat > + TableRows< RowKey, Row, CellKey, CellFormat > + for AsTable< '_, T, RowKey, Row, CellKey, CellFormat > + where + for< 'a > T : Fields< RowKey, &'a Row, Value< 'a > = &'a Row > + 'a, + Row : Clone + Cells< CellKey, CellFormat >, + // Title : fmt::Display, + // Cell : fmt::Display, + // Cell : std::borrow::ToOwned + ?Sized, + CellKey : fmt::Debug + Clone + std::cmp::Eq + std::hash::Hash, + CellFormat : Copy + 'static, + { + + fn rows< 'a >( &'a self ) -> impl IteratorTrait< Item = &'a Row > + where Row : 'a + { + self.as_ref().fields() + .filter_map( move | ( _k, e ) | + { + Some( e ) + // match e.0 + // { + // Some( e ) => Some( e.into_owned() ), + // None => None, + // } + }) + .collect::< Vec< _ > >().into_iter() + } + + } + + // = + + /// A trait for iterating over all rows of a table. + pub trait TableSize + { + /// Returns size of a table. + fn mcells( &self ) -> [ usize ; 2 ]; + } + + impl< T, RowKey, Row, CellKey, CellFormat > TableSize + for AsTable< '_, T, RowKey, Row, CellKey, CellFormat > + where + Self : TableRows< RowKey, Row, CellKey, CellFormat >, + Row : Clone + Cells< CellKey, CellFormat >, + // Title : fmt::Display, + // Cell : fmt::Display, + // Cell : std::borrow::ToOwned + ?Sized, + CellKey : fmt::Debug + Clone + std::cmp::Eq + std::hash::Hash, + CellFormat : Copy + 'static, + { + fn mcells( &self ) -> [ usize ; 2 ] + { + let mut rows = self.rows(); + let nrows = rows.len(); + let row = rows.clone().next(); + if let Some( row2 ) = row + { + let cit = row2.cells().clone(); + let mcells = cit.len(); + [ nrows, mcells ] + // [ 0, 0 ] + } + else + { + [ 0, 0 ] + } + } + } + + // = + + /// Trait returning headers of a table if any. + pub trait TableHeader< CellKey > + { + /// Returns an iterator over all fields of the specified type within the entity. + fn header( &self ) -> Option< impl IteratorTrait< Item = ( CellKey, Cow< '_, str > ) > >; + } + + impl< T, RowKey, Row, CellKey, CellFormat > TableHeader< CellKey > + for AsTable< '_, T, RowKey, Row, CellKey, CellFormat > + where + Self : TableRows< RowKey, Row, CellKey, CellFormat >, + Row : Clone + Cells< CellKey, CellFormat >, + CellKey : fmt::Debug + Clone + std::cmp::Eq + std::hash::Hash, + CellKey : fmt::Display, + CellKey : AsRef< str >, + CellFormat : Copy + 'static, + { + + fn header( &self ) -> Option< impl IteratorTrait< Item = ( CellKey, Cow< '_, str > ) > > + { + let mut rows = self.rows(); + let row = rows.next(); + if let Some( row ) = row + { + Some + ( + row + .cells() + .map( | ( key, _title ) | ( key.clone(), Cow::Owned( format!( "{}", key ) ) ) ) + .collect::< Vec< _ > >() + .into_iter() + ) + } + else + { + None + } + } + + } + + // = + +} + +#[ allow( unused_imports ) ] +pub use own::*; + +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own +{ + use super::*; + #[ doc( inline ) ] + pub use orphan::*; +} + +/// Orphan namespace of the module. +#[ allow( unused_imports ) ] +pub mod orphan +{ + use super::*; + #[ doc( inline ) ] + pub use exposed::*; +} + +/// Exposed namespace of the module. +#[ allow( unused_imports ) ] +pub mod exposed +{ + use super::*; + + #[ doc( inline ) ] + pub use private:: + { + Cells, + TableRows, + TableSize, + TableHeader, + }; + +} + +/// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] +pub mod prelude +{ + use super::*; +} diff --git a/module/core/format_tools/src/format/to_string.rs b/module/core/format_tools/src/format/to_string.rs new file mode 100644 index 0000000000..d3f36e9c5f --- /dev/null +++ b/module/core/format_tools/src/format/to_string.rs @@ -0,0 +1,160 @@ +//! +//! Flexible ToString augmentation. +//! + +/// Internal namespace. +pub( crate ) mod private +{ + + use std:: + { + fmt, + borrow::Cow, + }; + + // == + + /// Marker type for returning reference representing instance instead of allocating new string. + #[ derive( Debug, Default, Clone, Copy ) ] + pub struct WithRef; + + /// Marker type for using Debug formatting. + #[ derive( Debug, Default, Clone, Copy ) ] + pub struct WithDebug; + + /// Marker type for using Debug multiline formatting. + #[ derive( Debug, Default, Clone, Copy ) ] + pub struct WithDebugMultiline; + + /// Marker type for using Display formatting. + #[ derive( Debug, Default, Clone, Copy ) ] + pub struct WithDisplay; + + /// Marker type for usign Well formatting. + #[ derive( Debug, Default, Clone, Copy ) ] + pub struct WithWell; + + // == + + /// Trait to convert a type to a string using a specified formatting method. + pub trait ToStringWith< How > + { + /// Converts the type to a string using the specified formatting method. + fn to_string_with< 's >( &'s self ) -> Cow< 's, str >; + } + + impl< 'a, T > ToStringWith< WithRef > for T + where + T : 'a, + T : AsRef< str >, + T : ?Sized, + { + /// Converts the type to a string using Display formatting. + #[ inline ] + fn to_string_with< 's >( &'s self ) -> Cow< 's, str > + { + println!( " - WithRef" ); + Cow::Borrowed( self.as_ref() ) + } + } + + impl< 'a, T > ToStringWith< WithDebug > for T + where + T : fmt::Debug, + T : ?Sized, + { + /// Converts the type to a string using Debug formatting. + #[ inline ] + fn to_string_with< 's >( &'s self ) -> Cow< 's, str > + { + println!( " - WithDebug {:?}", self ); + Cow::Owned( format!( "{:?}", self ) ) + } + } + + impl< 'a, T > ToStringWith< WithDebugMultiline > for T + where + T : fmt::Debug, + T : ?Sized, + { + /// Converts the type to a string using Debug formatting. + #[ inline ] + fn to_string_with< 's >( &'s self ) -> Cow< 's, str > + { + println!( " - WithDebugMultiline {:#?}", self ); + Cow::Owned( format!( "{:#?}", self ) ) + } + } + + impl< 'a, T > ToStringWith< WithDisplay > for T + where + T : 'a, + T : fmt::Display, + T : ?Sized, + { + /// Converts the type to a string using Display formatting. + #[ inline ] + fn to_string_with< 's >( &'s self ) -> Cow< 's, str > + { + println!( " - WithDisplay {}", self ); + Cow::Owned( format!( "{}", self ) ) + } + } + +} + +mod aref; + +#[ doc( inline ) ] +#[ allow( unused_imports ) ] +pub use own::*; + +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own +{ + use super::*; + + #[ doc( inline ) ] + pub use orphan::*; + +} + +/// Orphan namespace of the module. +#[ allow( unused_imports ) ] +pub mod orphan +{ + use super::*; + pub use super::super::to_string; + + #[ doc( inline ) ] + pub use exposed::*; + + #[ doc( inline ) ] + pub use private:: + { + WithDebug, + WithDebugMultiline, + WithDisplay, + WithRef, + WithWell, + ToStringWith, + }; + +} + +/// Exposed namespace of the module. +#[ allow( unused_imports ) ] +pub mod exposed +{ + use super::*; + #[ doc( inline ) ] + pub use prelude::*; +} + +/// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] +pub mod prelude +{ + use super::*; +} diff --git a/module/core/format_tools/src/format/to_string/aref.rs b/module/core/format_tools/src/format/to_string/aref.rs new file mode 100644 index 0000000000..fa1332734d --- /dev/null +++ b/module/core/format_tools/src/format/to_string/aref.rs @@ -0,0 +1,79 @@ +//! +//! Wrapper to wrap argument for trait `ToStringWith`. +//! + +// zzz : qqq : write derive for this with variable length +use core::ops::{ Deref }; + +/// Reference wrapper to make into string conversion with fallback. +#[ allow( missing_debug_implementations ) ] +#[ repr( transparent ) ] +pub struct Ref< 'a, T, How > +( pub Ref2< 'a, T, How > ) +where + &'a T : Copy, + T : ?Sized, +; + +/// Internal reference wrapper to make into string conversion with fallback. +#[ allow( missing_debug_implementations ) ] +#[ repr( transparent ) ] +pub struct Ref2< 'a, T, How > +( pub &'a T, ::core::marker::PhantomData< fn() -> How > ) +where + ::core::marker::PhantomData< fn() -> How > : Copy, + &'a T : Copy, + T : ?Sized, +; + +impl< 'a, T, How > Ref< 'a, T, How > +{ + + // /// Retrive inner value. + // #[ inline( always ) ] + // pub fn inner( self ) -> &'a T + // { + // self.0.0 + // } + +} + +impl< 'a, T, How > Clone for Ref< 'a, T, How > +{ + #[ inline( always ) ] + fn clone( &self ) -> Self + { + *self + } +} + +impl< 'a, T, How > Clone for Ref2< 'a, T, How > +{ + #[ inline( always ) ] + fn clone( &self ) -> Self + { + *self + } +} + +impl< 'a, T, How > Copy for Ref< 'a, T, How > {} +impl< 'a, T, How > Copy for Ref2< 'a, T, How > {} + +impl< 'a, T, How > Deref for Ref< 'a, T, How > +{ + type Target = Ref2< 'a, T, How >; + fn deref( &self ) -> &Self::Target + { + &self.0 + } +} + +impl< 'a, T, How > From< &'a T > for Ref< 'a, T, How > +where + T : ?Sized, +{ + fn from( src : &'a T ) -> Self + { + Ref( Ref2( src, std::marker::PhantomData ) ) + } +} diff --git a/module/core/format_tools/src/format/to_string_with_fallback.rs b/module/core/format_tools/src/format/to_string_with_fallback.rs new file mode 100644 index 0000000000..49f4d2e1a2 --- /dev/null +++ b/module/core/format_tools/src/format/to_string_with_fallback.rs @@ -0,0 +1,262 @@ +//! +//! Flexible ToString augmentation. +//! + +/// Internal namespace. +pub( crate ) mod private +{ + use crate::*; + + pub use super:: + { + aref::{ Ref, Ref2, Ref3 }, + }; + + use std:: + { + borrow::Cow, + }; + + // == + + /// Trait to convert a type to a string with a fallback formatting. + pub trait ToStringWithFallback< 'a, How, Fallback1, Fallback2 > + where + How : 'static, + Fallback1 : 'static, + Fallback2 : 'static, + { + /// Converts the type to a string using the specified formatting or a fallback. + fn to_string_with_fallback( self ) -> Cow< 'a, str > + ; + } + + impl< 'a, T, How, Fallback1, Fallback2 > ToStringWithFallback< 'a, How, Fallback1, Fallback2 > + for Ref< 'a, T, How, Fallback1, Fallback2 > + where + T : ToStringWith< How > + ?Sized, + How : 'static, + Fallback1 : 'static, + Fallback2 : 'static, + { + /// Converts the type to a string using the fallback formatting. + #[ inline ] + fn to_string_with_fallback( self ) -> Cow< 'a, str > + where + { + self.0.0.0.to_string_with() + } + } + + impl< 'a, T, How, Fallback1, Fallback2 > ToStringWithFallback< 'a, How, Fallback1, Fallback2 > + for Ref2< 'a, T, How, Fallback1, Fallback2 > + where + T : ToStringWith< Fallback1 > + ?Sized, + How : 'static, + Fallback1 : 'static, + Fallback2 : 'static, + { + /// Converts the type to a string using the fallback formatting. + #[ inline ] + fn to_string_with_fallback( self ) -> Cow< 'a, str > + { + self.0.0.to_string_with() + } + } + + impl< 'a, T, How, Fallback1, Fallback2 > ToStringWithFallback< 'a, How, Fallback1, Fallback2 > + for Ref3< 'a, T, How, Fallback1, Fallback2 > + where + T : ToStringWith< Fallback2 > + ?Sized, + How : 'static, + Fallback1 : 'static, + Fallback2 : 'static, + { + /// Converts the type to a string using the specified formatting. + #[ inline ] + fn to_string_with_fallback( self ) -> Cow< 'a, str > + { + self.0.to_string_with() + } + } + + // + + /// Macro to convert a value to a string using a specified formatting method with a fallback. + /// + /// # Parameters + /// - `$how`: The primary formatting type (e.g., `WithDebug`, `WithDisplay`). + /// - `$fallback1`: The first fallback formatting type. + /// - `$fallback2`: The second fallback formatting type (optional). + /// - `$src`: The source value to format. + /// + /// # Example + /// ```rust + /// use core::fmt; + /// use format_tools:: + /// { + /// WithRef, + /// WithDebug, + /// WithDisplay, + /// to_string_with_fallback, + /// }; + /// + /// // Define a struct that implements both Debug and Display traits. + /// struct Both; + /// + /// impl fmt::Debug for Both + /// { + /// fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> fmt::Result + /// { + /// write!( f, "This is debug" ) + /// } + /// } + /// + /// impl fmt::Display for Both + /// { + /// 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; + /// + /// impl fmt::Debug for OnlyDebug + /// { + /// 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; + /// let got = to_string_with_fallback!( WithDisplay, WithDebug, &src ); + /// let exp = "This is display".to_string(); + /// // The primary formatting method WithDisplay is used. + /// assert_eq!( got, exp ); + /// + /// // Example usage: Using OnlyDebug which implements only Debug. + /// let src = OnlyDebug; + /// let got = to_string_with_fallback!( WithDisplay, WithDebug, &src ); + /// let exp = "This is debug".to_string(); + /// // The primary formatting method WithDisplay is not available, so the fallback WithDebug is used. + /// assert_eq!( got, exp ); + /// + /// // Example usage: Using a struct that might need a second fallback. + /// struct OnlyDebugFallback; + /// + /// impl fmt::Debug for OnlyDebugFallback + /// { + /// fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> fmt::Result + /// { + /// write!( f, "This is debug fallback" ) + /// } + /// } + /// + /// // Example usage: Using OnlyDebugFallback which implements only Debug. + /// let src = OnlyDebugFallback; + /// let got = to_string_with_fallback!( WithRef, WithDisplay, WithDebug, &src ); + /// let exp = "This is debug fallback".to_string(); + /// // The primary formatting method WithDisplay is not available, so the second fallback WithDebugFallback is used. + /// assert_eq!( got, exp ); + /// ``` + + #[ macro_export ] + macro_rules! to_string_with_fallback + { + + ( $how : ty, $fallback1 : ty, $src : expr ) + => + {{ + use $crate::ToStringWithFallback; + $crate + ::to_string_with_fallback + ::Ref + ::< '_, _, $how, $fallback1, $fallback1 > + ::from( $src ) + .to_string_with_fallback() + }}; + + ( $how : ty, $fallback1 : ty, $fallback2 : ty, $src : expr ) + => + {{ + use $crate::ToStringWithFallback; + $crate + ::to_string_with_fallback + ::Ref + ::< '_, _, $how, $fallback1, $fallback2 > + ::from( $src ) + .to_string_with_fallback() + }}; + + } + + pub use to_string_with_fallback; +} + +mod aref; + +#[ doc( inline ) ] +#[ allow( unused_imports ) ] +pub use own::*; + +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own +{ + use super::*; + + #[ doc( inline ) ] + pub use orphan::*; + #[ doc( inline ) ] + pub use private:: + { + Ref, + Ref2, + Ref3, + to_string_with_fallback, + }; +} + +/// Orphan namespace of the module. +#[ allow( unused_imports ) ] +pub mod orphan +{ + use super::*; + pub use super::super::to_string_with_fallback; + + #[ doc( inline ) ] + pub use exposed::*; + + #[ doc( inline ) ] + pub use private:: + { + ToStringWithFallback, + }; + +} + +/// Exposed namespace of the module. +#[ allow( unused_imports ) ] +pub mod exposed +{ + use super::*; + #[ doc( inline ) ] + pub use prelude::*; + + #[ doc( inline ) ] + pub use private:: + { + }; + +} + +/// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] +pub mod prelude +{ + use super::*; +} diff --git a/module/core/format_tools/src/format/to_string_with_fallback/aref.rs b/module/core/format_tools/src/format/to_string_with_fallback/aref.rs new file mode 100644 index 0000000000..b06c078e15 --- /dev/null +++ b/module/core/format_tools/src/format/to_string_with_fallback/aref.rs @@ -0,0 +1,113 @@ +//! +//! Wrapper to wrap argument for trait `ToStringWithFallback`. +//! + +use core::ops::{ Deref }; + +/// Reference wrapper to make into string conversion with fallback. +#[ allow( missing_debug_implementations ) ] +#[ repr( transparent ) ] +pub struct Ref< 'a, T, How, Fallback1, Fallback2 > +( pub Ref2< 'a, T, How, Fallback1, Fallback2 > ) +where + &'a T : Copy, + T : ?Sized, +; + +/// Internal reference wrapper to make into string conversion with fallback. +#[ allow( missing_debug_implementations ) ] +#[ repr( transparent ) ] +pub struct Ref2< 'a, T, How, Fallback1, Fallback2 > +( pub Ref3< 'a, T, How, Fallback1, Fallback2 > ) +where + &'a T : Copy, + T : ?Sized, +; + +/// Internal reference wrapper to make into string conversion with fallback. +#[ allow( missing_debug_implementations ) ] +#[ repr( transparent ) ] +pub struct Ref3< 'a, T, How, Fallback1, Fallback2 > +( pub &'a T, ::core::marker::PhantomData< fn() -> ( How, Fallback1, Fallback2 ) > ) +where + &'a T : Copy, + T : ?Sized, +; + +impl< 'a, T, How, Fallback1, Fallback2 > Ref< 'a, T, How, Fallback1, Fallback2 > +{ + + /// Just a constructor. + #[ inline( always ) ] + pub fn inner( self ) -> &'a T + { + self.0.0.0 + } + +} + +impl< 'a, T, How, Fallback1, Fallback2 > Clone for Ref< 'a, T, How, Fallback1, Fallback2 > +{ + #[ inline( always ) ] + fn clone( &self ) -> Self + { + *self + } +} + +impl< 'a, T, How, Fallback1, Fallback2 > Clone for Ref2< 'a, T, How, Fallback1, Fallback2 > +{ + #[ inline( always ) ] + fn clone( &self ) -> Self + { + *self + } +} + +impl< 'a, T, How, Fallback1, Fallback2 > Clone for Ref3< 'a, T, How, Fallback1, Fallback2 > +{ + #[ inline( always ) ] + fn clone( &self ) -> Self + { + *self + } +} + +impl< 'a, T, How, Fallback1, Fallback2 > Copy for Ref< 'a, T, How, Fallback1, Fallback2 > {} +impl< 'a, T, How, Fallback1, Fallback2 > Copy for Ref2< 'a, T, How, Fallback1, Fallback2 > {} +impl< 'a, T, How, Fallback1, Fallback2 > Copy for Ref3< 'a, T, How, Fallback1, Fallback2 > {} + +impl< 'a, T, How, Fallback1, Fallback2 > Deref for Ref< 'a, T, How, Fallback1, Fallback2 > +{ + type Target = Ref2< 'a, T, How, Fallback1, Fallback2 >; + fn deref( &self ) -> &Self::Target + { + &self.0 + } +} + +impl< 'a, T, How, Fallback1, Fallback2 > Deref for Ref2< 'a, T, How, Fallback1, Fallback2 > +{ + type Target = Ref3< 'a, T, How, Fallback1, Fallback2 >; + fn deref( &self ) -> &Self::Target + { + &self.0 + } +} + +impl< 'a, T, How, Fallback1, Fallback2 > Deref for Ref3< 'a, T, How, Fallback1, Fallback2 > +{ + type Target = T; + fn deref( &self ) -> &Self::Target + { + &self.0 + } +} + +impl< 'a, T, How, Fallback1, Fallback2 > From< &'a T > for Ref< 'a, T, How, Fallback1, Fallback2 > +{ + fn from( src : &'a T ) -> Self + { + Ref( Ref2( Ref3( src, std::marker::PhantomData ) ) ) + } +} diff --git a/module/core/format_tools/src/lib.rs b/module/core/format_tools/src/lib.rs new file mode 100644 index 0000000000..bfd4a579f8 --- /dev/null +++ b/module/core/format_tools/src/lib.rs @@ -0,0 +1,92 @@ +#![ 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/reflect_tools/latest/reflect_tools/" ) ] +#![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/", "Readme.md" ) ) ] + +#[ cfg( feature = "enabled" ) ] +pub mod format; + +/// Namespace with dependencies. +#[ cfg( feature = "enabled" ) ] +pub mod dependency +{ + pub use ::reflect_tools; + pub use ::former; +} + +#[ cfg( feature = "enabled" ) ] +#[ doc( inline ) ] +#[ allow( unused_imports ) ] +pub use own::*; + +/// Own namespace of the module. +#[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] +pub mod own +{ + use super::*; + + #[ doc( inline ) ] + pub use orphan::*; + + #[ doc( inline ) ] + pub use super::format::own::*; + + // #[ doc( inline ) ] + // pub use super::format::orphan::*; + +} + +/// Orphan namespace of the module. +#[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] +pub mod orphan +{ + use super::*; + + #[ doc( inline ) ] + pub use super::format::orphan::*; + + #[ doc( inline ) ] + pub use exposed::*; +} + +/// Exposed namespace of the module. +#[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] +pub mod exposed +{ + use super::*; + + #[ doc( inline ) ] + pub use prelude::*; + + #[ doc( inline ) ] + pub use super::format::exposed::*; + + // #[ doc( inline ) ] + // pub use super::format::exposed::*; + + #[ doc( inline ) ] + pub use super::dependency::reflect_tools:: + { + Fields, + IteratorTrait, + }; + +} + +/// Prelude to use essentials: `use my_module::prelude::*`. +#[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] +pub mod prelude +{ + use super::*; + + #[ doc( inline ) ] + pub use super::format::prelude::*; + + // #[ doc( inline ) ] + // pub use super::format::prelude::*; + +} diff --git a/module/core/format_tools/tests/inc/fields_test.rs b/module/core/format_tools/tests/inc/fields_test.rs new file mode 100644 index 0000000000..3152710341 --- /dev/null +++ b/module/core/format_tools/tests/inc/fields_test.rs @@ -0,0 +1,135 @@ +#[ allow( unused_imports ) ] +use super::*; + +use the_module:: +{ + Fields, + IteratorTrait, + MaybeAs, + WithRef, +}; + +use std:: +{ + // fmt, + collections::HashMap, + borrow::Cow, +}; + +/// Struct representing a test object with various fields. +#[ derive( Clone, Debug ) ] +pub struct TestObject +{ + pub id : String, + pub created_at : i64, + pub file_ids : Vec< String >, + pub tools : Option< Vec< HashMap< String, String > > >, +} + +impl Fields< &'static str, MaybeAs< '_, str, WithRef > > +for TestObject +{ + type Value< 'v > = MaybeAs< 'v, str, WithRef >; + + fn fields( &self ) -> impl IteratorTrait< Item = ( &'static str, MaybeAs< '_, str, WithRef > ) > + { + use format_tools::ref_or_display_or_debug::field; + let mut dst : Vec< ( &'static str, MaybeAs< '_, str, WithRef > ) > = Vec::new(); + + dst.push( field!( &self.id ) ); + dst.push( field!( &self.created_at ) ); + dst.push( field!( &self.file_ids ) ); + + if let Some( tools ) = &self.tools + { + dst.push( field!( tools ) ); + } + else + { + dst.push( ( "tools", MaybeAs::none() ) ); + } + + dst.into_iter() + } +} + +// + +#[ test ] +fn basic_with_ref_display_debug() +{ + let test_object = TestObject + { + id : "12345".to_string(), + created_at : 1627845583, + file_ids : vec![ "file1".to_string(), "file2".to_string() ], + tools : Some + ( + vec! + [{ + let mut map = HashMap::new(); + map.insert( "tool1".to_string(), "value1".to_string() ); + map.insert( "tool2".to_string(), "value2".to_string() ); + map + }] + ), + }; + + let fields : Vec< ( &str, MaybeAs< '_, str, WithRef > ) > = + Fields::< &'static str, MaybeAs< '_, str, WithRef > >::fields( &test_object ).collect(); + + // let fields : Vec< ( &str, MaybeAs< '_, str, WithRef > ) > = test_object.fields().collect(); + + assert_eq!( fields.len(), 4 ); + assert!( fields[ 0 ].1.is_borrowed() ); + assert!( !fields[ 1 ].1.is_borrowed() ); + assert!( !fields[ 2 ].1.is_borrowed() ); + assert!( !fields[ 3 ].1.is_borrowed() ); + assert_eq!( fields[ 0 ], ( "id", Some( Cow::Borrowed( "12345" ) ).into() ) ); + assert_eq!( fields[ 0 ], ( "id", Some( Cow::Owned( "12345".to_string() ) ).into() ) ); + assert_eq!( fields[ 1 ], ( "created_at", Some( Cow::Owned( "1627845583".to_string() ) ).into() ) ); + assert_eq!( fields[ 2 ], ( "file_ids", Some( Cow::Owned( "[\"file1\", \"file2\"]".to_string() ) ).into() ) ); + assert_eq!( fields[ 3 ].0, "tools" ); + +} + +// + +#[ test ] +fn test_vec_fields() +{ + + let test_objects = vec! + [ + TestObject + { + id : "12345".to_string(), + created_at : 1627845583, + file_ids : vec![ "file1".to_string(), "file2".to_string() ], + tools : Some + ( + vec! + [{ + let mut map = HashMap::new(); + map.insert( "tool1".to_string(), "value1".to_string() ); + map.insert( "tool2".to_string(), "value2".to_string() ); + map + }] + ), + }, + TestObject + { + id : "67890".to_string(), + created_at : 13, + file_ids : vec![ "file3".to_string(), "file4".to_string() ], + tools : None, + }, + ]; + + // let fields : Vec< _ > = test_objects.fields().collect(); + let fields : Vec< _ > = Fields::< usize, Option< _ > >::fields( &test_objects ).collect(); + assert_eq!( fields.len(), 2 ); + assert_eq!( fields[ 0 ].0, 0 ); + assert_eq!( fields[ 1 ].0, 1 ); + +} diff --git a/module/core/format_tools/tests/inc/md_math_test.rs b/module/core/format_tools/tests/inc/md_math_test.rs new file mode 100644 index 0000000000..ac8c8c3fbd --- /dev/null +++ b/module/core/format_tools/tests/inc/md_math_test.rs @@ -0,0 +1,17 @@ +#[ allow( unused_imports ) ] +use super::*; + +#[ test ] +fn md_offset_basic() +{ + use the_module::md_math::MdOffset; + + let md_size = [ 10, 100, 1000 ]; + let md_index = [ 2, 3, 4 ]; + let got = md_size.md_offset( md_index ); + let exp = 2 + 3 * 10 + 4 * 10 * 100; + assert_eq!( got, exp ); + + // 2 * 100'000 + +} diff --git a/module/core/format_tools/tests/inc/mod.rs b/module/core/format_tools/tests/inc/mod.rs new file mode 100644 index 0000000000..a907ea3486 --- /dev/null +++ b/module/core/format_tools/tests/inc/mod.rs @@ -0,0 +1,18 @@ +#[ allow( unused_imports ) ] +use super::*; + +#[ cfg( feature = "enabled" ) ] +#[ path = "." ] +mod fundamental +{ + #[ allow( unused_imports ) ] + use super::*; + + mod fields_test; + mod md_math_test; + mod print_test; + mod string_test; + mod to_string_test; + mod to_string_with_fallback_test; + +} diff --git a/module/core/format_tools/tests/inc/print_test.rs b/module/core/format_tools/tests/inc/print_test.rs new file mode 100644 index 0000000000..dd45f73de8 --- /dev/null +++ b/module/core/format_tools/tests/inc/print_test.rs @@ -0,0 +1,191 @@ +#[ allow( unused_imports ) ] +use super::*; + +use the_module:: +{ + Fields, + IteratorTrait, + AsTable, + Cells, + TableSize, + TableRows, + TableHeader, + Context, + WithRef, + MaybeAs, +}; + +use std:: +{ + collections::HashMap, + borrow::Cow, +}; + +/// Struct representing a test object with various fields. +#[ derive( Clone, Debug ) ] +pub struct TestObject +{ + pub id : String, + pub created_at : i64, + pub file_ids : Vec< String >, + pub tools : Option< Vec< HashMap< String, String > > >, +} + +impl Fields< &'static str, MaybeAs< '_, str, WithRef > > +for TestObject +{ + type Value< 'v > = MaybeAs< 'v, str, WithRef >; + + fn fields( &self ) -> impl IteratorTrait< Item = ( &'static str, MaybeAs< '_, str, WithRef > ) > + { + // use format_tools::ref_or_display_or_debug_multiline::field; + use format_tools::ref_or_display_or_debug::field; + let mut dst : Vec< ( &'static str, MaybeAs< '_, str, WithRef > ) > = Vec::new(); + + dst.push( field!( &self.id ) ); + dst.push( field!( &self.created_at ) ); + dst.push( field!( &self.file_ids ) ); + + if let Some( tools ) = &self.tools + { + dst.push( field!( tools ) ); + } + else + { + dst.push( ( "tools", MaybeAs::none() ) ); + } + + dst.into_iter() + } +} + +// + +fn test_objects_gen() -> Vec< TestObject > +{ + + vec! + [ + 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 + } + ] + ), + }, + ] + +} + +// + +#[ test ] +fn table_to_string() +// where + // for< 'a > AsTable< 'a, Vec< TestObject >, usize, TestObject, &'static str, String, &'static str > : TableFormatter< 'a >, +{ + use the_module::TableToString; + let test_objects = test_objects_gen(); + + let cells = Cells::< &'static str, WithRef >::cells( &test_objects[ 0 ] ); + assert_eq!( cells.len(), 4 ); + let cells = Cells::< &'static str, WithRef >::cells( &test_objects[ 1 ] ); + assert_eq!( cells.len(), 4 ); + drop( cells ); + + let as_table : AsTable< '_, Vec< TestObject >, usize, TestObject, &str, WithRef > = AsTable::new( &test_objects ); + let size = TableSize::mcells( &as_table ); + assert_eq!( size, [ 2, 4 ] ); + let rows = TableRows::rows( &as_table ); + assert_eq!( rows.len(), 2 ); + dbg!( rows.collect::< Vec< _ > >() ); + let header = TableHeader::header( &as_table ); + assert!( header.is_some() ); + let header = header.unwrap(); + assert_eq!( header.len(), 4 ); + assert_eq!( header.clone().collect::< Vec< _ > >(), vec! + [ + ( "id", Cow::Owned( "id".to_string() ) ), + ( "created_at", Cow::Owned( "created_at".to_string() ) ), + ( "file_ids", Cow::Owned( "file_ids".to_string() ) ), + ( "tools", Cow::Owned( "tools".to_string() ) ) + ]); + dbg!( header.collect::< Vec< _ > >() ); + + let mut output = String::new(); + let mut context = Context::new( &mut output, Default::default() ); + let got = the_module::TableFormatter::fmt( &as_table, &mut context ); + assert!( got.is_ok() ); + println!( "{}", &output ); + + // with explicit arguments + + let as_table : AsTable< '_, Vec< TestObject >, usize, TestObject, &str, WithRef > = 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" ) ); + + // 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!( "{table_string}" ); + +} + +#[ test ] +fn custom_formatter() +{ + // use the_module::TableToString; + let test_objects = test_objects_gen(); + + let mut output = String::new(); + let mut formatter = the_module::Styles::default(); + formatter.cell_separator = " | ".into(); + formatter.row_prefix = "> ".into(); + formatter.row_postfix = " <".into(); + + let as_table = AsTable::new( &test_objects ); + let mut context = Context::new( &mut output, formatter ); + let got = the_module::TableFormatter::fmt( &as_table, &mut context ); + assert!( got.is_ok() ); + // let table_string = got.unwrap(); + + assert!( output.contains( "id" ) ); + assert!( output.contains( "created_at" ) ); + assert!( output.contains( "file_ids" ) ); + assert!( output.contains( "tools" ) ); + println!( "{output}" ); + +} + +// xxx diff --git a/module/core/format_tools/tests/inc/string_test.rs b/module/core/format_tools/tests/inc/string_test.rs new file mode 100644 index 0000000000..044cdc4b91 --- /dev/null +++ b/module/core/format_tools/tests/inc/string_test.rs @@ -0,0 +1,144 @@ +#[ allow( unused_imports ) ] +use super::*; + +#[ test ] +fn empty_string() +{ + use the_module::string; + let input = ""; + let exp = [ 0, 1 ]; + let got = string::size( input ); + assert_eq!( got, exp ); +} + +#[ test ] +fn single_line_no_newline() +{ + use the_module::string; + + let input = "Hello, World!"; + let exp = [ 13, 1 ]; + let got = string::size( input ); + assert_eq!( got, exp ); + + let input = "[\"file1\", \"file2\"]"; + let exp = [ 18, 1 ]; + let got = string::size( input ); + assert_eq!( got, exp ); + +} + +#[ test ] +fn single_line_with_newline() +{ + use the_module::string; + let input = "Hello, World!\n"; + let exp = [ 13, 2 ]; + let got = string::size( input ); + assert_eq!( got, exp ); +} + +#[ test ] +fn multiple_lines_varying_lengths() +{ + use the_module::string; + let input = "Hello\nWorld!\nThis is a test."; + let exp = [ 15, 3 ]; + let got = string::size( input ); + assert_eq!( got, exp ); +} + +#[ test ] +fn only_newlines() +{ + use the_module::string; + let input = "\n\n\n"; + let exp = [ 0, 4 ]; + let got = string::size( input ); + assert_eq!( got, exp ); +} + +#[ test ] +fn very_long_lines() +{ + use the_module::string; + let input = "a".repeat( 1000 ); + let exp = [ 1000, 1 ]; + let got = string::size( input ); + assert_eq!( got, exp ); +} + +#[ test ] +fn special_characters_whitespace() +{ + use the_module::string; + let input = " \t\n \t\n"; + let exp = [ 2, 3 ]; + let got = string::size( input ); + assert_eq!( got, exp ); +} + +#[ test ] +fn assumption_str_lines_skip_the_last_line() +{ + + let src = "abc"; + let got : Vec< &str > = src.lines().collect(); + let exp = vec![ "abc" ]; + assert_eq!( got, exp ); + + let src = ""; + let got : Vec< &str > = src.lines().collect(); + let exp : Vec< &str > = vec![]; + // let exp = vec![ "" ]; // should be + assert_eq!( got, exp ); + + let src = "\n"; + let got : Vec< &str > = src.lines().collect(); + let exp = vec![ "" ]; + // let exp = vec![ "", "" ]; // should be + assert_eq!( got, exp ); + + let src = "a\nb"; + let got : Vec< &str > = src.lines().collect(); + let exp = vec![ "a", "b" ]; + assert_eq!( got, exp ); + + let src = "\na\nb\n"; + let got : Vec< &str > = src.lines().collect(); + let exp = vec![ "", "a", "b" ]; + // let exp = vec![ "", "a", "b", "" ]; should be + assert_eq!( got, exp ); + +} + +#[ test ] +fn lines_basic() +{ + use the_module::string; + + let src = "abc"; + let got : Vec< &str > = string::lines( src ).collect(); + let exp = vec![ "abc" ]; + assert_eq!( got, exp ); + + let src = ""; + let got : Vec< &str > = string::lines( src ).collect(); + let exp = vec![ "" ]; + assert_eq!( got, exp ); + + let src = "\n"; + let got : Vec< &str > = string::lines( src ).collect(); + let exp = vec![ "", "" ]; + assert_eq!( got, exp ); + + let src = "a\nb"; + let got : Vec< &str > = string::lines( src ).collect(); + let exp = vec![ "a", "b" ]; + assert_eq!( got, exp ); + + let src = "\na\nb\n"; + let got : Vec< &str > = string::lines( src ).collect(); + let exp = vec![ "", "a", "b", "" ]; + assert_eq!( got, exp ); +} diff --git a/module/core/format_tools/tests/inc/to_string_test.rs b/module/core/format_tools/tests/inc/to_string_test.rs new file mode 100644 index 0000000000..de50c1a546 --- /dev/null +++ b/module/core/format_tools/tests/inc/to_string_test.rs @@ -0,0 +1,104 @@ +#[ allow( unused_imports ) ] +use super::*; + +use the_module:: +{ + ToStringWith, + WithDebug, + WithDisplay, +}; + +use std:: +{ + borrow::Cow, +}; + +// + +#[ test ] +fn to_string_with_test() +{ + + // - + + let src = 13i32; + let got = ToStringWith::< WithDebug >::to_string_with( &src ); + let exp = "13".to_string(); + a_id!( got, exp ); + + let src = "abc".to_string(); + let got = ToStringWith::< WithDebug >::to_string_with( &src ); + let exp = "\"abc\"".to_string(); + a_id!( got, exp ); + + // - + + let src = 13i32; + let got = ToStringWith::< WithDisplay >::to_string_with( &src ); + let exp = "13".to_string(); + a_id!( got, exp ); + + let src = "abc".to_string(); + let got = ToStringWith::< WithDisplay >::to_string_with( &src ); + let exp = "abc".to_string(); + a_id!( got, exp ); + + // - + +} + +// + +#[ test ] +fn borrowed() +{ + + let src = 13; + let got = ToStringWith::< WithDisplay >::to_string_with( &src ); + let exp : Cow< '_, str > = Cow::Owned( "13".to_string() ); + a_id!( got, exp ); + a_true!( matches!( got, Cow::Owned( _ ) ) ); + +} + +// + +#[ test ] +fn borrowed_str() +{ + use the_module::{ ToStringWith }; + + // let src = "str"; + // let got = to_string::Ref::< '_, str, WithDisplay >::from( src ).to_string_with(); + // let exp : Cow< '_, str > = Cow::Borrowed( "str" ); + // a_id!( got, exp ); + // a_true!( matches!( got, Cow::Borrowed( _ ) ) ); + + let src = "str"; + let got = ToStringWith::< WithDisplay >::to_string_with( &src ); + let exp : Cow< '_, str > = Cow::Borrowed( "str" ); + a_id!( got, exp ); + a_true!( !matches!( got, Cow::Borrowed( _ ) ) ); + +} + +// + +#[ test ] +fn borrowed_string() +{ + use the_module::{ ToStringWith }; + + // let src = "string".to_string(); + // let got = to_string::Ref::< '_, String, WithDisplay >::from( &src ).to_string_with(); + // let exp : Cow< '_, str > = Cow::Borrowed( "string" ); + // a_id!( got, exp ); + // a_true!( matches!( got, Cow::Borrowed( _ ) ) ); + + let src = "string".to_string(); + let got = ToStringWith::< WithDisplay >::to_string_with( &src ); + let exp : Cow< '_, str > = Cow::Borrowed( "string" ); + a_id!( got, exp ); + a_true!( !matches!( got, Cow::Borrowed( _ ) ) ); + +} diff --git a/module/core/format_tools/tests/inc/to_string_with_fallback_test.rs b/module/core/format_tools/tests/inc/to_string_with_fallback_test.rs new file mode 100644 index 0000000000..bd9947cd71 --- /dev/null +++ b/module/core/format_tools/tests/inc/to_string_with_fallback_test.rs @@ -0,0 +1,285 @@ +#[ allow( unused_imports ) ] +use super::*; + +use the_module:: +{ + ToStringWithFallback, + // ToStringWithFallbackParams, + WithRef, + WithDebug, + WithDisplay, + // the_module::to_string_with_fallback::Ref, + to_string_with_fallback, +}; + +use std:: +{ + // fmt, + // collections::HashMap, + borrow::Cow, +}; + +// + +#[ test ] +fn to_string_with_fallback_basic() +{ + + // - the_module::to_string_with_fallback::Ref should implement copy + + fn f1( _src : the_module::to_string_with_fallback::Ref::< '_, Struct1, WithDisplay, WithDebug, WithDebug > ) + where + for< 'a > the_module::to_string_with_fallback::Ref::< 'a, Struct1, WithDisplay, WithDebug, WithDebug > : Copy + Clone, + {} + + struct Struct1; + let src = Struct1; + let ref1 = the_module::to_string_with_fallback::Ref::< '_, _, WithDisplay, WithDebug, WithDebug >::from( &src ); + let ref2 = ref1; + f1( ref1 ); + f1( ref2 ); + + // - + + let src = 13i32; + let got = the_module::to_string_with_fallback::Ref::< '_, _, WithDisplay, WithDebug, WithDebug >::from( &src ).to_string_with_fallback(); + let exp = "13".to_string(); + a_id!( got, exp ); + + let src = "abc".to_string(); + let got = the_module::to_string_with_fallback::Ref::< '_, _, WithDisplay, WithDebug, WithDebug >::from( &src ).to_string_with_fallback(); + let exp = "abc".to_string(); + a_id!( got, exp ); + + // - + +} + +// + +#[ test ] +fn to_string_with_fallback_variants() +{ + + // - only display + + struct OnlyDisplay; + impl fmt::Display for OnlyDisplay + { + fn fmt( &self, f : &mut fmt::Formatter<'_> ) -> fmt::Result + { + write!( f, "This is display" ) + } + } + + let src = OnlyDisplay; + let got = the_module::to_string_with_fallback::Ref::< '_, _, WithDisplay, WithDebug, WithDebug >::from( &src ).to_string_with_fallback(); + let exp = "This is display".to_string(); + a_id!( got, exp ); + + // - only debug + + struct OnlyDebug; + + impl fmt::Debug for OnlyDebug + { + fn fmt( &self, f : &mut fmt::Formatter<'_> ) -> fmt::Result + { + write!( f, "This is debug" ) + } + } + + let src = OnlyDebug; + let _ref1 = the_module::to_string_with_fallback::Ref::< '_, _, WithDisplay, WithDebug, WithDebug >::from( &src ); + + let src = OnlyDebug; + let got = the_module::to_string_with_fallback::Ref::< '_, _, WithDisplay, WithDebug, WithDebug >::from( &src ).to_string_with_fallback(); + let exp = "This is debug".to_string(); + a_id!( got, exp ); + + let src = OnlyDebug; + let got = the_module::to_string_with_fallback::Ref::< '_, _, WithDebug, WithDisplay, WithDisplay >::from( &src ).to_string_with_fallback(); + let exp = "This is debug".to_string(); + a_id!( got, exp ); + + // - both debug and display + + struct Both; + + impl fmt::Debug for Both + { + fn fmt( &self, f : &mut fmt::Formatter<'_> ) -> fmt::Result + { + write!( f, "This is debug" ) + } + } + + impl fmt::Display for Both + { + fn fmt( &self, f : &mut fmt::Formatter<'_> ) -> fmt::Result + { + write!( f, "This is display" ) + } + } + + let src = Both; + let got = the_module::to_string_with_fallback::Ref::< '_, _, WithDisplay, WithDebug, WithDebug >::from( &src ).to_string_with_fallback(); + let exp = "This is display".to_string(); + a_id!( got, exp ); + + let src = Both; + let got = the_module::to_string_with_fallback::Ref::< '_, _, WithDebug, WithDisplay, WithDisplay >::from( &src ).to_string_with_fallback(); + let exp = "This is debug".to_string(); + a_id!( got, exp ); + + // - + +} + +// + +#[ test ] +fn to_string_with_fallback_macro() +{ + + // - only debug + + struct OnlyDebug; + + impl fmt::Debug for OnlyDebug + { + fn fmt( &self, f : &mut fmt::Formatter<'_> ) -> fmt::Result + { + write!( f, "This is debug" ) + } + } + + let src = OnlyDebug; + let got = to_string_with_fallback!( WithDisplay, WithDebug, &src ); + let exp = "This is debug".to_string(); + a_id!( got, exp ); + + let src = OnlyDebug; + let got = to_string_with_fallback!( WithDebug, WithDisplay, &src ); + let exp = "This is debug".to_string(); + a_id!( got, exp ); + + // - both debug and display + + struct Both; + + impl fmt::Debug for Both + { + fn fmt( &self, f : &mut fmt::Formatter<'_> ) -> fmt::Result + { + write!( f, "This is debug" ) + } + } + + impl fmt::Display for Both + { + fn fmt( &self, f : &mut fmt::Formatter<'_> ) -> fmt::Result + { + write!( f, "This is display" ) + } + } + + let src = Both; + let got = to_string_with_fallback!( WithDisplay, WithDebug, &src ); + let exp = "This is display".to_string(); + a_id!( got, exp ); + + let src = Both; + let got = to_string_with_fallback!( WithDebug, WithDisplay, &src ); + let exp = "This is debug".to_string(); + a_id!( got, exp ); + +} + +// + +#[ test ] +fn display_is_not_implemented() +{ + + let src = vec![ 1, 2, 3 ]; + let got = the_module + ::to_string_with_fallback + ::Ref + ::< '_, _, WithDisplay, WithDisplay, WithDebug > + ::from( &src ) + .to_string_with_fallback(); + let exp : Cow< '_, String > = Cow::Owned( "[1, 2, 3]".to_string() ); + a_id!( got, exp ); + + let src = vec![ 1, 2, 3 ]; + let got = to_string_with_fallback!( WithDisplay, WithDebug, &src ); + let exp : Cow< '_, String > = Cow::Owned( "[1, 2, 3]".to_string() ); + a_id!( got, exp ); + +} + +// + +// #[ test ] +// fn borrowed_str() +// { +// use the_module::{ to_string, ToStringWith }; +// +// let src = "str"; +// let got = to_string::Ref::< '_, str, WithDisplay >::from( src ).to_string_with(); +// let exp : Cow< '_, str > = Cow::Borrowed( "str" ); +// a_id!( got, exp ); +// a_true!( matches!( got, Cow::Borrowed( _ ) ) ); +// +// let src = "str"; +// let got = ToStringWith::< WithDisplay >::to_string_with( &src ); +// let exp : Cow< '_, str > = Cow::Borrowed( "str" ); +// a_id!( got, exp ); +// a_true!( !matches!( got, Cow::Borrowed( _ ) ) ); +// +// } + +// + +#[ test ] +fn borrowed_str() +{ + // use the_module::{ to_string, ToStringWith }; + + let src = "str"; + let got = format_tools::to_string_with_fallback!( WithRef, WithDisplay, WithDebug, &src ); + let exp : Cow< '_, str > = Cow::Borrowed( "str" ); + a_id!( got, exp ); + a_true!( matches!( got, Cow::Borrowed( _ ) ) ); + + let src = "str"; + let got = format_tools::to_string_with_fallback!( WithDebug, WithDisplay, &src ); + let exp : Cow< '_, str > = Cow::Owned( "\"str\"".to_string() ); + a_id!( got, exp ); + a_true!( matches!( got, Cow::Owned( _ ) ) ); + +} + +// + +#[ test ] +fn borrowed_string() +{ + // use the_module::{ to_string, ToStringWith }; + + let src = "string".to_string(); + let got = format_tools::to_string_with_fallback!( WithRef, WithDisplay, WithDebug, &src ); + let exp : Cow< '_, str > = Cow::Borrowed( "string" ); + a_id!( got, exp ); + a_true!( matches!( got, Cow::Borrowed( _ ) ) ); + + let src = "string".to_string(); + let got = format_tools::to_string_with_fallback!( WithDebug, WithDisplay, &src ); + let exp : Cow< '_, str > = Cow::Owned( "\"string\"".to_string() ); + a_id!( got, exp ); + a_true!( matches!( got, Cow::Owned( _ ) ) ); + +} + +// diff --git a/module/core/format_tools/tests/smoke_test.rs b/module/core/format_tools/tests/smoke_test.rs new file mode 100644 index 0000000000..828e9b016b --- /dev/null +++ b/module/core/format_tools/tests/smoke_test.rs @@ -0,0 +1,14 @@ + + +#[ test ] +fn local_smoke_test() +{ + ::test_tools::smoke_test_for_local_run(); +} + + +#[ test ] +fn published_smoke_test() +{ + ::test_tools::smoke_test_for_published_run(); +} diff --git a/module/core/format_tools/tests/tests.rs b/module/core/format_tools/tests/tests.rs new file mode 100644 index 0000000000..eae1668ea0 --- /dev/null +++ b/module/core/format_tools/tests/tests.rs @@ -0,0 +1,10 @@ +// #![ feature( trace_macros ) ] + +#[ allow( unused_imports ) ] +use format_tools as the_module; +#[ allow( unused_imports ) ] +use test_tools::exposed::*; + +#[ cfg( feature = "enabled" ) ] +mod inc; + diff --git a/module/core/former/Cargo.toml b/module/core/former/Cargo.toml index 746331fb21..660e4977d2 100644 --- a/module/core/former/Cargo.toml +++ b/module/core/former/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "former" -version = "2.2.0" +version = "2.7.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", @@ -12,7 +12,7 @@ documentation = "https://docs.rs/former" repository = "https://github.com/Wandalen/wTools/tree/master/module/core/former" homepage = "https://github.com/Wandalen/wTools/tree/master/module/core/former" description = """ -A flexible and extensible implementation of the builder pattern. +A flexible implementation of the Builder pattern supporting nested builders and collection-specific subformers. """ categories = [ "algorithms", "development-tools" ] keywords = [ "fundamental", "general-purpose", "builder-pattern" ] @@ -29,7 +29,6 @@ all-features = false no_std = [ "former_types/no_std", "collection_tools/no_std" ] use_alloc = [ "no_std", "former_types/use_alloc", "collection_tools/use_alloc" ] - # no_std = [ "collection_tools/no_std" ] # use_alloc = [ "no_std", "collection_tools/use_alloc" ] @@ -41,25 +40,23 @@ default = [ "derive_component_assign", "derive_components_assign", "derive_from_components", + "types_former", + "types_component_assign", ] full = [ - "enabled", - "derive_former", - "derive_components", - "derive_component_from", - "derive_component_assign", - "derive_components_assign", - "derive_from_components", + "default", ] enabled = [ "former_meta/enabled", "former_types/enabled" ] -derive_former = [ "former_meta/derive_former", "former_types/derive_former" ] -derive_components = [ "former_meta/derive_components", "former_types/types_components" ] -derive_component_assign = [ "derive_components", "former_meta/derive_component_assign", "former_types/types_component_assign" ] -derive_components_assign = [ "derive_components", "derive_component_assign", "former_meta/derive_components_assign" ] -derive_component_from = [ "derive_components", "former_meta/derive_component_from" ] -derive_from_components = [ "derive_components", "former_meta/derive_from_components" ] +derive_former = [ "former_meta/derive_former", "types_former" ] +derive_components = [ "former_meta/derive_components", "derive_component_assign", "derive_components_assign", "derive_component_from", "derive_from_components" ] +derive_component_assign = [ "former_meta/derive_component_assign", "types_component_assign" ] +derive_components_assign = [ "derive_component_assign", "former_meta/derive_components_assign" ] +derive_component_from = [ "former_meta/derive_component_from" ] +derive_from_components = [ "former_meta/derive_from_components" ] +types_former = [ "former_types/types_former" ] +types_component_assign = [ "former_types/types_component_assign" ] [dependencies] former_meta = { workspace = true } diff --git a/module/core/former/Readme.md b/module/core/former/Readme.md index 05852dba11..d36ce4b061 100644 --- a/module/core/former/Readme.md +++ b/module/core/former/Readme.md @@ -5,19 +5,29 @@ [![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) [![rust-status](https://github.com/Wandalen/wTools/actions/workflows/module_former_push.yml/badge.svg)](https://github.com/Wandalen/wTools/actions/workflows/module_former_push.yml) [![docs.rs](https://img.shields.io/docsrs/former?color=e3e8f0&logo=docs.rs)](https://docs.rs/former) [![Open in Gitpod](https://raster.shields.io/static/v1?label=try&message=online&color=eee&logo=gitpod&logoColor=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=module%2Fcore%2Fformer%2Fexamples%2Fformer_trivial.rs,RUN_POSTFIX=--example%20former_trivial/https://github.com/Wandalen/wTools) [![discord](https://img.shields.io/discord/872391416519737405?color=eee&logo=discord&logoColor=eee&label=ask)](https://discord.gg/m3YfbXpUUY) -A flexible and extensible implementation of the builder pattern. +A flexible implementation of the Builder pattern supporting nested builders and collection-specific subformers. -It offers specialized subformers for common Rust collections like `Vec`, `HashMap`, and `HashSet`, enabling the construction of complex data structures in a fluent and intuitive manner. +The Builder pattern allows you to construct objects step by step, using only the steps you need. Any fields not explicitly set will receive default values. By implementing this pattern, you can avoid passing numerous parameters into your constructors. + +This crate offers specialized subformers for common Rust collections, enabling the construction of complex data structures in a fluent and intuitive manner. Additionally, it provides the ability to define and reuse formers as subformers within other formers. ## How Former Works -- **Trait Derivation** : By deriving `Former` on a struct, you automatically generate builder methods for each field. -- **Fluent Interface** : Each field's builder method allows for setting the value of that field and returns a mutable reference to the builder, - enabling method chaining. -- **Optional Fields** : Optional fields can be easily handled without needing to explicitly set them to `None`. -- **Finalization** : The `.form()` method finalizes the building process and returns the constructed struct instance. +- **Derivation**: By deriving `Former` on a struct, you automatically generate builder methods for each field. +- **Fluent Interface**: Each field's builder method allows for setting the value of that field and returns a mutable reference to the builder, enabling method chaining. +- **Optional Fields**: Optional fields can be easily handled without needing to explicitly set them to `None`. +- **Finalization**: The `.form()` method finalizes the building process and returns the constructed struct instance. +- **Subforming**: If a field has its own former defined or is a container of items for which a former is defined, it can be used as a subformer. + +This approach abstracts away the need for manually implementing a builder for each struct, making the code more readable and maintainable. + +## Comparison + +The Former crate and the abstract Builder pattern concept share a common goal: to construct complex objects step-by-step, ensuring they are always in a valid state and hiding internal structures. Both use a fluent interface for setting fields and support default values for fields that aren't explicitly set. They also have a finalization method to return the constructed object (.form() in Former, build() in [traditional Builder](https://refactoring.guru/design-patterns/builder)). + +However, the Former crate extends the traditional Builder pattern by automating the generation of builder methods using macros. This eliminates the need for manual implementation, which is often required in the abstract concept. Additionally, Former supports nested builders and subformers for complex data structures, allowing for more sophisticated object construction. -This approach abstracts away the need for manually implementing a builder for each struct, making code more readable and maintainable. +Advanced features such as custom setters, subformer reuse, storage-specific fields, mutators, and context management further differentiate Former from the [traditional approach](https://refactoring.guru/design-patterns/builder), which generally focuses on simpler use-cases without these capabilities. Moreover, while the traditional Builder pattern often includes a director class to manage the construction process, Former is not responsible for that aspect. ## Example : Trivial @@ -28,7 +38,7 @@ This approach abstracts away the need for manually implementing a builder for ea -The provided code snippet illustrates a basic use-case of the Former, which is used to apply the builder pattern for structured and flexible object creation. Below is a detailed explanation of each part of the markdown chapter, aimed at clarifying how the Former trait simplifies struct instantiation. +The provided code snippet illustrates a basic use-case of the Former, which is used to apply the builder pattern for to construct complex objects step-by-step, ensuring they are always in a valid state and hiding internal structures. ```rust # #[ cfg( any( not( feature = "derive_former" ), not( feature = "enabled" ) ) ) ] @@ -674,7 +684,7 @@ These setters ensure that developers can precisely and efficiently set propertie ## Example : Collection Setter for a Vector -This example demonstrates how to employ the `Former` trait to configure a `Vec` using a collection setter in a structured manner. +This example demonstrates how to employ the `Former` to configure a `Vec` using a collection setter in a structured manner. ```rust # #[ cfg( not( all( feature = "enabled", feature = "derive_former", any( feature = "use_alloc", not( feature = "no_std" ) ) ) ) ) ] @@ -710,7 +720,7 @@ Try out `cargo run --example former_collection_vector`. ## Example : Collection Setter for a Hashmap -This example demonstrates how to effectively employ the `Former` trait to configure a `HashMap` using a collection setter. +This example demonstrates how to effectively employ the `Former` to configure a `HashMap` using a collection setter. ```rust # #[ cfg( not( all( feature = "enabled", feature = "derive_former", any( feature = "use_alloc", not( feature = "no_std" ) ) ) ) ) ] @@ -747,7 +757,7 @@ Try out `cargo run --example former_collection_hashmap`. ## Example : Collection Setter for a Hashset -This example demonstrates the use of the `Former` trait to build a `collection_tools::HashSet` through subforming. +This example demonstrates the use of the `Former` to build a `collection_tools::HashSet` through subforming. ```rust # #[ cfg( not( all( feature = "enabled", feature = "derive_former", any( feature = "use_alloc", not( feature = "no_std" ) ) ) ) ) ] @@ -784,7 +794,7 @@ Try out `cargo run --example former_collection_hashset`. ## Example : Custom Scalar Setter -This example demonstrates the implementation of a scalar setter using the `Former` trait. Unlike the more complex subform and collection setters shown in previous examples, this example focuses on a straightforward approach to directly set a scalar value within a parent entity. The `Parent` struct manages a `HashMap` of `Child` entities, and the scalar setter is used to set the entire `HashMap` directly. +This example demonstrates the implementation of a scalar setter using the `Former`. Unlike the more complex subform and collection setters shown in previous examples, this example focuses on a straightforward approach to directly set a scalar value within a parent entity. The `Parent` struct manages a `HashMap` of `Child` entities, and the scalar setter is used to set the entire `HashMap` directly. The `child` function within `ParentFormer` is a custom subform setter that plays a crucial role. It uniquely employs the `ChildFormer` to add and configure children by their names within the parent's builder pattern. This method demonstrates a powerful technique for integrating subformers that manage specific elements of a collection—each child entity in this case. @@ -870,7 +880,7 @@ Try out `cargo run --example former_custom_scalar_setter`. ## Example : Custom Subform Scalar Setter -Implementation of a custom subform scalar setter using the `Former` trait in Rust. +Implementation of a custom subform scalar setter using the `Former`. This example focuses on the usage of a subform scalar setter to manage complex scalar types within a parent structure. Unlike more general subform setters that handle collections, this setter specifically configures scalar fields that have @@ -945,7 +955,7 @@ their own formers, allowing for detailed configuration within a nested builder p ## Example : Custom Subform Collection Setter -This example demonstrates the use of collection setters to manage complex nested data structures with the `Former` trait, focusing on a parent-child relationship structured around a collection `HashMap`. Unlike typical builder patterns that add individual elements using subform setters, this example uses a collection setter to manage the entire collection of children. +This example demonstrates the use of collection setters to manage complex nested data structures with the `Former`, focusing on a parent-child relationship structured around a collection `HashMap`. Unlike typical builder patterns that add individual elements using subform setters, this example uses a collection setter to manage the entire collection of children. The `child` function within `ParentFormer` is a custom subform setter that plays a crucial role. It uniquely employs the `ChildFormer` to add and configure children by their names within the parent's builder pattern. This method demonstrates a powerful technique for integrating subformers that manage specific elements of a collection—each child entity in this case. @@ -1026,7 +1036,7 @@ Try out `cargo run --example former_custom_subform_collection`. ## Example : Custom Subform Entry Setter -This example illustrates the implementation of nested builder patterns using the `Former` trait, emphasizing a parent-child relationship. Here, the `Parent` struct utilizes `ChildFormer` as a custom subformer to dynamically manage its `child` field—a `HashMap`. Each child in the `HashMap` is uniquely identified and configured via the `ChildFormer`. +This example illustrates the implementation of nested builder patterns using the `Former`, emphasizing a parent-child relationship. Here, the `Parent` struct utilizes `ChildFormer` as a custom subformer to dynamically manage its `child` field—a `HashMap`. Each child in the `HashMap` is uniquely identified and configured via the `ChildFormer`. The `child` function within `ParentFormer` is a custom subform setter that plays a crucial role. It uniquely employs the `ChildFormer` to add and configure children by their names within the parent's builder pattern. This method demonstrates a powerful technique for integrating subformers that manage specific elements of a collection—each child entity in this case. @@ -1224,7 +1234,7 @@ held within the storage. assert_eq!( got, exp ); dbg!( got ); // > got = Struct1 { - // > c: "13 - abc", + // > c : "13 - abc", // > } # } @@ -1246,7 +1256,7 @@ Two key definition Traits: - Building upon `FormerDefinitionTypes`, this trait incorporates the `FormingEnd` callback, linking the formation types with a definitive ending. It specifies how the formation process should conclude, which may involve validations, transformations, or integrations into larger structures. - The inclusion of the `End` type parameter specifies the end conditions of the formation process, effectively connecting the temporary state held in storage to its ultimate form. -## Overview of Formation Traits +## Overview of Formation Traits System The formation process utilizes several core traits, each serving a specific purpose in the lifecycle of entity creation. These traits ensure that entities are constructed methodically, adhering to a structured pattern that enhances maintainability and scalability. Below is a summary of these key traits: diff --git a/module/core/former/examples/former_collection_hashmap.rs b/module/core/former/examples/former_collection_hashmap.rs index 93b7ea3526..81380c81f3 100644 --- a/module/core/former/examples/former_collection_hashmap.rs +++ b/module/core/former/examples/former_collection_hashmap.rs @@ -1,5 +1,5 @@ //! -//! This example demonstrates how to effectively employ the `Former` trait to configure a `HashMap` using a collection setter. +//! This example demonstrates how to effectively employ the `Former` to configure a `HashMap` using a collection setter. //! #[ cfg( not( all( feature = "enabled", feature = "derive_former", any( feature = "use_alloc", not( feature = "no_std" ) ) ) ) ) ] diff --git a/module/core/former/examples/former_collection_hashset.rs b/module/core/former/examples/former_collection_hashset.rs index 81c81f604f..1eda3a38e8 100644 --- a/module/core/former/examples/former_collection_hashset.rs +++ b/module/core/former/examples/former_collection_hashset.rs @@ -1,5 +1,5 @@ //! -//! This example demonstrates the use of the `Former` trait to build a `collection_tools::HashSet` through subforming. +//! This example demonstrates the use of the `Former` to build a `collection_tools::HashSet` through subforming. //! #[ cfg( not( all( feature = "enabled", feature = "derive_former", any( feature = "use_alloc", not( feature = "no_std" ) ) ) ) ) ] diff --git a/module/core/former/examples/former_collection_vector.rs b/module/core/former/examples/former_collection_vector.rs index b51b4fa378..cb8ff724d7 100644 --- a/module/core/former/examples/former_collection_vector.rs +++ b/module/core/former/examples/former_collection_vector.rs @@ -1,5 +1,5 @@ //! -//! This example demonstrates how to employ the `Former` trait to configure a `Vec` using a collection setter in a structured manner. +//! This example demonstrates how to employ the `Former` to configure a `Vec` using a collection setter in a structured manner. //! #[ cfg( not( all( feature = "enabled", feature = "derive_former", any( feature = "use_alloc", not( feature = "no_std" ) ) ) ) ) ] diff --git a/module/core/former/examples/former_custom_mutator.rs b/module/core/former/examples/former_custom_mutator.rs index e70323e588..af2956c29e 100644 --- a/module/core/former/examples/former_custom_mutator.rs +++ b/module/core/former/examples/former_custom_mutator.rs @@ -70,7 +70,7 @@ fn main() assert_eq!( got, exp ); dbg!( got ); // > got = Struct1 { - // > c: "13 - abc", + // > c : "13 - abc", // > } } diff --git a/module/core/former/examples/former_custom_scalar_setter.rs b/module/core/former/examples/former_custom_scalar_setter.rs index 753adcc618..13a90a4fef 100644 --- a/module/core/former/examples/former_custom_scalar_setter.rs +++ b/module/core/former/examples/former_custom_scalar_setter.rs @@ -2,7 +2,7 @@ //! ## Example : Custom Scalar Setter //! -//! Use of a scalar setter within a `Former` trait implementation to directly assign a `HashMap` of `Child` entities to a `Parent` structure using a custom setter function. +//! Use of a scalar setter within a `Former` implementation to directly assign a `HashMap` of `Child` entities to a `Parent` structure using a custom setter function. //! //! Unlike the more complex subform and collection setters shown in previous examples, this example focuses on a straightforward approach to directly set a scalar value within a parent entity. The `Parent` struct manages a `HashMap` of `Child` entities, and the scalar setter is used to set the entire `HashMap` directly. The `child` function within `ParentFormer` is a custom subform setter that plays a crucial role. It uniquely employs the `ChildFormer` to add and configure children by their names within the parent's builder pattern. This method demonstrates a powerful technique for integrating subformers that manage specific elements of a collection—each child entity in this case. //! diff --git a/module/core/former/examples/former_custom_subform_collection.rs b/module/core/former/examples/former_custom_subform_collection.rs index f0de7350a0..e2012c04f8 100644 --- a/module/core/former/examples/former_custom_subform_collection.rs +++ b/module/core/former/examples/former_custom_subform_collection.rs @@ -3,7 +3,7 @@ //! //! ## Example : Custom Subform Collection Setter //! -//! This example demonstrates the use of collection setters to manage complex nested data structures with the `Former` trait, focusing on a parent-child relationship structured around a collection `HashMap`. Unlike typical builder patterns that add individual elements using subform setters, this example uses a collection setter to manage the entire collection of children. +//! This example demonstrates the use of collection setters to manage complex nested data structures with the `Former`, focusing on a parent-child relationship structured around a collection `HashMap`. Unlike typical builder patterns that add individual elements using subform setters, this example uses a collection setter to manage the entire collection of children. //! //! The `child` function within `ParentFormer` is a custom subform setter that plays a crucial role. It uniquely employs the `ChildFormer` to add and configure children by their names within the parent's builder pattern. This method demonstrates a powerful technique for integrating subformers that manage specific elements of a collection—each child entity in this case. //! diff --git a/module/core/former/examples/former_custom_subform_entry.rs b/module/core/former/examples/former_custom_subform_entry.rs index e046434da8..5b70161373 100644 --- a/module/core/former/examples/former_custom_subform_entry.rs +++ b/module/core/former/examples/former_custom_subform_entry.rs @@ -2,7 +2,7 @@ //! ## Example : Custom Subform Entry Setter //! -//! This example illustrates the implementation of nested builder patterns using the `Former` trait, emphasizing a parent-child relationship. Here, the `Parent` struct utilizes `ChildFormer` as a custom subformer to dynamically manage its `child` field—a `HashMap`. Each child in the `HashMap` is uniquely identified and configured via the `ChildFormer`. +//! This example illustrates the implementation of nested builder patterns using the `Former`, emphasizing a parent-child relationship. Here, the `Parent` struct utilizes `ChildFormer` as a custom subformer to dynamically manage its `child` field—a `HashMap`. Each child in the `HashMap` is uniquely identified and configured via the `ChildFormer`. //! //! The `child` function within `ParentFormer` is a custom subform setter that plays a crucial role. It uniquely employs the `ChildFormer` to add and configure children by their names within the parent's builder pattern. This method demonstrates a powerful technique for integrating subformers that manage specific elements of a collection—each child entity in this case. //! diff --git a/module/core/former/examples/former_custom_subform_entry2.rs b/module/core/former/examples/former_custom_subform_entry2.rs index c4592ee34f..b8199fb36c 100644 --- a/module/core/former/examples/former_custom_subform_entry2.rs +++ b/module/core/former/examples/former_custom_subform_entry2.rs @@ -1,7 +1,7 @@ // Example former_custom_subformer2.rs //! -//! This example extends the demonstration of nested builder patterns using the `Former` trait, highlighting a parent-child relationship similar to the `former_custom_subformer.rs`. However, this variant, `former_custom_subformer2.rs`, showcases a more flexible but complex approach to managing the `child` field in the `Parent` struct—a `HashMap` of `Child` entities. Instead of relying on a predefined subformer setter (`_child_subform_entry`), this example constructs the subformer logic directly using closures. This method provides greater control over how children are added and managed within the `Parent`. +//! This example extends the demonstration of nested builder patterns using the `Former`, highlighting a parent-child relationship similar to the `former_custom_subformer.rs`. However, this variant, `former_custom_subformer2.rs`, showcases a more flexible but complex approach to managing the `child` field in the `Parent` struct—a `HashMap` of `Child` entities. Instead of relying on a predefined subformer setter (`_child_subform_entry`), this example constructs the subformer logic directly using closures. This method provides greater control over how children are added and managed within the `Parent`. //! //! #### Custom Subform Setter //! diff --git a/module/core/former/examples/former_custom_subform_scalar.rs b/module/core/former/examples/former_custom_subform_scalar.rs index 7bb0eb97cd..436cbea3e9 100644 --- a/module/core/former/examples/former_custom_subform_scalar.rs +++ b/module/core/former/examples/former_custom_subform_scalar.rs @@ -3,7 +3,7 @@ //! //! ## Example : Custom Subform Scalar Setter //! -//! Implementation of a custom subform scalar setter using the `Former` trait in Rust. +//! Implementation of a custom subform scalar setter using the `Former`. //! //! This example focuses on the usage of a subform scalar setter to manage complex scalar types within a parent structure. //! Unlike more general subform setters that handle collections, this setter specifically configures scalar fields that have diff --git a/module/core/former/examples/former_trivial.rs b/module/core/former/examples/former_trivial.rs index b330278f68..3d19f12dd6 100644 --- a/module/core/former/examples/former_trivial.rs +++ b/module/core/former/examples/former_trivial.rs @@ -1,19 +1,6 @@ -//! # Builder Pattern Implementation with Former +//! ## Example : Trivial //! -//! This module demonstrates the use of the `Former` trait to apply the builder pattern for Rust structs. -//! The `Former` trait simplifies the instantiation of structs by enabling a fluent, method-chaining approach -//! to set fields before finalizing the instance with `.form()`. It is particularly useful for structs with optional fields -//! or when a clear and concise way to instantiate complex data structures is needed. -//! -//! ## How Former Works -//! -//! - **Trait Derivation** : By deriving `Former` on a struct, you automatically generate builder methods for each field. -//! - **Fluent Interface** : Each field's builder method allows for setting the value of that field and returns a mutable reference to the builder, -//! enabling method chaining. -//! - **Optional Fields** : Optional fields can be easily handled without needing to explicitly set them to `None`. -//! - **Finalization** : The `.form()` method finalizes the building process and returns the constructed struct instance. -//! -//! This approach abstracts away the need for manually implementing a builder for each struct, making code more readable and maintainable. +//! The provided code snippet illustrates a basic use-case of the Former, which is used to apply the builder pattern for to construct complex objects step-by-step, ensuring they are always in a valid state and hiding internal structures. //! #[ cfg( any( not( feature = "derive_former" ), not( feature = "enabled" ) ) ) ] diff --git a/module/core/former/examples/former_trivial_expaned.rs b/module/core/former/examples/former_trivial_expaned.rs index 4968b11838..a2e557bedf 100644 --- a/module/core/former/examples/former_trivial_expaned.rs +++ b/module/core/former/examples/former_trivial_expaned.rs @@ -1,20 +1,10 @@ #![ allow( dead_code ) ] -//! # Builder Pattern Implementation with Former -//! -//! This module demonstrates the use of the `Former` trait to apply the builder pattern for Rust structs. -//! The `Former` trait simplifies the instantiation of structs by enabling a fluent, method-chaining approach -//! to set fields before finalizing the instance with `.form()`. It is particularly useful for structs with optional fields -//! or when a clear and concise way to instantiate complex data structures is needed. -//! -//! ## How Former Works + +//! ## Example : Trivial //! -//! - **Trait Derivation** : By deriving `Former` on a struct, you automatically generate builder methods for each field. -//! - **Fluent Interface** : Each field's builder method allows for setting the value of that field and returns a mutable reference to the builder, -//! enabling method chaining. -//! - **Optional Fields** : Optional fields can be easily handled without needing to explicitly set them to `None`. -//! - **Finalization** : The `.form()` method finalizes the building process and returns the constructed struct instance. +//! The provided code snippet illustrates a basic use-case of the Former, which is used to apply the builder pattern for to construct complex objects step-by-step, ensuring they are always in a valid state and hiding internal structures. //! -//! This approach abstracts away the need for manually implementing a builder for each struct, making code more readable and maintainable. +//! It's generated by macros code. //! #[ cfg( any( not( feature = "derive_former" ), not( feature = "enabled" ) ) ) ] diff --git a/module/core/former/src/lib.rs b/module/core/former/src/lib.rs index 2eb4e674d2..635a8e85e0 100644 --- a/module/core/former/src/lib.rs +++ b/module/core/former/src/lib.rs @@ -4,34 +4,6 @@ #![ doc( html_root_url = "https://docs.rs/former/latest/former/" ) ] #![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/", "Readme.md" ) ) ] -// /// Axiomatic things. -// #[ cfg( feature = "enabled" ) ] -// #[ cfg( feature = "derive_former" ) ] -// mod axiomatic; -// /// Forming process. -// #[ cfg( feature = "enabled" ) ] -// #[ cfg( feature = "derive_former" ) ] -// mod definition; -// /// Forming process. -// #[ cfg( feature = "enabled" ) ] -// #[ cfg( feature = "derive_former" ) ] -// mod forming; -// /// Storage. -// #[ cfg( feature = "enabled" ) ] -// #[ cfg( feature = "derive_former" ) ] -// mod storage; -// -// /// Interface for collections. -// #[ cfg( feature = "enabled" ) ] -// #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] -// #[ cfg( feature = "derive_former" ) ] -// mod collection; -// -// /// Component-based forming. -// #[ cfg( feature = "enabled" ) ] -// #[ cfg( any( feature = "derive_component_from", feature = "derive_component_assign" ) ) ] -// mod component; - /// Namespace with dependencies. #[ cfg( feature = "enabled" ) ] pub mod dependency @@ -43,15 +15,16 @@ pub mod dependency #[ doc( inline ) ] #[ allow( unused_imports ) ] #[ cfg( feature = "enabled" ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. +/// Own namespace of the module. #[ cfg( feature = "enabled" ) ] -pub mod protected +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use former_meta as derive; @@ -59,21 +32,23 @@ pub mod protected /// Parented namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] @@ -83,34 +58,14 @@ pub mod exposed #[ allow( unused_imports ) ] pub use former_types::exposed::*; -// #[ doc( inline ) ] -// #[ allow( unused_imports ) ] -// #[ cfg( feature = "derive_former" ) ] -// pub use super:: -// { -// axiomatic::*, -// definition::*, -// forming::*, -// storage::*, -// }; -// -// #[ doc( inline ) ] -// #[ allow( unused_imports ) ] -// #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] -// #[ cfg( feature = "derive_former" ) ] -// pub use super::collection::*; - } /// Prelude to use essentials: `use my_module::prelude::*`. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod prelude { - - // #[ doc( inline ) ] - // #[ allow( unused_imports ) ] - // #[ cfg( any( feature = "derive_component_from", feature = "derive_component_assign" ) ) ] - // pub use super::component::*; + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] diff --git a/module/core/former/tests/inc/components_tests/component_assign.rs b/module/core/former/tests/inc/components_tests/component_assign.rs index 546cb3852b..cf02ef8935 100644 --- a/module/core/former/tests/inc/components_tests/component_assign.rs +++ b/module/core/former/tests/inc/components_tests/component_assign.rs @@ -3,6 +3,7 @@ use super::*; #[ allow( unused_imports ) ] use former::Assign; +// #[ derive( Default, PartialEq, Debug, former::Assign ) ] // #[ debug ] diff --git a/module/core/former/tests/inc/components_tests/only_test/component_assign.rs b/module/core/former/tests/inc/components_tests/only_test/component_assign.rs index 0adb4ed674..0da82e46a7 100644 --- a/module/core/former/tests/inc/components_tests/only_test/component_assign.rs +++ b/module/core/former/tests/inc/components_tests/only_test/component_assign.rs @@ -9,4 +9,11 @@ fn component_assign() got.assign( "John" ); assert_eq!( got, Person { age : 13, name : "John".to_string() } ); + let mut got : Person = Default::default(); + got = got + .impute( 13 ) + .impute( "John" ) + ; + assert_eq!( got, Person { age : 13, name : "John".to_string() } ); + } diff --git a/module/core/former/tests/inc/former_tests/name_collision_former_hashmap_without_parameter.rs b/module/core/former/tests/inc/former_tests/name_collision_former_hashmap_without_parameter.rs index 31df1f43e6..a1396f3ba2 100644 --- a/module/core/former/tests/inc/former_tests/name_collision_former_hashmap_without_parameter.rs +++ b/module/core/former/tests/inc/former_tests/name_collision_former_hashmap_without_parameter.rs @@ -1,3 +1,5 @@ +#![ allow( dead_code ) ] + use super::*; use the_module::Former; diff --git a/module/core/former/tests/inc/former_tests/name_collision_former_vector_without_parameter.rs b/module/core/former/tests/inc/former_tests/name_collision_former_vector_without_parameter.rs index c79d0e8ba3..605bf9f4f4 100644 --- a/module/core/former/tests/inc/former_tests/name_collision_former_vector_without_parameter.rs +++ b/module/core/former/tests/inc/former_tests/name_collision_former_vector_without_parameter.rs @@ -1,3 +1,5 @@ +#![ allow( dead_code ) ] + use super::*; use the_module::Former; diff --git a/module/core/former/tests/inc/former_tests/name_collisions.rs b/module/core/former/tests/inc/former_tests/name_collisions.rs index e23adcdd45..2dba7ce21f 100644 --- a/module/core/former/tests/inc/former_tests/name_collisions.rs +++ b/module/core/former/tests/inc/former_tests/name_collisions.rs @@ -1,3 +1,5 @@ +#![ allow( dead_code ) ] + #[ allow( unused_imports ) ] use super::*; diff --git a/module/core/former/tests/inc/former_tests/parametrized_slice_manual.rs b/module/core/former/tests/inc/former_tests/parametrized_slice_manual.rs index 6b9632f366..e0195c4433 100644 --- a/module/core/former/tests/inc/former_tests/parametrized_slice_manual.rs +++ b/module/core/former/tests/inc/former_tests/parametrized_slice_manual.rs @@ -122,20 +122,20 @@ impl< 'a > former::StoragePreform for Struct1FormerStorage< 'a > { trait MaybeDefault< T > { - fn maybe_default( self : & Self ) -> T + fn maybe_default( self : &Self ) -> T { panic!( "Field 'string_slice_1' isn't initialized" ) } } - impl< T > MaybeDefault< T > for & ::core::marker::PhantomData< T > {} + impl< T > MaybeDefault< T > for &::core::marker::PhantomData< T > {} impl< T > MaybeDefault< T > for ::core::marker::PhantomData< T > where T : ::core::default::Default, { - fn maybe_default( self : & Self ) -> T { T::default() } + fn maybe_default( self : &Self ) -> T { T::default() } } - (& ::core::marker::PhantomData::< &'a str >).maybe_default() + ( &::core::marker::PhantomData::< &'a str > ).maybe_default() } }; let result = Struct1 { string_slice_1, }; diff --git a/module/core/former/tests/smoke_test.rs b/module/core/former/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/core/former/tests/smoke_test.rs +++ b/module/core/former/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/core/former_meta/Cargo.toml b/module/core/former_meta/Cargo.toml index 3e865a04a8..aec58c6c0d 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.2.0" +version = "2.7.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", @@ -12,7 +12,7 @@ documentation = "https://docs.rs/former_meta" repository = "https://github.com/Wandalen/wTools/tree/master/module/core/former_meta" homepage = "https://github.com/Wandalen/wTools/tree/master/module/core/former_meta" description = """ -Former - a variation of builder pattern. Implementation of its derive macro. Should not be used independently, instead use module::former which relies on the module. +A flexible implementation of the Builder pattern supporting nested builders and collection-specific subformers. Implementation of its derive macro. Should not be used independently, instead use module::former which relies on the module. """ categories = [ "algorithms", "development-tools" ] keywords = [ "fundamental", "general-purpose", "builder-pattern" ] @@ -36,34 +36,25 @@ default = [ "derive_from_components", ] full = [ - "enabled", - "derive_former", - "derive_components", - "derive_component_from", - "derive_component_assign", - "derive_components_assign", - "derive_from_components", + "default", ] enabled = [ "macro_tools/enabled", "iter_tools/enabled", "former_types/enabled" ] derive_former = [ "convert_case" ] -derive_components = [] +derive_components = [ "derive_component_assign", "derive_components_assign", "derive_component_from", "derive_from_components" ] derive_component_assign = [] -derive_components_assign = [ "derive_components", "derive_component_assign", "convert_case" ] -derive_component_from = [ "derive_components" ] -derive_from_components = [ "derive_components" ] +derive_components_assign = [ "derive_component_assign", "convert_case" ] +derive_component_from = [] +derive_from_components = [] [lib] proc-macro = true [dependencies] -macro_tools = { workspace = true } # qqq : optimize set of features -former_types = { workspace = true, features = [ "enabled", "types_component_assign" ] } +macro_tools = { workspace = true, features = [ "attr", "attr_prop", "ct", "item_struct", "container_kind", "diag", "phantom", "generic_params", "generic_args", "typ", "derive" ] } # qqq : xxx : optimize set of features +former_types = { workspace = true, features = [ "types_component_assign" ] } iter_tools = { workspace = true } convert_case = { version = "0.6.0", default-features = false, optional = true, features = [] } -const_format = { version = "0.2.32" } -# zzz : reexport const_format [dev-dependencies] test_tools = { workspace = true, features = [ "full" ] } -former = { workspace = true, features = [ "full" ] } diff --git a/module/core/former_meta/Readme.md b/module/core/former_meta/Readme.md index e7eeaec814..716940ba96 100644 --- a/module/core/former_meta/Readme.md +++ b/module/core/former_meta/Readme.md @@ -5,7 +5,7 @@ [![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) [![rust-status](https://github.com/Wandalen/wTools/actions/workflows/module_former_meta_push.yml/badge.svg)](https://github.com/Wandalen/wTools/actions/workflows/module_former_meta_push.yml) [![docs.rs](https://img.shields.io/docsrs/former_meta?color=e3e8f0&logo=docs.rs)](https://docs.rs/former_meta) [![discord](https://img.shields.io/discord/872391416519737405?color=eee&logo=discord&logoColor=eee&label=ask)](https://discord.gg/m3YfbXpUUY) -Former - a variation of builder pattern. Implementation of its derive macro. Should not be used independently, instead use module::former which relies on the module. +A flexible implementation of the Builder pattern supporting nested builders and collection-specific subformers. Implementation of its derive macro. Should not be used independently, instead use module::former which relies on the module. Not intended to be used without runtime. This module and runtime is aggregate in module::former is [here](https://github.com/Wandalen/wTools/tree/master/module/core/former). diff --git a/module/core/former_meta/src/derive_former/field.rs b/module/core/former_meta/src/derive_former/field.rs index 13a702b308..7135d9370a 100644 --- a/module/core/former_meta/src/derive_former/field.rs +++ b/module/core/former_meta/src/derive_former/field.rs @@ -1040,7 +1040,7 @@ preformed elements to this storage. # Type Parameters -- `Types2`: Represents the specific types associated with the `Former` trait being applied, +- `Types2`: Represents the specific types associated with the `Former` being applied, which include storage, formed type, and context. - `Definition`: Defines the `FormerDefinition` that outlines the storage structure and the end conditions for the formation process. diff --git a/module/core/former_meta/src/derive_former/field_attrs.rs b/module/core/former_meta/src/derive_former/field_attrs.rs index 0dd3cf3edc..a662fe20ae 100644 --- a/module/core/former_meta/src/derive_former/field_attrs.rs +++ b/module/core/former_meta/src/derive_former/field_attrs.rs @@ -3,6 +3,7 @@ use super::*; use macro_tools:: { + ct, Result, AttributeComponent, AttributePropertyComponent, @@ -56,7 +57,7 @@ impl FieldAttributes { let mut result = Self::default(); // Known attributes for error reporting - let known_attributes = const_format::concatcp! + let known_attributes = ct::concatcp! ( "Known attributes are : ", "debug", @@ -195,7 +196,7 @@ impl syn::parse::Parse for AttributeConfig let error = | ident : &syn::Ident | -> syn::Error { - let known = const_format::concatcp! + let known = ct::concatcp! ( "Known entries of attribute ", AttributeConfig::KEYWORD, " are : ", AttributePropertyDefault::KEYWORD, @@ -354,7 +355,7 @@ impl syn::parse::Parse for AttributeScalarSetter let error = | ident : &syn::Ident | -> syn::Error { - let known = const_format::concatcp! + let known = ct::concatcp! ( "Known entries of attribute ", AttributeScalarSetter::KEYWORD, " are : ", AttributePropertyName::KEYWORD, @@ -529,7 +530,7 @@ impl syn::parse::Parse for AttributeSubformScalarSetter let error = | ident : &syn::Ident | -> syn::Error { - let known = const_format::concatcp! + let known = ct::concatcp! ( "Known entries of attribute ", AttributeSubformScalarSetter::KEYWORD, " are : ", AttributePropertyName::KEYWORD, @@ -718,7 +719,7 @@ impl syn::parse::Parse for AttributeSubformCollectionSetter let error = | ident : &syn::Ident | -> syn::Error { - let known = const_format::concatcp! + let known = ct::concatcp! ( "Known entries of attribute ", AttributeSubformCollectionSetter::KEYWORD, " are : ", AttributePropertyName::KEYWORD, @@ -902,7 +903,7 @@ impl syn::parse::Parse for AttributeSubformEntrySetter let error = | ident : &syn::Ident | -> syn::Error { - let known = const_format::concatcp! + let known = ct::concatcp! ( "Known entries of attribute ", AttributeSubformEntrySetter::KEYWORD, " are : ", AttributePropertyName::KEYWORD, diff --git a/module/core/former_meta/src/derive_former/struct_attrs.rs b/module/core/former_meta/src/derive_former/struct_attrs.rs index 44e8273292..31d6ab3491 100644 --- a/module/core/former_meta/src/derive_former/struct_attrs.rs +++ b/module/core/former_meta/src/derive_former/struct_attrs.rs @@ -6,6 +6,7 @@ use super::*; use macro_tools:: { + ct, Result, AttributeComponent, AttributePropertyComponent, @@ -41,7 +42,7 @@ impl ItemAttributes let error = | attr : &syn::Attribute | -> syn::Error { - let known_attributes = const_format::concatcp! + let known_attributes = ct::concatcp! ( "Known attirbutes are : ", "debug", @@ -336,7 +337,7 @@ impl syn::parse::Parse for AttributeMutator let error = | ident : &syn::Ident | -> syn::Error { - let known = const_format::concatcp! + let known = ct::concatcp! ( "Known entries of attribute ", AttributeMutator::KEYWORD, " are : ", AttributePropertyCustom::KEYWORD, diff --git a/module/core/former_meta/src/lib.rs b/module/core/former_meta/src/lib.rs index 3a4d6af4d0..e1fdae8504 100644 --- a/module/core/former_meta/src/lib.rs +++ b/module/core/former_meta/src/lib.rs @@ -10,7 +10,7 @@ use macro_tools::prelude::*; mod derive_former; #[ cfg( feature = "enabled" ) ] -#[ cfg( feature = "derive_components" ) ] +#[ cfg( any( feature = "derive_components", feature = "derive_component_from", feature = "derive_from_components", feature = "derive_component_assign", feature = "derive_component_assign", feature = "derive_components_assign" ) ) ] mod component { @@ -56,7 +56,7 @@ mod component /// /// Below is a typical usage example where the macro is applied to a struct: /// -/// ```rust +/// ```rust, ignore /// /// # #[ cfg( all( feature = "derive_former", feature = "enabled" ) ) ] /// # fn main() @@ -139,7 +139,9 @@ pub fn former( input : proc_macro::TokenStream ) -> proc_macro::TokenStream /// ```rust /// # fn main() /// # { -/// #[ derive( former::ComponentFrom ) ] +/// use former_meta::ComponentFrom; +/// +/// #[ derive( ComponentFrom ) ] /// struct Person /// { /// pub age : i32, @@ -191,9 +193,10 @@ pub fn component_from( input : proc_macro::TokenStream ) -> proc_macro::TokenStr /// Given a struct definition annotated with `#[ derive( Assign ) ]` : /// /// ```rust -/// use former::Assign; +/// use former_types::Assign; +/// use former_meta::Assign; /// -/// #[ derive( Default, PartialEq, Debug, former::Assign ) ] +/// #[ derive( Default, PartialEq, Debug, Assign ) ] /// struct Person /// { /// age : i32, @@ -211,7 +214,8 @@ pub fn component_from( input : proc_macro::TokenStream ) -> proc_macro::TokenStr /// The procedural macro generates the following implementations for `Person` : /// /// ```rust -/// use former::Assign; +/// use former_types::Assign; +/// use former_meta::Assign; /// /// #[ derive( Default, PartialEq, Debug ) ] /// struct Person @@ -283,7 +287,7 @@ pub fn component_assign( input : proc_macro::TokenStream ) -> proc_macro::TokenS /// /// An example when we encapsulate parameters passed to a function in a struct. /// -/// ```rust +/// ```rust, ignore /// use former::{ Assign, ComponentsAssign }; /// /// #[ derive( Default, Assign, ComponentsAssign ) ] @@ -342,7 +346,7 @@ pub fn component_assign( input : proc_macro::TokenStream ) -> proc_macro::TokenS /// /// Which expands approximately into : /// -/// ```rust +/// ```rust, ignore /// use former::{ Assign, ComponentsAssign }; /// /// #[derive(Default)] @@ -537,7 +541,7 @@ pub fn components_assign( input : proc_macro::TokenStream ) -> proc_macro::Token /// Given the structs `Options1` and `Options2`, where `Options2` is a subset of `Options1`: /// /// ```rust -/// use former::FromComponents; +/// use former_meta::FromComponents; /// /// #[ derive( Debug, Default, PartialEq ) ] /// pub struct Options1 diff --git a/module/core/former_meta/tests/smoke_test.rs b/module/core/former_meta/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/core/former_meta/tests/smoke_test.rs +++ b/module/core/former_meta/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/core/former_types/Cargo.toml b/module/core/former_types/Cargo.toml index d6b6ca5fb3..75ae5bce43 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.2.0" +version = "2.7.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", @@ -11,7 +11,7 @@ documentation = "https://docs.rs/former" repository = "https://github.com/Wandalen/wTools/tree/master/module/core/former" homepage = "https://github.com/Wandalen/wTools/tree/master/module/core/former" description = """ -A flexible and extensible implementation of the builder pattern. Its compile-time structures and traits that are not generated but reused. +A flexible implementation of the Builder pattern supporting nested builders and collection-specific subformers. Its compile-time structures and traits that are not generated but reused. """ categories = [ "algorithms", "development-tools" ] keywords = [ "fundamental", "general-purpose", "builder-pattern" ] @@ -30,21 +30,18 @@ use_alloc = [ "no_std", "collection_tools/use_alloc" ] default = [ "enabled", - "derive_former", - "types_components", + "types_former", "types_component_assign", ] full = [ "enabled", - "derive_former", - "types_components", + "types_former", "types_component_assign", ] enabled = [ "collection_tools/enabled" ] -derive_former = [] -types_components = [] -types_component_assign = [ "types_components" ] +types_former = [] +types_component_assign = [] [dependencies] diff --git a/module/core/former_types/Readme.md b/module/core/former_types/Readme.md index 42346b3bc0..30e14aaf08 100644 --- a/module/core/former_types/Readme.md +++ b/module/core/former_types/Readme.md @@ -6,7 +6,7 @@ [![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) [![rust-status](https://github.com/Wandalen/wTools/actions/workflows/module_former_types_push.yml/badge.svg)](https://github.com/Wandalen/wTools/actions/workflows/module_former_types_push.yml) [![docs.rs](https://img.shields.io/docsrs/former_types?color=e3e8f0&logo=docs.rs)](https://docs.rs/former_types) [![Open in Gitpod](https://raster.shields.io/static/v1?label=try&message=online&color=eee&logo=gitpod&logoColor=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=module%2Fcore%2Fformer_types%2Fexamples%2Fformer_types_trivial.rs,RUN_POSTFIX=--example%20former_types_trivial/https://github.com/Wandalen/wTools) [![discord](https://img.shields.io/discord/872391416519737405?color=eee&logo=discord&logoColor=eee&label=ask)](https://discord.gg/m3YfbXpUUY) -A flexible and extensible implementation of the builder pattern. Its compile-time structures and traits that are not generated but reused. +A flexible implementation of the Builder pattern supporting nested builders and collection-specific subformers. Its compile-time structures and traits that are not generated but reused. ## Example: Using Trait Assign @@ -17,10 +17,10 @@ and implements the `Assign` trait for its fields. It shows how to use these impl instance using different types that can be converted into the required types. ```rust -#[ cfg( any( not( feature = "derive_former" ), not( feature = "enabled" ) ) ) ] +#[ cfg( any( not( feature = "types_former" ), not( feature = "enabled" ) ) ) ] fn main() {} -#[ cfg( all( feature = "derive_former", feature = "enabled" ) ) ] +#[ cfg( all( feature = "types_former", feature = "enabled" ) ) ] fn main() { use former_types::Assign; diff --git a/module/core/former_types/examples/former_types_trivial.rs b/module/core/former_types/examples/former_types_trivial.rs index c379293640..41c937b73a 100644 --- a/module/core/former_types/examples/former_types_trivial.rs +++ b/module/core/former_types/examples/former_types_trivial.rs @@ -20,10 +20,10 @@ //! - `got.assign( "John" )`: Assigns the string `"John"` to the `name` field. //! -#[ cfg( any( not( feature = "derive_former" ), not( feature = "enabled" ) ) ) ] +#[ cfg( any( not( feature = "types_former" ), not( feature = "enabled" ) ) ) ] fn main() {} -#[ cfg( all( feature = "derive_former", feature = "enabled" ) ) ] +#[ cfg( all( feature = "types_former", feature = "enabled" ) ) ] fn main() { use former_types::Assign; diff --git a/module/core/former_types/src/collection.rs b/module/core/former_types/src/collection.rs index eac724c018..2bb8dc88f3 100644 --- a/module/core/former_types/src/collection.rs +++ b/module/core/former_types/src/collection.rs @@ -515,35 +515,37 @@ mod vector_deque; #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } /// Parented namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { EntryToVal, @@ -574,6 +576,8 @@ pub mod exposed } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; } diff --git a/module/core/former_types/src/collection/binary_heap.rs b/module/core/former_types/src/collection/binary_heap.rs index 6652fe0c4e..ae76f5e4f8 100644 --- a/module/core/former_types/src/collection/binary_heap.rs +++ b/module/core/former_types/src/collection/binary_heap.rs @@ -125,8 +125,7 @@ where /// Holds the generic parameters for the `BinaryHeapDefinition`. /// /// This struct acts as a companion to `BinaryHeapDefinition`, providing a concrete definition of types used -/// in the formation process. It is crucial for linking the type parameters with the operational mechanics -/// of the formation and ensuring type safety and correctness throughout the formation lifecycle. +/// in the formation process. /// /// # Type Parameters /// diff --git a/module/core/former_types/src/component.rs b/module/core/former_types/src/component.rs index 21398497d8..9e846e2673 100644 --- a/module/core/former_types/src/component.rs +++ b/module/core/former_types/src/component.rs @@ -47,6 +47,18 @@ where /// This method takes ownership of the given value (`component`), which is of type `IntoT`. /// `component` is then converted into type `T` and set as the component of the object. fn assign( &mut self, component : IntoT ); + + /// Sets or replaces the component on the object with the given value. + /// Unlike function (`assing`) function (`impute`) also consumes self and return it what is useful for builder pattern. + #[ inline( always ) ] + fn impute( mut self, component : IntoT ) -> Self + where + Self : Sized, + { + self.assign( component ); + self + } + } /// Extension trait to provide a method for setting a component on an `Option` diff --git a/module/core/former_types/src/definition.rs b/module/core/former_types/src/definition.rs index 38563df0e8..3605ddef0c 100644 --- a/module/core/former_types/src/definition.rs +++ b/module/core/former_types/src/definition.rs @@ -90,7 +90,7 @@ pub trait FormerDefinition : Sized type Storage : Default; /// The type of the entity being formed. It is - /// generally the structure for which the `Former` trait is derived, representing the fully formed + /// generally the structure for which the `Former` is derived, representing the fully formed /// state of the entity. However, it can differ if a custom `FormingEnd` or a different `Formed` type /// is defined to handle specific forming logic or requirements. type Formed; diff --git a/module/core/former_types/src/lib.rs b/module/core/former_types/src/lib.rs index 51cfc78eab..39196a30e7 100644 --- a/module/core/former_types/src/lib.rs +++ b/module/core/former_types/src/lib.rs @@ -6,25 +6,25 @@ /// Axiomatic things. #[ cfg( feature = "enabled" ) ] -#[ cfg( feature = "derive_former" ) ] +#[ cfg( feature = "types_former" ) ] mod axiomatic; /// Definition of former. #[ cfg( feature = "enabled" ) ] -#[ cfg( feature = "derive_former" ) ] +#[ cfg( feature = "types_former" ) ] mod definition; /// Forming process. #[ cfg( feature = "enabled" ) ] -#[ cfg( feature = "derive_former" ) ] +#[ cfg( feature = "types_former" ) ] mod forming; /// Storage. #[ cfg( feature = "enabled" ) ] -#[ cfg( feature = "derive_former" ) ] +#[ cfg( feature = "types_former" ) ] mod storage; /// Interface for collections. #[ cfg( feature = "enabled" ) ] #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] -#[ cfg( feature = "derive_former" ) ] +#[ cfg( feature = "types_former" ) ] mod collection; /// Component-based forming. @@ -42,38 +42,47 @@ pub mod dependency #[ doc( inline ) ] #[ allow( unused_imports ) ] #[ cfg( feature = "enabled" ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. +/// Own namespace of the module. #[ cfg( feature = "enabled" ) ] -pub mod protected +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } /// Parented namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; + #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; + + #[ doc( inline ) ] + #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] + #[ cfg( feature = "types_former" ) ] + pub use collection::orphan::*; + } /// Exposed namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - #[ cfg( feature = "derive_former" ) ] + #[ cfg( feature = "types_former" ) ] pub use super:: { axiomatic::*, @@ -83,19 +92,26 @@ pub mod exposed }; #[ doc( inline ) ] - #[ allow( unused_imports ) ] #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] - #[ cfg( feature = "derive_former" ) ] - pub use super::collection::*; + #[ cfg( feature = "types_former" ) ] + pub use collection::exposed::*; } /// Prelude to use essentials: `use my_module::prelude::*`. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; + #[ doc( inline ) ] - #[ allow( unused_imports ) ] #[ cfg( any( feature = "types_component_assign" ) ) ] - pub use super::component::*; + pub use component::*; + + #[ doc( inline ) ] + #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] + #[ cfg( feature = "types_former" ) ] + pub use collection::prelude::*; + } diff --git a/module/core/former_types/src/storage.rs b/module/core/former_types/src/storage.rs index 02e20e78d5..8b37f0e654 100644 --- a/module/core/former_types/src/storage.rs +++ b/module/core/former_types/src/storage.rs @@ -30,7 +30,7 @@ pub trait Storage : ::core::default::Default /// This trait is crucial for transitioning the mutable, intermediate storage state into the final, /// immutable state of an entity. The transformation is typically performed once all configurations /// and modifications are applied to the storage during the forming process. The type `Preformed` and `Formed` is -/// generally the structure for which the `Former` trait is derived, representing the fully formed +/// generally the structure for which the `Former` is derived, representing the fully formed /// state of the entity. However, it can differ if a custom `FormingEnd` or a different `Formed` type /// is defined to handle specific forming logic or requirements. /// But even if `Formed` is custom `Preformed` is always that structure. diff --git a/module/core/former_types/tests/inc/mod.rs b/module/core/former_types/tests/inc/mod.rs index 59fea4b027..79269a3c6f 100644 --- a/module/core/former_types/tests/inc/mod.rs +++ b/module/core/former_types/tests/inc/mod.rs @@ -3,7 +3,7 @@ #[ allow( unused_imports ) ] use super::*; -#[ cfg( feature = "derive_former" ) ] +#[ cfg( feature = "types_former" ) ] #[ path = "../../../former/tests/inc/former_tests" ] mod former_tests { @@ -27,7 +27,6 @@ mod former_tests } -#[ cfg( feature = "types_components" ) ] #[ path = "../../../former/tests/inc/components_tests" ] mod components_tests { diff --git a/module/core/former_types/tests/smoke_test.rs b/module/core/former_types/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/core/former_types/tests/smoke_test.rs +++ b/module/core/former_types/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/core/former_types/tests/tests.rs b/module/core/former_types/tests/tests.rs index caea26275c..2928305813 100644 --- a/module/core/former_types/tests/tests.rs +++ b/module/core/former_types/tests/tests.rs @@ -1,5 +1,5 @@ -include!( "../../../../module/step/meta/src/module/terminal.rs" ); +include!( "../../../../module/step/meta/src/module/aggregating.rs" ); #[ allow( unused_imports ) ] use test_tools::exposed::*; diff --git a/module/core/fs_tools/src/fs/fs.rs b/module/core/fs_tools/src/fs/fs.rs index eb6f6508de..adace8b2c2 100644 --- a/module/core/fs_tools/src/fs/fs.rs +++ b/module/core/fs_tools/src/fs/fs.rs @@ -51,37 +51,42 @@ pub( crate ) mod private } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Shared with parent namespace of the module +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; // use super::private::TempDir; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; } diff --git a/module/core/fs_tools/src/fs/lib.rs b/module/core/fs_tools/src/fs/lib.rs index 1789116600..5dbf05e2f1 100644 --- a/module/core/fs_tools/src/fs/lib.rs +++ b/module/core/fs_tools/src/fs/lib.rs @@ -14,12 +14,13 @@ pub mod dependency { } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::fs::orphan::*; @@ -27,30 +28,34 @@ pub mod protected #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Shared with parent namespace of the module +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::fs::exposed::*; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::fs::prelude::*; diff --git a/module/core/fs_tools/tests/smoke_test.rs b/module/core/fs_tools/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/core/fs_tools/tests/smoke_test.rs +++ b/module/core/fs_tools/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/core/implements/Cargo.toml b/module/core/implements/Cargo.toml index 77f0b3ac2d..44a51ad680 100644 --- a/module/core/implements/Cargo.toml +++ b/module/core/implements/Cargo.toml @@ -24,7 +24,7 @@ workspace = true features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] + [features] default = [ "enabled" ] diff --git a/module/core/implements/src/lib.rs b/module/core/implements/src/lib.rs index 92cdcaa96e..69290aca5e 100644 --- a/module/core/implements/src/lib.rs +++ b/module/core/implements/src/lib.rs @@ -72,42 +72,46 @@ pub( crate ) mod private #[ doc( inline ) ] #[ allow( unused_imports ) ] #[ cfg( feature = "enabled" ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. +/// Own namespace of the module. #[ cfg( feature = "enabled" ) ] -pub mod protected +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } /// Orphan namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; } /// Prelude to use essentials: `use my_module::prelude::*`. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { implements, instance_of, diff --git a/module/core/implements/tests/smoke_test.rs b/module/core/implements/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/core/implements/tests/smoke_test.rs +++ b/module/core/implements/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/core/impls_index/src/impls_index/func.rs b/module/core/impls_index/src/impls_index/func.rs index cf9bed4e69..cc5185e2da 100644 --- a/module/core/impls_index/src/impls_index/func.rs +++ b/module/core/impls_index/src/impls_index/func.rs @@ -233,27 +233,30 @@ pub( crate ) mod private } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::private::fn_rename; + pub use private::fn_rename; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::private::fn_name; + pub use private::fn_name; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::private::fns; + pub use private::fns; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::private::fns2; - // pub use super::private::ignore_macro; + pub use private::fns2; + // pub use private::ignore_macro; } diff --git a/module/core/impls_index/src/impls_index/impls.rs b/module/core/impls_index/src/impls_index/impls.rs index 2d07e37d9c..b3b9236ad2 100644 --- a/module/core/impls_index/src/impls_index/impls.rs +++ b/module/core/impls_index/src/impls_index/impls.rs @@ -376,20 +376,22 @@ pub( crate ) mod private } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { index, tests_index, diff --git a/module/core/impls_index/src/impls_index/mod.rs b/module/core/impls_index/src/impls_index/mod.rs index 3fa0ed3c93..c0795b3f3e 100644 --- a/module/core/impls_index/src/impls_index/mod.rs +++ b/module/core/impls_index/src/impls_index/mod.rs @@ -22,31 +22,34 @@ pub mod impls; #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } /// Shared with parent namespace of the module +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; // pub use super::dependency; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::impls::exposed::*; @@ -56,8 +59,10 @@ pub mod exposed } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::impls::prelude::*; diff --git a/module/core/impls_index/src/lib.rs b/module/core/impls_index/src/lib.rs index f70d8cc177..ec229443d8 100644 --- a/module/core/impls_index/src/lib.rs +++ b/module/core/impls_index/src/lib.rs @@ -19,15 +19,16 @@ pub mod dependency #[ cfg( feature = "enabled" ) ] #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. +/// Own namespace of the module. #[ cfg( feature = "enabled" ) ] -pub mod protected +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::impls_index::orphan::*; @@ -35,20 +36,22 @@ pub mod protected /// Orphan namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::impls_index::exposed::*; @@ -56,8 +59,10 @@ pub mod exposed /// Prelude to use essentials: `use my_module::prelude::*`. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::impls_index::prelude::*; diff --git a/module/core/impls_index/tests/smoke_test.rs b/module/core/impls_index/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/core/impls_index/tests/smoke_test.rs +++ b/module/core/impls_index/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/core/impls_index_meta/Cargo.toml b/module/core/impls_index_meta/Cargo.toml index d3b1c21a9f..ce629d78b3 100644 --- a/module/core/impls_index_meta/Cargo.toml +++ b/module/core/impls_index_meta/Cargo.toml @@ -23,7 +23,7 @@ workspace = true [package.metadata.docs.rs] features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] + [features] default = [ "enabled" ] @@ -34,6 +34,6 @@ enabled = [ "macro_tools/enabled" ] proc-macro = true [dependencies] -macro_tools = { workspace = true } +macro_tools = { workspace = true, features = [ "name", "quantifier" ] } [dev-dependencies] diff --git a/module/core/include_md/Cargo.toml b/module/core/include_md/Cargo.toml index 410d16c21b..ad29aa3f81 100644 --- a/module/core/include_md/Cargo.toml +++ b/module/core/include_md/Cargo.toml @@ -24,7 +24,7 @@ workspace = true features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] + include = [ "/rust/impl/_blank", "/Cargo.toml", diff --git a/module/core/include_md/src/_blank/standard_lib.rs b/module/core/include_md/src/_blank/standard_lib.rs index d335841385..3569434028 100644 --- a/module/core/include_md/src/_blank/standard_lib.rs +++ b/module/core/include_md/src/_blank/standard_lib.rs @@ -21,33 +21,39 @@ pub mod dependency { } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Parented namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; } diff --git a/module/core/include_md/tests/smoke_test.rs b/module/core/include_md/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/core/include_md/tests/smoke_test.rs +++ b/module/core/include_md/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/core/inspect_type/Cargo.toml b/module/core/inspect_type/Cargo.toml index 8c55f439ac..cebba6d857 100644 --- a/module/core/inspect_type/Cargo.toml +++ b/module/core/inspect_type/Cargo.toml @@ -24,15 +24,10 @@ workspace = true features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] - [features] default = [ "enabled" ] full = [ "enabled" ] -no_std = [] -use_alloc = [ "no_std" ] enabled = [] -# nightly = [] [dependencies] diff --git a/module/core/inspect_type/build.rs b/module/core/inspect_type/build.rs index 43860208a5..e1ddc05383 100644 --- a/module/core/inspect_type/build.rs +++ b/module/core/inspect_type/build.rs @@ -13,19 +13,23 @@ fn main() Channel::Stable => { println!("cargo:rustc-cfg=RUSTC_IS_STABLE"); + println!("cargo:rustc-check-cfg=cfg(RUSTC_IS_STABLE)"); } Channel::Beta => { println!("cargo:rustc-cfg=RUSTC_IS_BETA"); + println!("cargo:rustc-check-cfg=cfg(RUSTC_IS_BETA)"); } Channel::Nightly => { println!("cargo:rustc-cfg=RUSTC_IS_NIGHTLY"); + println!("cargo:rustc-check-cfg=cfg(RUSTC_IS_NIGHTLY)"); } Channel::Dev => { println!("cargo:rustc-cfg=RUSTC_IS_DEV"); + println!("cargo:rustc-check-cfg=cfg(RUSTC_IS_DEV)"); } } -} \ No newline at end of file +} diff --git a/module/core/inspect_type/src/lib.rs b/module/core/inspect_type/src/lib.rs index 046f3332f9..9c08a04308 100644 --- a/module/core/inspect_type/src/lib.rs +++ b/module/core/inspect_type/src/lib.rs @@ -1,32 +1,8 @@ -#![ cfg_attr( feature = "no_std", no_std ) ] #![ 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/inspect_type/latest/inspect_type/" ) ] -// #![ deny( rust_2018_idioms ) ] -// #![ deny( missing_debug_implementations ) ] -// #![ deny( missing_docs ) ] - -// #![ cfg( rustversion::nightly ) ] -// #![ feature( type_name_of_val ) ] -// #![ cfg_attr( feature = "type_name_of_val", feature( type_name_of_val ) ) ] - -// #![ cfg_attr( RUSTC_IS_NIGHTLY, feature( type_name_of_val ) ) ] - -//! -//! Diagnostic-purpose tools to inspect type of a variable and its size. -//! - #![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/", "Readme.md" ) ) ] - -// #[ cfg( not( feature = "no_std" ) ) ] -// /// Little experiment. -// #[ derive( Debug ) ] -// pub struct Experimental( i32 ); - -// #[ cfg( feature = "nightly" ) ] -// #[ cfg( feature = "type_name_of_val" ) ] -// #[ rustversion::nightly ] #[ cfg( RUSTC_IS_NIGHTLY ) ] mod nightly { @@ -79,40 +55,44 @@ mod nightly #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; // #[ cfg( feature = "nightly" ) ] // #[ rustversion::nightly ] // #[ cfg( feature = "type_name_of_val" ) ] #[ cfg( RUSTC_IS_NIGHTLY ) ] #[ doc( inline ) ] - #[ allow( unused_imports ) ] pub use super::nightly::*; } diff --git a/module/core/inspect_type/tests/smoke_test.rs b/module/core/inspect_type/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/core/inspect_type/tests/smoke_test.rs +++ b/module/core/inspect_type/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/core/inspect_type/tests/tests.rs b/module/core/inspect_type/tests/tests.rs index e24b02720c..1b4624edf8 100644 --- a/module/core/inspect_type/tests/tests.rs +++ b/module/core/inspect_type/tests/tests.rs @@ -1,3 +1,5 @@ +// #![ no_std ] + // #![ cfg_attr( feature = "no_std", no_std ) ] // #![ cfg( custom_inner_attributes ) ] // #![ test_tools::nightly ] diff --git a/module/core/interval_adapter/Cargo.toml b/module/core/interval_adapter/Cargo.toml index f08b7f12a0..40b7639448 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.21.0" +version = "0.23.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", @@ -24,11 +24,10 @@ workspace = true features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] [features] -default = [ "enabled" ] -full = [ "enabled" ] +default = [ "enabled", "no_std" ] +full = [ "default" ] no_std = [] use_alloc = [ "no_std" ] enabled = [] diff --git a/module/core/interval_adapter/src/lib.rs b/module/core/interval_adapter/src/lib.rs index 8391104eda..e553c31824 100644 --- a/module/core/interval_adapter/src/lib.rs +++ b/module/core/interval_adapter/src/lib.rs @@ -2,19 +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/winterval/latest/winterval/" ) ] -// #![ deny( rust_2018_idioms ) ] -// #![ deny( missing_debug_implementations ) ] -// #![ deny( missing_docs ) ] - -// #![ feature( step_trait ) ] - -/* zzz : consider https://doc.rust-lang.org/std/ops/trait.RangeBounds.html */ -/* zzz : implement iterator */ - -//! -//! Interval adapter for both open/closed implementations of intervals ( ranges ). -//! - #![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/", "Readme.md" ) ) ] /// Internal namespace. @@ -589,36 +576,38 @@ pub( crate ) mod private #[ allow( unused_imports ) ] #[ cfg( feature = "enabled" ) ] // #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. +/// Own namespace of the module. #[ cfg( feature = "enabled" ) ] -pub mod protected +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } /// Parented namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { Bound, BoundExt, @@ -638,11 +627,12 @@ pub mod exposed /// Prelude to use essentials: `use my_module::prelude::*`. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { IterableInterval, NonIterableInterval, diff --git a/module/core/interval_adapter/tests/inc/mod.rs b/module/core/interval_adapter/tests/inc/mod.rs index 0014f67a76..3751758e7b 100644 --- a/module/core/interval_adapter/tests/inc/mod.rs +++ b/module/core/interval_adapter/tests/inc/mod.rs @@ -1,3 +1,4 @@ + #[ allow( unused_imports ) ] use super::*; @@ -193,6 +194,7 @@ tests_impls! { for i in interval { + #[ cfg( not( feature = "no_std" ) ) ] println!( "{i}" ); } } @@ -216,6 +218,7 @@ tests_impls! fn f1( interval : impl NonIterableInterval ) { + #[ cfg( not( feature = "no_std" ) ) ] println!( "Do something with this {:?} .. {:?} interval", interval.left(), interval.right() ); } diff --git a/module/core/interval_adapter/tests/interval_tests.rs b/module/core/interval_adapter/tests/interval_tests.rs index 8b71381bfb..fc2c020c01 100644 --- a/module/core/interval_adapter/tests/interval_tests.rs +++ b/module/core/interval_adapter/tests/interval_tests.rs @@ -1,3 +1,5 @@ +#![ cfg_attr( feature = "no_std", no_std ) ] + #[ allow( unused_imports ) ] use interval_adapter as the_module; #[ allow( unused_imports ) ] diff --git a/module/core/is_slice/Cargo.toml b/module/core/is_slice/Cargo.toml index b3cb822caa..b0945c3613 100644 --- a/module/core/is_slice/Cargo.toml +++ b/module/core/is_slice/Cargo.toml @@ -24,13 +24,9 @@ workspace = true features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] - [features] default = [ "enabled" ] full = [ "enabled" ] -no_std = [] -use_alloc = [ "no_std" ] enabled = [] [dependencies] diff --git a/module/core/is_slice/src/lib.rs b/module/core/is_slice/src/lib.rs index eea3ea5978..585e41c80c 100644 --- a/module/core/is_slice/src/lib.rs +++ b/module/core/is_slice/src/lib.rs @@ -1,15 +1,7 @@ -#![ cfg_attr( feature = "no_std", no_std ) ] +#![ no_std ] #![ 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/inspect_type/latest/inspect_type/" ) ] -// #![ deny( rust_2018_idioms ) ] -// #![ deny( missing_debug_implementations ) ] -// #![ deny( missing_docs ) ] - -//! -//! Diagnostic-purpose tools to inspect type of a variable and its size. -//! - #![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/", "Readme.md" ) ) ] #[ cfg( feature = "enabled" ) ] @@ -74,53 +66,57 @@ pub( crate ) mod private #[ doc( inline ) ] #[ allow( unused_imports ) ] #[ cfg( feature = "enabled" ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. +/// Own namespace of the module. #[ cfg( feature = "enabled" ) ] -pub mod protected +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } /// Orphan namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; } #[ cfg( feature = "enabled" ) ] /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; // #[ doc( inline ) ] // #[ allow( unused_imports ) ] - // pub use super::private:: + // pub use private:: // { // }; - #[ cfg( feature = "nightly" ) ] - #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::nightly::*; + // #[ cfg( feature = "nightly" ) ] + // #[ doc( inline ) ] + // #[ allow( unused_imports ) ] + // pub use super::nightly::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { is_slice, }; diff --git a/module/core/is_slice/tests/inc/mod.rs b/module/core/is_slice/tests/inc/mod.rs index f2b9dec7e1..d2e9305da9 100644 --- a/module/core/is_slice/tests/inc/mod.rs +++ b/module/core/is_slice/tests/inc/mod.rs @@ -1,3 +1,5 @@ +#![ no_std ] + #[ allow( unused_imports ) ] use super::*; diff --git a/module/core/is_slice/tests/smoke_test.rs b/module/core/is_slice/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/core/is_slice/tests/smoke_test.rs +++ b/module/core/is_slice/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/core/iter_tools/Cargo.toml b/module/core/iter_tools/Cargo.toml index 233ac33f5b..ea0b221df3 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.17.0" +version = "0.20.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", @@ -24,18 +24,30 @@ workspace = true features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] - [features] -default = [ "enabled" ] -full = [ "enabled" ] +default = [ + "enabled", + "iter_trait", + "iter_ext", +] +full = [ "default" ] no_std = [] use_alloc = [ "itertools/use_alloc" ] -enabled = [] +enabled = [ "clone_dyn_types/enabled" ] + +iter_trait = [] +iter_ext = [] + +# qqq : work out set of features [dependencies] + +# external itertools = { version = "~0.11.0", features = [ "use_std" ] } # qqq : update +# internal +clone_dyn_types = { workspace = true, features = [] } + [dev-dependencies] test_tools = { workspace = true } diff --git a/module/core/iter_tools/src/iter.rs b/module/core/iter_tools/src/iter.rs index 3a9218186f..5ac6abe106 100644 --- a/module/core/iter_tools/src/iter.rs +++ b/module/core/iter_tools/src/iter.rs @@ -1,26 +1,171 @@ -#[ cfg( not( feature = "no_std" ) ) ] +// #[ cfg( not( feature = "no_std" ) ) ] pub( crate ) mod private { - use ::itertools::process_results; - - // fn collect_results< I, T, E >( iter : I ) -> core::result::Result< Vec< T >, E > - // where - // I : Iterator< Item = core::result::Result< T, E > > + Clone, - // E : core::fmt::Debug, - // { - // for e in iter.clone() - // { - // if e.is_err() - // { - // e?; - // } - // } - // Ok( iter.map( | e | e.unwrap() ).collect() ) - // } + #[ allow( unused_imports ) ] + use crate::*; + // use ::itertools::process_results; + use clone_dyn_types::CloneDyn; + + /// Trait that encapsulates an iterator with specific characteristics and implemetning `CloneDyn`. + /// + /// The `_IterTrait` trait is designed to represent iterators that may yield references to items ( `&'a T` ). + /// These iterators must also implement the `ExactSizeIterator` and `DoubleEndedIterator` traits. + /// This combination ensures that the iterator can: + /// - Provide an exact size hint ( `ExactSizeIterator` ), + /// - Be traversed from both ends ( `DoubleEndedIterator` ). + /// + /// Additionally, the iterator must implement the `CloneDyn` trait, which allows cloning of trait objects. + /// + /// # Example + /// ```rust + /// use iter_tools::_IterTrait; + /// + /// // Example struct that implements Iterator, ExactSizeIterator, DoubleEndedIterator, and CloneDyn. + /// #[ derive( Clone ) ] + /// struct MyIterator + /// { + /// // internal fields + /// } + /// + /// impl Iterator for MyIterator + /// { + /// type Item = i32; + /// + /// fn next( &mut self ) -> Option< Self::Item > + /// { + /// // implementation + /// Some( 1 ) + /// } + /// } + /// + /// impl ExactSizeIterator for MyIterator + /// { + /// fn len( &self ) -> usize + /// { + /// // implementation + /// 1 + /// } + /// } + /// + /// impl DoubleEndedIterator for MyIterator + /// { + /// fn next_back( &mut self ) -> Option< Self::Item > + /// { + /// // implementation + /// Some( 1 ) + /// } + /// } + /// + /// ``` + + #[ cfg( feature = "iter_trait" ) ] + pub trait _IterTrait< 'a, T > + where + T : 'a, + Self : Iterator< Item = T > + ExactSizeIterator< Item = T > + DoubleEndedIterator, + Self : CloneDyn, + { + } + + #[ cfg( feature = "iter_trait" ) ] + impl< 'a, T, I > _IterTrait< 'a, T > for I + where + T : 'a, + Self : Iterator< Item = T > + ExactSizeIterator< Item = T > + DoubleEndedIterator, + Self : CloneDyn, + { + } + + /// Trait that encapsulates a clonable iterator with specific characteristics, tailored for use with the `syn` crate. + /// + /// The `IterTrait` trait is designed to represent iterators that may yield references to items ( `&'a T` ) within the `syn` crate. + /// These iterators must also implement the `ExactSizeIterator`, `DoubleEndedIterator`, and `Clone` traits. + /// This combination ensures that the iterator can: + /// - Provide an exact size hint ( `ExactSizeIterator` ), + /// - Be traversed from both ends ( `DoubleEndedIterator` ), + /// - Be clonable ( `Clone` ). + /// + #[ cfg( feature = "iter_trait" ) ] + pub trait IterTrait< 'a, T > + where + T : 'a, + Self : _IterTrait< 'a, T > + Clone, + { + } + + #[ cfg( feature = "iter_trait" ) ] + impl< 'a, T, I > IterTrait< 'a, T > for I + where + T : 'a, + Self : _IterTrait< 'a, T > + Clone, + { + } + + /// Implement `Clone` for boxed `_IterTrait` trait objects. + /// + /// This allows cloning of boxed iterators that implement `_IterTrait`. + #[ cfg( feature = "iter_trait" ) ] + #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] + #[ allow( non_local_definitions ) ] + impl< 'c, T > Clone for Box< dyn _IterTrait< 'c, T > + 'c > + { + #[ inline ] + fn clone( &self ) -> Self + { + clone_dyn_types::clone_into_box( &**self ) + } + } + + #[ cfg( feature = "iter_trait" ) ] + #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] + #[ allow( non_local_definitions ) ] + impl< 'c, T > Clone for Box< dyn _IterTrait< 'c, T > + Send + 'c > + { + #[ inline ] + fn clone( &self ) -> Self + { + clone_dyn_types::clone_into_box( &**self ) + } + } + + #[ cfg( feature = "iter_trait" ) ] + #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] + #[ allow( non_local_definitions ) ] + impl< 'c, T > Clone for Box< dyn _IterTrait< 'c, T > + Sync + 'c > + { + #[ inline ] + fn clone( &self ) -> Self + { + clone_dyn_types::clone_into_box( &**self ) + } + } + + #[ cfg( feature = "iter_trait" ) ] + #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] + #[ allow( non_local_definitions ) ] + impl< 'c, T > Clone for Box< dyn _IterTrait< 'c, T > + Send + Sync + 'c > + { + #[ inline ] + fn clone( &self ) -> Self + { + clone_dyn_types::clone_into_box( &**self ) + } + } + + /// Type alias for boxed `_IterTrait` trait objects. + /// + /// Prefer `BoxedIter` over `impl _IterTrait` when using trait objects ( `dyn _IterTrait` ) because the concrete type in return is less restrictive than `impl _IterTrait`. + /// + #[ cfg( feature = "iter_trait" ) ] + #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] + pub type BoxedIter< 'a, T > = Box< dyn _IterTrait< 'a, T > + 'a >; /// Extension of iterator. + // zzz : review + #[ cfg( feature = "iter_ext" ) ] + #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] pub trait IterExt where Self : core::iter::Iterator, @@ -29,14 +174,13 @@ pub( crate ) mod private fn map_result< F, RE, El >( self, f : F ) -> core::result::Result< Vec< El >, RE > where Self : Sized + Clone, - // Self : Sized, F : FnMut( < Self as core::iter::Iterator >::Item ) -> core::result::Result< El, RE >, RE : core::fmt::Debug, - // El : Clone, - // core::result::Result< El, RE > : Clone, ; } + #[ cfg( feature = "iter_ext" ) ] + #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] impl< Iterator > IterExt for Iterator where Iterator : core::iter::Iterator, @@ -46,16 +190,10 @@ pub( crate ) mod private Self : Sized + Clone, F : FnMut( < Self as core::iter::Iterator >::Item ) -> core::result::Result< El, RE >, RE : core::fmt::Debug, - // El : Clone, - // core::result::Result< El, RE > : Clone, { let vars_maybe = self.map( f ); - let vars : Vec< _ > = process_results( vars_maybe, | iter | iter.collect() )?; - // let vars = collect_results( vars_maybe.clone() )?; + let vars : Vec< _ > = ::itertools::process_results( vars_maybe, | iter | iter.collect() )?; Ok( vars ) - // let result : ( Vec< _ >, Vec< _ >, Vec< _ > ) - // = vars.into_iter().multiunzip(); - // Ok( result ) } } @@ -63,36 +201,28 @@ pub( crate ) mod private #[ doc( inline ) ] #[ allow( unused_imports ) ] -#[ cfg( feature = "enabled" ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -#[ cfg( feature = "enabled" ) ] -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; + } /// Orphan namespace of the module. -#[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod orphan { - #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; -} + use super::*; -/// Exposed namespace of the module. -pub mod exposed -{ #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use exposed::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] pub use ::itertools:: { all, @@ -132,21 +262,51 @@ pub mod exposed unfold, // zip, zip_eq, + Itertools, }; #[ cfg( not( feature = "no_std" ) ) ] #[ doc( inline ) ] - #[ allow( unused_imports ) ] pub use std::iter::zip; +} + +/// Exposed namespace of the module. +#[ allow( unused_imports ) ] +pub mod exposed +{ + use super::*; + + #[ doc( inline ) ] + pub use prelude::*; + + #[ doc( inline ) ] + #[ cfg( feature = "iter_trait" ) ] + pub use private:: + { + _IterTrait, + IterTrait, + }; + + #[ doc( inline ) ] + #[ cfg( feature = "iter_trait" ) ] + #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] + pub use private:: + { + BoxedIter, + }; + + + } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] pub use ::itertools:: { Diff, @@ -156,13 +316,12 @@ pub mod prelude MinMaxResult, Position, Itertools, - /*MultiUnzip,*/ PeekingNext, }; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - #[ cfg( not( feature = "no_std" ) ) ] - pub use super::private::IterExt; + #[ cfg( feature = "iter_ext" ) ] + #[ cfg( any( not( feature = "no_std" ), feature = "use_alloc" ) ) ] + pub use private::IterExt; } diff --git a/module/core/iter_tools/src/lib.rs b/module/core/iter_tools/src/lib.rs index 043285af78..caa22f5593 100644 --- a/module/core/iter_tools/src/lib.rs +++ b/module/core/iter_tools/src/lib.rs @@ -2,16 +2,15 @@ #![ 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/iter_tools/latest/iter_tools/" ) ] -// #![ deny( rust_2018_idioms ) ] -// #![ deny( missing_debug_implementations ) ] -// #![ deny( missing_docs ) ] - -//! -//! Collection of general purpose tools to iterate. Currently it simply reexports itertools. -//! - #![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/", "Readme.md" ) ) ] +#[ cfg( all( feature = "no_std", feature = "use_alloc" ) ) ] +extern crate alloc; +#[ cfg( all( feature = "no_std", feature = "use_alloc" ) ) ] +use alloc::boxed::Box; +#[ cfg( all( feature = "no_std", feature = "use_alloc" ) ) ] +use alloc::vec::Vec; + /// Core module. #[ cfg( feature = "enabled" ) ] pub mod iter; @@ -26,45 +25,52 @@ pub mod dependency #[ doc( inline ) ] #[ allow( unused_imports ) ] #[ cfg( feature = "enabled" ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. +/// Own namespace of the module. #[ cfg( feature = "enabled" ) ] -pub mod protected +#[ allow( unused_imports ) ] +pub mod own { + use super::*; + #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; + #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::iter::orphan::*; + } /// Orphan namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] pub use super::iter::exposed::*; } /// Prelude to use essentials: `use my_module::prelude::*`. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::iter::prelude::*; diff --git a/module/core/iter_tools/tests/smoke_test.rs b/module/core/iter_tools/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/core/iter_tools/tests/smoke_test.rs +++ b/module/core/iter_tools/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/core/macro_tools/Cargo.toml b/module/core/macro_tools/Cargo.toml index 7b960db025..bb96ca0fab 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.28.0" +version = "0.38.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", @@ -23,14 +23,76 @@ workspace = true [package.metadata.docs.rs] features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] + [features] -default = [ "enabled" ] -full = [ "enabled" ] -enabled = [ "former_types/enabled", "interval_adapter/enabled" ] +default = [ + "enabled", + "attr", + "attr_prop", + "components", + "ct", + "container_kind", + "derive", + "diag", + "equation", + "generic_args", + "generic_params", + "item", + "item_struct", + "name", + "kw", + "phantom", + "punctuated", + "quantifier", + "struct_like", + "tokens", + "typ", + "typed", +] +full = [ + "default", +] + +enabled = [ + "former_types/enabled", + "interval_adapter/enabled", + "clone_dyn_types/enabled", + "iter_tools/enabled", +] + +attr = [ "diag", "quantifier" ] +attr_prop = [ "components" ] +components = [] +ct = [] +container_kind = [ "typ" ] +derive = [] +diag = [] +equation = [] +generic_args = [] +generic_params = [ "punctuated" ] +item = [ "punctuated" ] +item_struct = [] +iter = [] +name = [] +kw = [] +phantom = [ "item" ] +punctuated = [] +quantifier = [] +struct_like = [ "item_struct" ] +tokens = [] +typ = [] +typed = [] # qqq : put all files under features: macro_attr, macro_container_kind, ... +# qqq : optimize features list +# qqq : make sure all combinations of features are working and passing test + +# qqq : expose features +# syn_derive +# syn_parsing +# syn_printing +# syn_clone [dependencies] @@ -38,13 +100,13 @@ enabled = [ "former_types/enabled", "interval_adapter/enabled" ] proc-macro2 = { version = "~1.0.78", features = [] } quote = { version = "~1.0.35", features = [] } syn = { version = "~2.0.52", features = [ "full", "extra-traits" ] } - -# qqq : optimize features list +const_format = { version = "0.2.32", features = [] } ## internal interval_adapter = { workspace = true, features = [] } +iter_tools = { workspace = true, features = [ "iter_trait" ] } +clone_dyn_types = { workspace = true, features = [] } former_types = { workspace = true, features = [ "types_component_assign" ] } [dev-dependencies] test_tools = { workspace = true } -const_format = { version = "0.2.32" } diff --git a/module/core/macro_tools/Readme.md b/module/core/macro_tools/Readme.md index 62e2e0013a..6d148200b3 100644 --- a/module/core/macro_tools/Readme.md +++ b/module/core/macro_tools/Readme.md @@ -15,9 +15,9 @@ The purpose of `typ::type_parameters` is to extract type parameters from a given In this example, we generate a type `core::option::Option` and extract its type parameters. ```rust -#[ cfg( not( feature = "enabled" ) ) ] +#[ cfg( not( all( feature = "enabled", feature = "typ" ) ) ) ] fn main(){} -#[ cfg( feature = "enabled" ) ] +#[ cfg( all( feature = "enabled", feature = "typ" ) ) ] fn main() { // Import necessary macros and modules from the `macro_tools` crate. @@ -80,15 +80,16 @@ defined in other crates. ```rust -#[ cfg( not( all( feature = "enabled", debug_assertions ) ) ) ] +#[ cfg( not( all( feature = "enabled", feature = "attr_prop", debug_assertions ) ) ) ] fn main(){} -#[ cfg( all( feature = "enabled", debug_assertions ) ) ] +#[ cfg( all( feature = "enabled", feature = "attr_prop", debug_assertions ) ) ] fn main() { use macro_tools:: { attr, + ct, syn_err, return_syn_err, qt, @@ -97,8 +98,8 @@ fn main() AttributePropertyComponent, AttributePropertyBoolean, AttributePropertySingletone, + Assign, }; - use former_types::Assign; /// Represents the attributes of a struct. Aggregates all its attributes. #[ derive( Debug, Default ) ] @@ -121,12 +122,11 @@ fn main() // Closure to generate an error message for unknown attributes. let error = | attr : & syn::Attribute | -> syn::Error { - let known_attributes = const_format::concatcp! + let known_attributes = ct::str::format! ( - "Known attributes are: ", + "Known attributes are: {}, {}.", "debug", - ", ", AttributeMutator::KEYWORD, - "." + AttributeMutator::KEYWORD, ); syn_err! ( @@ -241,12 +241,12 @@ fn main() let error = | ident : & syn::Ident | -> syn::Error { - let known = const_format::concatcp! + let known = ct::str::format! ( - "Known entries of attribute ", AttributeMutator::KEYWORD, " are: ", + "Known entries of attribute {} are: {}, {}.", + AttributeMutator::KEYWORD, AttributePropertyCustom::KEYWORD, - ", ", AttributePropertyDebug::KEYWORD, - "." + AttributePropertyDebug::KEYWORD, ); syn_err! ( diff --git a/module/core/macro_tools/examples/macro_tools_attr_prop.rs b/module/core/macro_tools/examples/macro_tools_attr_prop.rs index 4625e15154..b5369750d5 100644 --- a/module/core/macro_tools/examples/macro_tools_attr_prop.rs +++ b/module/core/macro_tools/examples/macro_tools_attr_prop.rs @@ -26,15 +26,15 @@ //! defined in other crates. //! -#[ cfg( not( all( feature = "enabled", debug_assertions ) ) ) ] +#[ cfg( not( all( feature = "enabled", feature = "attr_prop", debug_assertions ) ) ) ] fn main(){} -#[ cfg( all( feature = "enabled", debug_assertions ) ) ] +#[ cfg( all( feature = "enabled", feature = "attr_prop", debug_assertions ) ) ] fn main() { use macro_tools:: { - attr, + ct, syn_err, return_syn_err, qt, @@ -43,8 +43,8 @@ fn main() AttributePropertyComponent, AttributePropertyBoolean, AttributePropertySingletone, + Assign, }; - use former_types::Assign; /// Represents the attributes of a struct. Aggregates all its attributes. #[ derive( Debug, Default ) ] @@ -67,12 +67,11 @@ fn main() // Closure to generate an error message for unknown attributes. let error = | attr : & syn::Attribute | -> syn::Error { - let known_attributes = const_format::concatcp! + let known_attributes = ct::str::format! ( - "Known attributes are: ", + "Known attributes are: {}, {}.", "debug", - ", ", AttributeMutator::KEYWORD, - "." + AttributeMutator::KEYWORD, ); syn_err! ( @@ -192,12 +191,12 @@ fn main() let error = | ident : & syn::Ident | -> syn::Error { - let known = const_format::concatcp! + let known = ct::str::format! ( - "Known entries of attribute ", AttributeMutator::KEYWORD, " are: ", + "Known entries of attribute {} are: {}, {}.", + AttributeMutator::KEYWORD, AttributePropertyCustom::KEYWORD, - ", ", AttributePropertyDebug::KEYWORD, - "." + AttributePropertyDebug::KEYWORD, ); syn_err! ( diff --git a/module/core/macro_tools/examples/macro_tools_trivial.rs b/module/core/macro_tools/examples/macro_tools_trivial.rs index e92559b193..c0a1e27982 100644 --- a/module/core/macro_tools/examples/macro_tools_trivial.rs +++ b/module/core/macro_tools/examples/macro_tools_trivial.rs @@ -6,9 +6,9 @@ //! In this example, we generate a type `core::option::Option` and extract its type parameters. //! -#[ cfg( not( feature = "enabled" ) ) ] +#[ cfg( not( all( feature = "enabled", feature = "typ" ) ) ) ] fn main(){} -#[ cfg( feature = "enabled" ) ] +#[ cfg( all( feature = "enabled", feature = "typ" ) ) ] fn main() { // Import necessary macros and modules from the `macro_tools` crate. diff --git a/module/core/macro_tools/src/attr.rs b/module/core/macro_tools/src/attr.rs index 4524ded53e..07a425d23e 100644 --- a/module/core/macro_tools/src/attr.rs +++ b/module/core/macro_tools/src/attr.rs @@ -50,7 +50,7 @@ pub( crate ) mod private /// ``` /// - pub fn has_debug< 'a >( attrs : impl Iterator< Item = &'a syn::Attribute > ) -> Result< bool > + pub fn has_debug< 'a >( attrs : impl Iterator< Item = &'a syn::Attribute > ) -> syn::Result< bool > { for attr in attrs { @@ -211,7 +211,7 @@ pub( crate ) mod private impl syn::parse::Parse for AttributesInner { - fn parse( input : ParseStream< '_ > ) -> Result< Self > + fn parse( input : ParseStream< '_ > ) -> syn::Result< Self > { // let mut result : Self = from!(); let mut result : Self = Default::default(); @@ -286,7 +286,7 @@ pub( crate ) mod private impl syn::parse::Parse for AttributesOuter { - fn parse( input : ParseStream< '_ > ) -> Result< Self > + fn parse( input : ParseStream< '_ > ) -> syn::Result< Self > { let mut result : Self = Default::default(); loop @@ -321,6 +321,46 @@ pub( crate ) mod private } } + impl syn::parse::Parse + for Many< AttributesInner > + { + fn parse( input : ParseStream< '_ > ) -> syn::Result< Self > + { + let mut result = Self::new(); + loop + { + // let lookahead = input.lookahead1(); + if !input.peek( Token![ # ] ) + { + break; + } + result.0.push( input.parse()? ); + } + Ok( result ) + } + } + + impl syn::parse::Parse + for Many< AttributesOuter > + { + fn parse( input : ParseStream< '_ > ) -> syn::Result< Self > + { + let mut result = Self::new(); + loop + { + // let lookahead = input.lookahead1(); + if !input.peek( Token![ # ] ) + { + break; + } + result.0.push( input.parse()? ); + } + Ok( result ) + } + } + + impl AsMuchAsPossibleNoDelimiter for syn::Item {} + /// Trait for components of a structure aggregating attributes that can be constructed from a meta attribute. /// /// The `AttributeComponent` trait defines the interface for components that can be created @@ -335,7 +375,7 @@ pub( crate ) mod private /// # Example /// /// ```rust - /// use macro_tools::{ AttributeComponent, Result }; + /// use macro_tools::{ AttributeComponent, syn::Result }; /// use syn::{ Attribute, Error }; /// /// struct MyComponent; @@ -344,7 +384,7 @@ pub( crate ) mod private /// { /// const KEYWORD : &'static str = "my_component"; /// - /// fn from_meta( attr : &Attribute ) -> Result + /// fn from_meta( attr : &Attribute ) -> syn::Result /// { /// // Parsing logic here /// // Return Ok(MyComponent) if parsing is successful @@ -360,7 +400,7 @@ pub( crate ) mod private /// /// # Returns /// - /// A `Result` containing the constructed component if successful, or an error if the parsing fails. + /// A `syn::Result` containing the constructed component if successful, or an error if the parsing fails. /// pub trait AttributeComponent where @@ -384,59 +424,27 @@ pub( crate ) mod private /// /// # Returns /// - /// A `Result` containing the constructed component if successful, or an error if the parsing fails. - fn from_meta( attr : &syn::Attribute ) -> Result< Self >; - } + /// A `syn::Result` containing the constructed component if successful, or an error if the parsing fails. + fn from_meta( attr : &syn::Attribute ) -> syn::Result< Self >; - /// Trait for properties of an attribute component that can be identified by a keyword. - /// - /// The `AttributePropertyComponent` trait defines the interface for attribute properties - /// that can be identified by a specific keyword. Implementors of this trait are required - /// to define a constant `KEYWORD` that identifies the type of the property. - /// - /// This trait is useful in scenarios where attributes may have multiple properties - /// that need to be parsed and handled separately. By defining a unique keyword for each property, - /// the parsing logic can accurately identify and process each property. - /// - /// # Example - /// - /// ```rust - /// use macro_tools::AttributePropertyComponent; - /// - /// struct MyProperty; - /// - /// impl AttributePropertyComponent for MyProperty - /// { - /// const KEYWORD : &'static str = "my_property"; - /// } - /// ``` - /// - pub trait AttributePropertyComponent - where - Self : Sized, - { - /// The keyword that identifies the component. - /// - /// This constant is used to match the attribute to the corresponding property. - /// Each implementor of this trait must provide a unique keyword for its type. - const KEYWORD : &'static str; + // zzz : redo maybe } } #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { // equation, has_debug, @@ -445,33 +453,35 @@ pub mod protected } /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { - pub use super::protected as attr; + use super::*; + pub use super::super::attr; + #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { AttributesInner, AttributesOuter, - AttributeComponent, - AttributePropertyComponent, }; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; } diff --git a/module/core/macro_tools/src/attr_prop.rs b/module/core/macro_tools/src/attr_prop.rs index 4e5020eff2..cb2bb2c51d 100644 --- a/module/core/macro_tools/src/attr_prop.rs +++ b/module/core/macro_tools/src/attr_prop.rs @@ -107,53 +107,97 @@ pub( crate ) mod private { // use crate::*; + /// Trait for properties of an attribute component that can be identified by a keyword. + /// + /// The `AttributePropertyComponent` trait defines the interface for attribute properties + /// that can be identified by a specific keyword. Implementors of this trait are required + /// to define a constant `KEYWORD` that identifies the type of the property. + /// + /// This trait is useful in scenarios where attributes may have multiple properties + /// that need to be parsed and handled separately. By defining a unique keyword for each property, + /// the parsing logic can accurately identify and process each property. + /// + /// # Example + /// + /// ```rust + /// use macro_tools::AttributePropertyComponent; + /// + /// struct MyProperty; + /// + /// impl AttributePropertyComponent for MyProperty + /// { + /// const KEYWORD : &'static str = "my_property"; + /// } + /// ``` + /// + pub trait AttributePropertyComponent + where + Self : Sized, + { + /// The keyword that identifies the component. + /// + /// This constant is used to match the attribute to the corresponding property. + /// Each implementor of this trait must provide a unique keyword for its type. + const KEYWORD : &'static str; + } + } #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { }; } /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { - pub use super::protected as attr_prop; + use super::*; + pub use super::super::attr_prop; + + // pub use super::own as attr_prop; + #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; + #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super:: { + private::AttributePropertyComponent, + singletone::AttributePropertySingletone, singletone::AttributePropertySingletoneMarker, singletone_optional::AttributePropertyOptionalSingletone, singletone_optional::AttributePropertyOptionalSingletoneMarker, + boolean::AttributePropertyBoolean, boolean::AttributePropertyBooleanMarker, boolean_optional::AttributePropertyOptionalBoolean, boolean_optional::AttributePropertyOptionalBooleanMarker, + syn::AttributePropertySyn, syn::AttributePropertySynMarker, syn_optional::AttributePropertyOptionalSyn, @@ -163,6 +207,8 @@ pub mod exposed } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; } diff --git a/module/core/macro_tools/src/attr_prop/boolean.rs b/module/core/macro_tools/src/attr_prop/boolean.rs index 4472b3ae42..fa786b990d 100644 --- a/module/core/macro_tools/src/attr_prop/boolean.rs +++ b/module/core/macro_tools/src/attr_prop/boolean.rs @@ -4,7 +4,7 @@ //! use crate::*; -use former_types::Assign; +// use former_types::Assign; /// Default marker for `AttributePropertyBoolean`. /// Used if no marker is defined as parameter. diff --git a/module/core/macro_tools/src/attr_prop/boolean_optional.rs b/module/core/macro_tools/src/attr_prop/boolean_optional.rs index 680803f4c8..e695db40dd 100644 --- a/module/core/macro_tools/src/attr_prop/boolean_optional.rs +++ b/module/core/macro_tools/src/attr_prop/boolean_optional.rs @@ -4,7 +4,7 @@ //! use crate::*; -use former_types::Assign; +use components::Assign; /// Default marker for `AttributePropertyOptionalSingletone`. /// Used if no marker is defined as parameter. diff --git a/module/core/macro_tools/src/attr_prop/singletone.rs b/module/core/macro_tools/src/attr_prop/singletone.rs index 1d55d9ac7c..0e6970bdd0 100644 --- a/module/core/macro_tools/src/attr_prop/singletone.rs +++ b/module/core/macro_tools/src/attr_prop/singletone.rs @@ -12,7 +12,7 @@ //! This is useful for attributes that need to enable or disable features or flags. use crate::*; -use former_types::Assign; +// use former_types::Assign; /// Default marker for `AttributePropertySingletone`. /// Used if no marker is defined as parameter. diff --git a/module/core/macro_tools/src/attr_prop/singletone_optional.rs b/module/core/macro_tools/src/attr_prop/singletone_optional.rs index 39c3dd9940..7d500cc94f 100644 --- a/module/core/macro_tools/src/attr_prop/singletone_optional.rs +++ b/module/core/macro_tools/src/attr_prop/singletone_optional.rs @@ -14,7 +14,7 @@ //! This is useful for attributes that need to enable or disable features or flags. use crate::*; -use former_types::Assign; +// use former_types::Assign; /// Default marker for `AttributePropertyOptionalSingletone`. /// Used if no marker is defined as parameter. diff --git a/module/core/macro_tools/src/attr_prop/syn.rs b/module/core/macro_tools/src/attr_prop/syn.rs index c60a21cfdd..183ead1a3a 100644 --- a/module/core/macro_tools/src/attr_prop/syn.rs +++ b/module/core/macro_tools/src/attr_prop/syn.rs @@ -3,7 +3,7 @@ //! use crate::*; -use former_types::Assign; +// use former_types::Assign; /// Default marker for `AttributePropertySyn`. /// Used if no marker is defined as parameter. diff --git a/module/core/macro_tools/src/attr_prop/syn_optional.rs b/module/core/macro_tools/src/attr_prop/syn_optional.rs index d595e9496a..4e5bba2783 100644 --- a/module/core/macro_tools/src/attr_prop/syn_optional.rs +++ b/module/core/macro_tools/src/attr_prop/syn_optional.rs @@ -3,7 +3,7 @@ //! use crate::*; -use former_types::Assign; +// use former_types::Assign; /// Default marker for `AttributePropertyOptionalSyn`. /// Used if no marker is defined as parameter. diff --git a/module/core/macro_tools/src/components.rs b/module/core/macro_tools/src/components.rs new file mode 100644 index 0000000000..158f11dc07 --- /dev/null +++ b/module/core/macro_tools/src/components.rs @@ -0,0 +1,70 @@ +//! +//! Type-based assigning. +//! + +/// Internal namespace. +pub( crate ) mod private +{ +} + +#[ doc( inline ) ] +#[ allow( unused_imports ) ] +pub use own::*; + +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own +{ + use super::*; + #[ doc( inline ) ] + pub use orphan::*; + #[ doc( inline ) ] + pub use private:: + { + }; + #[ doc( inline ) ] + #[ allow( unused_imports ) ] + pub use ::former_types::own::*; +} + +/// Orphan namespace of the module. +#[ allow( unused_imports ) ] +pub mod orphan +{ + use super::*; + #[ doc( inline ) ] + pub use exposed::*; +} + +/// Exposed namespace of the module. +#[ allow( unused_imports ) ] +pub mod exposed +{ + use super::*; + pub use super::super::components; + + #[ doc( inline ) ] + pub use prelude::*; + + #[ doc( inline ) ] + #[ allow( unused_imports ) ] + pub use ::former_types::exposed::*; + + #[ doc( inline ) ] + pub use private:: + { + }; + +} + +/// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] +pub mod prelude +{ + use super::*; + + #[ doc( inline ) ] + #[ allow( unused_imports ) ] + pub use ::former_types::prelude::*; + +} diff --git a/module/core/macro_tools/src/container_kind.rs b/module/core/macro_tools/src/container_kind.rs index a516594e47..51a981b890 100644 --- a/module/core/macro_tools/src/container_kind.rs +++ b/module/core/macro_tools/src/container_kind.rs @@ -98,18 +98,18 @@ pub( crate ) mod private #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { ContainerKind, of_type, @@ -119,24 +119,30 @@ pub mod protected } /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { - pub use super::protected as container_kind; + use super::*; + pub use super::super::container_kind; + + // pub use super::own as container_kind; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; } diff --git a/module/core/macro_tools/src/ct.rs b/module/core/macro_tools/src/ct.rs new file mode 100644 index 0000000000..e70a1d7ced --- /dev/null +++ b/module/core/macro_tools/src/ct.rs @@ -0,0 +1,64 @@ +//! +//! Compile-time tools. +//! + +/// Internal namespace. +pub( crate ) mod private +{ +} + +/// Compile-time const expressions for strings. +pub mod str; + +/// Compile-time tools. +#[ doc( inline ) ] +#[ allow( unused_imports ) ] +pub use own::*; + +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own +{ + use super::*; + + #[ doc( inline ) ] + pub use orphan::*; + #[ doc( inline ) ] + pub use private:: + { + }; + #[ doc( inline ) ] + pub use ::const_format::*; +} + +/// Orphan namespace of the module. +#[ allow( unused_imports ) ] +pub mod orphan +{ + use super::*; + #[ doc( inline ) ] + pub use exposed::*; +} + +/// Exposed namespace of the module. +#[ allow( unused_imports ) ] +pub mod exposed +{ + use super::*; + pub use super::super::ct; + + // pub use super::own as ct; + #[ doc( inline ) ] + pub use prelude::*; + #[ doc( inline ) ] + pub use private:: + { + }; +} + +/// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] +pub mod prelude +{ + use super::*; +} diff --git a/module/core/macro_tools/src/ct/str.rs b/module/core/macro_tools/src/ct/str.rs new file mode 100644 index 0000000000..f0fd4271e2 --- /dev/null +++ b/module/core/macro_tools/src/ct/str.rs @@ -0,0 +1,8 @@ + +#[ doc( inline ) ] +#[ allow( unused_imports ) ] +pub use ::const_format:: +{ + concatcp as concat, + formatcp as format, +}; diff --git a/module/core/macro_tools/src/derive.rs b/module/core/macro_tools/src/derive.rs index 13db46db90..f6f70fd362 100644 --- a/module/core/macro_tools/src/derive.rs +++ b/module/core/macro_tools/src/derive.rs @@ -48,18 +48,18 @@ pub( crate ) mod private #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { named_fields, }; @@ -67,37 +67,39 @@ pub mod protected } /// Parented namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { - pub use super::protected as derive; + use super::*; + pub use super::super::derive; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { }; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { }; diff --git a/module/core/macro_tools/src/diag.rs b/module/core/macro_tools/src/diag.rs index 10a7e9e0a5..ae5a24a8fb 100644 --- a/module/core/macro_tools/src/diag.rs +++ b/module/core/macro_tools/src/diag.rs @@ -7,12 +7,6 @@ pub( crate ) mod private { use crate::*; - /// - /// Result with syn::Error. - /// - - pub type Result< T > = std::result::Result< T, syn::Error >; - /// Adds indentation and optional prefix/postfix to each line of the given string. /// /// This function iterates over each line in the input string and applies the specified @@ -384,38 +378,49 @@ pub( crate ) mod private #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; + #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; + } /// Parented namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; + + // #[ doc( inline ) ] + // #[ allow( unused_imports ) ] + // pub use private:: + // { + // Result, + // }; + } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { - pub use super::protected as diag; + use super::*; + pub use super::super::diag; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { - Result, indentation, report_format, report_print, @@ -424,12 +429,13 @@ pub mod exposed } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { tree_print, code_print, @@ -441,5 +447,5 @@ pub mod prelude }; // #[ doc( inline ) ] - // pub use super::private::Result; + // pub use private::Result; } diff --git a/module/core/macro_tools/src/drop.rs b/module/core/macro_tools/src/drop.rs deleted file mode 100644 index f6e5814e48..0000000000 --- a/module/core/macro_tools/src/drop.rs +++ /dev/null @@ -1,96 +0,0 @@ -//! -//! zzz : write -//! - -// zzz : investiage and reuse for iterating -// https://docs.rs/syn/latest/src/syn/punctuated.rs.html#724 -// https://docs.rs/syn/latest/src/syn/drops.rs.html#11-16 - -/// Internal namespace. -pub mod private -{ - // use crate::*; - -// /// zzz : write documentation -// #[ repr( transparent ) ] -// pub struct NoDrop< T : ?Sized >( std::mem::ManuallyDrop< T > ); -// -// impl< T > NoDrop< T > -// { -// /// zzz : write documentation -// pub fn new( value : T ) -> Self -// where -// T : TrivialDrop, -// { -// NoDrop( std::mem::ManuallyDrop::new( value ) ) -// } -// } -// -// impl< T : ?Sized > std::ops::Deref for NoDrop< T > -// { -// type Target = T; -// fn deref( &self ) -> &Self::Target -// { -// &self.0 -// } -// } -// -// impl< T : ?Sized > std::ops::DerefMut for NoDrop< T > -// { -// fn deref_mut( &mut self ) -> &mut Self::Target -// { -// &mut self.0 -// } -// } -// -// /// zzz : write documentation -// pub trait TrivialDrop {} -// -// impl< T > TrivialDrop for std::iter::Empty< T > {} -// impl< 'a, T > TrivialDrop for std::slice::Iter< 'a, T > {} -// impl< 'a, T > TrivialDrop for std::slice::IterMut< 'a, T > {} -// impl< 'a, T > TrivialDrop for std::option::IntoIter< &'a T > {} -// impl< 'a, T > TrivialDrop for std::option::IntoIter< &'a mut T > {} - -} - -#[ 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::*; - #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: - { - // NoDrop, - // TrivialDrop, - }; -} - -/// Orphan namespace of the module. -pub mod orphan -{ - #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; -} - -/// Exposed namespace of the module. -pub mod exposed -{ - pub use super::protected as drop; - #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; -} - -/// Prelude to use essentials: `use my_module::prelude::*`. -pub mod prelude -{ -} diff --git a/module/core/macro_tools/src/equation.rs b/module/core/macro_tools/src/equation.rs index 36bab1ccab..f00a52e267 100644 --- a/module/core/macro_tools/src/equation.rs +++ b/module/core/macro_tools/src/equation.rs @@ -115,46 +115,50 @@ pub( crate ) mod private #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { from_meta, }; } /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { - pub use super::protected as equation; + use super::*; + pub use super::super::equation; + #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { Equation, }; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; } diff --git a/module/core/macro_tools/src/generic_args.rs b/module/core/macro_tools/src/generic_args.rs index 56f70d64a6..b77d8609ca 100644 --- a/module/core/macro_tools/src/generic_args.rs +++ b/module/core/macro_tools/src/generic_args.rs @@ -88,8 +88,8 @@ pub( crate ) mod private /// syn::{parse_quote, AngleBracketedGenericArguments}, /// }; /// - /// let a: AngleBracketedGenericArguments = parse_quote! { <'a, T: Clone, U: Default> }; - /// let b: AngleBracketedGenericArguments = parse_quote! { <'b, V: core::fmt::Debug> }; + /// let a : AngleBracketedGenericArguments = parse_quote! { <'a, T: Clone, U: Default> }; + /// let b : AngleBracketedGenericArguments = parse_quote! { <'b, V: core::fmt::Debug> }; /// let merged = generic_args::merge(&a, &b); /// /// let expected: AngleBracketedGenericArguments = parse_quote! { <'a, 'b, T: Clone, U: Default, V: core::fmt::Debug> }; @@ -142,45 +142,44 @@ pub( crate ) mod private #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { - - //! - //! This module provides utilities to handle and manipulate generic arguments using the `syn` crate. It includes traits and functions for transforming, merging, and managing generic parameters within procedural macros, enabling seamless syntactic analysis and code generation. - //! + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { merge, }; } /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { IntoGenericArgs, }; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { - pub use super::protected as generic_args; + use super::*; + pub use super::super::generic_args; + #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super:: @@ -190,6 +189,8 @@ pub mod exposed } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; } diff --git a/module/core/macro_tools/src/generic_params.rs b/module/core/macro_tools/src/generic_params.rs index 09f4445e5b..85ee5d91ff 100644 --- a/module/core/macro_tools/src/generic_params.rs +++ b/module/core/macro_tools/src/generic_params.rs @@ -6,6 +6,8 @@ pub( crate ) mod private { use crate::*; + use crate::IterTrait; + // use iter_tools::IterTrait; /// A `GenericsWithWhere` struct to handle the parsing of Rust generics with an explicit `where` clause. /// @@ -281,7 +283,13 @@ pub( crate ) mod private /// ]); /// ``` - pub fn names< 'a >( generics : &'a syn::Generics ) -> impl IterTrait< 'a, &'a syn::Ident > + Clone + pub fn names< 'a >( generics : &'a syn::Generics ) + -> impl IterTrait< 'a, &'a syn::Ident > + // -> std::iter::Map + // < + // syn::punctuated::Iter< 'a, syn::GenericParam >, + // impl FnMut( &'a syn::GenericParam ) -> &'a syn::Ident + 'a, + // > { generics.params.iter().map( | param | match param { @@ -498,21 +506,18 @@ pub( crate ) mod private #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -pub mod protected +#[ allow( unused_imports ) ] +/// Own namespace of the module. +pub mod own { - - //! - //! Functions and structures to handle and manipulate generic parameters using the `syn` crate. It's designed to support macro-driven code generation by simplifying, merging, extracting, and decomposing `syn::Generics`. - //! + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { merge, only_names, @@ -522,23 +527,26 @@ pub mod protected } /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { GenericsWithWhere, }; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { - pub use super::protected as generic_params; + use super::*; + pub use super::super::generic_params; + #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super:: @@ -548,6 +556,8 @@ pub mod exposed } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; } diff --git a/module/core/macro_tools/src/item.rs b/module/core/macro_tools/src/item.rs index 2bd19814b2..8728fd5299 100644 --- a/module/core/macro_tools/src/item.rs +++ b/module/core/macro_tools/src/item.rs @@ -84,44 +84,42 @@ pub( crate ) mod private #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -// qqq : zzz : make sure documentation look good. generate, review and fix every file -/// This module provides various utilities and namespaces for working with `syn::Item`, specifically focusing on -/// ensuring syntactical correctness and managing different visibility levels within the code. It includes functions -/// to manipulate the structure of items, handle different kinds of fields, and provide a structured approach to -/// organizing the codebase into different access levels. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { ensure_comma, }; } /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { }; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { - // pub use super::protected as item; - pub use super::protected as item; + use super::*; + pub use super::super::item; + #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super:: @@ -131,6 +129,8 @@ pub mod exposed } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; } diff --git a/module/core/macro_tools/src/item_struct.rs b/module/core/macro_tools/src/item_struct.rs index 6404e000c0..9a729be958 100644 --- a/module/core/macro_tools/src/item_struct.rs +++ b/module/core/macro_tools/src/item_struct.rs @@ -6,19 +6,23 @@ pub( crate ) mod private { use crate::*; + // use iter_tools::{ IterTrait, BoxedIter }; /// Extracts the types of each field into a vector. - // pub fn field_types< 'a >( t : &'a syn::ItemStruct ) -> impl IterTrait< 'a, &'a syn::Type > + Clone - pub fn field_types< 'a >( t : &'a syn::ItemStruct ) -> impl IterTrait< 'a, &'a syn::Type > + Clone + pub fn field_types< 'a >( t : &'a syn::ItemStruct ) + -> + impl IterTrait< 'a, &'a syn::Type > + // -> std::iter::Map + // < + // syn::punctuated::Iter< 'a, syn::Field >, + // impl FnMut( &'a syn::Field ) -> &'a syn::Type + 'a, + // > { t.fields.iter().map( | field | &field.ty ) } /// Retrieves the names of each field, if they exist. - // pub fn field_names< 'a >( t : &'a syn::ItemStruct ) -> Option< impl IterTrait< 'a, &'a syn::Ident > + 'a > - pub fn field_names< 'a >( t : &'a syn::ItemStruct ) -> Option< Box< dyn IterTrait< 'a, &'a syn::Ident > + '_ > > - // pub fn field_names< 'a >( t : &'a syn::ItemStruct ) -> Option< Box< dyn IterTrait< 'a, syn::Ident > + '_ > > - // pub fn field_names< 'a >( t : &'a syn::ItemStruct ) -> impl IterTrait< 'a, syn::Ident > + pub fn field_names< 'a >( t : &'a syn::ItemStruct ) -> Option< BoxedIter< 'a, &'a syn::Ident > > { match &t.fields { @@ -74,19 +78,18 @@ pub( crate ) mod private #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { - // fields_many, field_types, field_names, first_field_type, @@ -95,23 +98,28 @@ pub mod protected } /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { - pub use super::protected as item_struct; + use super::*; + pub use super::super::item_struct; + #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; } diff --git a/module/core/macro_tools/src/iter.rs b/module/core/macro_tools/src/iter.rs index 59d4d614f3..e8cce795af 100644 --- a/module/core/macro_tools/src/iter.rs +++ b/module/core/macro_tools/src/iter.rs @@ -1,126 +1,61 @@ //! -//! Iterators. +//! Tailored iterator. //! /// Internal namespace. pub( crate ) mod private { - // use crate::*; - - /// Trait that encapsulates an iterator with specific characteristics, tailored for use with the `syn` crate. - /// - /// The `IterTrait` trait is designed to represent iterators that may yield references to items (`&'a T`) within the `syn` crate. - /// These iterators must also implement the `ExactSizeIterator` and `DoubleEndedIterator` traits. - /// This combination ensures that the iterator can: - /// - Provide an exact size hint (`ExactSizeIterator`), - /// - Be traversed from both ends (`DoubleEndedIterator`). - /// - pub trait IterTrait< 'a, T > - where - T : 'a, - Self : Iterator< Item = T > + ExactSizeIterator< Item = T > + DoubleEndedIterator, - { - // fn clone_box( &self ) -> Box< dyn IterTrait< 'a, T > + 'a >; - } - - impl< 'a, T, I > IterTrait< 'a, T > for I - where - T : 'a, - Self : Iterator< Item = T > + ExactSizeIterator< Item = T > + DoubleEndedIterator // + Clone, - { - - // fn clone_box( &self ) -> Box< dyn IterTrait< 'a, T > + 'a > - // { - // Box::new( self.clone() ) - // } - - } - -// /// Trait that encapsulates an iterator with specific characteristics, tailored for use with the `syn` crate. -// /// -// /// The `IterTrait2` trait is designed to represent iterators that yield references to items (`&'a T`) within the `syn` crate. -// /// These iterators must also implement the `ExactSizeIterator` and `DoubleEndedIterator` traits. -// /// This combination ensures that the iterator can: -// /// - Provide an exact size hint (`ExactSizeIterator`), -// /// - Be traversed from both ends (`DoubleEndedIterator`). -// /// -// pub trait IterTrait2< T > -// where -// Self : Iterator< Item = T > + ExactSizeIterator< Item = T > + DoubleEndedIterator, -// { -// } -// -// impl< T, I > IterTrait2< T > for I -// where -// Self : Iterator< Item = T > + ExactSizeIterator< Item = T > + DoubleEndedIterator, -// { -// } -// -// /// Trait that encapsulates an iterator with specific characteristics, tailored for use with the `syn` crate. -// /// -// /// The `IterTrait3` trait is designed to represent iterators that yield references to items (`&'a T`) within the `syn` crate. -// /// These iterators must also implement the `ExactSizeIterator` and `DoubleEndedIterator` traits. -// /// This combination ensures that the iterator can: -// /// - Provide an exact size hint (`ExactSizeIterator`), -// /// - Be traversed from both ends (`DoubleEndedIterator`). -// /// -// pub trait IterTrait3< 'a, T : 'a > -// where -// Self : Iterator< Item = T > + ExactSizeIterator< Item = T > + DoubleEndedIterator, -// { -// } -// -// impl< 'a, T : 'a, I > IterTrait3< 'a, T > for I -// where -// Self : Iterator< Item = T > + ExactSizeIterator< Item = T > + DoubleEndedIterator, -// { -// } - } #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Tailoted iterator. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::private:: - { - }; + pub use iter_tools::own::*; } /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { - pub use super::protected as iter; + use super::*; + // pub use super::super::iter; + #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; + #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::private:: - { - IterTrait, - // IterTrait2, - // IterTrait3, - }; + pub use iter_tools::exposed::*; + } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; + + #[ doc( inline ) ] + #[ allow( unused_imports ) ] + pub use iter_tools::prelude::*; + } diff --git a/module/core/macro_tools/src/kw.rs b/module/core/macro_tools/src/kw.rs new file mode 100644 index 0000000000..7eee30efab --- /dev/null +++ b/module/core/macro_tools/src/kw.rs @@ -0,0 +1,71 @@ +//! +//! Keywords +//! + +/// Internal namespace. +pub( crate ) mod private +{ + // use crate::*; + + const KEYWORDS : &[ &str ] = + &[ + "as", "break", "const", "continue", "crate", "else", "enum", "extern", "false", "fn", + "for", "if", "impl", "in", "let", "loop", "match", "mod", "move", "mut", "pub", "ref", + "return", "self", "Self", "static", "struct", "super", "trait", "true", "type", "unsafe", + "use", "where", "while", "async", "await", "dyn", + ]; + + // qqq : cover by test + /// Check is string a keyword. + pub fn is( src : &str ) -> bool + { + KEYWORDS.contains( &src ) + } + +} + +#[ doc( inline ) ] +#[ allow( unused_imports ) ] +pub use own::*; + +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own +{ + use super::*; + #[ doc( inline ) ] + pub use orphan::*; +} + +/// Orphan namespace of the module. +#[ allow( unused_imports ) ] +pub mod orphan +{ + use super::*; + #[ doc( inline ) ] + pub use exposed::*; +} + +/// Exposed namespace of the module. +#[ allow( unused_imports ) ] +pub mod exposed +{ + use super::*; + pub use super::super::kw; + + #[ doc( inline ) ] + pub use prelude::*; + #[ doc( inline ) ] + pub use private:: + { + is, + }; +} + +/// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] +pub mod prelude +{ + use super::*; +} + diff --git a/module/core/macro_tools/src/lib.rs b/module/core/macro_tools/src/lib.rs index 85bafc8eb4..23fa3143ce 100644 --- a/module/core/macro_tools/src/lib.rs +++ b/module/core/macro_tools/src/lib.rs @@ -3,172 +3,309 @@ #![ doc( html_root_url = "https://docs.rs/proc_macro_tools/latest/proc_macro_tools/" ) ] #![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/", "Readme.md" ) ) ] -// qqq : review every page of generated documentation improve how it look as well as its content -// -// attr -// Protected namespace of the module. -// container_kind -// Protected namespace of the module. -// dependency -// Dependencies of the module. -// derive -// Protected namespace of the module. -// diag -// Protected namespace of the module. -// drop -// Protected namespace of the module. -// exposed -// Exposed namespace of the module. - -/// Modular files. + +/// Internal namespace. #[ cfg( feature = "enabled" ) ] -#[ path = "." ] -mod file +pub( crate ) mod private { - // use super::*; - pub mod attr; - pub mod attr_prop; - pub mod container_kind; - pub mod derive; - pub mod diag; - pub mod drop; - pub mod equation; - pub mod generic_args; - pub mod generic_params; - pub mod item; - pub mod item_struct; - pub mod iter; - pub mod name; - pub mod phantom; - pub mod punctuated; - pub mod quantifier; - pub mod struct_like; - pub mod tokens; - pub mod typ; + use crate::*; + + /// + /// Result with syn::Error. + /// + + pub type Result< T > = std::result::Result< T, syn::Error >; + } +// qqq : improve description of each file + +#[ cfg( all( feature = "enabled", feature = "attr" ) ) ] +pub mod attr; +#[ cfg( all( feature = "enabled", feature = "attr_prop" ) ) ] +pub mod attr_prop; +#[ cfg( all( feature = "enabled", feature = "components" ) ) ] +pub mod components; +#[ cfg( all( feature = "enabled", feature = "ct" ) ) ] +pub mod ct; +#[ cfg( all( feature = "enabled", feature = "container_kind" ) ) ] +pub mod container_kind; +#[ cfg( all( feature = "enabled", feature = "derive" ) ) ] +pub mod derive; +#[ cfg( all( feature = "enabled", feature = "diag" ) ) ] +pub mod diag; +#[ cfg( all( feature = "enabled", feature = "equation" ) ) ] +pub mod equation; +#[ cfg( all( feature = "enabled", feature = "generic_args" ) ) ] +pub mod generic_args; +#[ cfg( all( feature = "enabled", feature = "generic_params" ) ) ] +pub mod generic_params; +#[ cfg( all( feature = "enabled", feature = "item" ) ) ] +pub mod item; +#[ cfg( all( feature = "enabled", feature = "item_struct" ) ) ] +pub mod item_struct; +#[ cfg( all( feature = "enabled", feature = "name" ) ) ] +pub mod name; +#[ cfg( all( feature = "enabled", feature = "kw" ) ) ] +pub mod kw; +#[ cfg( all( feature = "enabled", feature = "phantom" ) ) ] +pub mod phantom; +#[ cfg( all( feature = "enabled", feature = "punctuated" ) ) ] +pub mod punctuated; +#[ cfg( all( feature = "enabled", feature = "quantifier" ) ) ] +pub mod quantifier; +#[ cfg( all( feature = "enabled", feature = "struct_like" ) ) ] +pub mod struct_like; +#[ cfg( all( feature = "enabled", feature = "tokens" ) ) ] +pub mod tokens; +#[ cfg( all( feature = "enabled", feature = "typ" ) ) ] +pub mod typ; +#[ cfg( all( feature = "enabled", feature = "typed" ) ) ] +pub mod typed; + +#[ cfg( all( feature = "enabled" ) ) ] +pub mod iter; + /// /// Dependencies of the module. /// #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod dependency { pub use ::syn; pub use ::quote; pub use ::proc_macro2; pub use ::interval_adapter; + pub use ::clone_dyn_types; + pub use ::former_types; } #[ doc( inline ) ] #[ allow( unused_imports ) ] #[ cfg( feature = "enabled" ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. +// qqq : put every file of the first level under feature + +/// Own namespace of the module. #[ cfg( feature = "enabled" ) ] -pub mod protected +#[ allow( unused_imports ) ] +pub mod own { - #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super:: + // use super::*; + + mod _all { - orphan::*, - }; + use super::super::*; + pub use orphan::*; + + pub use private:: + { + Result, + }; + + #[ cfg( feature = "attr" ) ] + pub use attr::orphan::*; + #[ cfg( feature = "attr_prop" ) ] + pub use attr_prop::orphan::*; + #[ cfg( feature = "components" ) ] + pub use components::orphan::*; + #[ cfg( feature = "container_kind" ) ] + pub use container_kind::orphan::*; + #[ cfg( feature = "ct" ) ] + pub use ct::orphan::*; + #[ cfg( feature = "derive" ) ] + pub use derive::orphan::*; + #[ cfg( feature = "diag" ) ] + pub use diag::orphan::*; + #[ cfg( feature = "equation" ) ] + pub use equation::orphan::*; + #[ cfg( feature = "generic_args" ) ] + pub use generic_args::orphan::*; + #[ cfg( feature = "generic_params" ) ] + pub use generic_params::orphan::*; + #[ cfg( feature = "item" ) ] + pub use item::orphan::*; + #[ cfg( feature = "item_struct" ) ] + pub use item_struct::orphan::*; + #[ cfg( feature = "name" ) ] + pub use name::orphan::*; + #[ cfg( feature = "kw" ) ] + pub use kw::orphan::*; + #[ cfg( feature = "phantom" ) ] + pub use phantom::orphan::*; + #[ cfg( feature = "punctuated" ) ] + pub use punctuated::orphan::*; + #[ cfg( feature = "quantifier" ) ] + pub use quantifier::orphan::*; + #[ cfg( feature = "struct_like" ) ] + pub use struct_like::orphan::*; + #[ cfg( feature = "tokens" ) ] + pub use tokens::orphan::*; + #[ cfg( feature = "typ" ) ] + pub use typ::orphan::*; + #[ cfg( feature = "typed" ) ] + pub use typed::orphan::*; + + pub use iter::orphan::*; + + } + #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::file:: - { - attr::orphan::*, - attr_prop::orphan::*, - container_kind::orphan::*, - derive::orphan::*, - diag::orphan::*, - drop::orphan::*, - equation::orphan::*, - generic_args::orphan::*, - generic_params::orphan::*, - item::orphan::*, - item_struct::orphan::*, - iter::orphan::*, - name::orphan::*, - phantom::orphan::*, - punctuated::orphan::*, - quantifier::orphan::*, - struct_like::orphan::*, - tokens::orphan::*, - typ::orphan::*, - }; + pub use _all::*; + } /// Parented namespace of the module. #[ cfg( feature = "enabled" ) ] + #[ allow( unused_imports ) ] pub mod orphan { + use super::*; + + mod _all + { + use super::super::*; + pub use exposed::*; + } + #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use _all::*; + } /// Exposed namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; - #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use quote:: + mod _all { - format_ident, - quote, - quote_spanned, - }; + use super::super::*; + pub use prelude::*; - #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super:: - { - prelude::*, - }; + #[ cfg( feature = "attr" ) ] + pub use attr::exposed::*; + #[ cfg( feature = "attr_prop" ) ] + pub use attr_prop::exposed::*; + #[ cfg( feature = "components" ) ] + pub use components::exposed::*; + #[ cfg( feature = "container_kind" ) ] + pub use container_kind::exposed::*; + #[ cfg( feature = "ct" ) ] + pub use ct::exposed::*; + #[ cfg( feature = "derive" ) ] + pub use derive::exposed::*; + #[ cfg( feature = "diag" ) ] + pub use diag::exposed::*; + #[ cfg( feature = "equation" ) ] + pub use equation::exposed::*; + #[ cfg( feature = "generic_args" ) ] + pub use generic_args::exposed::*; + #[ cfg( feature = "generic_params" ) ] + pub use generic_params::exposed::*; + #[ cfg( feature = "item" ) ] + pub use item::exposed::*; + #[ cfg( feature = "item_struct" ) ] + pub use item_struct::exposed::*; + #[ cfg( feature = "name" ) ] + pub use name::exposed::*; + #[ cfg( feature = "kw" ) ] + pub use kw::exposed::*; + #[ cfg( feature = "phantom" ) ] + pub use phantom::exposed::*; + #[ cfg( feature = "punctuated" ) ] + pub use punctuated::exposed::*; + #[ cfg( feature = "quantifier" ) ] + pub use quantifier::exposed::*; + #[ cfg( feature = "struct_like" ) ] + pub use struct_like::exposed::*; + #[ cfg( feature = "tokens" ) ] + pub use tokens::exposed::*; + #[ cfg( feature = "typ" ) ] + pub use typ::exposed::*; + #[ cfg( feature = "typed" ) ] + pub use typed::exposed::*; + + pub use iter::exposed::*; + + } #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::file:: - { - attr::exposed::*, - attr_prop::exposed::*, - container_kind::exposed::*, - derive::orphan::*, - diag::exposed::*, - drop::exposed::*, - equation::exposed::*, - generic_args::exposed::*, - generic_params::exposed::*, - item::exposed::*, - item_struct::exposed::*, - iter::exposed::*, - name::exposed::*, - phantom::exposed::*, - punctuated::exposed::*, - quantifier::exposed::*, - struct_like::exposed::*, - tokens::exposed::*, - typ::exposed::*, - }; + pub use _all::*; } /// Prelude to use essentials: `use my_module::prelude::*`. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; + + mod _all + { + use super::super::*; + // pub use prelude::*; + + #[ cfg( feature = "attr" ) ] + pub use attr::prelude::*; + #[ cfg( feature = "attr_prop" ) ] + pub use attr_prop::prelude::*; + #[ cfg( feature = "components" ) ] + pub use components::prelude::*; + #[ cfg( feature = "container_kind" ) ] + pub use container_kind::prelude::*; + #[ cfg( feature = "ct" ) ] + pub use ct::prelude::*; + #[ cfg( feature = "derive" ) ] + pub use derive::prelude::*; + #[ cfg( feature = "diag" ) ] + pub use diag::prelude::*; + #[ cfg( feature = "equation" ) ] + pub use equation::prelude::*; + #[ cfg( feature = "generic_args" ) ] + pub use generic_args::prelude::*; + #[ cfg( feature = "generic_params" ) ] + pub use generic_params::prelude::*; + #[ cfg( feature = "item" ) ] + pub use item::prelude::*; + #[ cfg( feature = "item_struct" ) ] + pub use item_struct::prelude::*; + #[ cfg( feature = "name" ) ] + pub use name::prelude::*; + #[ cfg( feature = "kw" ) ] + pub use kw::exposed::*; + #[ cfg( feature = "phantom" ) ] + pub use phantom::prelude::*; + #[ cfg( feature = "punctuated" ) ] + pub use punctuated::prelude::*; + #[ cfg( feature = "quantifier" ) ] + pub use quantifier::prelude::*; + #[ cfg( feature = "struct_like" ) ] + pub use struct_like::prelude::*; + #[ cfg( feature = "tokens" ) ] + pub use tokens::prelude::*; + #[ cfg( feature = "typ" ) ] + pub use typ::prelude::*; + #[ cfg( feature = "typed" ) ] + pub use typed::prelude::*; + + pub use iter::prelude::*; + + } + + #[ doc( inline ) ] + pub use _all::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] pub use ::interval_adapter::prelude::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] pub use ::syn; #[ doc( inline ) ] @@ -183,13 +320,15 @@ pub mod prelude #[ allow( unused_imports ) ] pub use ::quote:: { + quote, quote as qt, + quote_spanned, format_ident, }; - #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use ::syn::spanned::Spanned; + // #[ doc( inline ) ] + // #[ allow( unused_imports ) ] + // pub use ::syn::spanned::Spanned; #[ doc( inline ) ] #[ allow( unused_imports ) ] @@ -197,6 +336,7 @@ pub mod prelude { parse::ParseStream, Token, + spanned::Spanned, braced, bracketed, custom_keyword, @@ -209,31 +349,6 @@ pub mod prelude parse_quote_spanned as parse_qt_spanned, }; - #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::file:: - { - attr::prelude::*, - attr_prop::prelude::*, - container_kind::prelude::*, - derive::orphan::*, - diag::prelude::*, - drop::prelude::*, - equation::prelude::*, - generic_args::prelude::*, - generic_params::prelude::*, - item::prelude::*, - item_struct::prelude::*, - iter::prelude::*, - name::prelude::*, - phantom::prelude::*, - punctuated::prelude::*, - quantifier::prelude::*, - struct_like::prelude::*, - tokens::prelude::*, - typ::prelude::*, - }; - } // qqq : introduce features. make it smart. discuss list of features before implementing diff --git a/module/core/macro_tools/src/name.rs b/module/core/macro_tools/src/name.rs index b88fc03f0a..085899942c 100644 --- a/module/core/macro_tools/src/name.rs +++ b/module/core/macro_tools/src/name.rs @@ -226,37 +226,45 @@ pub( crate ) mod private #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { - pub use super::protected as name; + use super::*; + + pub use super::super::name; + // pub use super::own as name; + #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::private::Name; + pub use private::Name; } diff --git a/module/core/macro_tools/src/phantom.rs b/module/core/macro_tools/src/phantom.rs index 32f2de06b0..ebcd408cef 100644 --- a/module/core/macro_tools/src/phantom.rs +++ b/module/core/macro_tools/src/phantom.rs @@ -93,7 +93,20 @@ pub( crate ) mod private }, syn::Fields::Unit => { - // No fields to modify in a unit struct + let phantom_field : syn::Field = syn::parse_quote! + { + #phantom + }; + + // Replace syn::Fields::Unit to syn::Fields::Unnamed + input.fields = syn::Fields::Unnamed + ( + syn::FieldsUnnamed + { + paren_token : Default::default(), + unnamed : syn::punctuated::Punctuated::from_iter( vec![phantom_field] ) + } + ) } }; @@ -179,23 +192,18 @@ pub( crate ) mod private #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -pub mod protected +#[ allow( unused_imports ) ] +/// Own namespace of the module. +pub mod own { - - //! - //! Responsible for generating marker `PhantomData` fields to avoid the rule requiring the usage of all generic parameters in a struct. This is often necessary to ensure that Rust's type system correctly tracks the ownership and lifetimes of these parameters without needing them to be explicitly used in the struct's fields. - //! - //! Functions and structures to handle and manipulate `PhantomData` fields in structs using the `syn` crate. These utilities ensure that generic parameters are correctly accounted for in type checking, even if they are not directly used in the struct's fields. - //! + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { add_to_item, tuple, @@ -203,22 +211,27 @@ pub mod protected } /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { }; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { - pub use super::protected as phantom; + use super::*; + + pub use super::super::phantom; + // pub use super::own as phantom; + #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super:: @@ -228,6 +241,8 @@ pub mod exposed } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; } diff --git a/module/core/macro_tools/src/punctuated.rs b/module/core/macro_tools/src/punctuated.rs index 0eb1eb50dd..7850550e4e 100644 --- a/module/core/macro_tools/src/punctuated.rs +++ b/module/core/macro_tools/src/punctuated.rs @@ -22,39 +22,41 @@ pub( crate ) mod private #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -pub mod protected +#[ allow( unused_imports ) ] +/// Own namespace of the module. +pub mod own { - //! - //! Structures and functions for handling `syn::punctuated::Punctuated` collections. - //! - //! This module provides functionality to manipulate and ensure correct punctuation in `syn::punctuated::Punctuated` collections, commonly used in procedural macros to represent sequences of elements separated by punctuation marks, such as commas. - //! + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { ensure_trailing_comma, }; } /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { - pub use super::protected as punctuated; + use super::*; + + pub use super::super::punctuated; + // pub use super::own as punctuated; + #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super:: @@ -64,6 +66,8 @@ pub mod exposed } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; } diff --git a/module/core/macro_tools/src/quantifier.rs b/module/core/macro_tools/src/quantifier.rs index 15901b7f89..8a9e83d0b8 100644 --- a/module/core/macro_tools/src/quantifier.rs +++ b/module/core/macro_tools/src/quantifier.rs @@ -75,7 +75,7 @@ pub( crate ) mod private T1 : Element + syn::parse::Parse, T2 : Element + syn::parse::Parse, { - fn parse( input : ParseStream< '_ > ) -> Result< Self > + fn parse( input : ParseStream< '_ > ) -> syn::Result< Self > { Ok( Self( input.parse()?, input.parse()? ) ) } @@ -195,7 +195,7 @@ pub( crate ) mod private where T : Element + syn::parse::Parse + AsMuchAsPossibleNoDelimiter, { - fn parse( input : syn::parse::ParseStream< '_ > ) -> Result< Self > + fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self > { let mut items = vec![]; while !input.is_empty() @@ -207,14 +207,14 @@ pub( crate ) mod private } } -// zzz : make that working +// qqq : zzz : make that working // // impl< T > syn::parse::Parse // for Many< T > // where // T : Element + WhileDelimiter, // { -// fn parse( input : syn::parse::ParseStream< '_ > ) -> Result< Self > +// fn parse( input : syn::parse::ParseStream< '_ > ) -> syn::Result< Self > // { // let mut result = Self::new(); // loop @@ -242,94 +242,44 @@ pub( crate ) mod private // type Delimiter = syn::token::Pound; // } - impl syn::parse::Parse - for Many< AttributesInner > - { - fn parse( input : ParseStream< '_ > ) -> Result< Self > - { - let mut result = Self::new(); - loop - { - // let lookahead = input.lookahead1(); - if !input.peek( Token![ # ] ) - { - break; - } - result.0.push( input.parse()? ); - } - Ok( result ) - } - } - - impl syn::parse::Parse - for Many< AttributesOuter > - { - fn parse( input : ParseStream< '_ > ) -> Result< Self > - { - let mut result = Self::new(); - loop - { - // let lookahead = input.lookahead1(); - if !input.peek( Token![ # ] ) - { - break; - } - result.0.push( input.parse()? ); - } - Ok( result ) - } - } - - impl AsMuchAsPossibleNoDelimiter for syn::Item {} - - // impl syn::parse::Parse - // for Many< syn::Item > - // { - // fn parse( input : syn::parse::ParseStream< '_ > ) -> Result< Self > - // { - // let mut items = vec![]; - // while !input.is_empty() - // { - // let item : syn::Item = input.parse()?; - // items.push( item ); - // } - // Ok( Self( items ) ) - // } - // } - } #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { - pub use super::protected as quantifier; + use super::*; + + pub use super::super::quantifier; + // pub use super::own as quantifier; + #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { AsMuchAsPossibleNoDelimiter, Pair, @@ -338,11 +288,12 @@ pub mod exposed } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { }; } diff --git a/module/core/macro_tools/src/struct_like.rs b/module/core/macro_tools/src/struct_like.rs index 55b90ba0eb..8839e7b2b8 100644 --- a/module/core/macro_tools/src/struct_like.rs +++ b/module/core/macro_tools/src/struct_like.rs @@ -6,10 +6,9 @@ pub( crate ) mod private { use crate::*; - // use interval_adapter::BoundExt; /// Enum to encapsulate either a field from a struct or a variant from an enum. - #[ derive( Debug, PartialEq ) ] + #[ derive( Debug, PartialEq, Clone ) ] pub enum FieldOrVariant< 'a > { /// Represents a field within a struct or union. @@ -18,6 +17,10 @@ pub( crate ) mod private Variant( &'a syn::Variant ), } + impl< 'a > Copy for FieldOrVariant< 'a > + { + } + impl< 'a > From< &'a syn::Field > for FieldOrVariant< 'a > { fn from( field : &'a syn::Field ) -> Self @@ -245,25 +248,27 @@ pub( crate ) mod private impl StructLike { + /// Returns an iterator over elements of the item. - pub fn elements< 'a >( &'a self ) -> impl IterTrait< 'a, FieldOrVariant< 'a > > + 'a + // pub fn elements< 'a >( &'a self ) -> impl IterTrait< 'a, FieldOrVariant< 'a > > + 'a + pub fn elements< 'a >( &'a self ) -> BoxedIter< 'a, FieldOrVariant< 'a > > { match self { StructLike::Unit( _ ) => { let empty : Vec< FieldOrVariant< 'a > > = vec![]; - Box::new( empty.into_iter() ) as Box< dyn IterTrait< 'a, FieldOrVariant< 'a > > > + Box::new( empty.into_iter() ) }, StructLike::Struct( item ) => { let fields = item.fields.iter().map( FieldOrVariant::from ); - Box::new( fields ) as Box< dyn IterTrait< 'a, FieldOrVariant< 'a > > > + Box::new( fields ) }, StructLike::Enum( item ) => { let variants = item.variants.iter().map( FieldOrVariant::from ); - Box::new( variants ) as Box< dyn IterTrait< 'a, FieldOrVariant< 'a > > > + Box::new( variants ) }, } } @@ -349,11 +354,10 @@ pub( crate ) mod private } /// Returns an iterator over fields of the item. - // pub fn fields( &self ) -> Box< dyn Iterator< Item = &syn::Field > + '_ > - pub fn fields< 'a >( &'a self ) -> Box< dyn IterTrait< 'a, &'a syn::Field > + '_ > // pub fn fields< 'a >( &'a self ) -> impl IterTrait< 'a, &'a syn::Field > + pub fn fields< 'a >( &'a self ) -> BoxedIter< 'a, &'a syn::Field > { - match self + let result : BoxedIter< 'a, &'a syn::Field > = match self { StructLike::Unit( _item ) => { @@ -367,14 +371,13 @@ pub( crate ) mod private { Box::new( std::iter::empty() ) }, - } + }; + result } /// Extracts the name of each field. - // pub fn field_names( &self ) -> Box< dyn Iterator< Item = Option< &syn::Ident > > + '_ > - // pub fn field_names< 'a >( &'a self ) -> Box< dyn IterTrait< 'a, Option< &'a syn::Ident > > + '_ > - // pub fn field_names< 'a >( &'a self ) -> Option< Box< dyn IterTrait< 'a, &'a syn::Ident > + '_ > > - pub fn field_names< 'a >( &'a self ) -> Option< impl IterTrait< 'a, &'a syn::Ident > + '_ > + // pub fn field_names< 'a >( &'a self ) -> Option< impl IterTrait< 'a, &'a syn::Ident > + '_ > + pub fn field_names< 'a >( &'a self ) -> Option< BoxedIter< 'a, &'a syn::Ident >> { match self { @@ -388,26 +391,33 @@ pub( crate ) mod private }, StructLike::Enum( _item ) => { - Some( Box::new( self.fields().map( | field | field.ident.as_ref().unwrap() ) ) ) - // Box::new( std::iter::empty() ) + let iter = Box::new( self.fields().map( | field | field.ident.as_ref().unwrap() ) ); + Some( iter ) }, } - - // Box::new( self.fields().map( | field | field.ident.as_ref() ) ) } /// Extracts the type of each field. - // pub fn field_types( &self ) -> Box< dyn Iterator< Item = &syn::Type > + '_ > - // pub fn field_types< 'a >( &'a self ) -> Box< dyn IterTrait< 'a, &'a syn::Type > + '_ > - pub fn field_types< 'a >( &'a self ) -> impl IterTrait< 'a, &'a syn::Type > + pub fn field_types<'a>( &'a self ) + -> BoxedIter< 'a, &'a syn::Type > + // -> std::iter::Map + // < + // std::boxed::Box< dyn _IterTrait< '_, &syn::Field > + 'a >, + // impl FnMut( &'a syn::Field ) -> &'a syn::Type + 'a, + // > { - Box::new( self.fields().map( | field | &field.ty ) ) + Box::new( self.fields().map( move | field | &field.ty ) ) } /// Extracts the name of each field. - // pub fn field_attrs( &self ) -> Box< dyn Iterator< Item = &Vec< syn::Attribute > > + '_ > - // pub fn field_attrs< 'a >( &'a self ) -> Box< dyn IterTrait< 'a, &'a Vec< syn::Attribute > > + '_ > - pub fn field_attrs< 'a >( &'a self ) -> impl IterTrait< 'a, &'a Vec< syn::Attribute > > + // pub fn field_attrs< 'a >( &'a self ) -> impl IterTrait< 'a, &'a Vec< syn::Attribute > > + pub fn field_attrs<'a>( &'a self ) + -> BoxedIter< 'a, &'a Vec< syn::Attribute > > + // -> std::iter::Map + // < + // std::boxed::Box< dyn _IterTrait< '_, &syn::Field > + 'a >, + // impl FnMut( &'a syn::Field ) -> &'a Vec< syn::Attribute > + 'a, + // > { Box::new( self.fields().map( | field | &field.attrs ) ) } @@ -427,17 +437,17 @@ pub( crate ) mod private #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { StructLike, FieldOrVariant, @@ -445,23 +455,28 @@ pub mod protected } /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { - pub use super::protected as struct_like; + use super::*; + pub use super::super::struct_like; + #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; } diff --git a/module/core/macro_tools/src/tokens.rs b/module/core/macro_tools/src/tokens.rs index 7a09fc4689..872357a610 100644 --- a/module/core/macro_tools/src/tokens.rs +++ b/module/core/macro_tools/src/tokens.rs @@ -75,41 +75,48 @@ pub( crate ) mod private #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { - pub use super::protected as tokens; + use super::*; + + pub use super::super::tokens; + // pub use super::own as tokens; + #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { Tokens, }; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; } diff --git a/module/core/macro_tools/src/typ.rs b/module/core/macro_tools/src/typ.rs index 609cc717e3..1d865d8ab8 100644 --- a/module/core/macro_tools/src/typ.rs +++ b/module/core/macro_tools/src/typ.rs @@ -90,25 +90,6 @@ pub( crate ) mod private vec![ ty ] } -// /// Extract generics from a type. -// pub fn all_type_parameters( type_example : &syn::Type ) -// -> -// Option< syn::punctuated::Punctuated< syn::GenericArgument, syn::token::Comma > > -// { -// if let syn::Type::Path( type_path ) = type_example -// { -// let segments = &type_path.path.segments; -// let last_segment = segments.last()?; -// -// if let syn::PathArguments::AngleBracketed( generics ) = &last_segment.arguments -// { -// return Some( generics.args.clone() ); -// } -// } -// None -// } - - /// Checks if a given [`syn::Type`] is an `Option` type. /// /// This function examines a type to determine if it represents an `Option`. @@ -156,45 +137,52 @@ pub( crate ) mod private #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { type_rightmost, type_parameters, - // all_type_parameters, is_optional, parameter_first, }; } /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { - pub use super::protected as typ; + use super::*; + + pub use super::super::typ; + + // pub use super::own as typ; + #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; } diff --git a/module/core/macro_tools/src/typed.rs b/module/core/macro_tools/src/typed.rs new file mode 100644 index 0000000000..50fdf6036d --- /dev/null +++ b/module/core/macro_tools/src/typed.rs @@ -0,0 +1,61 @@ +//! +//! Typed parsing. +//! + +/// Internal namespace. +pub( crate ) mod private +{ + // use crate::*; + +} + +#[ doc( inline ) ] +#[ allow( unused_imports ) ] +pub use own::*; + +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own +{ + use super::*; + + #[ doc( inline ) ] + pub use orphan::*; + + #[ doc( inline ) ] + pub use private:: + { + }; + + pub use syn::{ parse_quote, parse_quote as qt }; + +} + +/// Orphan namespace of the module. +#[ allow( unused_imports ) ] +pub mod orphan +{ + use super::*; + #[ doc( inline ) ] + pub use exposed::*; +} + +/// Exposed namespace of the module. +#[ allow( unused_imports ) ] +pub mod exposed +{ + use super::*; + pub use super::super::typed; + + // pub use super::own as typ; + + #[ doc( inline ) ] + pub use prelude::*; +} + +/// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] +pub mod prelude +{ + use super::*; +} diff --git a/module/core/macro_tools/tests/inc/attr_prop_test.rs b/module/core/macro_tools/tests/inc/attr_prop_test.rs index e2fdb5ecb6..4621031b8a 100644 --- a/module/core/macro_tools/tests/inc/attr_prop_test.rs +++ b/module/core/macro_tools/tests/inc/attr_prop_test.rs @@ -4,6 +4,7 @@ use quote::ToTokens; #[ test ] fn attr_prop_test() { + use the_module::{ AttributePropertyComponent, AttributePropertyBoolean, AttributePropertyOptionalSingletone }; #[ derive( Debug, Default, Clone, Copy ) ] pub struct DebugMarker; @@ -11,10 +12,10 @@ fn attr_prop_test() #[ derive( Debug, Default, Clone, Copy ) ] pub struct EnabledMarker; - pub trait AttributePropertyComponent - { - const KEYWORD : &'static str; - } + // pub trait AttributePropertyComponent + // { + // const KEYWORD : &'static str; + // } impl AttributePropertyComponent for DebugMarker { @@ -104,6 +105,8 @@ fn attr_prop_test() #[ test ] fn attribute_property_enabled() { + use the_module::AttributePropertyOptionalSingletone; + // Test default value let attr : AttributePropertyOptionalSingletone = Default::default(); assert_eq!( attr.internal(), None ); diff --git a/module/core/macro_tools/tests/inc/attr_test.rs b/module/core/macro_tools/tests/inc/attr_test.rs index dab489f65d..ff787e8f00 100644 --- a/module/core/macro_tools/tests/inc/attr_test.rs +++ b/module/core/macro_tools/tests/inc/attr_test.rs @@ -1,5 +1,6 @@ use super::*; +use the_module::{ attr, qt, Result }; // @@ -35,6 +36,7 @@ fn is_standard_edge_cases() #[ test ] fn attribute_component_from_meta() { + use the_module::AttributeComponent; struct MyComponent; impl AttributeComponent for MyComponent @@ -74,3 +76,67 @@ fn attribute_component_from_meta() // Assert that the construction failed assert!( result.is_err() ); } + +#[ test ] +fn attribute_basic() -> Result< () > +{ + use macro_tools::syn::parse::Parser; + + // test.case( "AttributesOuter" ); + let code = qt! + { + #[ derive( Copy ) ] + #[ derive( Clone ) ] + #[ derive( Debug ) ] + }; + let got = syn::parse2::< the_module::AttributesOuter >( code ).unwrap(); + let exp = the_module::AttributesOuter::from( syn::Attribute::parse_outer.parse2( qt! + { + #[ derive( Copy ) ] + #[ derive( Clone ) ] + #[ derive( Debug ) ] + } )? ); + a_id!( got, exp ); + + // test.case( "AttributesInner" ); + let code = qt! + { + // #![ deny( missing_docs ) ] + #![ warn( something ) ] + }; + let got = syn::parse2::< the_module::AttributesInner >( code ).unwrap(); + let exp = the_module::AttributesInner::from( syn::Attribute::parse_inner.parse2( qt! + { + // #![ deny( missing_docs ) ] + #![ warn( something ) ] + } )? ); + a_id!( got, exp ); + + // test.case( "AttributesInner" ); + let code = qt! + { + #![ warn( missing_docs1 ) ] + #![ warn( missing_docs2 ) ] + #[ warn( something1 ) ] + #[ warn( something2 ) ] + }; + let got = syn::parse2::< the_module::Pair< the_module::AttributesInner, the_module::AttributesOuter > >( code ).unwrap(); + let exp = the_module::Pair::from + (( + the_module::AttributesInner::from( syn::Attribute::parse_inner.parse2( qt! + { + #![ warn( missing_docs1 ) ] + #![ warn( missing_docs2 ) ] + } )? ), + the_module::AttributesOuter::from( syn::Attribute::parse_outer.parse2( qt! + { + #[ warn( something1 ) ] + #[ warn( something2 ) ] + } )? ), + )); + a_id!( got, exp ); + + // + + Ok( () ) +} diff --git a/module/core/macro_tools/tests/inc/compile_time_test.rs b/module/core/macro_tools/tests/inc/compile_time_test.rs new file mode 100644 index 0000000000..90e9dd7fca --- /dev/null +++ b/module/core/macro_tools/tests/inc/compile_time_test.rs @@ -0,0 +1,40 @@ + +use super::*; + +// + +#[ test ] +fn concat() +{ + use the_module::ct; + + const KEYWORD : &'static str = "keyword"; + let got = ct::str::concat! + ( + "Known attirbutes are : ", + KEYWORD, + ".", + ); + let exp = "Known attirbutes are : keyword."; + a_id!( got, exp ); + +} + +// + +#[ test ] +fn format() +{ + use the_module::ct; + + const KEYWORD : &'static str = "keyword"; + let got = ct::str::format! + ( + "Known attirbutes are : {}{}", + KEYWORD, + ".", + ); + let exp = "Known attirbutes are : keyword."; + a_id!( got, exp ); + +} diff --git a/module/core/macro_tools/tests/inc/container_kind_test.rs b/module/core/macro_tools/tests/inc/container_kind_test.rs index e6669410a1..b88fae9b22 100644 --- a/module/core/macro_tools/tests/inc/container_kind_test.rs +++ b/module/core/macro_tools/tests/inc/container_kind_test.rs @@ -1,5 +1,6 @@ use super::*; +use the_module::qt; // diff --git a/module/core/macro_tools/tests/inc/derive_test.rs b/module/core/macro_tools/tests/inc/derive_test.rs index b6983e34d5..9142c0cadd 100644 --- a/module/core/macro_tools/tests/inc/derive_test.rs +++ b/module/core/macro_tools/tests/inc/derive_test.rs @@ -6,7 +6,7 @@ use super::*; #[test] fn named_fields_with_named_fields() { - use syn::{parse_quote, punctuated::Punctuated, Field, token::Comma}; + use syn::{ parse_quote, punctuated::Punctuated, Field, token::Comma }; use the_module::derive; let ast: syn::DeriveInput = parse_quote! @@ -21,8 +21,8 @@ fn named_fields_with_named_fields() let result = derive::named_fields( &ast ).expect( "Expected successful extraction of named fields" ); let mut expected_fields = Punctuated::new(); - let field_a : Field = parse_quote! { a: i32 }; - let field_b : Field = parse_quote! { b: String }; + let field_a : Field = parse_quote! { a : i32 }; + let field_b : Field = parse_quote! { b : String }; expected_fields.push_value( field_a); expected_fields.push_punct( Comma::default() ); expected_fields.push_value( field_b ); diff --git a/module/core/macro_tools/tests/inc/diag_test.rs b/module/core/macro_tools/tests/inc/diag_test.rs index e39db7d824..6ac8786a9b 100644 --- a/module/core/macro_tools/tests/inc/diag_test.rs +++ b/module/core/macro_tools/tests/inc/diag_test.rs @@ -1,5 +1,6 @@ use super::*; +use the_module::{ qt, tree_print }; // diff --git a/module/core/macro_tools/tests/inc/equation_test.rs b/module/core/macro_tools/tests/inc/equation_test.rs index 735d8261fc..6ae0e9c806 100644 --- a/module/core/macro_tools/tests/inc/equation_test.rs +++ b/module/core/macro_tools/tests/inc/equation_test.rs @@ -1,5 +1,6 @@ use super::*; +use the_module::{ parse_quote, qt, code_to_str, tree_print, Result }; // @@ -10,6 +11,7 @@ tests_impls! fn equation_test() -> Result< () > { use syn::spanned::Spanned; + use the_module::equation; // test.case( "basic" ); let input = qt! @@ -77,6 +79,7 @@ tests_impls! fn equation_from_meta_test() { + use the_module::equation; let attr1 : syn::Attribute = syn::parse_quote!( #[ default( 31 ) ] ); tree_print!( attr1 ); diff --git a/module/core/macro_tools/tests/inc/generic_args_test.rs b/module/core/macro_tools/tests/inc/generic_args_test.rs index 8076737930..56cbe65c50 100644 --- a/module/core/macro_tools/tests/inc/generic_args_test.rs +++ b/module/core/macro_tools/tests/inc/generic_args_test.rs @@ -1,5 +1,6 @@ use super::*; +use the_module::parse_quote; // diff --git a/module/core/macro_tools/tests/inc/generic_params_test.rs b/module/core/macro_tools/tests/inc/generic_params_test.rs index 12e82142a9..0e7b771367 100644 --- a/module/core/macro_tools/tests/inc/generic_params_test.rs +++ b/module/core/macro_tools/tests/inc/generic_params_test.rs @@ -1,5 +1,6 @@ use super::*; +use the_module::parse_quote; // diff --git a/module/core/macro_tools/tests/inc/mod.rs b/module/core/macro_tools/tests/inc/mod.rs index 9ed0a80bee..c28692fdf0 100644 --- a/module/core/macro_tools/tests/inc/mod.rs +++ b/module/core/macro_tools/tests/inc/mod.rs @@ -3,8 +3,6 @@ use super::*; #[ allow( unused_imports ) ] use test_tools::exposed::*; -#[ allow( unused_imports ) ] -use the_module::protected::*; #[ allow( unused_imports ) ] #[ cfg( feature = "enabled" ) ] @@ -14,23 +12,39 @@ mod if_enabled use super::*; + #[ cfg( feature = "attr" ) ] mod attr_test; + #[ cfg( feature = "attr_prop" ) ] mod attr_prop_test; mod basic_test; + #[ cfg( feature = "ct" ) ] + mod compile_time_test; + #[ cfg( feature = "container_kind" ) ] mod container_kind_test; + #[ cfg( feature = "derive" ) ] mod derive_test; + #[ cfg( feature = "diag" ) ] mod diag_test; mod drop_test; + #[ cfg( feature = "equation" ) ] mod equation_test; + #[ cfg( feature = "generic_args" ) ] mod generic_args_test; + #[ cfg( feature = "generic_params" ) ] mod generic_params_test; + #[ cfg( feature = "item" ) ] mod item_test; + #[ cfg( feature = "item_struct" ) ] mod item_struct_test; + #[ cfg( feature = "phantom" ) ] mod phantom_test; + #[ cfg( feature = "quantifier" ) ] mod quantifier_test; + #[ cfg( feature = "struct_like" ) ] mod struct_like_test; - mod syntax_test; + #[ cfg( feature = "tokens" ) ] mod tokens_test; + #[ cfg( feature = "typ" ) ] mod typ_test; } diff --git a/module/core/macro_tools/tests/inc/phantom_test.rs b/module/core/macro_tools/tests/inc/phantom_test.rs index 44c3610e66..65ad2e653a 100644 --- a/module/core/macro_tools/tests/inc/phantom_test.rs +++ b/module/core/macro_tools/tests/inc/phantom_test.rs @@ -1,5 +1,6 @@ use super::*; +use the_module::{ tree_print }; #[ test ] fn phantom_add_basic() diff --git a/module/core/macro_tools/tests/inc/quantifier_test.rs b/module/core/macro_tools/tests/inc/quantifier_test.rs index 5a6c59bcf3..a0e3a52ad8 100644 --- a/module/core/macro_tools/tests/inc/quantifier_test.rs +++ b/module/core/macro_tools/tests/inc/quantifier_test.rs @@ -1,5 +1,6 @@ use super::*; +use the_module::{ qt, Result }; // diff --git a/module/core/macro_tools/tests/inc/syntax_test.rs b/module/core/macro_tools/tests/inc/syntax_test.rs deleted file mode 100644 index adddd1285d..0000000000 --- a/module/core/macro_tools/tests/inc/syntax_test.rs +++ /dev/null @@ -1,83 +0,0 @@ - -use super::*; - -// - -tests_impls! -{ - - // - - fn attribute() -> Result< () > - { - use macro_tools::syn::parse::Parser; - - // test.case( "AttributesOuter" ); - let code = qt! - { - #[ derive( Copy ) ] - #[ derive( Clone ) ] - #[ derive( Debug ) ] - }; - let got = syn::parse2::< the_module::AttributesOuter >( code ).unwrap(); - let exp = the_module::AttributesOuter::from( syn::Attribute::parse_outer.parse2( qt! - { - #[ derive( Copy ) ] - #[ derive( Clone ) ] - #[ derive( Debug ) ] - } )? ); - a_id!( got, exp ); - - // test.case( "AttributesInner" ); - let code = qt! - { - // #![ deny( missing_docs ) ] - #![ warn( something ) ] - }; - let got = syn::parse2::< the_module::AttributesInner >( code ).unwrap(); - let exp = the_module::AttributesInner::from( syn::Attribute::parse_inner.parse2( qt! - { - // #![ deny( missing_docs ) ] - #![ warn( something ) ] - } )? ); - a_id!( got, exp ); - - // test.case( "AttributesInner" ); - let code = qt! - { - #![ warn( missing_docs1 ) ] - #![ warn( missing_docs2 ) ] - #[ warn( something1 ) ] - #[ warn( something2 ) ] - }; - let got = syn::parse2::< the_module::Pair< the_module::AttributesInner, the_module::AttributesOuter > >( code ).unwrap(); - let exp = the_module::Pair::from - (( - the_module::AttributesInner::from( syn::Attribute::parse_inner.parse2( qt! - { - #![ warn( missing_docs1 ) ] - #![ warn( missing_docs2 ) ] - } )? ), - the_module::AttributesOuter::from( syn::Attribute::parse_outer.parse2( qt! - { - #[ warn( something1 ) ] - #[ warn( something2 ) ] - } )? ), - )); - a_id!( got, exp ); - - // - - Ok( () ) - } - - // - -} - -// - -tests_index! -{ - attribute, -} diff --git a/module/core/macro_tools/tests/inc/tokens_test.rs b/module/core/macro_tools/tests/inc/tokens_test.rs index fcae746f5d..8e26e06d57 100644 --- a/module/core/macro_tools/tests/inc/tokens_test.rs +++ b/module/core/macro_tools/tests/inc/tokens_test.rs @@ -1,5 +1,6 @@ use super::*; +use the_module::{ tree_print }; // diff --git a/module/core/macro_tools/tests/inc/typ_Test.rs b/module/core/macro_tools/tests/inc/typ_test.rs similarity index 94% rename from module/core/macro_tools/tests/inc/typ_Test.rs rename to module/core/macro_tools/tests/inc/typ_test.rs index 174c2c243b..cd3a08a7a0 100644 --- a/module/core/macro_tools/tests/inc/typ_Test.rs +++ b/module/core/macro_tools/tests/inc/typ_test.rs @@ -1,5 +1,6 @@ use super::*; +use the_module::qt; // @@ -7,7 +8,7 @@ use super::*; fn is_optional_with_option_type() { use syn::parse_str; - use macro_tools::typ::is_optional; + use the_module::typ::is_optional; let type_string = "Option"; let parsed_type : syn::Type = parse_str( type_string ).expect( "Type should parse correctly" ); @@ -19,7 +20,7 @@ fn is_optional_with_option_type() fn is_optional_with_non_option_type() { use syn::parse_str; - use macro_tools::typ::is_optional; + use the_module::typ::is_optional; let type_string = "Vec"; let parsed_type : syn::Type = parse_str( type_string ).expect( "Type should parse correctly" ); @@ -31,7 +32,7 @@ fn is_optional_with_non_option_type() fn is_optional_with_nested_option_type() { use syn::parse_str; - use macro_tools::typ::is_optional; + use the_module::typ::is_optional; let type_string = "Option>"; let parsed_type : syn::Type = parse_str( type_string ).expect( "Type should parse correctly" ); @@ -43,7 +44,7 @@ fn is_optional_with_nested_option_type() fn is_optional_with_similar_name_type() { use syn::parse_str; - use macro_tools::typ::is_optional; + use the_module::typ::is_optional; let type_string = "OptionalValue"; let parsed_type : syn::Type = parse_str( type_string ).expect( "Type should parse correctly" ); @@ -55,7 +56,7 @@ fn is_optional_with_similar_name_type() fn is_optional_with_empty_input() { use syn::{ parse_str, Type }; - use macro_tools::typ::is_optional; + use the_module::typ::is_optional; let type_string = ""; let parsed_type_result = parse_str::< Type >( type_string ); @@ -69,7 +70,7 @@ fn is_optional_with_empty_input() fn parameter_first_with_multiple_generics() { use syn::{ parse_str, Type }; - use macro_tools::typ::parameter_first; + use the_module::typ::parameter_first; let type_string = "Result, Error>"; let parsed_type : Type = parse_str( type_string ).expect( "Type should parse correctly" ); @@ -84,7 +85,7 @@ fn parameter_first_with_multiple_generics() fn parameter_first_with_no_generics() { use syn::{ parse_str, Type }; - use macro_tools::typ::parameter_first; + use the_module::typ::parameter_first; let type_string = "i32"; let parsed_type : Type = parse_str( type_string ).expect( "Type should parse correctly" ); @@ -101,7 +102,7 @@ fn parameter_first_with_no_generics() fn parameter_first_with_single_generic() { use syn::{ parse_str, Type }; - use macro_tools::typ::parameter_first; + use the_module::typ::parameter_first; let type_string = "Vec< i32 >"; let parsed_type : Type = parse_str( type_string ).expect( "Type should parse correctly" ); @@ -116,7 +117,7 @@ fn parameter_first_with_single_generic() fn parameter_first_with_deeply_nested_generics() { use syn::{ parse_str, Type }; - use macro_tools::typ::parameter_first; + use the_module::typ::parameter_first; let type_string = "Vec< HashMap< String, Option< i32 > > >"; let parsed_type : Type = parse_str( type_string ).expect( "Type should parse correctly" ); diff --git a/module/core/macro_tools/tests/smoke_test.rs b/module/core/macro_tools/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/core/macro_tools/tests/smoke_test.rs +++ b/module/core/macro_tools/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/core/mem_tools/Cargo.toml b/module/core/mem_tools/Cargo.toml index 08bc56fc1a..fd90f9d727 100644 --- a/module/core/mem_tools/Cargo.toml +++ b/module/core/mem_tools/Cargo.toml @@ -24,7 +24,7 @@ workspace = true features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] + include = [ "/rust/impl/mem", "/Cargo.toml", diff --git a/module/core/mem_tools/src/lib.rs b/module/core/mem_tools/src/lib.rs index fffffc6fdd..03270e0a05 100644 --- a/module/core/mem_tools/src/lib.rs +++ b/module/core/mem_tools/src/lib.rs @@ -26,15 +26,16 @@ pub mod mem; #[ doc( inline ) ] #[ allow( unused_imports ) ] #[ cfg( feature = "enabled" ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. +/// Own namespace of the module. #[ cfg( feature = "enabled" ) ] -pub mod protected +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::mem::orphan::*; @@ -42,20 +43,22 @@ pub mod protected /// Orphan namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::mem::exposed::*; @@ -63,8 +66,10 @@ pub mod exposed /// Prelude to use essentials: `use my_module::prelude::*`. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::mem::prelude::*; diff --git a/module/core/mem_tools/src/mem.rs b/module/core/mem_tools/src/mem.rs index b0c7e199f5..d56abd3dd6 100644 --- a/module/core/mem_tools/src/mem.rs +++ b/module/core/mem_tools/src/mem.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - // use crate::protected::*; + // use crate::own::*; /// /// Are two pointers points on the same data. @@ -64,9 +64,11 @@ pub( crate ) mod private } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super:: @@ -77,11 +79,13 @@ pub mod protected #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super:: @@ -95,14 +99,17 @@ pub mod orphan } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; } diff --git a/module/core/mem_tools/tests/smoke_test.rs b/module/core/mem_tools/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/core/mem_tools/tests/smoke_test.rs +++ b/module/core/mem_tools/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/core/meta_tools/Cargo.toml b/module/core/meta_tools/Cargo.toml index 1fc7ff399b..282db2f43f 100644 --- a/module/core/meta_tools/Cargo.toml +++ b/module/core/meta_tools/Cargo.toml @@ -24,7 +24,7 @@ workspace = true features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] + [features] default = [ diff --git a/module/core/meta_tools/tests/smoke_test.rs b/module/core/meta_tools/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/core/meta_tools/tests/smoke_test.rs +++ b/module/core/meta_tools/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/core/mod_interface/Cargo.toml b/module/core/mod_interface/Cargo.toml index bc096312e0..549671e950 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.21.0" +version = "0.22.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", @@ -23,7 +23,7 @@ workspace = true [package.metadata.docs.rs] features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] + [features] default = [ "enabled" ] diff --git a/module/core/mod_interface/Readme.md b/module/core/mod_interface/Readme.md index 1115dea469..fcb4643b8f 100644 --- a/module/core/mod_interface/Readme.md +++ b/module/core/mod_interface/Readme.md @@ -73,56 +73,64 @@ pub mod inner pub fn inner_is() -> bool { true } } - /// Protected namespace of the module. - pub mod protected + /// Own namespace of the module. + pub mod own { - pub use super::orphan::*; + pub use orphan::*; } - pub use protected::*; + pub use own::*; /// Orphan namespace of the module. pub mod orphan { - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. pub mod exposed { - pub use super::prelude::*; + pub use prelude::*; } /// Prelude to use essentials: `use my_module::prelude::*`. pub mod prelude { - pub use super::private::inner_is; + pub use private::inner_is; } } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { - pub use super::orphan::*; + use super::*; + pub use orphan::*; pub use super::inner::orphan::*; } -pub use protected::*; +pub use own::*; /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { - pub use super::exposed::*; + use super::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { - pub use super::prelude::*; + use super::*; + pub use prelude::*; pub use super::inner::exposed::*; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; pub use super::inner::prelude::*; } ``` diff --git a/module/core/mod_interface/src/lib.rs b/module/core/mod_interface/src/lib.rs index 582ad8e8c9..30c7731f89 100644 --- a/module/core/mod_interface/src/lib.rs +++ b/module/core/mod_interface/src/lib.rs @@ -15,15 +15,16 @@ pub mod dependency #[ doc( inline ) ] #[ allow( unused_imports ) ] #[ cfg( feature = "enabled" ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. +/// Own namespace of the module. #[ cfg( feature = "enabled" ) ] -pub mod protected +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] @@ -33,27 +34,31 @@ pub mod protected /// Orphan namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; } /// Prelude to use essentials: `use my_module::prelude::*`. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use mod_interface_meta::*; diff --git a/module/core/mod_interface/tests/inc/derive/attr_debug/layer_a.rs b/module/core/mod_interface/tests/inc/derive/attr_debug/layer_a.rs index f1e9f256fb..8c49982711 100644 --- a/module/core/mod_interface/tests/inc/derive/attr_debug/layer_a.rs +++ b/module/core/mod_interface/tests/inc/derive/attr_debug/layer_a.rs @@ -4,14 +4,15 @@ mod private { } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; - /// layer_a_protected - pub fn layer_a_protected() -> bool + pub use orphan::*; + /// layer_a_own + pub fn layer_a_own() -> bool { true } @@ -19,14 +20,15 @@ pub mod protected #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; /// layer_a_orphan pub fn layer_a_orphan() -> bool { @@ -35,11 +37,12 @@ pub mod orphan } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; /// layer_a_exposed pub fn layer_a_exposed() -> bool { @@ -48,8 +51,10 @@ pub mod exposed } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; /// layer_a_prelude pub fn layer_a_prelude() -> bool { diff --git a/module/core/mod_interface/tests/inc/derive/layer/layer_a.rs b/module/core/mod_interface/tests/inc/derive/layer/layer_a.rs index f1e9f256fb..8c49982711 100644 --- a/module/core/mod_interface/tests/inc/derive/layer/layer_a.rs +++ b/module/core/mod_interface/tests/inc/derive/layer/layer_a.rs @@ -4,14 +4,15 @@ mod private { } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; - /// layer_a_protected - pub fn layer_a_protected() -> bool + pub use orphan::*; + /// layer_a_own + pub fn layer_a_own() -> bool { true } @@ -19,14 +20,15 @@ pub mod protected #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; /// layer_a_orphan pub fn layer_a_orphan() -> bool { @@ -35,11 +37,12 @@ pub mod orphan } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; /// layer_a_exposed pub fn layer_a_exposed() -> bool { @@ -48,8 +51,10 @@ pub mod exposed } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; /// layer_a_prelude pub fn layer_a_prelude() -> bool { diff --git a/module/core/mod_interface/tests/inc/derive/layer/layer_b.rs b/module/core/mod_interface/tests/inc/derive/layer/layer_b.rs index 8051e73936..1e15689f05 100644 --- a/module/core/mod_interface/tests/inc/derive/layer/layer_b.rs +++ b/module/core/mod_interface/tests/inc/derive/layer/layer_b.rs @@ -4,14 +4,15 @@ mod private { } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; - /// layer_b_protected - pub fn layer_b_protected() -> bool + pub use orphan::*; + /// layer_b_own + pub fn layer_b_own() -> bool { true } @@ -19,14 +20,15 @@ pub mod protected #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; /// layer_b_orphan pub fn layer_b_orphan() -> bool { @@ -35,11 +37,12 @@ pub mod orphan } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; /// layer_b_exposed pub fn layer_b_exposed() -> bool { @@ -48,8 +51,10 @@ pub mod exposed } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; /// layer_b_prelude pub fn layer_b_prelude() -> bool { diff --git a/module/core/mod_interface/tests/inc/derive/layer_bad_vis/layer_a.rs b/module/core/mod_interface/tests/inc/derive/layer_bad_vis/layer_a.rs index f1e9f256fb..8c49982711 100644 --- a/module/core/mod_interface/tests/inc/derive/layer_bad_vis/layer_a.rs +++ b/module/core/mod_interface/tests/inc/derive/layer_bad_vis/layer_a.rs @@ -4,14 +4,15 @@ mod private { } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; - /// layer_a_protected - pub fn layer_a_protected() -> bool + pub use orphan::*; + /// layer_a_own + pub fn layer_a_own() -> bool { true } @@ -19,14 +20,15 @@ pub mod protected #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; /// layer_a_orphan pub fn layer_a_orphan() -> bool { @@ -35,11 +37,12 @@ pub mod orphan } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; /// layer_a_exposed pub fn layer_a_exposed() -> bool { @@ -48,8 +51,10 @@ pub mod exposed } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; /// layer_a_prelude pub fn layer_a_prelude() -> bool { diff --git a/module/core/mod_interface/tests/inc/derive/layer_have_layer/layer_a.rs b/module/core/mod_interface/tests/inc/derive/layer_have_layer/layer_a.rs index 8ba8f1e9e6..dfffa8d8a8 100644 --- a/module/core/mod_interface/tests/inc/derive/layer_have_layer/layer_a.rs +++ b/module/core/mod_interface/tests/inc/derive/layer_have_layer/layer_a.rs @@ -5,8 +5,8 @@ use super::tools::*; mod private { - /// layer_a_protected - pub fn layer_a_protected() -> bool + /// layer_a_own + pub fn layer_a_own() -> bool { true } @@ -38,13 +38,13 @@ mod_interface! // orphan use super::private:: // { - // protected where layer_a_protected as layer_a_protected2, + // protected where layer_a_own as layer_a_own2, // layer_a_orphan, // exposed where layer_a_exposed, // prelude where layer_a_prelude, // }; - protected use { layer_a_protected }; + own use { layer_a_own }; orphan use layer_a_orphan; exposed use layer_a_exposed; prelude use layer_a_prelude; diff --git a/module/core/mod_interface/tests/inc/derive/layer_have_layer/layer_b.rs b/module/core/mod_interface/tests/inc/derive/layer_have_layer/layer_b.rs index 5ee8e574aa..9f17f61637 100644 --- a/module/core/mod_interface/tests/inc/derive/layer_have_layer/layer_b.rs +++ b/module/core/mod_interface/tests/inc/derive/layer_have_layer/layer_b.rs @@ -5,8 +5,8 @@ use super::tools::*; mod private { - /// layer_b_protected - pub fn layer_b_protected() -> bool + /// layer_b_own + pub fn layer_b_own() -> bool { true } @@ -42,7 +42,7 @@ pub struct SubStruct2 mod_interface! { - protected use layer_b_protected; + own use layer_b_own; orphan use { layer_b_orphan }; exposed use { layer_b_exposed }; prelude use layer_b_prelude; diff --git a/module/core/mod_interface/tests/inc/derive/layer_have_layer_cfg/layer_a.rs b/module/core/mod_interface/tests/inc/derive/layer_have_layer_cfg/layer_a.rs index 8ba8f1e9e6..dfffa8d8a8 100644 --- a/module/core/mod_interface/tests/inc/derive/layer_have_layer_cfg/layer_a.rs +++ b/module/core/mod_interface/tests/inc/derive/layer_have_layer_cfg/layer_a.rs @@ -5,8 +5,8 @@ use super::tools::*; mod private { - /// layer_a_protected - pub fn layer_a_protected() -> bool + /// layer_a_own + pub fn layer_a_own() -> bool { true } @@ -38,13 +38,13 @@ mod_interface! // orphan use super::private:: // { - // protected where layer_a_protected as layer_a_protected2, + // protected where layer_a_own as layer_a_own2, // layer_a_orphan, // exposed where layer_a_exposed, // prelude where layer_a_prelude, // }; - protected use { layer_a_protected }; + own use { layer_a_own }; orphan use layer_a_orphan; exposed use layer_a_exposed; prelude use layer_a_prelude; diff --git a/module/core/mod_interface/tests/inc/derive/layer_have_layer_cfg/layer_b.rs b/module/core/mod_interface/tests/inc/derive/layer_have_layer_cfg/layer_b.rs index 5ee8e574aa..9f17f61637 100644 --- a/module/core/mod_interface/tests/inc/derive/layer_have_layer_cfg/layer_b.rs +++ b/module/core/mod_interface/tests/inc/derive/layer_have_layer_cfg/layer_b.rs @@ -5,8 +5,8 @@ use super::tools::*; mod private { - /// layer_b_protected - pub fn layer_b_protected() -> bool + /// layer_b_own + pub fn layer_b_own() -> bool { true } @@ -42,7 +42,7 @@ pub struct SubStruct2 mod_interface! { - protected use layer_b_protected; + own use layer_b_own; orphan use { layer_b_orphan }; exposed use { layer_b_exposed }; prelude use layer_b_prelude; diff --git a/module/core/mod_interface/tests/inc/derive/layer_have_layer_separate_use/layer_a.rs b/module/core/mod_interface/tests/inc/derive/layer_have_layer_separate_use/layer_a.rs index b5b8b613f1..8d8d6b1faf 100644 --- a/module/core/mod_interface/tests/inc/derive/layer_have_layer_separate_use/layer_a.rs +++ b/module/core/mod_interface/tests/inc/derive/layer_have_layer_separate_use/layer_a.rs @@ -5,8 +5,8 @@ use super::tools::*; mod private { - /// layer_a_protected - pub fn layer_a_protected() -> bool + /// layer_a_own + pub fn layer_a_own() -> bool { true } @@ -36,7 +36,7 @@ mod private mod_interface! { - protected use { layer_a_protected }; + own use { layer_a_own }; orphan use layer_a_orphan; exposed use layer_a_exposed; prelude use layer_a_prelude; diff --git a/module/core/mod_interface/tests/inc/derive/layer_have_layer_separate_use/layer_b.rs b/module/core/mod_interface/tests/inc/derive/layer_have_layer_separate_use/layer_b.rs index 5ee8e574aa..9f17f61637 100644 --- a/module/core/mod_interface/tests/inc/derive/layer_have_layer_separate_use/layer_b.rs +++ b/module/core/mod_interface/tests/inc/derive/layer_have_layer_separate_use/layer_b.rs @@ -5,8 +5,8 @@ use super::tools::*; mod private { - /// layer_b_protected - pub fn layer_b_protected() -> bool + /// layer_b_own + pub fn layer_b_own() -> bool { true } @@ -42,7 +42,7 @@ pub struct SubStruct2 mod_interface! { - protected use layer_b_protected; + own use layer_b_own; orphan use { layer_b_orphan }; exposed use { layer_b_exposed }; prelude use layer_b_prelude; diff --git a/module/core/mod_interface/tests/inc/derive/layer_have_layer_separate_use_two/layer_a.rs b/module/core/mod_interface/tests/inc/derive/layer_have_layer_separate_use_two/layer_a.rs index b5b8b613f1..8d8d6b1faf 100644 --- a/module/core/mod_interface/tests/inc/derive/layer_have_layer_separate_use_two/layer_a.rs +++ b/module/core/mod_interface/tests/inc/derive/layer_have_layer_separate_use_two/layer_a.rs @@ -5,8 +5,8 @@ use super::tools::*; mod private { - /// layer_a_protected - pub fn layer_a_protected() -> bool + /// layer_a_own + pub fn layer_a_own() -> bool { true } @@ -36,7 +36,7 @@ mod private mod_interface! { - protected use { layer_a_protected }; + own use { layer_a_own }; orphan use layer_a_orphan; exposed use layer_a_exposed; prelude use layer_a_prelude; diff --git a/module/core/mod_interface/tests/inc/derive/layer_have_layer_separate_use_two/layer_b.rs b/module/core/mod_interface/tests/inc/derive/layer_have_layer_separate_use_two/layer_b.rs index 5ee8e574aa..9f17f61637 100644 --- a/module/core/mod_interface/tests/inc/derive/layer_have_layer_separate_use_two/layer_b.rs +++ b/module/core/mod_interface/tests/inc/derive/layer_have_layer_separate_use_two/layer_b.rs @@ -5,8 +5,8 @@ use super::tools::*; mod private { - /// layer_b_protected - pub fn layer_b_protected() -> bool + /// layer_b_own + pub fn layer_b_own() -> bool { true } @@ -42,7 +42,7 @@ pub struct SubStruct2 mod_interface! { - protected use layer_b_protected; + own use layer_b_own; orphan use { layer_b_orphan }; exposed use { layer_b_exposed }; prelude use layer_b_prelude; diff --git a/module/core/mod_interface/tests/inc/derive/layer_unknown_vis/layer_a.rs b/module/core/mod_interface/tests/inc/derive/layer_unknown_vis/layer_a.rs index f1e9f256fb..8c49982711 100644 --- a/module/core/mod_interface/tests/inc/derive/layer_unknown_vis/layer_a.rs +++ b/module/core/mod_interface/tests/inc/derive/layer_unknown_vis/layer_a.rs @@ -4,14 +4,15 @@ mod private { } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; - /// layer_a_protected - pub fn layer_a_protected() -> bool + pub use orphan::*; + /// layer_a_own + pub fn layer_a_own() -> bool { true } @@ -19,14 +20,15 @@ pub mod protected #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; /// layer_a_orphan pub fn layer_a_orphan() -> bool { @@ -35,11 +37,12 @@ pub mod orphan } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; /// layer_a_exposed pub fn layer_a_exposed() -> bool { @@ -48,8 +51,10 @@ pub mod exposed } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; /// layer_a_prelude pub fn layer_a_prelude() -> bool { diff --git a/module/core/mod_interface/tests/inc/derive/layer_use_cfg/layer_a.rs b/module/core/mod_interface/tests/inc/derive/layer_use_cfg/layer_a.rs index 8ba8f1e9e6..dfffa8d8a8 100644 --- a/module/core/mod_interface/tests/inc/derive/layer_use_cfg/layer_a.rs +++ b/module/core/mod_interface/tests/inc/derive/layer_use_cfg/layer_a.rs @@ -5,8 +5,8 @@ use super::tools::*; mod private { - /// layer_a_protected - pub fn layer_a_protected() -> bool + /// layer_a_own + pub fn layer_a_own() -> bool { true } @@ -38,13 +38,13 @@ mod_interface! // orphan use super::private:: // { - // protected where layer_a_protected as layer_a_protected2, + // protected where layer_a_own as layer_a_own2, // layer_a_orphan, // exposed where layer_a_exposed, // prelude where layer_a_prelude, // }; - protected use { layer_a_protected }; + own use { layer_a_own }; orphan use layer_a_orphan; exposed use layer_a_exposed; prelude use layer_a_prelude; diff --git a/module/core/mod_interface/tests/inc/derive/layer_use_cfg/layer_b.rs b/module/core/mod_interface/tests/inc/derive/layer_use_cfg/layer_b.rs index 5ee8e574aa..9f17f61637 100644 --- a/module/core/mod_interface/tests/inc/derive/layer_use_cfg/layer_b.rs +++ b/module/core/mod_interface/tests/inc/derive/layer_use_cfg/layer_b.rs @@ -5,8 +5,8 @@ use super::tools::*; mod private { - /// layer_b_protected - pub fn layer_b_protected() -> bool + /// layer_b_own + pub fn layer_b_own() -> bool { true } @@ -42,7 +42,7 @@ pub struct SubStruct2 mod_interface! { - protected use layer_b_protected; + own use layer_b_own; orphan use { layer_b_orphan }; exposed use { layer_b_exposed }; prelude use layer_b_prelude; diff --git a/module/core/mod_interface/tests/inc/derive/micro_modules/mod.rs b/module/core/mod_interface/tests/inc/derive/micro_modules/mod.rs index 3e924ca630..09c94a139e 100644 --- a/module/core/mod_interface/tests/inc/derive/micro_modules/mod.rs +++ b/module/core/mod_interface/tests/inc/derive/micro_modules/mod.rs @@ -9,8 +9,8 @@ mod private mod_interface! { - /// mod_protected - protected mod mod_protected; + /// mod_own + own mod mod_own; /// mod_orphan orphan mod mod_orphan; /// mod_exposed diff --git a/module/core/mod_interface/tests/inc/derive/micro_modules/mod_protected.rs b/module/core/mod_interface/tests/inc/derive/micro_modules/mod_protected.rs index 3bd5325a02..a6619cc0c4 100644 --- a/module/core/mod_interface/tests/inc/derive/micro_modules/mod_protected.rs +++ b/module/core/mod_interface/tests/inc/derive/micro_modules/mod_protected.rs @@ -1,5 +1,5 @@ -/// has_protected -pub fn has_protected() -> bool +/// has_own +pub fn has_own() -> bool { true } \ No newline at end of file diff --git a/module/core/mod_interface/tests/inc/derive/micro_modules_two/mod.rs b/module/core/mod_interface/tests/inc/derive/micro_modules_two/mod.rs index 3481dfdef2..9071caf2d1 100644 --- a/module/core/mod_interface/tests/inc/derive/micro_modules_two/mod.rs +++ b/module/core/mod_interface/tests/inc/derive/micro_modules_two/mod.rs @@ -9,10 +9,10 @@ mod private mod_interface! { - /// mod_protected1 - protected mod mod_protected1; - /// mod_protected2 - protected mod mod_protected2; + /// mod_own1 + own mod mod_own1; + /// mod_own2 + own mod mod_own2; /// mod_orphan1 orphan mod mod_orphan1; /// mod_orphan2 diff --git a/module/core/mod_interface/tests/inc/derive/micro_modules_two/mod_protected1.rs b/module/core/mod_interface/tests/inc/derive/micro_modules_two/mod_protected1.rs index c95649476e..a314e81b31 100644 --- a/module/core/mod_interface/tests/inc/derive/micro_modules_two/mod_protected1.rs +++ b/module/core/mod_interface/tests/inc/derive/micro_modules_two/mod_protected1.rs @@ -1,5 +1,5 @@ -/// has_protected1 -pub fn has_protected1() -> bool +/// has_own1 +pub fn has_own1() -> bool { true } \ No newline at end of file diff --git a/module/core/mod_interface/tests/inc/derive/micro_modules_two/mod_protected2.rs b/module/core/mod_interface/tests/inc/derive/micro_modules_two/mod_protected2.rs index 8466c075b3..5b59e31a83 100644 --- a/module/core/mod_interface/tests/inc/derive/micro_modules_two/mod_protected2.rs +++ b/module/core/mod_interface/tests/inc/derive/micro_modules_two/mod_protected2.rs @@ -1,5 +1,5 @@ -/// has_protected2 -pub fn has_protected2() -> bool +/// has_own2 +pub fn has_own2() -> bool { true } diff --git a/module/core/mod_interface/tests/inc/derive/micro_modules_two_joined/mod.rs b/module/core/mod_interface/tests/inc/derive/micro_modules_two_joined/mod.rs index da5ed051d0..ced5712479 100644 --- a/module/core/mod_interface/tests/inc/derive/micro_modules_two_joined/mod.rs +++ b/module/core/mod_interface/tests/inc/derive/micro_modules_two_joined/mod.rs @@ -9,12 +9,12 @@ mod private mod_interface! { - protected mod + own mod { - /// mod_protected1 - mod_protected1, - /// mod_protected2 - mod_protected2, + /// mod_own1 + mod_own1, + /// mod_own2 + mod_own2, }; orphan mod { diff --git a/module/core/mod_interface/tests/inc/derive/micro_modules_two_joined/mod_protected1.rs b/module/core/mod_interface/tests/inc/derive/micro_modules_two_joined/mod_protected1.rs index c95649476e..a314e81b31 100644 --- a/module/core/mod_interface/tests/inc/derive/micro_modules_two_joined/mod_protected1.rs +++ b/module/core/mod_interface/tests/inc/derive/micro_modules_two_joined/mod_protected1.rs @@ -1,5 +1,5 @@ -/// has_protected1 -pub fn has_protected1() -> bool +/// has_own1 +pub fn has_own1() -> bool { true } \ No newline at end of file diff --git a/module/core/mod_interface/tests/inc/derive/micro_modules_two_joined/mod_protected2.rs b/module/core/mod_interface/tests/inc/derive/micro_modules_two_joined/mod_protected2.rs index a163ea8af5..b442687a02 100644 --- a/module/core/mod_interface/tests/inc/derive/micro_modules_two_joined/mod_protected2.rs +++ b/module/core/mod_interface/tests/inc/derive/micro_modules_two_joined/mod_protected2.rs @@ -1,5 +1,5 @@ -/// has_protected2 -pub fn has_protected2() -> bool +/// has_own2 +pub fn has_own2() -> bool { true } \ No newline at end of file diff --git a/module/core/mod_interface/tests/inc/derive/use_as/layer_x.rs b/module/core/mod_interface/tests/inc/derive/use_as/layer_x.rs index f1e9f256fb..8c49982711 100644 --- a/module/core/mod_interface/tests/inc/derive/use_as/layer_x.rs +++ b/module/core/mod_interface/tests/inc/derive/use_as/layer_x.rs @@ -4,14 +4,15 @@ mod private { } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; - /// layer_a_protected - pub fn layer_a_protected() -> bool + pub use orphan::*; + /// layer_a_own + pub fn layer_a_own() -> bool { true } @@ -19,14 +20,15 @@ pub mod protected #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; /// layer_a_orphan pub fn layer_a_orphan() -> bool { @@ -35,11 +37,12 @@ pub mod orphan } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; /// layer_a_exposed pub fn layer_a_exposed() -> bool { @@ -48,8 +51,10 @@ pub mod exposed } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; /// layer_a_prelude pub fn layer_a_prelude() -> bool { diff --git a/module/core/mod_interface/tests/inc/derive/use_as/layer_y.rs b/module/core/mod_interface/tests/inc/derive/use_as/layer_y.rs index 8051e73936..1e15689f05 100644 --- a/module/core/mod_interface/tests/inc/derive/use_as/layer_y.rs +++ b/module/core/mod_interface/tests/inc/derive/use_as/layer_y.rs @@ -4,14 +4,15 @@ mod private { } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; - /// layer_b_protected - pub fn layer_b_protected() -> bool + pub use orphan::*; + /// layer_b_own + pub fn layer_b_own() -> bool { true } @@ -19,14 +20,15 @@ pub mod protected #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; /// layer_b_orphan pub fn layer_b_orphan() -> bool { @@ -35,11 +37,12 @@ pub mod orphan } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; /// layer_b_exposed pub fn layer_b_exposed() -> bool { @@ -48,8 +51,10 @@ pub mod exposed } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; /// layer_b_prelude pub fn layer_b_prelude() -> bool { diff --git a/module/core/mod_interface/tests/inc/derive/use_as/manual_only.rs b/module/core/mod_interface/tests/inc/derive/use_as/manual_only.rs index 816287978c..f6fcb2f162 100644 --- a/module/core/mod_interface/tests/inc/derive/use_as/manual_only.rs +++ b/module/core/mod_interface/tests/inc/derive/use_as/manual_only.rs @@ -5,9 +5,11 @@ use layer_x as layer_a; #[allow(unused_imports)] pub use protected :: * ; -#[doc = r" Protected namespace of the module."] -pub mod protected +#[doc = r" Own namespace of the module."] +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[doc(inline)] #[allow(unused_imports)] @@ -21,8 +23,10 @@ pub mod protected } #[doc = r" Orphan namespace of the module."] +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[doc(inline)] #[allow(unused_imports)] @@ -31,8 +35,10 @@ pub mod orphan } #[doc = r" Exposed namespace of the module."] +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[doc(inline)] #[allow(unused_imports)] pub use super :: prelude :: * ; @@ -44,8 +50,10 @@ pub mod exposed } #[doc = r" Prelude to use essentials: `use my_module::prelude::*`."] +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[doc(inline)] #[allow(unused_imports)] #[doc = " layer_a"] diff --git a/module/core/mod_interface/tests/inc/derive/use_basic/layer_a.rs b/module/core/mod_interface/tests/inc/derive/use_basic/layer_a.rs index f1e9f256fb..8c49982711 100644 --- a/module/core/mod_interface/tests/inc/derive/use_basic/layer_a.rs +++ b/module/core/mod_interface/tests/inc/derive/use_basic/layer_a.rs @@ -4,14 +4,15 @@ mod private { } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; - /// layer_a_protected - pub fn layer_a_protected() -> bool + pub use orphan::*; + /// layer_a_own + pub fn layer_a_own() -> bool { true } @@ -19,14 +20,15 @@ pub mod protected #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; /// layer_a_orphan pub fn layer_a_orphan() -> bool { @@ -35,11 +37,12 @@ pub mod orphan } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; /// layer_a_exposed pub fn layer_a_exposed() -> bool { @@ -48,8 +51,10 @@ pub mod exposed } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; /// layer_a_prelude pub fn layer_a_prelude() -> bool { diff --git a/module/core/mod_interface/tests/inc/derive/use_basic/layer_b.rs b/module/core/mod_interface/tests/inc/derive/use_basic/layer_b.rs index 8051e73936..1e15689f05 100644 --- a/module/core/mod_interface/tests/inc/derive/use_basic/layer_b.rs +++ b/module/core/mod_interface/tests/inc/derive/use_basic/layer_b.rs @@ -4,14 +4,15 @@ mod private { } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; - /// layer_b_protected - pub fn layer_b_protected() -> bool + pub use orphan::*; + /// layer_b_own + pub fn layer_b_own() -> bool { true } @@ -19,14 +20,15 @@ pub mod protected #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; /// layer_b_orphan pub fn layer_b_orphan() -> bool { @@ -35,11 +37,12 @@ pub mod orphan } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; /// layer_b_exposed pub fn layer_b_exposed() -> bool { @@ -48,8 +51,10 @@ pub mod exposed } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; /// layer_b_prelude pub fn layer_b_prelude() -> bool { diff --git a/module/core/mod_interface/tests/inc/manual/layer/layer_a.rs b/module/core/mod_interface/tests/inc/manual/layer/layer_a.rs index f1e9f256fb..8c49982711 100644 --- a/module/core/mod_interface/tests/inc/manual/layer/layer_a.rs +++ b/module/core/mod_interface/tests/inc/manual/layer/layer_a.rs @@ -4,14 +4,15 @@ mod private { } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; - /// layer_a_protected - pub fn layer_a_protected() -> bool + pub use orphan::*; + /// layer_a_own + pub fn layer_a_own() -> bool { true } @@ -19,14 +20,15 @@ pub mod protected #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; /// layer_a_orphan pub fn layer_a_orphan() -> bool { @@ -35,11 +37,12 @@ pub mod orphan } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; /// layer_a_exposed pub fn layer_a_exposed() -> bool { @@ -48,8 +51,10 @@ pub mod exposed } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; /// layer_a_prelude pub fn layer_a_prelude() -> bool { diff --git a/module/core/mod_interface/tests/inc/manual/layer/layer_b.rs b/module/core/mod_interface/tests/inc/manual/layer/layer_b.rs index 8051e73936..1e15689f05 100644 --- a/module/core/mod_interface/tests/inc/manual/layer/layer_b.rs +++ b/module/core/mod_interface/tests/inc/manual/layer/layer_b.rs @@ -4,14 +4,15 @@ mod private { } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; - /// layer_b_protected - pub fn layer_b_protected() -> bool + pub use orphan::*; + /// layer_b_own + pub fn layer_b_own() -> bool { true } @@ -19,14 +20,15 @@ pub mod protected #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; /// layer_b_orphan pub fn layer_b_orphan() -> bool { @@ -35,11 +37,12 @@ pub mod orphan } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; /// layer_b_exposed pub fn layer_b_exposed() -> bool { @@ -48,8 +51,10 @@ pub mod exposed } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; /// layer_b_prelude pub fn layer_b_prelude() -> bool { diff --git a/module/core/mod_interface/tests/inc/manual/layer/mod.rs b/module/core/mod_interface/tests/inc/manual/layer/mod.rs index ea4b8b33bc..044ff08dbf 100644 --- a/module/core/mod_interface/tests/inc/manual/layer/mod.rs +++ b/module/core/mod_interface/tests/inc/manual/layer/mod.rs @@ -11,12 +11,13 @@ pub mod layer_a; /// layer_b pub mod layer_b; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::layer_a::orphan::*; @@ -27,22 +28,24 @@ pub mod protected #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::layer_a::exposed::*; @@ -52,8 +55,10 @@ pub mod exposed } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::layer_a::prelude::*; diff --git a/module/core/mod_interface/tests/inc/manual/layer_use/layer_a.rs b/module/core/mod_interface/tests/inc/manual/layer_use/layer_a.rs index 7e0b8bd94b..91a75eba06 100644 --- a/module/core/mod_interface/tests/inc/manual/layer_use/layer_a.rs +++ b/module/core/mod_interface/tests/inc/manual/layer_use/layer_a.rs @@ -3,8 +3,8 @@ mod private { - /// layer_a_protected - pub fn layer_a_protected() -> bool + /// layer_a_own + pub fn layer_a_own() -> bool { true } @@ -29,47 +29,52 @@ mod private } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::private::layer_a_protected; + pub use private::layer_a_own; } #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::private::layer_a_orphan; + pub use private::layer_a_orphan; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::private::layer_a_exposed; + pub use private::layer_a_exposed; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::private::layer_a_prelude; + pub use private::layer_a_prelude; } diff --git a/module/core/mod_interface/tests/inc/manual/layer_use/layer_b.rs b/module/core/mod_interface/tests/inc/manual/layer_use/layer_b.rs index 9a68ea64fd..aa5802c05e 100644 --- a/module/core/mod_interface/tests/inc/manual/layer_use/layer_b.rs +++ b/module/core/mod_interface/tests/inc/manual/layer_use/layer_b.rs @@ -3,8 +3,8 @@ mod private { - /// layer_b_protected - pub fn layer_b_protected() -> bool + /// layer_b_own + pub fn layer_b_own() -> bool { true } @@ -29,47 +29,52 @@ mod private } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::private::layer_b_protected; + pub use private::layer_b_own; } #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::private::layer_b_orphan; + pub use private::layer_b_orphan; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::private::layer_b_exposed; + pub use private::layer_b_exposed; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::private::layer_b_prelude; + pub use private::layer_b_prelude; } diff --git a/module/core/mod_interface/tests/inc/manual/layer_use/mod.rs b/module/core/mod_interface/tests/inc/manual/layer_use/mod.rs index ea4b8b33bc..044ff08dbf 100644 --- a/module/core/mod_interface/tests/inc/manual/layer_use/mod.rs +++ b/module/core/mod_interface/tests/inc/manual/layer_use/mod.rs @@ -11,12 +11,13 @@ pub mod layer_a; /// layer_b pub mod layer_b; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::layer_a::orphan::*; @@ -27,22 +28,24 @@ pub mod protected #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::layer_a::exposed::*; @@ -52,8 +55,10 @@ pub mod exposed } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::layer_a::prelude::*; diff --git a/module/core/mod_interface/tests/inc/manual/micro_modules/mod.rs b/module/core/mod_interface/tests/inc/manual/micro_modules/mod.rs index f052ac97cc..65ba341ba1 100644 --- a/module/core/mod_interface/tests/inc/manual/micro_modules/mod.rs +++ b/module/core/mod_interface/tests/inc/manual/micro_modules/mod.rs @@ -6,45 +6,50 @@ mod private { } -pub mod mod_protected; +pub mod mod_own; pub mod mod_orphan; pub mod mod_exposed; pub mod mod_prelude; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; - pub use super::mod_protected; + pub use orphan::*; + pub use super::mod_own; } #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; pub use super::mod_orphan; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; pub use super::mod_exposed; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; pub use super::mod_prelude; } diff --git a/module/core/mod_interface/tests/inc/manual/micro_modules/mod_protected.rs b/module/core/mod_interface/tests/inc/manual/micro_modules/mod_protected.rs index 3bd5325a02..a6619cc0c4 100644 --- a/module/core/mod_interface/tests/inc/manual/micro_modules/mod_protected.rs +++ b/module/core/mod_interface/tests/inc/manual/micro_modules/mod_protected.rs @@ -1,5 +1,5 @@ -/// has_protected -pub fn has_protected() -> bool +/// has_own +pub fn has_own() -> bool { true } \ No newline at end of file diff --git a/module/core/mod_interface/tests/inc/manual/micro_modules_two/mod.rs b/module/core/mod_interface/tests/inc/manual/micro_modules_two/mod.rs index a48af7bc73..6a9a63843d 100644 --- a/module/core/mod_interface/tests/inc/manual/micro_modules_two/mod.rs +++ b/module/core/mod_interface/tests/inc/manual/micro_modules_two/mod.rs @@ -6,53 +6,58 @@ mod private { } -pub mod mod_protected1; +pub mod mod_own1; pub mod mod_orphan1; pub mod mod_exposed1; pub mod mod_prelude1; -pub mod mod_protected2; +pub mod mod_own2; pub mod mod_orphan2; pub mod mod_exposed2; pub mod mod_prelude2; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; - pub use super::mod_protected1; - pub use super::mod_protected2; + pub use orphan::*; + pub use super::mod_own1; + pub use super::mod_own2; } #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; pub use super::mod_orphan1; pub use super::mod_orphan2; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; pub use super::mod_exposed1; pub use super::mod_exposed2; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; pub use super::mod_prelude1; pub use super::mod_prelude2; } diff --git a/module/core/mod_interface/tests/inc/manual/micro_modules_two/mod_protected1.rs b/module/core/mod_interface/tests/inc/manual/micro_modules_two/mod_protected1.rs index c95649476e..a314e81b31 100644 --- a/module/core/mod_interface/tests/inc/manual/micro_modules_two/mod_protected1.rs +++ b/module/core/mod_interface/tests/inc/manual/micro_modules_two/mod_protected1.rs @@ -1,5 +1,5 @@ -/// has_protected1 -pub fn has_protected1() -> bool +/// has_own1 +pub fn has_own1() -> bool { true } \ No newline at end of file diff --git a/module/core/mod_interface/tests/inc/manual/micro_modules_two/mod_protected2.rs b/module/core/mod_interface/tests/inc/manual/micro_modules_two/mod_protected2.rs index a163ea8af5..b442687a02 100644 --- a/module/core/mod_interface/tests/inc/manual/micro_modules_two/mod_protected2.rs +++ b/module/core/mod_interface/tests/inc/manual/micro_modules_two/mod_protected2.rs @@ -1,5 +1,5 @@ -/// has_protected2 -pub fn has_protected2() -> bool +/// has_own2 +pub fn has_own2() -> bool { true } \ No newline at end of file diff --git a/module/core/mod_interface/tests/inc/only_test/layer_simple_only_test.rs b/module/core/mod_interface/tests/inc/only_test/layer_simple_only_test.rs index 12b14ca545..93b1190705 100644 --- a/module/core/mod_interface/tests/inc/only_test/layer_simple_only_test.rs +++ b/module/core/mod_interface/tests/inc/only_test/layer_simple_only_test.rs @@ -9,8 +9,8 @@ tests_impls! /* test.case( "root" ); */ { - a_id!( layer_a::layer_a_protected(), true ); - a_id!( layer_b::layer_b_protected(), true ); + a_id!( layer_a::layer_a_own(), true ); + a_id!( layer_b::layer_b_own(), true ); a_id!( layer_a::layer_a_orphan(), true ); a_id!( layer_b::layer_b_orphan(), true ); a_id!( layer_a::layer_a_exposed(), true ); @@ -21,8 +21,8 @@ tests_impls! /* test.case( "root" ); */ { - // a_id!( layer_a_protected(), true ); - // a_id!( layer_b_protected(), true ); + // a_id!( layer_a_own(), true ); + // a_id!( layer_b_own(), true ); a_id!( layer_a_orphan(), true ); a_id!( layer_b_orphan(), true ); a_id!( layer_a_exposed(), true ); @@ -33,20 +33,20 @@ tests_impls! /* test.case( "protected" ); */ { - // a_id!( protected::layer_a_protected(), true ); - // a_id!( protected::layer_b_protected(), true ); - a_id!( protected::layer_a_orphan(), true ); - a_id!( protected::layer_b_orphan(), true ); - a_id!( protected::layer_a_exposed(), true ); - a_id!( protected::layer_b_exposed(), true ); - a_id!( protected::layer_a_prelude(), true ); - a_id!( protected::layer_b_prelude(), true ); + // a_id!( own::layer_a_own(), true ); + // a_id!( own::layer_b_own(), true ); + a_id!( own::layer_a_orphan(), true ); + a_id!( own::layer_b_orphan(), true ); + a_id!( own::layer_a_exposed(), true ); + a_id!( own::layer_b_exposed(), true ); + a_id!( own::layer_a_prelude(), true ); + a_id!( own::layer_b_prelude(), true ); } /* test.case( "orphan" ); */ { - // a_id!( orphan::layer_a_protected(), true ); - // a_id!( orphan::layer_b_protected(), true ); + // a_id!( orphan::layer_a_own(), true ); + // a_id!( orphan::layer_b_own(), true ); // a_id!( orphan::layer_a_orphan(), true ); // a_id!( orphan::layer_b_orphan(), true ); a_id!( orphan::layer_a_exposed(), true ); @@ -57,8 +57,8 @@ tests_impls! /* test.case( "exposed" ); */ { - // a_id!( exposed::layer_a_protected(), true ); - // a_id!( exposed::layer_b_protected(), true ); + // a_id!( exposed::layer_a_own(), true ); + // a_id!( exposed::layer_b_own(), true ); // a_id!( exposed::layer_a_orphan(), true ); // a_id!( exposed::layer_b_orphan(), true ); a_id!( exposed::layer_a_exposed(), true ); @@ -69,8 +69,8 @@ tests_impls! /* test.case( "prelude" ); */ { - // a_id!( prelude::layer_a_protected(), true ); - // a_id!( prelude::layer_b_protected(), true ); + // a_id!( prelude::layer_a_own(), true ); + // a_id!( prelude::layer_b_own(), true ); // a_id!( prelude::layer_a_orphan(), true ); // a_id!( prelude::layer_b_orphan(), true ); // a_id!( prelude::layer_a_exposed(), true ); diff --git a/module/core/mod_interface/tests/inc/only_test/layer_single_only_test.rs b/module/core/mod_interface/tests/inc/only_test/layer_single_only_test.rs index ea9a785df0..5adb9cbe73 100644 --- a/module/core/mod_interface/tests/inc/only_test/layer_single_only_test.rs +++ b/module/core/mod_interface/tests/inc/only_test/layer_single_only_test.rs @@ -9,7 +9,7 @@ tests_impls! /* test.case( "root" ); */ { - a_id!( layer_a::layer_a_protected(), true ); + a_id!( layer_a::layer_a_own(), true ); a_id!( layer_a::layer_a_orphan(), true ); a_id!( layer_a::layer_a_exposed(), true ); a_id!( layer_a::layer_a_prelude(), true ); @@ -17,7 +17,7 @@ tests_impls! /* test.case( "root" ); */ { - // a_id!( layer_a_protected(), true ); + // a_id!( layer_a_own(), true ); a_id!( layer_a_orphan(), true ); a_id!( layer_a_exposed(), true ); a_id!( layer_a_prelude(), true ); @@ -25,15 +25,15 @@ tests_impls! /* test.case( "protected" ); */ { - // a_id!( protected::layer_a_protected(), true ); - a_id!( protected::layer_a_orphan(), true ); - a_id!( protected::layer_a_exposed(), true ); - a_id!( protected::layer_a_prelude(), true ); + // a_id!( own::layer_a_own(), true ); + a_id!( own::layer_a_orphan(), true ); + a_id!( own::layer_a_exposed(), true ); + a_id!( own::layer_a_prelude(), true ); } /* test.case( "orphan" ); */ { - // a_id!( orphan::layer_a_protected(), true ); + // a_id!( orphan::layer_a_own(), true ); // a_id!( orphan::layer_a_orphan(), true ); a_id!( orphan::layer_a_exposed(), true ); a_id!( orphan::layer_a_prelude(), true ); @@ -41,7 +41,7 @@ tests_impls! /* test.case( "exposed" ); */ { - // a_id!( exposed::layer_a_protected(), true ); + // a_id!( exposed::layer_a_own(), true ); // a_id!( exposed::layer_a_orphan(), true ); a_id!( exposed::layer_a_exposed(), true ); a_id!( exposed::layer_a_prelude(), true ); @@ -49,7 +49,7 @@ tests_impls! /* test.case( "prelude" ); */ { - // a_id!( prelude::layer_a_protected(), true ); + // a_id!( prelude::layer_a_own(), true ); // a_id!( prelude::layer_a_orphan(), true ); // a_id!( prelude::layer_a_exposed(), true ); a_id!( prelude::layer_a_prelude(), true ); diff --git a/module/core/mod_interface/tests/inc/only_test/micro_modules_only_test.rs b/module/core/mod_interface/tests/inc/only_test/micro_modules_only_test.rs index db02c32da5..b08874b8d0 100644 --- a/module/core/mod_interface/tests/inc/only_test/micro_modules_only_test.rs +++ b/module/core/mod_interface/tests/inc/only_test/micro_modules_only_test.rs @@ -8,24 +8,24 @@ tests_impls! { { - // a_id!( protected::mod_private::has_private(), true ); - a_id!( mod_protected::has_protected(), true ); + // a_id!( own::mod_private::has_private(), true ); + a_id!( mod_own::has_own(), true ); a_id!( mod_orphan::has_orphan(), true ); a_id!( mod_exposed::has_exposed(), true ); a_id!( mod_prelude::has_prelude(), true ); } { - // a_id!( protected::mod_private::has_private(), true ); - a_id!( protected::mod_protected::has_protected(), true ); - a_id!( protected::mod_orphan::has_orphan(), true ); - a_id!( protected::mod_exposed::has_exposed(), true ); - a_id!( protected::mod_prelude::has_prelude(), true ); + // a_id!( own::mod_private::has_private(), true ); + a_id!( own::mod_own::has_own(), true ); + a_id!( own::mod_orphan::has_orphan(), true ); + a_id!( own::mod_exposed::has_exposed(), true ); + a_id!( own::mod_prelude::has_prelude(), true ); } { // a_id!( orphan::mod_private::has_private(), true ); - // a_id!( orphan::mod_protected::has_protected(), true ); + // a_id!( orphan::mod_own::has_own(), true ); a_id!( orphan::mod_orphan::has_orphan(), true ); a_id!( orphan::mod_exposed::has_exposed(), true ); a_id!( orphan::mod_prelude::has_prelude(), true ); @@ -33,7 +33,7 @@ tests_impls! { // a_id!( exposed::mod_private::has_private(), true ); - // a_id!( exposed::mod_protected::has_protected(), true ); + // a_id!( exposed::mod_own::has_own(), true ); // a_id!( exposed::mod_orphan::has_orphan(), true ); a_id!( exposed::mod_exposed::has_exposed(), true ); a_id!( exposed::mod_prelude::has_prelude(), true ); @@ -41,7 +41,7 @@ tests_impls! { // a_id!( prelude::mod_private::has_private(), true ); - // a_id!( prelude::mod_protected::has_protected(), true ); + // a_id!( prelude::mod_own::has_own(), true ); // a_id!( prelude::mod_orphan::has_orphan(), true ); // a_id!( prelude::mod_exposed::has_exposed(), true ); a_id!( prelude::mod_prelude::has_prelude(), true ); diff --git a/module/core/mod_interface/tests/inc/only_test/micro_modules_two_only_test.rs b/module/core/mod_interface/tests/inc/only_test/micro_modules_two_only_test.rs index a9825ec197..a125123eed 100644 --- a/module/core/mod_interface/tests/inc/only_test/micro_modules_two_only_test.rs +++ b/module/core/mod_interface/tests/inc/only_test/micro_modules_two_only_test.rs @@ -10,8 +10,8 @@ tests_impls! { // a_id!( mod_private1::has_private1(), true ); // a_id!( mod_private2::has_private2(), true ); - a_id!( mod_protected1::has_protected1(), true ); - a_id!( mod_protected2::has_protected2(), true ); + a_id!( mod_own1::has_own1(), true ); + a_id!( mod_own2::has_own2(), true ); a_id!( mod_orphan1::has_orphan1(), true ); a_id!( mod_orphan2::has_orphan2(), true ); a_id!( mod_exposed1::has_exposed1(), true ); @@ -21,23 +21,23 @@ tests_impls! } { - // a_id!( protected::mod_private1::has_private1(), true ); - // a_id!( protected::mod_private2::has_private2(), true ); - a_id!( protected::mod_protected1::has_protected1(), true ); - a_id!( protected::mod_protected2::has_protected2(), true ); - a_id!( protected::mod_orphan1::has_orphan1(), true ); - a_id!( protected::mod_orphan2::has_orphan2(), true ); - a_id!( protected::mod_exposed1::has_exposed1(), true ); - a_id!( protected::mod_exposed2::has_exposed2(), true ); - a_id!( protected::mod_prelude1::has_prelude1(), true ); - a_id!( protected::mod_prelude2::has_prelude2(), true ); + // a_id!( own::mod_private1::has_private1(), true ); + // a_id!( own::mod_private2::has_private2(), true ); + a_id!( own::mod_own1::has_own1(), true ); + a_id!( own::mod_own2::has_own2(), true ); + a_id!( own::mod_orphan1::has_orphan1(), true ); + a_id!( own::mod_orphan2::has_orphan2(), true ); + a_id!( own::mod_exposed1::has_exposed1(), true ); + a_id!( own::mod_exposed2::has_exposed2(), true ); + a_id!( own::mod_prelude1::has_prelude1(), true ); + a_id!( own::mod_prelude2::has_prelude2(), true ); } { // a_id!( orphan::mod_private1::has_private1(), true ); // a_id!( orphan::mod_private2::has_private2(), true ); - // a_id!( orphan::mod_protected1::has_protected1(), true ); - // a_id!( orphan::mod_protected2::has_protected2(), true ); + // a_id!( orphan::mod_own1::has_own1(), true ); + // a_id!( orphan::mod_own2::has_own2(), true ); a_id!( orphan::mod_orphan1::has_orphan1(), true ); a_id!( orphan::mod_orphan2::has_orphan2(), true ); a_id!( orphan::mod_exposed1::has_exposed1(), true ); @@ -49,8 +49,8 @@ tests_impls! { // a_id!( exposed::mod_private1::has_private1(), true ); // a_id!( exposed::mod_private2::has_private2(), true ); - // a_id!( exposed::mod_protected1::has_protected1(), true ); - // a_id!( exposed::mod_protected2::has_protected2(), true ); + // a_id!( exposed::mod_own1::has_own1(), true ); + // a_id!( exposed::mod_own2::has_own2(), true ); // a_id!( exposed::mod_orphan1::has_orphan1(), true ); // a_id!( exposed::mod_orphan2::has_orphan2(), true ); a_id!( exposed::mod_exposed1::has_exposed1(), true ); @@ -62,8 +62,8 @@ tests_impls! { // a_id!( prelude::mod_private1::has_private1(), true ); // a_id!( prelude::mod_private2::has_private2(), true ); - // a_id!( prelude::mod_protected1::has_protected1(), true ); - // a_id!( prelude::mod_protected2::has_protected2(), true ); + // a_id!( prelude::mod_own1::has_own1(), true ); + // a_id!( prelude::mod_own2::has_own2(), true ); // a_id!( prelude::mod_orphan1::has_orphan1(), true ); // a_id!( prelude::mod_orphan2::has_orphan2(), true ); // a_id!( prelude::mod_exposed1::has_exposed1(), true ); diff --git a/module/core/mod_interface/tests/inc/only_test/use_non_layer_only_test.rs b/module/core/mod_interface/tests/inc/only_test/use_non_layer_only_test.rs index e0851aa35f..db252b6a5c 100644 --- a/module/core/mod_interface/tests/inc/only_test/use_non_layer_only_test.rs +++ b/module/core/mod_interface/tests/inc/only_test/use_non_layer_only_test.rs @@ -10,67 +10,67 @@ tests_impls! // test.case( "CrateStructForTesting1" ); { a_id!( layer_a::CrateStructForTesting1{}, layer_a::CrateStructForTesting1{} ); - a_id!( layer_a::protected::CrateStructForTesting1{}, layer_a::protected::CrateStructForTesting1{} ); + a_id!( layer_a::own::CrateStructForTesting1{}, layer_a::own::CrateStructForTesting1{} ); } // test.case( "SuperStruct" ); { a_id!( layer_a::SuperStruct1{}, layer_a::SuperStruct1{} ); - a_id!( layer_a::protected::SuperStruct1{}, layer_a::protected::SuperStruct1{} ); + a_id!( layer_a::own::SuperStruct1{}, layer_a::own::SuperStruct1{} ); } // test.case( "Vec" ); { a_id!( layer_a::Vec::< i32 >::new(), layer_a::Vec::< i32 >::new() ); - a_id!( layer_a::protected::Vec::< i32 >::new(), layer_a::protected::Vec::< i32 >::new() ); + a_id!( layer_a::own::Vec::< i32 >::new(), layer_a::own::Vec::< i32 >::new() ); a_id!( layer_a::orphan::Vec::< i32 >::new(), layer_a::orphan::Vec::< i32 >::new() ); // a_id!( layer_a::exposed::Vec::< i32 >::new(), layer_a::exposed::Vec::< i32 >::new() ); a_id!( Vec::< i32 >::new(), Vec::< i32 >::new() ); - a_id!( protected::Vec::< i32 >::new(), protected::Vec::< i32 >::new() ); + a_id!( own::Vec::< i32 >::new(), own::Vec::< i32 >::new() ); // a_id!( orphan::Vec::< i32 >::new(), orphan::Vec::< i32 >::new() ); } // test.case( "SubStruct2" ); { a_id!( layer_a::SubStruct2{}, layer_a::SubStruct2{} ); - a_id!( layer_a::protected::SubStruct2{}, layer_a::protected::SubStruct2{} ); + a_id!( layer_a::own::SubStruct2{}, layer_a::own::SubStruct2{} ); a_id!( layer_a::orphan::SubStruct2{}, layer_a::orphan::SubStruct2{} ); // a_id!( layer_a::exposed::SubStruct2{}, layer_a::exposed::SubStruct2{} ); a_id!( SubStruct2{}, SubStruct2{} ); - a_id!( protected::SubStruct2{}, protected::SubStruct2{} ); + a_id!( own::SubStruct2{}, own::SubStruct2{} ); // a_id!( orphan::SubStruct2{}, orphan::SubStruct2{} ); } // test.case( "SubStruct2" ); { a_id!( layer_a::SubStruct3{}, layer_a::SubStruct3{} ); - a_id!( layer_a::protected::SubStruct3{}, layer_a::protected::SubStruct3{} ); + a_id!( layer_a::own::SubStruct3{}, layer_a::own::SubStruct3{} ); a_id!( layer_a::orphan::SubStruct3{}, layer_a::orphan::SubStruct3{} ); // a_id!( layer_a::exposed::SubStruct3{}, layer_a::exposed::SubStruct3{} ); a_id!( SubStruct3{}, SubStruct3{} ); - a_id!( protected::SubStruct3{}, protected::SubStruct3{} ); + a_id!( own::SubStruct3{}, own::SubStruct3{} ); // a_id!( orphan::SubStruct3{}, orphan::SubStruct3{} ); } // test.case( "SubStruct2" ); { a_id!( layer_a::SubStruct4{}, layer_a::SubStruct4{} ); - a_id!( layer_a::protected::SubStruct4{}, layer_a::protected::SubStruct4{} ); + a_id!( layer_a::own::SubStruct4{}, layer_a::own::SubStruct4{} ); a_id!( layer_a::orphan::SubStruct4{}, layer_a::orphan::SubStruct4{} ); // a_id!( layer_a::exposed::SubStruct4{}, layer_a::exposed::SubStruct4{} ); a_id!( SubStruct4{}, SubStruct4{} ); - a_id!( protected::SubStruct4{}, protected::SubStruct4{} ); + a_id!( own::SubStruct4{}, own::SubStruct4{} ); // a_id!( orphan::SubStruct4{}, orphan::SubStruct4{} ); } // test.case( "SubStruct2" ); { a_id!( layer_a::PrivateStruct1{}, layer_a::PrivateStruct1{} ); - a_id!( layer_a::protected::PrivateStruct1{}, layer_a::protected::PrivateStruct1{} ); + a_id!( layer_a::own::PrivateStruct1{}, layer_a::own::PrivateStruct1{} ); a_id!( layer_a::orphan::PrivateStruct1{}, layer_a::orphan::PrivateStruct1{} ); // a_id!( layer_a::exposed::PrivateStruct1{}, layer_a::exposed::PrivateStruct1{} ); a_id!( PrivateStruct1{}, PrivateStruct1{} ); - a_id!( protected::PrivateStruct1{}, protected::PrivateStruct1{} ); + a_id!( own::PrivateStruct1{}, own::PrivateStruct1{} ); // a_id!( orphan::PrivateStruct1{}, orphan::PrivateStruct1{} ); } diff --git a/module/core/mod_interface/tests/smoke_test.rs b/module/core/mod_interface/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/core/mod_interface/tests/smoke_test.rs +++ b/module/core/mod_interface/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/core/mod_interface_meta/Cargo.toml b/module/core/mod_interface_meta/Cargo.toml index 8364db34d6..c892a6d31b 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.21.0" +version = "0.22.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", @@ -24,7 +24,7 @@ workspace = true features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] + include = [ "/rust/impl/meta/mod_interface_meta_lib.rs", "/rust/impl/meta/mod_interface/meta", diff --git a/module/core/mod_interface_meta/src/impls.rs b/module/core/mod_interface_meta/src/impls.rs index 0f4608e420..0b6ab3fa83 100644 --- a/module/core/mod_interface_meta/src/impls.rs +++ b/module/core/mod_interface_meta/src/impls.rs @@ -10,7 +10,7 @@ pub( crate ) mod private // x // use private::Type1; // use private::{ Type1, Type2 }; - // protected use private::Type1; + // own use private::Type1; // prelude use private::Type1; // = ? @@ -41,7 +41,7 @@ pub( crate ) mod private // - extending // x - // prelude exposed macromod mod_protected1; + // prelude exposed macromod mod_own1; // : protected -> exposed // : orphan -> exposed // : exposed -> exposed @@ -78,13 +78,13 @@ pub( crate ) mod private // mod { mod1, mod2 }; // + - // protected mod mod_protected1; + // own mod mod_own1; // orphan mod mod_orphan1; // exposed mod mod_exposed1; // prelude mod mod_prelude1; // + - // protected mod { mod_protected1, mod_protected2 }; + // own mod { mod_own1, mod_own2 }; // orphan mod { mod_orphan1, mod_orphan2 }; // exposed mod { mod_exposed1, mod_exposed2 }; // prelude mod { mod_prelude1, mod_prelude2 }; @@ -110,7 +110,7 @@ pub( crate ) mod private // clauses_map : &mut HashMap< u32, Vec< proc_macro2::TokenStream > >, ) -> - Result< () > + syn::Result< () > { let attrs1 = &record.attrs; @@ -145,7 +145,7 @@ pub( crate ) mod private }); } - c.clauses_map.get_mut( &VisProtected::Kind() ).unwrap().push( qt! + c.clauses_map.get_mut( &VisOwn::Kind() ).unwrap().push( qt! { #[ doc( inline ) ] #[ allow( unused_imports ) ] @@ -183,7 +183,7 @@ pub( crate ) mod private // clauses_map : &mut HashMap< u32, Vec< proc_macro2::TokenStream > >, ) -> - Result< () > + syn::Result< () > { let attrs1 = &record.attrs; let path = record.use_elements.as_ref().unwrap(); @@ -233,7 +233,7 @@ pub( crate ) mod private c : &'_ mut RecordContext< '_ >, ) -> - Result< () > + syn::Result< () > { let attrs1 = &record.attrs; let attrs2 = &element.0; @@ -263,7 +263,8 @@ pub( crate ) mod private #[ allow( unused_imports ) ] #attrs1 #attrs2 - pub use super::#path; + pub use #path; + // xxx : remove super? }); Ok( () ) @@ -280,7 +281,7 @@ pub( crate ) mod private c : &'_ mut RecordContext< '_ >, ) -> - Result< () > + syn::Result< () > { let attrs1 = &record.attrs; let attrs2 = &element.0; @@ -303,13 +304,13 @@ pub( crate ) mod private pub mod #path; }); - c.clauses_map.get_mut( &VisProtected::Kind() ).unwrap().push( qt! + c.clauses_map.get_mut( &VisOwn::Kind() ).unwrap().push( qt! { #[ doc( inline ) ] #[ allow( unused_imports ) ] #attrs1 #attrs2 - pub use super::#path::orphan::*; + pub use #path::orphan::*; }); c.clauses_map.get_mut( &VisExposed::Kind() ).unwrap().push( qt! @@ -318,7 +319,7 @@ pub( crate ) mod private #[ allow( unused_imports ) ] #attrs1 #attrs2 - pub use super::#path::exposed::*; + pub use #path::exposed::*; }); c.clauses_map.get_mut( &VisPrelude::Kind() ).unwrap().push( qt! @@ -327,7 +328,7 @@ pub( crate ) mod private #[ allow( unused_imports ) ] #attrs1 #attrs2 - pub use super::#path::prelude::*; + pub use #path::prelude::*; }); Ok( () ) @@ -337,7 +338,7 @@ pub( crate ) mod private /// Protocol of modularity unifying interface of a module and introducing layers. /// #[ allow ( dead_code ) ] - pub fn mod_interface( input : proc_macro::TokenStream ) -> Result< proc_macro2::TokenStream > + pub fn mod_interface( input : proc_macro::TokenStream ) -> syn::Result< proc_macro2::TokenStream > { use ElementType::*; @@ -352,7 +353,7 @@ pub( crate ) mod private let mut clauses_map : HashMap< _ , Vec< proc_macro2::TokenStream > > = HashMap::new(); clauses_map.insert( ClauseImmediates::Kind(), Vec::new() ); //clauses_map.insert( VisPrivate::Kind(), Vec::new() ); - clauses_map.insert( VisProtected::Kind(), Vec::new() ); + clauses_map.insert( VisOwn::Kind(), Vec::new() ); clauses_map.insert( VisOrphan::Kind(), Vec::new() ); clauses_map.insert( VisExposed::Kind(), Vec::new() ); clauses_map.insert( VisPrelude::Kind(), Vec::new() ); @@ -384,7 +385,7 @@ pub( crate ) mod private }, _ => { - record.elements.iter().try_for_each( | element | -> Result::< () > + record.elements.iter().try_for_each( | element | -> syn::Result::< () > { match record.element_type { @@ -400,16 +401,16 @@ pub( crate ) mod private { }, } - Result::Ok( () ) + syn::Result::Ok( () ) })?; } }; - Result::Ok( () ) + syn::Result::Ok( () ) })?; let immediates_clause = clauses_map.get( &ClauseImmediates::Kind() ).unwrap(); - let protected_clause = clauses_map.get( &VisProtected::Kind() ).unwrap(); + let protected_clause = clauses_map.get( &VisOwn::Kind() ).unwrap(); let orphan_clause = clauses_map.get( &VisOrphan::Kind() ).unwrap(); let exposed_clause = clauses_map.get( &VisExposed::Kind() ).unwrap(); let prelude_clause = clauses_map.get( &VisPrelude::Kind() ).unwrap(); @@ -421,38 +422,43 @@ pub( crate ) mod private #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use protected::*; + pub use own::*; - /// Protected namespace of the module. - pub mod protected + /// Own namespace of the module. + #[ allow( unused_imports ) ] + pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; #( #protected_clause )* } /// Orphan namespace of the module. + #[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; #( #orphan_clause )* } /// Exposed namespace of the module. + #[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #( #exposed_clause )* } /// Prelude to use essentials: `use my_module::prelude::*`. + #[ allow( unused_imports ) ] pub mod prelude { + use super::*; #( #prelude_clause )* } @@ -474,40 +480,42 @@ pub( crate ) mod private } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { - pub use super::orphan::*; + use super::*; + pub use orphan::*; } -pub use protected::*; +pub use own::*; /// Parented namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { - pub use super::exposed::*; + use super::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { - pub use super::prelude::*; - #[ allow( unused_imports ) ] - pub use super::private:: + use super::*; + pub use prelude::*; + pub use private:: { }; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { - #[ allow( unused_imports ) ] - pub use super::private:: + use super::*; + pub use private:: { mod_interface, }; } - -// xxx : clean up, ad solve problems -// - example based on simpified version of test::layer_have_layer with single sublayer -// - example with attribute `#![ debug ]` diff --git a/module/core/mod_interface_meta/src/lib.rs b/module/core/mod_interface_meta/src/lib.rs index eefcd860de..bb595ba9a2 100644 --- a/module/core/mod_interface_meta/src/lib.rs +++ b/module/core/mod_interface_meta/src/lib.rs @@ -4,6 +4,10 @@ #![ deny( dead_code ) ] #![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/", "Readme.md" ) ) ] +// xxx : clean up, ad solve problems +// - example based on simpified version of test::layer_have_layer with single sublayer +// - example with attribute `#![ debug ]` + // xxx : write good description and the main use-case // xxx : does not work. make it working @@ -19,13 +23,13 @@ // // xxx : make it working // // exposed use super; // exposed use super::super::compiletime; -// protected use +// own use // { // * // }; // } -// xxx : make use proper_path_tools::protected::path working +// xxx : make use proper_path_tools::own::path working // xxx : put modular files into a namespace `file` maybe // #[ cfg( feature = "enabled" ) ] @@ -38,6 +42,39 @@ // pub mod item_struct; // } +// xxx : check +// +// - does not work +// exposed use +// { +// ::former::Former, +// ::former::Assign, +// }; +// +// - work +// +// exposed use ::former:: +// { +// Former, +// Assign, +// }; + +// xxx : inherit all entities, somehow +// +// pub mod ca; +// +// crate::mod_interface! +// { +// // #![ debug ] +// +// // xxx : syntax for that, please +// use super::ca; +// own use super::ca::own::*; +// +// // /// Commands aggregator library. +// // layer ca; +// } + mod impls; #[ allow( unused_imports ) ] use impls::exposed::*; @@ -73,7 +110,7 @@ mod_interface! pub mod file2; private mod micro_private; - protected mod micro_protected; + own mod micro_own; orphan mod micro_orphan; exposed mod micro_exposed; prelude mod micro_prelude; diff --git a/module/core/mod_interface_meta/src/record.rs b/module/core/mod_interface_meta/src/record.rs index b078dcf6c6..8c6a76d57a 100644 --- a/module/core/mod_interface_meta/src/record.rs +++ b/module/core/mod_interface_meta/src/record.rs @@ -2,7 +2,6 @@ pub( crate ) mod private { use crate::*; - use derive_tools::IsVariant; use macro_tools::exposed::*; /// @@ -18,7 +17,7 @@ pub( crate ) mod private /// Kind of element. /// - #[ derive( IsVariant, Debug, PartialEq, Eq, Clone, Copy ) ] + #[ derive( Debug, PartialEq, Eq, Clone, Copy ) ] pub enum ElementType { MicroModule( syn::token::Mod ), @@ -31,7 +30,7 @@ pub( crate ) mod private impl syn::parse::Parse for ElementType { - fn parse( input : ParseStream< '_ > ) -> Result< Self > + fn parse( input : ParseStream< '_ > ) -> syn::Result< Self > { let lookahead = input.lookahead1(); let element_type = match() @@ -94,7 +93,7 @@ pub( crate ) mod private impl syn::parse::Parse for Record { - fn parse( input : ParseStream< '_ > ) -> Result< Self > + fn parse( input : ParseStream< '_ > ) -> syn::Result< Self > { let attrs = input.parse()?; @@ -187,7 +186,7 @@ pub( crate ) mod private { /// Validate each inner attribute of the thesis. #[ allow ( dead_code ) ] - pub fn inner_attributes_validate( &self ) -> Result< () > + pub fn inner_attributes_validate( &self ) -> syn::Result< () > { self.head.iter().try_for_each( | attr | { @@ -210,7 +209,7 @@ pub( crate ) mod private )); } - Result::Ok( () ) + syn::Result::Ok( () ) })?; Ok( () ) } @@ -229,7 +228,7 @@ pub( crate ) mod private impl syn::parse::Parse for Thesis { - fn parse( input : ParseStream< '_ > ) -> Result< Self > + fn parse( input : ParseStream< '_ > ) -> syn::Result< Self > { let head = input.parse()?; // let head = Default::default(); @@ -256,29 +255,31 @@ pub( crate ) mod private } #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { - #[ allow( unused_imports ) ] - pub use super::orphan::*; + use super::*; + pub use orphan::*; } /// Parented namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { - #[ allow( unused_imports ) ] - pub use super::exposed::*; + use super::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { - #[ allow( unused_imports ) ] - pub use super::prelude::*; - #[ allow( unused_imports ) ] - pub use super::private:: + use super::*; + pub use prelude::*; + pub use private:: { ElementType, Record, @@ -288,10 +289,11 @@ pub mod exposed } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { - #[ allow( unused_imports ) ] - pub use super::private:: + use super::*; + pub use private:: { }; } diff --git a/module/core/mod_interface_meta/src/use_tree.rs b/module/core/mod_interface_meta/src/use_tree.rs index a7c1397e96..3e92f8b6ad 100644 --- a/module/core/mod_interface_meta/src/use_tree.rs +++ b/module/core/mod_interface_meta/src/use_tree.rs @@ -2,7 +2,7 @@ pub( crate ) mod private { use macro_tools::prelude::*; - use macro_tools::Result; + // use macro_tools::syn::Result; // use macro_tools::err; #[ derive( Debug, PartialEq, Eq, Clone ) ] @@ -44,7 +44,7 @@ pub( crate ) mod private } /// Get pure path, cutting off `as module2` from `use module1 as module2`. - pub fn pure_path( &self ) -> Result< syn::punctuated::Punctuated< syn::Ident, Token![::] > > + pub fn pure_path( &self ) -> syn::Result< syn::punctuated::Punctuated< syn::Ident, Token![::] > > { use syn::UseTree::*; @@ -89,7 +89,7 @@ pub( crate ) mod private /// Pure path without super. /// Get pure path, cutting off `as module2` from `use module1 as module2`. /// Strip first `super::` in `super::some::module` - pub fn pure_without_super_path( &self ) -> Result< syn::punctuated::Punctuated< syn::Ident, Token![::] > > + pub fn pure_without_super_path( &self ) -> syn::Result< syn::punctuated::Punctuated< syn::Ident, Token![::] > > { let path = self.pure_path()?; if path.len() < 1 @@ -107,7 +107,7 @@ pub( crate ) mod private /// Adjusted path. /// Add `super::private::` to path unless it starts from `::` or `super` or `crate`. - pub fn adjsuted_implicit_path( &self ) -> Result< syn::punctuated::Punctuated< syn::Ident, Token![::] > > + pub fn adjsuted_implicit_path( &self ) -> syn::Result< syn::punctuated::Punctuated< syn::Ident, Token![::] > > { // use syn::UseTree::*; let pure_path = self.pure_path()?; @@ -144,7 +144,7 @@ pub( crate ) mod private impl syn::parse::Parse for UseTree { - fn parse( input : ParseStream< '_ > ) -> Result< Self > + fn parse( input : ParseStream< '_ > ) -> syn::Result< Self > { use syn::UseTree::*; let leading_colon = input.parse()?; @@ -207,30 +207,32 @@ pub( crate ) mod private } #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { - #[ allow( unused_imports ) ] - pub use super::orphan::*; + use super::*; + pub use orphan::*; } /// Parented namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { - #[ allow( unused_imports ) ] - pub use super::exposed::*; + use super::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { - #[ allow( unused_imports ) ] - pub use super::prelude::*; + use super::*; + pub use prelude::*; - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { UseTree, }; @@ -238,6 +240,8 @@ pub mod exposed } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; } diff --git a/module/core/mod_interface_meta/src/visibility.rs b/module/core/mod_interface_meta/src/visibility.rs index 10d8a68c48..90c91e602c 100644 --- a/module/core/mod_interface_meta/src/visibility.rs +++ b/module/core/mod_interface_meta/src/visibility.rs @@ -2,10 +2,10 @@ pub( crate ) mod private { use macro_tools::prelude::*; - use macro_tools::Result; + // use macro_tools::syn::Result; use core::hash::{ Hash, Hasher }; - pub const VALID_VISIBILITY_LIST_STR : &str = "[ private, protected, orphan, exposed, prelude ]"; + pub const VALID_VISIBILITY_LIST_STR : &str = "[ private, own, orphan, exposed, prelude ]"; /// /// Custom keywords @@ -15,7 +15,7 @@ pub( crate ) mod private { use super::*; // syn::custom_keyword!( private ); - syn::custom_keyword!( protected ); + syn::custom_keyword!( own ); syn::custom_keyword!( orphan ); syn::custom_keyword!( exposed ); syn::custom_keyword!( prelude ); @@ -217,7 +217,7 @@ pub( crate ) mod private } // Vis!( Private, VisPrivate, private, 1 ); - Vis!( Protected, VisProtected, protected, Protected ); + Vis!( Own, VisOwn, own, Own ); Vis!( Orphan, VisOrphan, orphan, Orphan ); Vis!( Exposed, VisExposed, exposed, Exposed ); Vis!( Prelude, VisPrelude, prelude, Prelude ); @@ -230,7 +230,7 @@ pub( crate ) mod private Clause!( ClauseImmediates, Immadiate ); // impl_valid_sub_namespace!( VisPrivate, false ); - impl_valid_sub_namespace!( VisProtected, true ); + impl_valid_sub_namespace!( VisOwn, true ); impl_valid_sub_namespace!( VisOrphan, true ); impl_valid_sub_namespace!( VisExposed, true ); impl_valid_sub_namespace!( VisPrelude, true ); @@ -260,7 +260,7 @@ pub( crate ) mod private #[ default ] Private, /// Owned by current file entities. - Protected, + Own, /// Should be used by parent. Orphan, /// Should be used by all ascendants in the current crate. @@ -283,7 +283,7 @@ pub( crate ) mod private pub enum Visibility { //Private( VisPrivate ), - Protected( VisProtected ), + Own( VisOwn ), Orphan( VisOrphan ), Exposed( VisExposed ), Prelude( VisPrelude ), @@ -298,37 +298,37 @@ pub( crate ) mod private impl Visibility { - fn parse_protected( input : ParseStream< '_ > ) -> Result< Self > + fn parse_own( input : ParseStream< '_ > ) -> syn::Result< Self > { - Self::_parse_vis::< VisProtected >( input ) + Self::_parse_vis::< VisOwn >( input ) } - fn parse_orphan( input : ParseStream< '_ > ) -> Result< Self > + fn parse_orphan( input : ParseStream< '_ > ) -> syn::Result< Self > { Self::_parse_vis::< VisOrphan >( input ) } - fn parse_exposed( input : ParseStream< '_ > ) -> Result< Self > + fn parse_exposed( input : ParseStream< '_ > ) -> syn::Result< Self > { Self::_parse_vis::< VisExposed >( input ) } - fn parse_prelude( input : ParseStream< '_ > ) -> Result< Self > + fn parse_prelude( input : ParseStream< '_ > ) -> syn::Result< Self > { Self::_parse_vis::< VisPrelude >( input ) } - fn parse_pub( input : ParseStream< '_ > ) -> Result< Self > + fn parse_pub( input : ParseStream< '_ > ) -> syn::Result< Self > { Self::_parse_vis::< VisPublic >( input ) } - // fn parse_pub( input : ParseStream< '_ > ) -> Result< Self > + // fn parse_pub( input : ParseStream< '_ > ) -> syn::Result< Self > // { // Ok( Visibility::Public( syn::VisPublic { pub_token : input.parse()? } ) ) // } - fn _parse_vis< Vis >( input : ParseStream< '_ > ) -> Result< Self > + fn _parse_vis< Vis >( input : ParseStream< '_ > ) -> syn::Result< Self > where Vis : Into< Visibility > + VisibilityInterface, { @@ -380,7 +380,7 @@ pub( crate ) mod private ).into() ) } - // fn parse_in_crate( input : ParseStream< '_ > ) -> Result< Self > + // fn parse_in_crate( input : ParseStream< '_ > ) -> syn::Result< Self > // { // if input.peek2( Token![ :: ] ) // { @@ -403,7 +403,7 @@ pub( crate ) mod private { // Visibility::Private( e ) => e.kind(), // Visibility::Crate( e ) => e.kind(), - Visibility::Protected( e ) => e.kind(), + Visibility::Own( e ) => e.kind(), Visibility::Orphan( e ) => e.kind(), Visibility::Exposed( e ) => e.kind(), Visibility::Prelude( e ) => e.kind(), @@ -421,7 +421,7 @@ pub( crate ) mod private { // Visibility::Private( e ) => e.restriction(), // Visibility::Crate( e ) => e.restriction(), - Visibility::Protected( e ) => e.restriction(), + Visibility::Own( e ) => e.restriction(), Visibility::Orphan( e ) => e.restriction(), Visibility::Exposed( e ) => e.restriction(), Visibility::Prelude( e ) => e.restriction(), @@ -435,7 +435,7 @@ pub( crate ) mod private impl syn::parse::Parse for Visibility { - fn parse( input : ParseStream< '_ > ) -> Result< Self > + fn parse( input : ParseStream< '_ > ) -> syn::Result< Self > { // Recognize an empty None-delimited group, as produced by a $:vis // matcher that matched no tokens. @@ -454,7 +454,7 @@ pub( crate ) mod private match() { //_case if input.peek( kw::private ) => Self::parse_private( input ), - _case if input.peek( kw::protected ) => Self::parse_protected( input ), + _case if input.peek( kw::own ) => Self::parse_own( input ), _case if input.peek( kw::orphan ) => Self::parse_orphan( input ), _case if input.peek( kw::exposed ) => Self::parse_exposed( input ), _case if input.peek( kw::prelude ) => Self::parse_prelude( input ), @@ -475,7 +475,7 @@ pub( crate ) mod private match self { //Visibility::Private( e ) => e.to_tokens( tokens ), - Visibility::Protected( e ) => e.to_tokens( tokens ), + Visibility::Own( e ) => e.to_tokens( tokens ), Visibility::Orphan( e ) => e.to_tokens( tokens ), Visibility::Exposed( e ) => e.to_tokens( tokens ), Visibility::Prelude( e ) => e.to_tokens( tokens ), @@ -501,7 +501,7 @@ pub( crate ) mod private match self { //Visibility::Private( e ) => e.valid_sub_namespace(), - Visibility::Protected( e ) => e.valid_sub_namespace(), + Visibility::Own( e ) => e.valid_sub_namespace(), Visibility::Orphan( e ) => e.valid_sub_namespace(), Visibility::Exposed( e ) => e.valid_sub_namespace(), Visibility::Prelude( e ) => e.valid_sub_namespace(), @@ -514,37 +514,39 @@ pub( crate ) mod private } #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { - #[ allow( unused_imports ) ] - pub use super::orphan::*; + use super::*; + pub use orphan::*; } /// Parented namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { - #[ allow( unused_imports ) ] - pub use super::exposed::*; + use super::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { - #[ allow( unused_imports ) ] - pub use super::prelude::*; + use super::*; + pub use prelude::*; - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { kw, VALID_VISIBILITY_LIST_STR, ValidSubNamespace, HasClauseKind, // VisPrivate, - VisProtected, + VisOwn, VisOrphan, VisExposed, VisPrelude, @@ -556,6 +558,8 @@ pub mod exposed } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; } diff --git a/module/core/mod_interface_meta/tests/smoke_test.rs b/module/core/mod_interface_meta/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/core/mod_interface_meta/tests/smoke_test.rs +++ b/module/core/mod_interface_meta/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/core/process_tools/Cargo.toml b/module/core/process_tools/Cargo.toml index f3e45a836d..cac87e2303 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.6.0" +version = "0.7.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", @@ -27,7 +27,7 @@ all-features = false [features] default = [ "enabled", "process_environment_is_cicd" ] -full = [ "enabled", "process_environment_is_cicd" ] +full = [ "default" ] enabled = [ "mod_interface/enabled", "former/enabled", @@ -43,7 +43,7 @@ process_environment_is_cicd = [] mod_interface = { workspace = true } former = { workspace = true, features = [ "derive_former" ] } proper_path_tools = { workspace = true } -error_tools = { workspace = true, features = [ "error_for_app" ] } # qqq : xxx : rid off error_for_app +error_tools = { workspace = true, features = [ "error_untyped" ] } iter_tools = { workspace = true } ## external diff --git a/module/core/process_tools/src/environment.rs b/module/core/process_tools/src/environment.rs index a69a622379..c31a836e49 100644 --- a/module/core/process_tools/src/environment.rs +++ b/module/core/process_tools/src/environment.rs @@ -50,5 +50,5 @@ pub( crate ) mod private crate::mod_interface! { #[ cfg( feature = "process_environment_is_cicd" ) ] - protected use is_cicd; + own use is_cicd; } diff --git a/module/core/process_tools/src/process.rs b/module/core/process_tools/src/process.rs index db954da17c..e2857e4152 100644 --- a/module/core/process_tools/src/process.rs +++ b/module/core/process_tools/src/process.rs @@ -14,8 +14,8 @@ pub( crate ) mod private use duct::cmd; use error_tools:: { - for_app::{ Error, Context, anyhow }, - Result, + untyped::{ Error, Context, format_err }, + // Result, }; use former::Former; use iter_tools::iter::Itertools; @@ -197,7 +197,7 @@ pub( crate ) mod private } else { - report.error = Err( anyhow!( "Process was finished with error code : {}", output.status ) ); + report.error = Err( format_err!( "Process was finished with error code : {}", output.status ) ); Err( report ) } @@ -272,7 +272,7 @@ pub( crate ) mod private { fn clone( &self ) -> Self { - Report + Self { command : self.command.clone(), current_path : self.current_path.clone(), @@ -324,8 +324,8 @@ pub( crate ) mod private crate::mod_interface! { - // protected use run_with_shell; - protected use run; - protected use Run; - protected use Report; + // own use run_with_shell; + own use run; + own use Run; + own use Report; } diff --git a/module/core/process_tools/tests/smoke_test.rs b/module/core/process_tools/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/core/process_tools/tests/smoke_test.rs +++ b/module/core/process_tools/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/core/program_tools/Cargo.toml b/module/core/program_tools/Cargo.toml index 30faf2edc3..1ba2675334 100644 --- a/module/core/program_tools/Cargo.toml +++ b/module/core/program_tools/Cargo.toml @@ -45,7 +45,7 @@ enabled = [ mod_interface = { workspace = true } former = { workspace = true, features = [ "derive_former" ] } proper_path_tools = { workspace = true } -error_tools = { workspace = true, features = [ "error_for_app" ] } # qqq : xxx : rid off error_for_app +error_tools = { workspace = true, features = [ "error_untyped" ] } # qqq : xxx : rid of error_untyped iter_tools = { workspace = true } # ## external diff --git a/module/core/program_tools/src/lib.rs b/module/core/program_tools/src/lib.rs index 71c19f2ab4..19f55a0993 100644 --- a/module/core/program_tools/src/lib.rs +++ b/module/core/program_tools/src/lib.rs @@ -4,7 +4,7 @@ #![ doc( html_root_url = "https://docs.rs/program_tools/latest/program_tools/" ) ] #![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/", "Readme.md" ) ) ] -#![ allow( unused_imports, dead_code, missing_docs ) ] // xxx : rid off +#![ allow( unused_imports, dead_code, missing_docs ) ] // xxx : rid of #[ cfg( feature = "enabled" ) ] use mod_interface::mod_interface; diff --git a/module/core/program_tools/src/program.rs b/module/core/program_tools/src/program.rs index 5ae707cf30..b049eb364e 100644 --- a/module/core/program_tools/src/program.rs +++ b/module/core/program_tools/src/program.rs @@ -143,7 +143,7 @@ crate::mod_interface! Program, }; - protected use + own use { Plan, Call, diff --git a/module/core/program_tools/tests/smoke_test.rs b/module/core/program_tools/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/core/program_tools/tests/smoke_test.rs +++ b/module/core/program_tools/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/core/proper_path_tools/Cargo.toml b/module/core/proper_path_tools/Cargo.toml index 1571d43e0f..d18650685a 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.7.0" +version = "0.8.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", @@ -24,19 +24,29 @@ features = [ "full" ] all-features = false [features] -default = [ "enabled", "path_unique_folder_name" ] -full = [ "enabled", "path_unique_folder_name", "derive_serde" ] +default = [ + "enabled", + "path_unique_folder_name", + "path_utf8", +] +full = [ + "default", + "derive_serde", + "path_utf8", +] no_std = [] use_alloc = [ "no_std" ] enabled = [ "mod_interface/enabled" ] path_unique_folder_name = [] derive_serde = [ "serde" ] +path_utf8 = [ "camino" ] [dependencies] regex = { version = "1.10.3" } mod_interface = { workspace = true } serde = { version = "1.0.197", optional = true, features = [ "derive" ] } +camino = { version = "1.1.7", optional = true, features = [] } [dev-dependencies] test_tools = { workspace = true } diff --git a/module/core/proper_path_tools/src/lib.rs b/module/core/proper_path_tools/src/lib.rs index d437f55081..1ac23b4abd 100644 --- a/module/core/proper_path_tools/src/lib.rs +++ b/module/core/proper_path_tools/src/lib.rs @@ -18,4 +18,11 @@ mod_interface! /// Basic functionality. layer path; + /// Transitive TryFrom and TryInto. + layer transitive; + + #[ cfg( feature = "path_utf8" ) ] + own use ::camino::{ Utf8Path, Utf8PathBuf }; + own use ::std::path::{ PathBuf, Path }; + } diff --git a/module/core/proper_path_tools/src/path.rs b/module/core/proper_path_tools/src/path.rs index 7e00e31d19..b7f1b0e277 100644 --- a/module/core/proper_path_tools/src/path.rs +++ b/module/core/proper_path_tools/src/path.rs @@ -5,20 +5,6 @@ pub( crate ) mod private #[ cfg( feature = "no_std" ) ] extern crate std; - // use std:: - // { - // path::{ Component, Path, PathBuf }, - // time::{ SystemTime, UNIX_EPOCH, SystemTimeError }, - // }; - // use cargo_metadata::camino::{ Utf8Path, Utf8PathBuf }; - - // // xxx : it's not path, but file - // /// Check if path is valid. - // pub fn valid_is( path : &str ) -> bool - // { - // std::fs::metadata( path ).is_ok() - // } - /// Determines if a given path string contains unescaped glob pattern characters. /// /// # Parameters: @@ -48,42 +34,43 @@ pub( crate ) mod private /// assert_eq!( path::is_glob( "file\\[0-9].txt" ), false ); // Escaped brackets, not a glob pattern /// ``` - pub fn is_glob( path : &str ) -> bool + // qqq : xxx : should probably be Path + pub fn is_glob( path : &str ) -> bool { let mut chars = path.chars().peekable(); let mut is_escaped = false; let mut in_brackets = false; let mut in_braces = false; - while let Some( c ) = chars.next() + while let Some( c ) = chars.next() { - if is_escaped + if is_escaped { // If the character is escaped, ignore its special meaning in the next iteration is_escaped = false; continue; } - match c + match c { - '\\' => + '\\' => { is_escaped = !is_escaped; } '*' | '?' if !in_brackets && !in_braces => return true, - '[' if !in_brackets && !in_braces && !is_escaped => + '[' if !in_brackets && !in_braces && !is_escaped => { // Enter a bracket block, indicating potential glob pattern in_brackets = true; // continue; // Ensure we don't immediately exit on the next char if it's ']' } - ']' if in_brackets => + ']' if in_brackets => { // in_brackets = false; return true; } '{' if !in_braces && !is_escaped => in_braces = true, - '}' if in_braces => + '}' if in_braces => { // in_braces = false; return true; @@ -152,33 +139,33 @@ pub( crate ) mod private let mut starts_with_dot = false; let mut iter = path.as_ref().components().peekable(); - if let Some( first ) = iter.peek() + if let Some( first ) = iter.peek() { starts_with_dot = matches!( first, Component::CurDir ); - if matches!( first, Component::RootDir ) + if matches!( first, Component::RootDir ) { components.push( Component::RootDir ); iter.next(); // Skip the root component in further processing } } - for component in iter + for component in iter { match component { - Component::ParentDir => + Component::ParentDir => { - match components.last() + match components.last() { - Some( Component::Normal( _ ) ) => + Some( Component::Normal( _ ) ) => { components.pop(); } - Some( Component::RootDir ) => + Some( Component::RootDir ) => { components.push( Component::ParentDir ); } - Some( Component::ParentDir ) | None => + Some( Component::ParentDir ) | None => { components.push( Component::ParentDir ); } @@ -191,12 +178,12 @@ pub( crate ) mod private } let mut normalized = PathBuf::new(); - if starts_with_dot || components.is_empty() + if starts_with_dot || components.is_empty() { normalized.push( "." ); } - for component in components.iter() + for component in components.iter() { normalized.push( component.as_os_str() ); } @@ -226,19 +213,22 @@ pub( crate ) mod private // println!( "b" ); let path = normalize( path ); - // In Windows the regular/legacy paths (C :\foo) are supported by all programs, but have lots of bizarre restrictions for backwards compatibility with MS-DOS. - // And there are Windows NT UNC paths (\\?\C :\foo), which are more robust and with fewer gotchas, but are rarely supported by Windows programs. Even Microsoft’s own! + // In Windows the regular/legacy paths (C:\foo) are supported by all programs, but have lots of bizarre restrictions for backwards compatibility with MS-DOS. + // And there are Windows NT UNC paths (\\?\C:\foo), which are more robust and with fewer gotchas, but are rarely supported by Windows programs. Even Microsoft’s own! // // https://github.com/rust-lang/rust/issues/42869 #[ cfg( target_os = "windows" ) ] - let path = + let path = { - const VERBATIM_PREFIX: &str = r#"\\?\"#; + const VERBATIM_PREFIX : &str = r#"\\?\"#; + // is necessary because of the normalization step that replaces the backslash with a slash. + const VERBATIM_PREFIX_MIRRORS_EDGE : &str = "//?/"; let p = path.display().to_string(); - if p.starts_with( VERBATIM_PREFIX ) + if p.starts_with( VERBATIM_PREFIX ) || p.starts_with( VERBATIM_PREFIX_MIRRORS_EDGE ) { PathBuf::from( &p[ VERBATIM_PREFIX.len().. ] ) - } else + } + else { path.into() } @@ -291,7 +281,7 @@ pub( crate ) mod private } // Increment and get the current value of the counter safely - let count = COUNTER.with( | counter | + let count = COUNTER.with( | counter | { let val = counter.get(); counter.set( val + 1 ); @@ -317,23 +307,24 @@ pub( crate ) mod private /// Examples: /// /// ``` + /// use std::path::PathBuf; + /// use proper_path_tools::path; /// - /// let paths = vec![ "a/b/c", "/d/e", "f/g" ]; - /// let joined = proper_path_tools::path::join_paths( paths.into_iter() ); + /// let paths = vec![ PathBuf::from( "a/b/c" ), PathBuf::from( "/d/e" ), PathBuf::from( "f/g" ) ]; + /// let joined = path::join_paths( paths.iter().map( | p | p.as_path() ) ); /// assert_eq!( joined, std::path::PathBuf::from( "/d/e/f/g" ) ); /// - /// let paths = vec![]; - /// let joined = proper_path_tools::path::join_paths( paths.into_iter() ); - /// assert_eq!( joined, std::path::PathBuf::from( "" ) ); - /// - /// let paths = vec![ "", "a/b", "", "c", "" ]; - /// let joined = proper_path_tools::path::join_paths( paths.into_iter() ); - /// assert_eq!( joined, std::path::PathBuf::from( "/a/b/c" ) ); + /// let paths = vec![ PathBuf::from( "" ), PathBuf::from( "a/b" ), PathBuf::from( "" ), PathBuf::from( "c" ), PathBuf::from( "" ) ]; + /// let joined = path::join_paths( paths.iter().map( | p | p.as_path() ) ); + /// assert_eq!( joined, std::path::PathBuf::from( PathBuf::from( "/a/b/c" ) ) ); /// /// ``` + // qqq : make macro paths_join!( ... ) pub fn join_paths< 'a, I >( paths : I ) -> std::path::PathBuf where - I : Iterator< Item = &'a str >, + // AsPath : AsRef< std::path::Path >, + // I : Iterator< Item = AsPath >, + I : Iterator< Item = &'a std::path::Path >, { #[ cfg( feature = "no_std" ) ] extern crate alloc; @@ -344,37 +335,39 @@ pub( crate ) mod private let mut result = String::new(); - for path in paths { - let mut path = path.replace( '\\', "/" ); + for path in paths + { + let mut path = path.to_string_lossy().replace( '\\', "/" ); path = path.replace( ':', "" ); + // qqq : this is a bug let mut added_slah = false; // If the path is empty, skip it - if path.is_empty() + if path.is_empty() { continue; } // If the path starts with '/', clear the result and set it to '/' - if path.starts_with('/') + if path.starts_with( '/' ) { result.clear(); result.push( '/' ); } // If the result doesn't end with '/', append '/' - else if !result.ends_with( '/' ) + else if !result.ends_with( '/' ) { added_slah = true; result.push( '/' ); } let components: Vec<&str> = path.split( '/' ).collect(); // Split the path into components - for ( idx, component ) in components.clone().into_iter().enumerate() + for ( idx, component ) in components.clone().into_iter().enumerate() { - match component + match component { - "." => + "." => { if ( result.ends_with( '/' ) && components.len() > idx + 1 && components[ idx + 1 ].is_empty() ) || components.len() == idx + 1 @@ -382,48 +375,48 @@ pub( crate ) mod private result.pop(); } } - ".." => + ".." => { - if result != "/" + if result != "/" { - if added_slah + if added_slah { result.pop(); added_slah = false; } let mut parts : Vec< _ > = result.split( '/' ).collect(); parts.pop(); - if let Some( part ) = parts.last() + if let Some( part ) = parts.last() { - if part.is_empty() + if part.is_empty() { parts.push( "" ); } } result = parts.join( "/" ); - if result.is_empty() + if result.is_empty() { result.push( '/' ); } - } else + } else { result.push_str( &components[ idx.. ].to_vec().join( "/" ) ); break; } } - _ => + _ => { - if !component.is_empty() + if !component.is_empty() { - if result.ends_with( '/' ) + if result.ends_with( '/' ) { result.push_str( component ); - } else + } else { result.push( '/' ); result.push_str( component ); } - } else if components.len() > idx + 1 && components[ idx + 1 ].is_empty() && path != "/" + } else if components.len() > idx + 1 && components[ idx + 1 ].is_empty() && path != "/" { result.push( '/' ); } @@ -431,7 +424,7 @@ pub( crate ) mod private } } - if path.ends_with( '/' ) && result != "/" + if path.ends_with( '/' ) && result != "/" { result.push( '/' ); } @@ -472,23 +465,25 @@ pub( crate ) mod private /// assert_eq!( extensions, expected ); /// ``` /// - pub fn exts( path : impl AsRef< std::path::Path > ) -> std::vec::Vec< std::string::String > + + // qqq : xxx : should return iterator + pub fn exts( path : impl AsRef< std::path::Path > ) -> std::vec::Vec< std::string::String > { #[ cfg( feature = "no_std" ) ] extern crate alloc; #[ cfg( feature = "no_std" ) ] use alloc::string::ToString; - if let Some( file_name ) = std::path::Path::new( path.as_ref() ).file_name() + if let Some( file_name ) = std::path::Path::new( path.as_ref() ).file_name() { - if let Some( file_name_str ) = file_name.to_str() + if let Some( file_name_str ) = file_name.to_str() { let mut file_name_str = file_name_str.to_string(); if file_name_str.starts_with( '.' ) { file_name_str.remove( 0 ); } - if let Some( dot_index ) = file_name_str.find( '.' ) + if let Some( dot_index ) = file_name_str.find( '.' ) { let extensions = &file_name_str[ dot_index + 1.. ]; @@ -533,7 +528,7 @@ pub( crate ) mod private /// assert_eq!(modified_path, None); /// ``` /// - pub fn without_ext( path : impl AsRef< std::path::Path > ) -> core::option::Option< std::path::PathBuf > + pub fn without_ext( path : impl AsRef< std::path::Path > ) -> core::option::Option< std::path::PathBuf > { use std::path::{ Path, PathBuf }; #[ cfg( feature = "no_std" ) ] @@ -548,17 +543,17 @@ pub( crate ) mod private let path_buf = Path::new( path.as_ref() ); - let parent = match path_buf.parent() + let parent = match path_buf.parent() { Some( parent ) => parent, None => return None, }; - let file_stem = match path_buf.file_stem() + let file_stem = match path_buf.file_stem() { - Some( name ) => + Some( name ) => { let ends = format!( "{}/", name.to_string_lossy() ); - if path.as_ref().to_string_lossy().ends_with( &ends ) + if path.as_ref().to_string_lossy().ends_with( &ends ) { ends } @@ -612,19 +607,19 @@ pub( crate ) mod private /// assert_eq!( modified_path, None ); /// ``` /// - pub fn change_ext( path : impl AsRef< std::path::Path >, ext : &str ) -> Option< std::path::PathBuf > + pub fn change_ext( path : impl AsRef< std::path::Path >, ext : &str ) -> Option< std::path::PathBuf > { use std::path::PathBuf; - if path.as_ref().to_string_lossy().is_empty() || !path.as_ref().to_string_lossy().is_ascii() || !ext.is_ascii() + if path.as_ref().to_string_lossy().is_empty() || !path.as_ref().to_string_lossy().is_ascii() || !ext.is_ascii() { return None; } let without_ext = without_ext( path )?; - if ext.is_empty() + if ext.is_empty() { Some( without_ext ) - } else + } else { Some( PathBuf::from( format!( "{}.{}", without_ext.to_string_lossy(), ext ) ) ) } @@ -654,9 +649,11 @@ pub( crate ) mod private /// assert_eq!( common_path, Some( "/a/b/".to_string() ) ); /// ``` /// - pub fn path_common< 'a, I >( paths : I ) -> Option< std::string::String > + + // xxx : qqq : should probably be PathBuf? + pub fn path_common< 'a, I >( paths : I ) -> Option< std::string::String > where - I: Iterator, + I: Iterator< Item = &'a str >, { use std::collections::HashMap; #[ cfg( feature = "no_std" ) ] @@ -665,18 +662,18 @@ pub( crate ) mod private use alloc::{ string::{ String, ToString }, vec::Vec }; let orig_paths : Vec< String > = paths.map( | path | path.to_string() ).collect(); - - if orig_paths.is_empty() + + if orig_paths.is_empty() { return None; } // Create a map to store directory frequencies let mut dir_freqs : HashMap< String, usize > = HashMap::new(); - + let mut paths = orig_paths.clone(); // Iterate over paths to count directory frequencies - for path in paths.iter_mut() + for path in paths.iter_mut() { path_remove_dots( path ); path_remove_double_dots( path ); @@ -686,11 +683,11 @@ pub( crate ) mod private // Iterate over directories for i in 0..dirs.len() { - + // Construct directory path let mut dir_path = dirs[ 0..i + 1 ].join( "/" ); - + // Increment frequency count *dir_freqs.entry( dir_path.clone() ).or_insert( 0 ) += 1; @@ -712,10 +709,10 @@ pub( crate ) mod private let mut result = common_dir.to_string(); - if result.is_empty() + if result.is_empty() { if orig_paths.iter().any( | path | path.starts_with( '/' ) ) - { + { result.push( '/' ); } else if orig_paths.iter().any( | path | path.starts_with( ".." ) ) @@ -743,10 +740,12 @@ pub( crate ) mod private /// /// * `path` - A mutable reference to a string representing the path to be cleaned. /// - fn path_remove_dots( path : &mut std::string::String ) + + // xxx : qqq : should probably be Path? + fn path_remove_dots( path : &mut std::string::String ) { let mut cleaned_parts = vec![]; - for part in path.split( '/' ) + for part in path.split( '/' ) { if part == "." { @@ -766,7 +765,9 @@ pub( crate ) mod private /// /// * `path` - A mutable reference to a string representing the path to be cleaned. /// - fn path_remove_double_dots( path : &mut std::string::String ) + + // xxx : qqq : should probably be Path? + fn path_remove_double_dots( path : &mut std::string::String ) { #[ cfg( feature = "no_std" ) ] extern crate alloc; @@ -775,9 +776,9 @@ pub( crate ) mod private let mut cleaned_parts: Vec< &str > = Vec::new(); let mut delete_empty_part = false; - for part in path.split( '/' ) + for part in path.split( '/' ) { - if part == ".." + if part == ".." { if let Some( pop ) = cleaned_parts.pop() { @@ -795,8 +796,8 @@ pub( crate ) mod private { cleaned_parts.push( ".." ); } - } - else + } + else { cleaned_parts.push( part ); } @@ -809,7 +810,7 @@ pub( crate ) mod private { *path = cleaned_parts.join( "/" ); } - + } /// Rebase the file path relative to a new base path, optionally removing a common prefix. @@ -849,7 +850,13 @@ pub( crate ) mod private /// assert_eq!( rebased_path, PathBuf::from( "/mnt/storage/documents/file.txt" ) ); /// ``` /// - pub fn rebase< T : AsRef< std::path::Path > >( file_path : T, new_path : T, old_path : Option< T > ) -> Option< std::path::PathBuf > + pub fn rebase< T : AsRef< std::path::Path > > + ( + file_path : T, + new_path : T, + old_path : Option< T > + ) + -> Option< std::path::PathBuf > { use std::path::Path; use std::path::PathBuf; @@ -858,7 +865,7 @@ pub( crate ) mod private if old_path.is_some() { let common = path_common( vec![ file_path.as_ref().to_str().unwrap(), old_path.unwrap().as_ref().to_str().unwrap() ].into_iter() )?; - + main_file_path = match main_file_path.strip_prefix( common ) { Ok( rel ) => rel, @@ -896,7 +903,7 @@ pub( crate ) mod private /// let relative_path = proper_path_tools::path::path_relative( from, to ); /// assert_eq!( relative_path, PathBuf::from( "../c/d" ) ); /// ``` - pub fn path_relative< T : AsRef< std::path::Path > >( from : T, to : T ) -> std::path::PathBuf + pub fn path_relative< T : AsRef< std::path::Path > >( from : T, to : T ) -> std::path::PathBuf { use std::path::PathBuf; #[ cfg( feature = "no_std" ) ] @@ -921,7 +928,7 @@ pub( crate ) mod private path_remove_double_dots( &mut to ); path_remove_dots( &mut from ); path_remove_dots( &mut to ); - + let mut from_parts: Vec< &str > = from.split( '/' ).collect(); let mut to_parts: Vec< &str > = to.split( '/' ).collect(); if from_parts.len() == 1 && from_parts[ 0 ].is_empty() @@ -933,9 +940,9 @@ pub( crate ) mod private to_parts.pop(); } let mut common_prefix = 0; - for ( idx, ( f, t ) ) in from_parts.iter().zip( to_parts.iter() ).enumerate() + for ( idx, ( f, t ) ) in from_parts.iter().zip( to_parts.iter() ).enumerate() { - if f != t + if f != t { break; } @@ -943,13 +950,13 @@ pub( crate ) mod private } let mut result = Vec::new(); // Add ".." for each directory not in common - for i in common_prefix..from_parts.len() + for i in common_prefix..from_parts.len() { - if from_parts[ common_prefix ].is_empty() || - ( - i == from_parts.len() - 1 + if from_parts[ common_prefix ].is_empty() || + ( + i == from_parts.len() - 1 && from_parts[ i ].is_empty() - && !to_parts.last().unwrap_or( &"" ).is_empty() + && !to_parts.last().unwrap_or( &"" ).is_empty() ) { continue; @@ -957,7 +964,7 @@ pub( crate ) mod private result.push( ".." ); } // Add the remaining directories from 'to' - for part in to_parts.iter().skip( common_prefix ) + for part in to_parts.iter().skip( common_prefix ) { result.push( *part ); } @@ -965,11 +972,11 @@ pub( crate ) mod private let mut relative_path = result.join( "/" ); // If the relative path is empty or the 'to' path is the same as the 'from' path, // set the relative path to "." - if relative_path.is_empty() || from == to + if relative_path.is_empty() || from == to { relative_path = ".".to_string(); } - + if to.ends_with( '/' ) && !relative_path.ends_with( '/' ) && to != "/" { relative_path.push( '/' ); @@ -985,9 +992,6 @@ pub( crate ) mod private PathBuf::from( relative_path ) } - - - /// Extracts the extension from the given path. /// /// This function takes a path and returns a string representing the extension of the file. @@ -1019,7 +1023,7 @@ pub( crate ) mod private /// assert_eq!( extension, "" ); /// ``` /// - pub fn ext( path : impl AsRef< std::path::Path > ) -> std::string::String + pub fn ext( path : impl AsRef< std::path::Path > ) -> std::string::String { use std::path::Path; #[ cfg( feature = "no_std" ) ] @@ -1027,12 +1031,12 @@ pub( crate ) mod private #[ cfg( feature = "no_std" ) ] use alloc::string::{ String, ToString }; - if path.as_ref().to_string_lossy().is_empty() + if path.as_ref().to_string_lossy().is_empty() { return String::new(); } let path_buf = Path::new( path.as_ref() ); - match path_buf.extension() + match path_buf.extension() { Some( ext ) => ext.to_string_lossy().to_string(), None => String::new(), @@ -1040,22 +1044,31 @@ pub( crate ) mod private } } -crate::mod_interface! { - protected use ext; - protected use exts; - protected use change_ext; - protected use path_relative; - protected use rebase; - protected use path_common; - protected use join_paths; - protected use without_ext; - protected use is_glob; - protected use normalize; - protected use canonicalize; +crate::mod_interface! +{ + + orphan use ext; + orphan use exts; + orphan use change_ext; + orphan use path_relative; + orphan use rebase; + orphan use path_common; + orphan use join_paths; + orphan use without_ext; + orphan use is_glob; + orphan use normalize; + orphan use canonicalize; + #[ cfg( feature = "path_unique_folder_name" ) ] - protected use unique_folder_name; + orphan use unique_folder_name; - /// Describe absolute path. Prefer using absolute path instead of relative when ever possible. + /// Describe absolute path. Prefer using absolute path instead of relative paths when ever possible. layer absolute_path; + /// Describe canonical path. Prefer using canonical path instead of native paths when ever possible. + layer canonical_path; + /// A type to symbolyze the crruent path. + layer current_path; + /// Describe native path. Use to pass path to the platfrom. + layer native_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 115c71d37b..ae9542d615 100644 --- a/module/core/proper_path_tools/src/path/absolute_path.rs +++ b/module/core/proper_path_tools/src/path/absolute_path.rs @@ -1,48 +1,120 @@ /// Internal namespace. pub( crate ) mod private { - #[cfg(feature="no_std")] - extern crate std; + use crate::*; + use std:: { - borrow::Cow, - fmt, + // borrow::Cow, path::{ Path, PathBuf }, + io, + }; + + use core:: + { + fmt, + ops:: + { + Deref, + DerefMut, + }, }; + + #[cfg(feature="no_std")] + extern crate std; + #[ cfg( feature = "derive_serde" ) ] use serde::{ Serialize, Deserialize }; + #[ cfg( feature = "path_utf8" ) ] + use camino::{ Utf8Path, Utf8PathBuf }; + /// Absolute path. #[ cfg_attr( feature = "derive_serde", derive( Serialize, Deserialize ) ) ] #[ derive( Debug, Default, Clone, Ord, PartialOrd, Eq, PartialEq, Hash ) ] pub struct AbsolutePath( PathBuf ); + impl AbsolutePath + { + + /// Returns the Path without its final component, if there is one. + /// Returns None if the path terminates in a root or prefix, or if it's the empty string. + #[ inline ] + pub fn parent( &self ) -> Option< AbsolutePath > + { + self.0.parent().map( PathBuf::from ).map( AbsolutePath ) + } + + /// Creates an owned `AbsolutePath` with path adjoined to self. + #[ inline ] + pub fn join< P >( &self, path : P ) -> AbsolutePath + where + P : AsRef< Path >, + { + Self::try_from( self.0.join( path ) ).unwrap() + } + + // /// Converts a `AbsolutePath` to a `Cow` + // pub fn to_string_lossy( &self ) -> Cow< '_, str > + // { + // self.0.to_string_lossy() + // } + + /// Determines whether base is a prefix of self. + /// + /// Only considers whole path components to match. + #[ inline ] + pub fn starts_with< P : AsRef< Path > >( &self, base : P ) -> bool + { + self.0.starts_with( base ) + } + + /// Returns inner type which is PathBuf. + #[ inline( always ) ] + pub fn inner( self ) -> PathBuf + { + self.0 + } + + } + impl fmt::Display for AbsolutePath { + #[ inline ] fn fmt( &self, f : &mut fmt::Formatter<'_> ) -> fmt::Result { write!( f, "{}", self.0.display() ) } } - impl< 'a > TryFrom< &'a str > for AbsolutePath + #[ inline ] + fn is_absolute( path : &Path ) -> bool + { + // None - not absolute + // with `.` or `..` at the first component - not absolute + !path.components().next().is_some_and( | c | c.as_os_str() == "." || c.as_os_str() == ".." ) + } + + impl TryFrom< PathBuf > for AbsolutePath { type Error = std::io::Error; - fn try_from( value : &'a str ) -> Result< Self, Self::Error > + #[ inline ] + fn try_from( src : PathBuf ) -> Result< Self, Self::Error > { - Ok( Self( path::canonicalize( value )? ) ) + < Self as TryFrom< &Path > >::try_from( &src.as_path() ) } } - impl TryFrom< PathBuf > for AbsolutePath + impl TryFrom< &PathBuf > for AbsolutePath { type Error = std::io::Error; - fn try_from( value : PathBuf ) -> Result< Self, Self::Error > + #[ inline ] + fn try_from( src : &PathBuf ) -> Result< Self, Self::Error > { - Ok( Self( path::canonicalize( value )? ) ) + < Self as TryFrom< &Path > >::try_from( &src.as_path() ) } } @@ -51,28 +123,123 @@ pub( crate ) mod private { type Error = std::io::Error; - fn try_from( value : &Path ) -> Result< Self, Self::Error > + #[ inline ] + fn try_from( src : &Path ) -> Result< Self, Self::Error > + { + // < Self as TryFrom< &str > >::try_from( src.to_string_lossy() ) + let path = path::canonicalize( src )?; + + // xxx + if !is_absolute( &path ) + { + return Err( io::Error::new( io::ErrorKind::InvalidData, "Path expected to be absolute, but it's not {path}" ) ) + } + + Ok( Self( path ) ) + } + } + + impl< 'a > TryFrom< &'a str > for AbsolutePath + { + type Error = std::io::Error; + + #[ inline ] + fn try_from( src : &'a str ) -> Result< Self, Self::Error > + { + < Self as TryFrom< &Path > >::try_from( src.as_ref() ) + } + } + +// impl TryFrom< &str > for AbsolutePath +// { +// type Error = std::io::Error; +// // type Error = PathError; +// +// #[ inline( always ) ] +// fn try_from( src : &str ) -> Result< Self, Self::Error > +// { +// Self::try_from( AbsolutePath::try_from( src )? ) +// } +// } + + #[ cfg( feature = "path_utf8" ) ] + impl TryFrom< Utf8PathBuf > for AbsolutePath + { + type Error = std::io::Error; + + #[ inline ] + fn try_from( src : Utf8PathBuf ) -> Result< Self, Self::Error > { - Ok( Self( path::canonicalize( value )? ) ) + AbsolutePath::try_from( src.as_std_path() ) } } - impl From< AbsolutePath > for PathBuf + #[ cfg( feature = "path_utf8" ) ] + impl TryFrom< &Utf8PathBuf > for AbsolutePath { - fn from( abs_path: AbsolutePath ) -> Self + type Error = std::io::Error; + + #[ inline ] + fn try_from( src : &Utf8PathBuf ) -> Result< Self, Self::Error > { - abs_path.0 + AbsolutePath::try_from( src.as_std_path() ) } } + #[ cfg( feature = "path_utf8" ) ] + impl TryFrom< &Utf8Path > for AbsolutePath + { + type Error = std::io::Error; + + #[ inline ] + fn try_from( src : &Utf8Path ) -> Result< Self, Self::Error > + { + AbsolutePath::try_from( src.as_std_path() ) + } + } + + impl From< AbsolutePath > for PathBuf + { + #[ inline ] + fn from( src : AbsolutePath ) -> Self + { + src.0 + } + } + + impl< 'a > TryFrom< &'a AbsolutePath > for &'a str + { + type Error = std::io::Error; + #[ inline ] + fn try_from( src : &'a AbsolutePath ) -> Result< &'a str, Self::Error > + { + src + .to_str() + .ok_or_else + ( + move || io::Error::new( io::ErrorKind::Other, format!( "Can't convert &PathBuf into &str {src}" ) ) + ) + } + } + + impl TryFrom< &AbsolutePath > for String + { + type Error = std::io::Error; + #[ inline ] + fn try_from( src : &AbsolutePath ) -> Result< String, Self::Error > + { + let src2 : &str = src.try_into()?; + Ok( src2.into() ) + } + } // impl TryFrom< Utf8PathBuf > for AbsolutePath // { // type Error = std::io::Error; // -// fn try_from( value : Utf8PathBuf ) -> Result< Self, Self::Error > +// fn try_from( src : Utf8PathBuf ) -> Result< Self, Self::Error > // { -// AbsolutePath::try_from( value.as_std_path() ) +// AbsolutePath::try_from( src.as_std_path() ) // } // } @@ -80,49 +247,93 @@ pub( crate ) mod private // { // type Error = std::io::Error; // -// fn try_from( value : &Utf8Path ) -> Result< Self, Self::Error > +// fn try_from( src : &Utf8Path ) -> Result< Self, Self::Error > // { -// AbsolutePath::try_from( value.as_std_path() ) +// AbsolutePath::try_from( src.as_std_path() ) // } // } - // xxx : use derives + // // xxx : use derives + // impl AsRef< Path > for AbsolutePath + // { + // fn as_ref( &self ) -> &Path + // { + // self.0.as_ref() + // } + // } + impl AsRef< Path > for AbsolutePath { + #[ inline ] fn as_ref( &self ) -> &Path { self.0.as_ref() } } - impl AbsolutePath + impl AsMut< Path > for AbsolutePath { - /// Returns the Path without its final component, if there is one. - /// Returns None if the path terminates in a root or prefix, or if it's the empty string. - pub fn parent( &self ) -> Option< AbsolutePath > + #[ inline ] + fn as_mut( &mut self ) -> &mut Path { - self.0.parent().map( PathBuf::from ).map( AbsolutePath ) + &mut self.0 } + } - /// Creates an owned `AbsolutePath` with path adjoined to self. - pub fn join< P >( &self, path : P ) -> AbsolutePath - where - P : AsRef< Path >, + impl Deref for AbsolutePath + { + type Target = Path; + #[ inline ] + fn deref( &self ) -> &Self::Target { - Self::try_from( self.0.join( path ) ).unwrap() + &self.0 } + } - /// Converts a `AbsolutePath` to a `Cow` - pub fn to_string_lossy( &self ) -> Cow< '_, str > + impl DerefMut for AbsolutePath + { + #[ inline ] + fn deref_mut( &mut self ) -> &mut Self::Target { - self.0.to_string_lossy() + &mut self.0 } - } +// /// Convertable into absolute path entity should implement the trait. +// pub trait TryIntoAbsolutePath +// { +// /// Error returned if conversion is failed. +// type Error; +// /// Method to convert the type into absolute path. +// fn into_absolute_path( self ) -> Result< AbsolutePath, Self::Error >; +// } +// +// // impl TryIntoAbsolutePath for AbsolutePath +// // { +// // type Error = std::io::Error; +// // #[ inline ] +// // fn into_absolute_path( self ) -> Result< AbsolutePath, Self::Error > +// // { +// // Ok( self ) +// // } +// // } +// +// impl< TryIntoAbsolutePathType > TryIntoAbsolutePath for TryIntoAbsolutePathType +// where +// TryIntoAbsolutePathType : TryInto< AbsolutePath >, +// { +// type Error = < Self as TryInto< AbsolutePath > >::Error; +// #[ inline ] +// fn into_absolute_path( self ) -> Result< AbsolutePath, Self::Error > +// { +// self.try_into() +// } +// } + } crate::mod_interface! { exposed use AbsolutePath; + // exposed use TryIntoAbsolutePath; } diff --git a/module/core/proper_path_tools/src/path/canonical_path.rs b/module/core/proper_path_tools/src/path/canonical_path.rs new file mode 100644 index 0000000000..b02c2dccbb --- /dev/null +++ b/module/core/proper_path_tools/src/path/canonical_path.rs @@ -0,0 +1,287 @@ +/// Internal namespace. +pub( crate ) mod private +{ + + use crate::*; + + use std:: + { + // borrow::Cow, + path::{ Path, PathBuf }, + io, + }; + + use core:: + { + fmt, + ops:: + { + Deref, + DerefMut, + }, + }; + + #[cfg(feature="no_std")] + extern crate std; + + #[ cfg( feature = "derive_serde" ) ] + use serde::{ Serialize, Deserialize }; + + #[ cfg( feature = "path_utf8" ) ] + use camino::{ Utf8Path, Utf8PathBuf }; + + /// Caninical path. + #[ cfg_attr( feature = "derive_serde", derive( Serialize, Deserialize ) ) ] + #[ derive( Debug, Default, Clone, Ord, PartialOrd, Eq, PartialEq, Hash ) ] + pub struct CanonicalPath( PathBuf ); + + impl CanonicalPath + { + + /// Returns the Path without its final component, if there is one. + /// Returns None if the path terminates in a root or prefix, or if it's the empty string. + #[ inline ] + pub fn parent( &self ) -> Option< CanonicalPath > + { + self.0.parent().map( PathBuf::from ).map( CanonicalPath ) + } + + /// Creates an owned `CanonicalPath` with path adjoined to self. + #[ inline ] + pub fn join< P >( &self, path : P ) -> CanonicalPath + where + P : AsRef< Path >, + { + Self::try_from( self.0.join( path ) ).unwrap() + } + + // /// Converts a `CanonicalPath` to a `Cow` + // pub fn to_string_lossy( &self ) -> Cow< '_, str > + // { + // self.0.to_string_lossy() + // } + + /// Determines whether base is a prefix of self. + /// + /// Only considers whole path components to match. + #[ inline ] + pub fn starts_with< P : AsRef< Path > >( &self, base : P ) -> bool + { + self.0.starts_with( base ) + } + + /// Returns inner type which is PathBuf. + #[ inline( always ) ] + pub fn inner( self ) -> PathBuf + { + self.0 + } + + } + + impl fmt::Display for CanonicalPath + { + #[ inline ] + fn fmt( &self, f : &mut fmt::Formatter<'_> ) -> fmt::Result + { + write!( f, "{}", self.0.display() ) + } + } + + // fn is_absolute( path : &Path ) -> bool + // { + // // None - not absolute + // // with `.` or `..` at the first component - not absolute + // !path.components().next().is_some_and( | c | c.as_os_str() == "." || c.as_os_str() == ".." ) + // } + + impl< 'a > TryFrom< &'a str > for CanonicalPath + { + type Error = std::io::Error; + + #[ inline ] + fn try_from( value : &'a str ) -> Result< Self, Self::Error > + { + let path = path::canonicalize( value )?; + // if !is_absolute( &path ) + // { + // return Err( io::Error::new( io::ErrorKind::InvalidData, "Path expected to be absolute" ) ) + // } + Ok( Self( path ) ) + } + } + + impl TryFrom< PathBuf > for CanonicalPath + { + type Error = std::io::Error; + + #[ inline ] + fn try_from( value : PathBuf ) -> Result< Self, Self::Error > + { + let path = path::canonicalize( value )?; + + // if !is_absolute( &path ) { return Err( io::Error::new( io::ErrorKind::InvalidData, "Path expected to be absolute" ) ) } + + Ok( Self( path ) ) + } + } + + // xxx : qqq : use Into< Path > + impl TryFrom< &Path > for CanonicalPath + { + type Error = std::io::Error; + + #[ inline ] + fn try_from( value : &Path ) -> Result< Self, Self::Error > + { + let path = path::canonicalize( value )?; + + // if !is_absolute( &path ) { return Err( io::Error::new( io::ErrorKind::InvalidData, "Path expected to be absolute" ) ) } + + Ok( Self( path ) ) + } + } + + #[ cfg( feature = "path_utf8" ) ] + impl TryFrom< Utf8PathBuf > for CanonicalPath + { + type Error = std::io::Error; + + #[ inline ] + fn try_from( value : Utf8PathBuf ) -> Result< Self, Self::Error > + { + CanonicalPath::try_from( value.as_std_path() ) + } + } + + #[ cfg( feature = "path_utf8" ) ] + impl TryFrom< &Utf8PathBuf > for CanonicalPath + { + type Error = std::io::Error; + + #[ inline ] + fn try_from( value : &Utf8PathBuf ) -> Result< Self, Self::Error > + { + CanonicalPath::try_from( value.as_std_path() ) + } + } + + #[ cfg( feature = "path_utf8" ) ] + impl TryFrom< &Utf8Path > for CanonicalPath + { + type Error = std::io::Error; + + #[ inline ] + fn try_from( value : &Utf8Path ) -> Result< Self, Self::Error > + { + CanonicalPath::try_from( value.as_std_path() ) + } + } + + impl From< CanonicalPath > for PathBuf + { + #[ inline ] + fn from( src : CanonicalPath ) -> Self + { + src.0 + } + } + + impl< 'a > TryFrom< &'a CanonicalPath > for &'a str + { + type Error = std::io::Error; + #[ inline ] + fn try_from( src : &'a CanonicalPath ) -> Result< &'a str, Self::Error > + { + src + .to_str() + .ok_or_else + ( + move || io::Error::new( io::ErrorKind::Other, format!( "Can't convert &PathBuf into &str {src}" ) ) + ) + } + } + + impl TryFrom< &CanonicalPath > for String + { + type Error = std::io::Error; + #[ inline ] + fn try_from( src : &CanonicalPath ) -> Result< String, Self::Error > + { + let src2 : &str = src.try_into()?; + Ok( src2.into() ) + } + } + +// impl TryFrom< Utf8PathBuf > for CanonicalPath +// { +// type Error = std::io::Error; +// +// fn try_from( value : Utf8PathBuf ) -> Result< Self, Self::Error > +// { +// CanonicalPath::try_from( value.as_std_path() ) +// } +// } + +// impl TryFrom< &Utf8Path > for CanonicalPath +// { +// type Error = std::io::Error; +// +// fn try_from( value : &Utf8Path ) -> Result< Self, Self::Error > +// { +// CanonicalPath::try_from( value.as_std_path() ) +// } +// } + + // // xxx : use derives + // impl AsRef< Path > for CanonicalPath + // { + // fn as_ref( &self ) -> &Path + // { + // self.0.as_ref() + // } + // } + + impl AsRef< Path > for CanonicalPath + { + #[ inline ] + fn as_ref( &self ) -> &Path + { + self.0.as_ref() + } + } + + impl AsMut< Path > for CanonicalPath + { + #[ inline ] + fn as_mut( &mut self ) -> &mut Path + { + &mut self.0 + } + } + + impl Deref for CanonicalPath + { + type Target = Path; + #[ inline ] + fn deref( &self ) -> &Self::Target + { + &self.0 + } + } + + impl DerefMut for CanonicalPath + { + #[ inline ] + fn deref_mut( &mut self ) -> &mut Self::Target + { + &mut self.0 + } + } + +} + +crate::mod_interface! +{ + exposed use CanonicalPath; +} diff --git a/module/core/proper_path_tools/src/path/current_path.rs b/module/core/proper_path_tools/src/path/current_path.rs new file mode 100644 index 0000000000..fe5c164242 --- /dev/null +++ b/module/core/proper_path_tools/src/path/current_path.rs @@ -0,0 +1,62 @@ +/// Internal namespace. +pub( crate ) mod private +{ + + use crate::*; + use std::env; + + /// Symbolize current path. + #[ derive( Clone, Copy, Debug, Default, PartialEq, Eq ) ] + pub struct CurrentPath; + + #[ cfg( feature = "path_utf8" ) ] + impl TryFrom< CurrentPath > for Utf8PathBuf + { + type Error = std::io::Error; + + #[ inline ] + fn try_from( src : CurrentPath ) -> Result< Self, Self::Error > + { + Utf8PathBuf::try_from( PathBuf::try_from( src )? ) + .map_err + ( + | err | + { + std::io::Error::new + ( + std::io::ErrorKind::NotFound, + format!( "Cant convert to utf8 {}", err ), + ) + } + ) + } + } + + impl TryFrom< CurrentPath > for PathBuf + { + type Error = std::io::Error; + + #[ inline ] + fn try_from( _ : CurrentPath ) -> Result< Self, Self::Error > + { + env::current_dir() + } + } + + impl TryFrom< CurrentPath > for AbsolutePath + { + type Error = std::io::Error; + + #[ inline ] + fn try_from( src : CurrentPath ) -> Result< Self, Self::Error > + { + AbsolutePath::try_from( PathBuf::try_from( src )? ) + } + } + +} + +crate::mod_interface! +{ + exposed use CurrentPath; +} diff --git a/module/core/proper_path_tools/src/path/native_path.rs b/module/core/proper_path_tools/src/path/native_path.rs new file mode 100644 index 0000000000..d192cc6966 --- /dev/null +++ b/module/core/proper_path_tools/src/path/native_path.rs @@ -0,0 +1,302 @@ +/// Internal namespace. +pub( crate ) mod private +{ + + use crate::*; + + use std:: + { + // borrow::Cow, + path::{ Path, PathBuf }, + io, + }; + + use core:: + { + fmt, + ops:: + { + Deref, + DerefMut, + }, + }; + + #[cfg(feature="no_std")] + extern crate std; + + #[ cfg( feature = "derive_serde" ) ] + use serde::{ Serialize, Deserialize }; + + #[ cfg( feature = "path_utf8" ) ] + use camino::{ Utf8Path, Utf8PathBuf }; + + /// Caninical path. + #[ cfg_attr( feature = "derive_serde", derive( Serialize, Deserialize ) ) ] + #[ derive( Debug, Default, Clone, Ord, PartialOrd, Eq, PartialEq, Hash ) ] + pub struct NativePath( PathBuf ); + + impl NativePath + { + + /// Returns the Path without its final component, if there is one. + /// Returns None if the path terminates in a root or prefix, or if it's the empty string. + #[ inline ] + pub fn parent( &self ) -> Option< NativePath > + { + self.0.parent().map( PathBuf::from ).map( NativePath ) + } + + /// Creates an owned `NativePath` with path adjoined to self. + #[ inline ] + pub fn join< P >( &self, path : P ) -> NativePath + where + P : AsRef< Path >, + { + Self::try_from( self.0.join( path ) ).unwrap() + } + + // /// Converts a `NativePath` to a `Cow` + // pub fn to_string_lossy( &self ) -> Cow< '_, str > + // { + // self.0.to_string_lossy() + // } + + /// Determines whether base is a prefix of self. + /// + /// Only considers whole path components to match. + #[ inline ] + pub fn starts_with< P : AsRef< Path > >( &self, base : P ) -> bool + { + self.0.starts_with( base ) + } + + /// Returns inner type which is PathBuf. + #[ inline( always ) ] + pub fn inner( self ) -> PathBuf + { + self.0 + } + + } + + impl fmt::Display for NativePath + { + #[ inline ] + fn fmt( &self, f : &mut fmt::Formatter<'_> ) -> fmt::Result + { + write!( f, "{}", self.0.display() ) + } + } + + // fn is_absolute( path : &Path ) -> bool + // { + // // None - not absolute + // // with `.` or `..` at the first component - not absolute + // !path.components().next().is_some_and( | c | c.as_os_str() == "." || c.as_os_str() == ".." ) + // } + + impl< 'a > TryFrom< &'a str > for NativePath + { + type Error = std::io::Error; + + #[ inline ] + fn try_from( value : &'a str ) -> Result< Self, Self::Error > + { + let path = path::canonicalize( value )?; + // if !is_absolute( &path ) + // { + // return Err( io::Error::new( io::ErrorKind::InvalidData, "Path expected to be absolute" ) ) + // } + Ok( Self( path ) ) + } + } + + impl TryFrom< PathBuf > for NativePath + { + type Error = std::io::Error; + + #[ inline ] + fn try_from( value : PathBuf ) -> Result< Self, Self::Error > + { + let path = path::canonicalize( value )?; + + // if !is_absolute( &path ) { return Err( io::Error::new( io::ErrorKind::InvalidData, "Path expected to be absolute" ) ) } + + Ok( Self( path ) ) + } + } + + impl TryFrom< &PathBuf > for NativePath + { + type Error = std::io::Error; + + #[ inline ] + fn try_from( value : &PathBuf ) -> Result< Self, Self::Error > + { + let path = path::canonicalize( value )?; + + // if !is_absolute( &path ) { return Err( io::Error::new( io::ErrorKind::InvalidData, "Path expected to be absolute" ) ) } + + Ok( Self( path ) ) + } + } + + // xxx : qqq : use Into< Path > + impl TryFrom< &Path > for NativePath + { + type Error = std::io::Error; + + #[ inline ] + fn try_from( value : &Path ) -> Result< Self, Self::Error > + { + let path = path::canonicalize( value )?; + + // if !is_absolute( &path ) { return Err( io::Error::new( io::ErrorKind::InvalidData, "Path expected to be absolute" ) ) } + + Ok( Self( path ) ) + } + } + + #[ cfg( feature = "path_utf8" ) ] + impl TryFrom< Utf8PathBuf > for NativePath + { + type Error = std::io::Error; + + #[ inline ] + fn try_from( value : Utf8PathBuf ) -> Result< Self, Self::Error > + { + NativePath::try_from( value.as_std_path() ) + } + } + + #[ cfg( feature = "path_utf8" ) ] + impl TryFrom< &Utf8PathBuf > for NativePath + { + type Error = std::io::Error; + + #[ inline ] + fn try_from( value : &Utf8PathBuf ) -> Result< Self, Self::Error > + { + NativePath::try_from( value.as_std_path() ) + } + } + + #[ cfg( feature = "path_utf8" ) ] + impl TryFrom< &Utf8Path > for NativePath + { + type Error = std::io::Error; + + #[ inline ] + fn try_from( value : &Utf8Path ) -> Result< Self, Self::Error > + { + NativePath::try_from( value.as_std_path() ) + } + } + + impl From< NativePath > for PathBuf + { + #[ inline ] + fn from( src : NativePath ) -> Self + { + src.0 + } + } + + impl< 'a > TryFrom< &'a NativePath > for &'a str + { + type Error = std::io::Error; + #[ inline ] + fn try_from( src : &'a NativePath ) -> Result< &'a str, Self::Error > + { + src + .to_str() + .ok_or_else + ( + move || io::Error::new( io::ErrorKind::Other, format!( "Can't convert &PathBuf into &str {src}" ) ) + ) + } + } + + impl TryFrom< &NativePath > for String + { + type Error = std::io::Error; + #[ inline ] + fn try_from( src : &NativePath ) -> Result< String, Self::Error > + { + let src2 : &str = src.try_into()?; + Ok( src2.into() ) + } + } + +// impl TryFrom< Utf8PathBuf > for NativePath +// { +// type Error = std::io::Error; +// +// fn try_from( value : Utf8PathBuf ) -> Result< Self, Self::Error > +// { +// NativePath::try_from( value.as_std_path() ) +// } +// } + +// impl TryFrom< &Utf8Path > for NativePath +// { +// type Error = std::io::Error; +// +// fn try_from( value : &Utf8Path ) -> Result< Self, Self::Error > +// { +// NativePath::try_from( value.as_std_path() ) +// } +// } + + // // xxx : use derives + // impl AsRef< Path > for NativePath + // { + // fn as_ref( &self ) -> &Path + // { + // self.0.as_ref() + // } + // } + + impl AsRef< Path > for NativePath + { + #[ inline ] + fn as_ref( &self ) -> &Path + { + self.0.as_ref() + } + } + + impl AsMut< Path > for NativePath + { + #[ inline ] + fn as_mut( &mut self ) -> &mut Path + { + &mut self.0 + } + } + + impl Deref for NativePath + { + type Target = Path; + #[ inline ] + fn deref( &self ) -> &Self::Target + { + &self.0 + } + } + + impl DerefMut for NativePath + { + #[ inline ] + fn deref_mut( &mut self ) -> &mut Self::Target + { + &mut self.0 + } + } + +} + +crate::mod_interface! +{ + exposed use NativePath; +} diff --git a/module/core/proper_path_tools/src/transitive.rs b/module/core/proper_path_tools/src/transitive.rs new file mode 100644 index 0000000000..a5bdd22627 --- /dev/null +++ b/module/core/proper_path_tools/src/transitive.rs @@ -0,0 +1,201 @@ +/// Internal namespace. +pub( crate ) mod private +{ + // xxx : move to derive_tools + + // qqq : write tests, lool into example + // + // impl< Initial > TransitiveTryFrom< AbsolutePath, PathError, Initial > + // for CrateDir + // where + // AbsolutePath : TryFrom< Initial >, + // PathError : From< < AbsolutePath as TryFrom< Initial > >::Error >, + // { + // } + + // qqq : implement transitive_from + // qqq : implement transitive_into + + // qqq : move to derive_tools + // qqq : write tests, look into example + // + // impl< Initial > TransitiveTryFrom< AbsolutePath, PathError, Initial > + // for CrateDir + // where + // AbsolutePath : TryFrom< Initial >, + // PathError : From< < AbsolutePath as TryFrom< Initial > >::Error >, + // { + // } + // qqq : implement transitive_try_into + // qqq : implement transitive_from + // qqq : implement transitive_into + + /// A trait to perform a transitive `try_from` conversion. + /// + /// This trait allows for a two-step conversion process where an initial type `Initial` + /// is first converted to an intermediate type `Transitive`, and then to the final type `Self`. + /// + /// # Type Parameters + /// + /// - `Error`: The error type that can be produced during the conversion. + /// - `Initial`: The initial type from which the conversion starts. + /// + /// # Requirements + /// + /// - `Transitive` must implement `TryFrom`. + /// - `Self` must implement `TryFrom` with the same error type. + /// - `Error` must implement `From<>::Error>`. + /// + /// # Example + /// + /// ```rust + /// use proper_path_tools::TransitiveTryFrom; + /// use std::convert::TryFrom; + /// + /// struct InitialType; + /// struct IntermediateType; + /// struct FinalType; + /// struct ConversionError; + /// + /// impl TryFrom< InitialType > for IntermediateType + /// { + /// type Error = ConversionError; + /// fn try_from( value : InitialType ) -> Result< Self, Self::Error > + /// { + /// // Conversion logic here + /// Ok( IntermediateType ) + /// } + /// } + /// + /// impl TryFrom< IntermediateType > for FinalType + /// { + /// type Error = ConversionError; + /// fn try_from( value : IntermediateType ) -> Result< Self, Self::Error > + /// { + /// // Conversion logic here + /// Ok( FinalType ) + /// } + /// } + /// + /// let initial = InitialType; + /// let final_result : Result< FinalType, ConversionError > = FinalType::transitive_try_from::< IntermediateType >( initial ); + /// ``` + pub trait TransitiveTryFrom< Error, Initial > + { + /// Performs a transitive `try_from` conversion. + /// + /// This method first converts the `src` of type `Initial` to the intermediate type `Transitive`, + /// and then converts the intermediate type to the final type `Self`. + /// + /// # Arguments + /// + /// - `src`: The initial value to be converted. + /// + /// # Returns + /// + /// - `Ok(Self)`: If both conversions succeed. + /// - `Err(Error)`: If either conversion fails. + /// + /// # Example + /// + /// See the trait-level documentation for an example. + #[ inline( always ) ] + fn transitive_try_from< Transitive >( src : Initial ) -> Result< Self, Error > + where + Transitive : TryFrom< Initial >, + Self : TryFrom< Transitive, Error = Error >, + Error : From< < Transitive as TryFrom< Initial > >::Error >, + { + let src2 = TryFrom::< Initial >::try_from( src )?; + TryFrom::< Transitive >::try_from( src2 ) + } + } + + impl< Initial, Error, Final > TransitiveTryFrom< Error, Initial > for Final {} + + /// A trait to perform a transitive `try_into` conversion. + /// + /// This trait allows for a two-step conversion process where an initial type `Self` + /// is first converted to an intermediate type `Transitive`, and then to the final type `Final`. + /// + /// # Type Parameters + /// + /// - `Error`: The error type that can be produced during the conversion. + /// - `Final`: The final type to which `Transitive` is converted. + /// + /// # Requirements + /// + /// - `Self` must implement `TryInto`. + /// - `Transitive` must implement `TryInto` with the same error type. + /// - `Error` must implement `From<>::Error>`. + /// + /// # Example + /// + /// ```rust + /// use proper_path_tools::TransitiveTryInto; + /// use std::convert::TryInto; + /// + /// struct InitialType; + /// struct IntermediateType; + /// struct FinalType; + /// struct ConversionError; + /// + /// impl TryInto< IntermediateType > for InitialType + /// { + /// type Error = ConversionError; + /// fn try_into( self ) -> Result< IntermediateType, Self::Error > + /// { + /// // Conversion logic here + /// Ok( IntermediateType ) + /// } + /// } + /// + /// impl TryInto< FinalType > for IntermediateType + /// { + /// type Error = ConversionError; + /// fn try_into( self ) -> Result< FinalType, Self::Error > + /// { + /// // Conversion logic here + /// Ok( FinalType ) + /// } + /// } + /// + /// let initial = InitialType; + /// let final_result : Result< FinalType, ConversionError > = initial.transitive_try_into::< IntermediateType >(); + /// ``` + pub trait TransitiveTryInto< Error, Final > : Sized + { + /// Performs a transitive `try_into` conversion. + /// + /// This method first converts `self` to the intermediate type `Transitive`, + /// and then converts the intermediate type to the final type `Final`. + /// + /// # Returns + /// + /// - `Ok(Final)`: If both conversions succeed. + /// - `Err(Error)`: If either conversion fails. + /// + /// # Example + /// + /// See the trait-level documentation for an example. + #[ inline( always ) ] + fn transitive_try_into< Transitive >( self ) -> Result< Final, Error > + where + Self : TryInto< Transitive >, + Transitive : TryInto< Final, Error = Error >, + Error : From< < Self as TryInto< Transitive > >::Error >, + { + let src2 = TryInto::< Transitive >::try_into( self )?; + TryInto::< Final >::try_into( src2 ) + } + } + + impl< Error, Final, Initial > TransitiveTryInto< Error, Final > for Initial {} + +} + +crate::mod_interface! +{ + exposed use TransitiveTryFrom; + exposed use TransitiveTryInto; +} 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 9ef2c83a5f..247be8c4b4 100644 --- a/module/core/proper_path_tools/tests/inc/absolute_path.rs +++ b/module/core/proper_path_tools/tests/inc/absolute_path.rs @@ -1,8 +1,15 @@ #[ allow( unused_imports ) ] use super::*; -use the_module::AbsolutePath; -use std::path::Path; -use std::path::PathBuf; + +use the_module:: +{ + AbsolutePath, + Path, + PathBuf, +}; + +// #[ cfg( feature = "path_utf8" ) ] +// use the_module::Utf8PathBuf; #[ test ] fn basic() @@ -15,32 +22,31 @@ fn basic() } #[ test ] -fn test_to_string_lossy() +fn test_to_string_lossy() { let path : AbsolutePath = "/path/to/file.txt".try_into().unwrap(); let result = path.to_string_lossy(); assert_eq!( result, "/path/to/file.txt" ); } #[test] -fn test_to_string_lossy_hard() +fn test_to_string_lossy_hard() { let abs_path : AbsolutePath = "/path/with/😀/unicode.txt".try_into().unwrap(); let string_lossy = abs_path.to_string_lossy(); assert_eq!( string_lossy, "/path/with/\u{1F600}/unicode.txt" ); } - #[test] -fn test_try_from_pathbuf() +fn test_try_from_pathbuf() { - + let path_buf = PathBuf::from( "/path/to/some/file.txt" ); let abs_path : AbsolutePath = path_buf.try_into().unwrap(); assert_eq!( abs_path.to_string_lossy(), "/path/to/some/file.txt" ); } #[test] -fn test_try_from_path() +fn test_try_from_path() { let path = Path::new( "/path/to/some/file.txt" ); let abs_path : AbsolutePath = path.try_into().unwrap(); @@ -48,7 +54,7 @@ fn test_try_from_path() } #[test] -fn test_parent() +fn test_parent() { let abs_path : AbsolutePath = "/path/to/some/file.txt".try_into().unwrap(); let parent_path = abs_path.parent().unwrap(); @@ -56,7 +62,7 @@ fn test_parent() } #[test] -fn test_join() +fn test_join() { let abs_path : AbsolutePath = "/path/to/some".try_into().unwrap(); let joined_path = abs_path.join( "file.txt" ); @@ -65,7 +71,7 @@ fn test_join() #[test] -fn test_relative_path_try_from_str() +fn test_relative_path_try_from_str() { let rel_path_str = "src/main.rs"; let rel_path = AbsolutePath::try_from( rel_path_str ).unwrap(); @@ -73,7 +79,7 @@ fn test_relative_path_try_from_str() } #[test] -fn test_relative_path_try_from_pathbuf() +fn test_relative_path_try_from_pathbuf() { let rel_path_buf = PathBuf::from( "src/main.rs" ); let rel_path = AbsolutePath::try_from( rel_path_buf.clone() ).unwrap(); @@ -81,7 +87,7 @@ fn test_relative_path_try_from_pathbuf() } #[test] -fn test_relative_path_try_from_path() +fn test_relative_path_try_from_path() { let rel_path = Path::new( "src/main.rs" ); let rel_path_result = AbsolutePath::try_from( rel_path ); @@ -90,7 +96,7 @@ fn test_relative_path_try_from_path() } #[test] -fn test_relative_path_parent() +fn test_relative_path_parent() { let rel_path = AbsolutePath::try_from( "src/main.rs" ).unwrap(); let parent_path = rel_path.parent().unwrap(); @@ -98,9 +104,9 @@ fn test_relative_path_parent() } #[test] -fn test_relative_path_join() +fn test_relative_path_join() { let rel_path = AbsolutePath::try_from( "src" ).unwrap(); let joined = rel_path.join( "main.rs" ); assert_eq!( joined.to_string_lossy(), "src/main.rs" ); -} \ No newline at end of file +} diff --git a/module/core/proper_path_tools/tests/inc/current_path.rs b/module/core/proper_path_tools/tests/inc/current_path.rs new file mode 100644 index 0000000000..628873a346 --- /dev/null +++ b/module/core/proper_path_tools/tests/inc/current_path.rs @@ -0,0 +1,33 @@ +#[ allow( unused_imports ) ] +use super::*; + +use the_module:: +{ + AbsolutePath, + // Path, + PathBuf, +}; + +#[ cfg( feature = "path_utf8" ) ] +use the_module::Utf8PathBuf; + +#[ test ] +fn basic() +{ + + let cd = the_module::CurrentPath; + let cd_path : PathBuf = cd.try_into().unwrap(); + println!( "cd_path : {cd_path:?}" ); + + let cd = the_module::CurrentPath; + let absolute_path : AbsolutePath = cd.try_into().unwrap(); + println!( "absolute_path : {absolute_path:?}" ); + + #[ cfg( feature = "path_utf8" ) ] + { + let cd = the_module::CurrentPath; + let utf8_path : Utf8PathBuf = cd.try_into().unwrap(); + println!( "utf8_path : {utf8_path:?}" ); + } + +} diff --git a/module/core/proper_path_tools/tests/inc/mod.rs b/module/core/proper_path_tools/tests/inc/mod.rs index 31872cad50..58e8721710 100644 --- a/module/core/proper_path_tools/tests/inc/mod.rs +++ b/module/core/proper_path_tools/tests/inc/mod.rs @@ -3,6 +3,8 @@ use super::*; mod absolute_path; +mod current_path; +mod path_canonicalize; mod path_change_ext; mod path_common; mod path_ext; @@ -12,6 +14,7 @@ mod path_join; mod path_normalize; mod path_relative; mod rebase_path; +mod transitive; mod without_ext; #[cfg(feature = "path_unique_folder_name")] diff --git a/module/core/proper_path_tools/tests/inc/path_canonicalize.rs b/module/core/proper_path_tools/tests/inc/path_canonicalize.rs new file mode 100644 index 0000000000..64cd4665f2 --- /dev/null +++ b/module/core/proper_path_tools/tests/inc/path_canonicalize.rs @@ -0,0 +1,50 @@ +#[ allow( unused_imports ) ] +use super::*; +use std::path::PathBuf; +use the_module::path; + +#[ test ] +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 ); + +} + +#[ test ] +fn basic() +{ + + let got = path::canonicalize( 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" ); + assert_eq!( got.unwrap(), exp ); + + let got = path::canonicalize( 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" ); + assert_eq!( got.unwrap(), exp ); + + let got = path::canonicalize( 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/" ); + assert_eq!( got.unwrap(), exp ); + + // xxx : qqq : does not work + // let got = path::canonicalize( PathBuf::from( "c:/src/" ) ); + // let exp = PathBuf::from( "/c/src/" ); + // assert_eq!( got.unwrap(), exp ); + +} diff --git a/module/core/proper_path_tools/tests/inc/path_join.rs b/module/core/proper_path_tools/tests/inc/path_join.rs index 4bc1c3db62..fa526ee19d 100644 --- a/module/core/proper_path_tools/tests/inc/path_join.rs +++ b/module/core/proper_path_tools/tests/inc/path_join.rs @@ -1,252 +1,450 @@ use super::*; - +use std::path::PathBuf; #[ test ] -fn join_empty() +fn join_empty() { - let ( expected, paths ) = ( "", vec![ "" ] ); - let result = the_module::path::join_paths( paths.clone().into_iter() ); - assert_eq!( result, std::path::PathBuf::from( expected ), "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", paths, expected, result.to_string_lossy() ); + let ( expected, paths ) : ( PathBuf, Vec< PathBuf > ) = ( "".into(), vec![ "".into() ] ); + let result = the_module::path::join_paths( paths.iter().map( |p| p.as_path() ) ); + assert_eq! + ( + result, + expected, + "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", + paths, + expected.display(), + result.to_string_lossy(), + ); } #[ test ] -fn join_several_empties() +fn join_several_empties() { - let ( expected, paths ) = ( "", vec![ "", "" ] ); - let result = the_module::path::join_paths( paths.clone().into_iter() ); - assert_eq!( result, std::path::PathBuf::from( expected ), "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", paths, expected, result.to_string_lossy() ); + let ( expected, paths ) : ( PathBuf, Vec< PathBuf > ) = ( "".into(), vec![ "".into(), "".into() ] ); + let result = the_module::path::join_paths( paths.iter().map( |p| p.as_path() ) ); + assert_eq! + ( + result, + expected, + "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", + paths, + expected.display(), + result.to_string_lossy(), + ); } - #[ test ] -fn root_with_absolute() +fn root_with_absolute() { - let ( expected, paths ) = ( "/a/b", vec![ "/", "/a/b" ] ); - let result = the_module::path::join_paths( paths.clone().into_iter() ); - assert_eq!( result, std::path::PathBuf::from( expected ), "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", paths, expected, result.to_string_lossy() ); + let ( expected, paths ) : ( PathBuf, Vec< PathBuf > ) = ( "/a/b".into(), vec![ "/".into(), "/a/b".into() ] ); + let result = the_module::path::join_paths( paths.iter().map( |p| p.as_path() ) ); + assert_eq! + ( + result, + expected, + "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", + paths, + expected.display(), + result.to_string_lossy(), + ); } - #[ test ] -fn root_with_relative() +fn root_with_relative() { - let ( expected, paths ) = ( "/a/b", vec![ "/", "a/b" ] ); - let result = the_module::path::join_paths( paths.clone().into_iter() ); - assert_eq!( result, std::path::PathBuf::from( expected ), "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", paths, expected, result.to_string_lossy() ); + let ( expected, paths ) : ( PathBuf, Vec< PathBuf > ) = ( "/a/b".into(), vec![ "/".into(), "a/b".into() ] ); + let result = the_module::path::join_paths( paths.iter().map( |p| p.as_path() ) ); + assert_eq! + ( + result, + expected, + "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", + paths, + expected.display(), + result.to_string_lossy(), + ); } - #[ test ] -fn dir_with_absolute() +fn dir_with_absolute() { - let ( expected, paths ) = ( "/a/b", vec![ "/dir", "/a/b" ] ); - let result = the_module::path::join_paths( paths.clone().into_iter() ); - assert_eq!( result, std::path::PathBuf::from( expected ), "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", paths, expected, result.to_string_lossy() ); + let ( expected, paths ) : ( PathBuf, Vec< PathBuf > ) = ( "/a/b".into(), vec![ "/dir".into(), "/a/b".into() ] ); + let result = the_module::path::join_paths( paths.iter().map( |p| p.as_path() ) ); + assert_eq! + ( + result, + expected, + "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", + paths, + expected.display(), + result.to_string_lossy(), + ); } - - #[ test ] -fn dir_with_relative() +fn dir_with_relative() { - let ( expected, paths ) = ( "/dir/a/b", vec![ "/dir", "a/b" ] ); - let result = the_module::path::join_paths( paths.clone().into_iter() ); - assert_eq!( result, std::path::PathBuf::from( expected ), "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", paths, expected, result.to_string_lossy() ); + let ( expected, paths ) : ( PathBuf, Vec< PathBuf > ) = ( "/dir/a/b".into(), vec![ "/dir".into(), "a/b".into() ] ); + let result = the_module::path::join_paths( paths.iter().map( |p| p.as_path() ) ); + assert_eq! + ( + result, + expected, + "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", + paths, + expected.display(), + result.to_string_lossy(), + ); } - #[ test ] -fn trailed_dir_with_absolute() +fn trailed_dir_with_absolute() { - let ( expected, paths ) = ( "/a/b", vec![ "/dir/", "/a/b" ] ); - let result = the_module::path::join_paths( paths.clone().into_iter() ); - assert_eq!( result, std::path::PathBuf::from( expected ), "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", paths, expected, result.to_string_lossy() ); + let ( expected, paths ) : ( PathBuf, Vec< PathBuf > ) = ( "/a/b".into(), vec![ "/dir/".into(), "/a/b".into() ] ); + let result = the_module::path::join_paths( paths.iter().map( |p| p.as_path() ) ); + assert_eq! + ( + result, + expected, + "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", + paths, + expected.display(), + result.to_string_lossy(), + ); } #[ test ] -fn trailed_dir_with_relative() +fn trailed_dir_with_relative() { - let ( expected, paths ) = ( "/dir/a/b", vec![ "/dir/", "a/b" ] ); - let result = the_module::path::join_paths( paths.clone().into_iter() ); - assert_eq!( result, std::path::PathBuf::from( expected ), "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", paths, expected, result.to_string_lossy() ); + let ( expected, paths ) : ( PathBuf, Vec< PathBuf > ) = ( "/dir/a/b".into(), vec![ "/dir/".into(), "a/b".into() ] ); + let result = the_module::path::join_paths( paths.iter().map( |p| p.as_path() ) ); + assert_eq! + ( + result, + expected, + "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", + paths, + expected.display(), + result.to_string_lossy(), + ); } - #[ test ] -fn dir_with_down() +fn dir_with_down() { - let ( expected, paths ) = ( "/a/b", vec![ "/dir", "../a/b" ] ); - let result = the_module::path::join_paths( paths.clone().into_iter() ); - assert_eq!( result, std::path::PathBuf::from( expected ), "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", paths, expected, result.to_string_lossy() ); + let ( expected, paths ) : ( PathBuf, Vec< PathBuf > ) = ( "/a/b".into(), vec![ "/dir".into(), "../a/b".into() ] ); + let result = the_module::path::join_paths( paths.iter().map( |p| p.as_path() ) ); + assert_eq! + ( + result, + expected, + "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", + paths, + expected.display(), + result.to_string_lossy(), + ); } - #[ test ] -fn trailed_dir_with_down() +fn trailed_dir_with_down() { - let ( expected, paths ) = ( "/dir/a/b", vec![ "/dir/", "../a/b" ] ); - let result = the_module::path::join_paths( paths.clone().into_iter() ); - assert_eq!( result, std::path::PathBuf::from( expected ), "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", paths, expected, result.to_string_lossy() ); + let ( expected, paths ) : ( PathBuf, Vec< PathBuf > ) = ( "/dir/a/b".into(), vec![ "/dir/".into(), "../a/b".into() ] ); + let result = the_module::path::join_paths( paths.iter().map( |p| p.as_path() ) ); + assert_eq! + ( + result, + expected, + "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", + paths, + expected.display(), + result.to_string_lossy(), + ); } - - #[ test ] -fn dir_with_several_down() +fn dir_with_several_down() { - let ( expected, paths ) = ( "/a/b", vec![ "/dir/dir2", "../../a/b" ] ); - let result = the_module::path::join_paths( paths.clone().into_iter() ); - assert_eq!( result, std::path::PathBuf::from( expected ), "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", paths, expected, result.to_string_lossy() ); + let ( expected, paths ) : ( PathBuf, Vec< PathBuf > ) = ( "/a/b".into(), vec![ "/dir/dir2".into(), "../../a/b".into() ] ); + let result = the_module::path::join_paths( paths.iter().map( |p| p.as_path() ) ); + assert_eq! + ( + result, + expected, + "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", + paths, + expected.display(), + result.to_string_lossy(), + ); } - #[ test ] -fn trailed_dir_with_several_down() +fn trailed_dir_with_several_down() { - let ( expected, paths ) = ( "/a/b", vec![ "/dir/", "../../a/b" ] ); - let result = the_module::path::join_paths( paths.clone().into_iter() ); - assert_eq!( result, std::path::PathBuf::from( expected ), "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", paths, expected, result.to_string_lossy() ); + let ( expected, paths ) : ( PathBuf, Vec< PathBuf > ) = ( "/a/b".into(), vec![ "/dir/".into(), "../../a/b".into() ] ); + let result = the_module::path::join_paths( paths.iter().map( |p| p.as_path() ) ); + assert_eq! + ( + result, + expected, + "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", + paths, + expected.display(), + result.to_string_lossy(), + ); } - #[ test ] -fn dir_with_several_down_go_out_of_root() +fn dir_with_several_down_go_out_of_root() { - let ( expected, paths ) = ( "/../a/b", vec![ "/dir", "../../a/b" ] ); - let result = the_module::path::join_paths( paths.clone().into_iter() ); - assert_eq!( result, std::path::PathBuf::from( expected ), "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", paths, expected, result.to_string_lossy() ); + let ( expected, paths ) : ( PathBuf, Vec< PathBuf > ) = ( "/../a/b".into(), vec![ "/dir".into(), "../../a/b".into() ] ); + let result = the_module::path::join_paths( paths.iter().map( |p| p.as_path() ) ); + assert_eq! + ( + result, + expected, + "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", + paths, + expected.display(), + result.to_string_lossy(), + ); } #[ test ] -fn trailed_absolute_with_trailed_down() +fn trailed_absolute_with_trailed_down() { - let ( expected, paths ) = ( "/a/b/", vec![ "/a/b/", "../" ] ); - let result = the_module::path::join_paths( paths.clone().into_iter() ); - assert_eq!( result, std::path::PathBuf::from( expected ), "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", paths, expected, result.to_string_lossy() ); + let ( expected, paths ) : ( PathBuf, Vec< PathBuf > ) = ( "/a/b/".into(), vec![ "/a/b/".into(), "../".into() ] ); + let result = the_module::path::join_paths( paths.iter().map( |p| p.as_path() ) ); + assert_eq! + ( + result, + expected, + "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", + paths, + expected.display(), + result.to_string_lossy(), + ); } - #[ test ] -fn absolute_with_trailed_down() +fn absolute_with_trailed_down() { - let ( expected, paths ) = ( "/a/", vec![ "/a/b", "../" ]) ; - let result = the_module::path::join_paths( paths.clone().into_iter() ); - assert_eq!( result, std::path::PathBuf::from( expected ), "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", paths, expected, result.to_string_lossy() ); + let ( expected, paths ) : ( PathBuf, Vec< PathBuf > ) = ( "/a/".into(), vec![ "/a/b".into(), "../".into() ] ); + let result = the_module::path::join_paths( paths.iter().map( |p| p.as_path() ) ); + assert_eq! + ( + result, + expected, + "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", + paths, + expected.display(), + result.to_string_lossy(), + ); } - #[ test ] -fn trailed_absolute_with_down() +fn trailed_absolute_with_down() { - let ( expected, paths ) = ( "/a/b", vec![ "/a/b/", ".." ] ); - let result = the_module::path::join_paths( paths.clone().into_iter() ); - assert_eq!( result, std::path::PathBuf::from( expected ), "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", paths, expected, result.to_string_lossy() ); + let ( expected, paths ) : ( PathBuf, Vec< PathBuf > ) = ( "/a/b".into(), vec![ "/a/b/".into(), "..".into() ] ); + let result = the_module::path::join_paths( paths.iter().map( |p| p.as_path() ) ); + assert_eq! + ( + result, + expected, + "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", + paths, + expected.display(), + result.to_string_lossy(), + ); } - #[ test ] -fn trailed_absolute_with_trailed_here() +fn trailed_absolute_with_trailed_here() { - let ( expected, paths ) = ( "/a/b/", vec![ "/a/b/", "./" ] ); - let result = the_module::path::join_paths( paths.clone().into_iter() ); - assert_eq!( result, std::path::PathBuf::from( expected ), "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", paths, expected, result.to_string_lossy() ); + let ( expected, paths ) : ( PathBuf, Vec< PathBuf > ) = ( "/a/b/".into(), vec![ "/a/b/".into(), "./".into() ] ); + let result = the_module::path::join_paths( paths.iter().map( |p| p.as_path() ) ); + assert_eq! + ( + result, + expected, + "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", + paths, + expected.display(), + result.to_string_lossy(), + ); } - - #[ test ] -fn absolute_with_trailed_here() +fn absolute_with_trailed_here() { - let ( expected, paths ) = ( "/a/b/", vec![ "/a/b", "./" ] ); - let result = the_module::path::join_paths( paths.clone().into_iter() ); - assert_eq!( result, std::path::PathBuf::from( expected ), "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", paths, expected, result.to_string_lossy() ); + let ( expected, paths ) : ( PathBuf, Vec< PathBuf > ) = ( "/a/b/".into(), vec![ "/a/b".into(), "./".into() ] ); + let result = the_module::path::join_paths( paths.iter().map( |p| p.as_path() ) ); + assert_eq! + ( + result, + expected, + "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", + paths, + expected.display(), + result.to_string_lossy(), + ); } - #[ test ] -fn trailed_absolute_with_here() +fn trailed_absolute_with_here() { - let ( expected, paths ) = ( "/a/b", vec![ "/a/b/", "." ] ); - let result = the_module::path::join_paths( paths.clone().into_iter() ); - assert_eq!( result, std::path::PathBuf::from( expected ), "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", paths, expected, result.to_string_lossy() ); + let ( expected, paths ) : ( PathBuf, Vec< PathBuf > ) = ( "/a/b".into(), vec![ "/a/b/".into(), ".".into() ] ); + let result = the_module::path::join_paths( paths.iter().map( |p| p.as_path() ) ); + assert_eq! + ( + result, + expected, + "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", + paths, + expected.display(), + result.to_string_lossy(), + ); } - #[ test ] -fn join_with_empty() +fn join_with_empty() { - let ( expected, paths ) = ( "/a/b/c", vec![ "", "a/b", "", "c", "" ] ); - let result = the_module::path::join_paths( paths.clone().into_iter() ); - assert_eq!( result, std::path::PathBuf::from( expected ), "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", paths, expected, result.to_string_lossy() ); + let ( expected, paths ) : ( PathBuf, Vec< PathBuf > ) = ( "/a/b/c".into(), vec![ "".into(), "a/b".into(), "".into(), "c".into(), "".into() ] ); + let result = the_module::path::join_paths( paths.iter().map( |p| p.as_path() ) ); + assert_eq! + ( + result, + expected, + "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", + paths, + expected.display(), + result.to_string_lossy(), + ); } #[ test ] -fn join_windows_os_paths() +fn join_windows_os_paths() { - let ( expected, paths ) = ( "/c/foo/bar/", vec![ "c:\\", "foo\\", "bar\\" ] ); - let result = the_module::path::join_paths( paths.clone().into_iter() ); - assert_eq!( result, std::path::PathBuf::from( expected ), "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", paths, expected, result.to_string_lossy() ); + let ( expected, paths ) : ( PathBuf, Vec< PathBuf > ) = ( "/c/foo/bar/".into(), vec![ "c:\\".into(), "foo\\".into(), "bar\\".into() ] ); + let result = the_module::path::join_paths( paths.iter().map( |p| p.as_path() ) ); + assert_eq! + ( + result, + expected, + "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", + paths, + expected.display(), + result.to_string_lossy(), + ); } - #[ test ] -fn join_unix_os_paths() +fn join_unix_os_paths() { - let ( expected, paths ) = ( "/baz/foo", vec![ "/bar/", "/baz", "foo/", "." ] ); - let result = the_module::path::join_paths( paths.clone().into_iter() ); - assert_eq!( result, std::path::PathBuf::from( expected ), "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", paths, expected, result.to_string_lossy() ); + let ( expected, paths ) : ( PathBuf, Vec< PathBuf > ) = ( "/baz/foo".into(), vec![ "/bar/".into(), "/baz".into(), "foo/".into(), ".".into() ] ); + let result = the_module::path::join_paths( paths.iter().map( |p| p.as_path() ) ); + assert_eq! + ( + result, + expected, + "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", + paths, + expected.display(), + result.to_string_lossy(), + ); } - #[ test ] -fn join_unix_os_paths_2() +fn join_unix_os_paths_2() { - let ( expected, paths ) = ( "/baz/foo/z", vec![ "/bar/", "/baz", "foo/", ".", "z" ] ); - let result = the_module::path::join_paths( paths.clone().into_iter() ); - assert_eq!( result, std::path::PathBuf::from( expected ), "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", paths, expected, result.to_string_lossy() ); + let ( expected, paths ) : ( PathBuf, Vec< PathBuf > ) = ( "/baz/foo/z".into(), vec![ "/bar/".into(), "/baz".into(), "foo/".into(), ".".into(), "z".into() ] ); + let result = the_module::path::join_paths( paths.iter().map( |p| p.as_path() ) ); + assert_eq! + ( + result, + expected, + "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", + paths, + expected.display(), + result.to_string_lossy(), + ); } - #[ test ] -fn more_complicated_cases_1() +fn more_complicated_cases_1() { - let ( expected, paths ) = ( "/aa/bb//cc", vec![ "/aa", "bb//", "cc" ] ); - let result = the_module::path::join_paths( paths.clone().into_iter() ); - assert_eq!( result, std::path::PathBuf::from( expected ), "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", paths, expected, result.to_string_lossy() ); + let ( expected, paths ) : ( PathBuf, Vec< PathBuf > ) = ( "/aa/bb//cc".into(), vec![ "/aa".into(), "bb//".into(), "cc".into() ] ); + let result = the_module::path::join_paths( paths.iter().map( |p| p.as_path() ) ); + assert_eq! + ( + result, + expected, + "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", + paths, + expected.display(), + result.to_string_lossy(), + ); } - - #[ test ] -fn more_complicated_cases_2() +fn more_complicated_cases_2() { - let ( expected, paths ) = ( "/bb/cc", vec![ "/aa", "/bb", "cc" ] ); - let result = the_module::path::join_paths( paths.clone().into_iter() ); - assert_eq!( result, std::path::PathBuf::from( expected ), "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", paths, expected, result.to_string_lossy() ); + let ( expected, paths ) : ( PathBuf, Vec< PathBuf > ) = ( "/bb/cc".into(), vec![ "/aa".into(), "/bb".into(), "cc".into() ] ); + let result = the_module::path::join_paths( paths.iter().map( |p| p.as_path() ) ); + assert_eq! + ( + result, + expected, + "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", + paths, + expected.display(), + result.to_string_lossy(), + ); } - #[ test ] -fn more_complicated_cases_3() +fn more_complicated_cases_3() { - let ( expected, paths ) = ( "//aa/bb//cc//", vec![ "//aa", "bb//", "cc//" ] ); - let result = the_module::path::join_paths( paths.clone().into_iter() ); - assert_eq!( result, std::path::PathBuf::from( expected ), "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", paths, expected, result.to_string_lossy() ); + let ( expected, paths ) : ( PathBuf, Vec< PathBuf > ) = ( "//aa/bb//cc//".into(), vec![ "//aa".into(), "bb//".into(), "cc//".into() ] ); + let result = the_module::path::join_paths( paths.iter().map( |p| p.as_path() ) ); + assert_eq! + ( + result, + expected, + "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", + paths, + expected.display(), + result.to_string_lossy(), + ); } - #[ test ] -fn more_complicated_cases_4() +fn more_complicated_cases_4() { - let ( expected, paths ) = ( "/aa/bb//cc", vec![ "/aa", "bb//", "cc", "." ] ); - let result = the_module::path::join_paths( paths.clone().into_iter() ); - assert_eq!( result, std::path::PathBuf::from( expected ), "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", paths, expected, result.to_string_lossy() ); + let ( expected, paths ) : ( PathBuf, Vec< PathBuf > ) = ( "/aa/bb//cc".into(), vec![ "/aa".into(), "bb//".into(), "cc".into(), ".".into() ] ); + let result = the_module::path::join_paths( paths.iter().map( |p| p.as_path() ) ); + assert_eq! + ( + result, + expected, + "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", + paths, + expected.display(), + result.to_string_lossy(), + ); } #[ test ] -fn more_complicated_cases_5() +fn more_complicated_cases_5() { - let ( expected, paths ) = ( "//b//d/..e", vec![ "/", "a", "//b//", "././c", "../d", "..e" ] ); - let result = the_module::path::join_paths( paths.clone().into_iter() ); - assert_eq!( result, std::path::PathBuf::from( expected ), "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", paths, expected, result.to_string_lossy() ); + let ( expected, paths ) : ( PathBuf, Vec< PathBuf > ) = ( "//b//d/..e".into(), vec![ "/".into(), "a".into(), "//b//".into(), "././c".into(), "../d".into(), "..e".into() ] ); + let result = the_module::path::join_paths( paths.iter().map( |p| p.as_path() ) ); + assert_eq! + ( + result, + expected, + "Test failed. Paths: '{:?}', Expected: '{}', Got: '{}'", + paths, + expected.display(), + result.to_string_lossy(), + ); } \ No newline at end of file diff --git a/module/core/proper_path_tools/tests/inc/path_relative.rs b/module/core/proper_path_tools/tests/inc/path_relative.rs index 7c9f6bfbed..7d5f0536c7 100644 --- a/module/core/proper_path_tools/tests/inc/path_relative.rs +++ b/module/core/proper_path_tools/tests/inc/path_relative.rs @@ -6,7 +6,7 @@ use std::path::PathBuf; // absolute path relative #[ test ] -fn test_absolute_a_minus_b() +fn test_absolute_a_minus_b() { let from = "/a"; let to = "/b"; @@ -15,7 +15,7 @@ fn test_absolute_a_minus_b() } #[ test ] -fn test_absolute_root_minus_b() +fn test_absolute_root_minus_b() { let from = "/"; let to = "/b"; @@ -24,7 +24,7 @@ fn test_absolute_root_minus_b() } #[ test ] -fn test_absolute_same_path() +fn test_absolute_same_path() { let from = "/aa/bb/cc"; let to = "/aa/bb/cc"; @@ -33,7 +33,7 @@ fn test_absolute_same_path() } #[ test ] -fn test_absolute_same_path_with_trail() +fn test_absolute_same_path_with_trail() { let from = "/aa/bb/cc"; let to = "/aa/bb/cc/"; @@ -42,7 +42,7 @@ fn test_absolute_same_path_with_trail() } #[ test ] -fn test_absolute_two_trailed_absolute_paths() +fn test_absolute_two_trailed_absolute_paths() { let from = "/a/b/"; let to = "/a/b/"; @@ -51,7 +51,7 @@ fn test_absolute_two_trailed_absolute_paths() } #[ test ] -fn test_absolute_two_absolute_paths_with_trail() +fn test_absolute_two_absolute_paths_with_trail() { let from = "/a/b"; let to = "/a/b/"; @@ -60,7 +60,7 @@ fn test_absolute_two_absolute_paths_with_trail() } #[ test ] -fn test_absolute_two_absolute_paths() +fn test_absolute_two_absolute_paths() { let from = "/a/b/"; let to = "/a/b"; @@ -69,7 +69,7 @@ fn test_absolute_two_absolute_paths() } #[ test ] -fn test_absolute_same_path_trail_to_not() +fn test_absolute_same_path_trail_to_not() { let from = "/aa/bb/cc/"; let to = "/aa/bb/cc"; @@ -78,7 +78,7 @@ fn test_absolute_same_path_trail_to_not() } #[ test ] -fn test_absolute_a_to_double_slash_b() +fn test_absolute_a_to_double_slash_b() { let from = "/a"; let to = "//b"; @@ -88,7 +88,7 @@ fn test_absolute_a_to_double_slash_b() #[ test ] -fn test_absolute_relative_to_nested() +fn test_absolute_relative_to_nested() { let from = "/foo/bar/baz/asdf/quux"; let to = "/foo/bar/baz/asdf/quux/new1"; @@ -97,7 +97,7 @@ fn test_absolute_relative_to_nested() } #[ test ] -fn test_absolute_out_of_relative_dir() +fn test_absolute_out_of_relative_dir() { let from = "/abc"; let to = "/a/b/z"; @@ -106,7 +106,7 @@ fn test_absolute_out_of_relative_dir() } #[ test ] -fn test_absolute_relative_root() +fn test_absolute_relative_root() { let from = "/"; let to = "/a/b/z"; @@ -116,7 +116,7 @@ fn test_absolute_relative_root() #[ test ] -fn test_long_not_direct() +fn test_long_not_direct() { let from = "/a/b/xx/yy/zz"; let to = "/a/b/files/x/y/z.txt"; @@ -125,7 +125,7 @@ fn test_long_not_direct() } #[ test ] -fn test_absolute_relative_to_parent_directory() +fn test_absolute_relative_to_parent_directory() { let from = "/aa/bb/cc"; let to = "/aa/bb"; @@ -134,7 +134,7 @@ fn test_absolute_relative_to_parent_directory() } #[ test ] -fn test_absolute_relative_to_parent_directory_file_trailed() +fn test_absolute_relative_to_parent_directory_file_trailed() { let from = "/aa/bb/cc"; let to = "/aa/bb/"; @@ -143,7 +143,7 @@ fn test_absolute_relative_to_parent_directory_file_trailed() } #[ test ] -fn test_absolute_relative_root_to_root() +fn test_absolute_relative_root_to_root() { let from = "/"; let to = "/"; @@ -152,7 +152,7 @@ fn test_absolute_relative_root_to_root() } #[ test ] -fn test_windows_disks() +fn test_windows_disks() { let from = "d:/"; let to = "c:/x/y"; @@ -162,7 +162,7 @@ fn test_windows_disks() #[ test ] -fn test_absolute_relative_to_parent_directory_both_trailed() +fn test_absolute_relative_to_parent_directory_both_trailed() { let from = "/aa/bb/cc/"; let to = "/aa/bb/"; @@ -172,7 +172,7 @@ fn test_absolute_relative_to_parent_directory_both_trailed() #[ test ] -fn test_absolute_a_with_trail_to_double_slash_b_with_trail() +fn test_absolute_a_with_trail_to_double_slash_b_with_trail() { let from = "/a/"; let to = "//b/"; @@ -181,7 +181,7 @@ fn test_absolute_a_with_trail_to_double_slash_b_with_trail() } #[ test ] -fn test_absolute_4_down() +fn test_absolute_4_down() { let from = "/aa//bb/cc/"; let to = "//xx/yy/zz/"; @@ -190,7 +190,7 @@ fn test_absolute_4_down() } #[ test ] -fn test_absolute_same_length_both_trailed() +fn test_absolute_same_length_both_trailed() { let from = "/aa//bb/cc/"; let to = "//xx/yy/zz/"; @@ -199,7 +199,7 @@ fn test_absolute_same_length_both_trailed() } #[ test ] -fn test_absolute_relative_to_parent_directory_base_trailed() +fn test_absolute_relative_to_parent_directory_base_trailed() { let from = "/aa/bb/cc/"; let to = "/aa/bb"; @@ -214,7 +214,7 @@ fn test_absolute_relative_to_parent_directory_base_trailed() // relative_path_relative #[ test ] -fn test_relative_dot_to_dot() +fn test_relative_dot_to_dot() { let from = "."; let to = "."; @@ -223,7 +223,7 @@ fn test_relative_dot_to_dot() } #[ test ] -fn test_relative_a_to_b() +fn test_relative_a_to_b() { let from = "a"; let to = "b"; @@ -232,7 +232,7 @@ fn test_relative_a_to_b() } #[ test ] -fn test_relative_a_b_to_b_c() +fn test_relative_a_b_to_b_c() { let from = "a/b"; let to = "b/c"; @@ -241,7 +241,7 @@ fn test_relative_a_b_to_b_c() } #[ test ] -fn test_relative_a_b_to_a_b_c() +fn test_relative_a_b_to_a_b_c() { let from = "a/b"; let to = "a/b/c"; @@ -250,7 +250,7 @@ fn test_relative_a_b_to_a_b_c() } #[ test ] -fn test_relative_a_b_c_to_a_b() +fn test_relative_a_b_c_to_a_b() { let from = "a/b/c"; let to = "a/b"; @@ -259,7 +259,7 @@ fn test_relative_a_b_c_to_a_b() } #[ test ] -fn test_relative_a_b_c_d_to_a_b_d_c() +fn test_relative_a_b_c_d_to_a_b_d_c() { let from = "a/b/c/d"; let to = "a/b/d/c"; @@ -268,7 +268,7 @@ fn test_relative_a_b_c_d_to_a_b_d_c() } #[ test ] -fn test_relative_a_to_dot_dot_a() +fn test_relative_a_to_dot_dot_a() { let from = "a"; let to = "../a"; @@ -277,7 +277,7 @@ fn test_relative_a_to_dot_dot_a() } #[ test ] -fn test_relative_a_slash_slash_b_to_a_slash_slash_c() +fn test_relative_a_slash_slash_b_to_a_slash_slash_c() { let from = "a//b"; let to = "a//c"; @@ -286,7 +286,7 @@ fn test_relative_a_slash_slash_b_to_a_slash_slash_c() } #[ test ] -fn test_relative_a_dot_slash_b_to_a_dot_slash_c() +fn test_relative_a_dot_slash_b_to_a_dot_slash_c() { let from = "a/./b"; let to = "a/./c"; @@ -295,7 +295,7 @@ fn test_relative_a_dot_slash_b_to_a_dot_slash_c() } #[ test ] -fn test_relative_a_dot_dot_slash_b_to_b() +fn test_relative_a_dot_dot_slash_b_to_b() { let from = "a/../b"; let to = "b"; @@ -304,7 +304,7 @@ fn test_relative_a_dot_dot_slash_b_to_b() } #[ test ] -fn test_relative_b_to_b_dot_dot_slash_b() +fn test_relative_b_to_b_dot_dot_slash_b() { let from = "b"; let to = "b/../b"; @@ -313,7 +313,7 @@ fn test_relative_b_to_b_dot_dot_slash_b() } #[ test ] -fn test_relative_dot_to_dot_dot() +fn test_relative_dot_to_dot_dot() { let from = "."; let to = ".."; @@ -322,7 +322,7 @@ fn test_relative_dot_to_dot_dot() } #[ test ] -fn test_relative_dot_to_dot_dot_dot() +fn test_relative_dot_to_dot_dot_dot() { let from = "."; let to = "../.."; @@ -331,7 +331,7 @@ fn test_relative_dot_to_dot_dot_dot() } #[ test ] -fn test_relative_dot_dot_to_dot_dot() +fn test_relative_dot_dot_to_dot_dot() { let from = ".."; let to = "../.."; @@ -340,7 +340,7 @@ fn test_relative_dot_dot_to_dot_dot() } #[ test ] -fn test_relative_dot_dot_to_dot_dot_dot() +fn test_relative_dot_dot_to_dot_dot_dot() { let from = ".."; let to = ".."; @@ -349,7 +349,7 @@ fn test_relative_dot_dot_to_dot_dot_dot() } #[ test ] -fn test_relative_dot_dot_a_b_to_dot_dot_c_d() +fn test_relative_dot_dot_a_b_to_dot_dot_c_d() { let from = "../a/b"; let to = "../c/d"; @@ -358,7 +358,7 @@ fn test_relative_dot_dot_a_b_to_dot_dot_c_d() } #[ test ] -fn test_relative_dot_to_b() +fn test_relative_dot_to_b() { let from = "."; let to = "b"; @@ -367,7 +367,7 @@ fn test_relative_dot_to_b() } #[ test ] -fn test_relative_dot_slash_to_b() +fn test_relative_dot_slash_to_b() { let from = "./"; let to = "b"; @@ -376,7 +376,7 @@ fn test_relative_dot_slash_to_b() } #[ test ] -fn test_relative_dot_to_b_slash() +fn test_relative_dot_to_b_slash() { let from = "."; let to = "b/"; @@ -385,7 +385,7 @@ fn test_relative_dot_to_b_slash() } #[ test ] -fn test_relative_dot_slash_to_b_slash() +fn test_relative_dot_slash_to_b_slash() { let from = "./"; let to = "b/"; @@ -394,7 +394,7 @@ fn test_relative_dot_slash_to_b_slash() } #[ test ] -fn test_relative_a_dot_dot_to_b_dot_dot() +fn test_relative_a_dot_dot_to_b_dot_dot() { let from = "a/../b/.."; let to = "b"; diff --git a/module/core/proper_path_tools/tests/inc/transitive.rs b/module/core/proper_path_tools/tests/inc/transitive.rs new file mode 100644 index 0000000000..e0b2da7acc --- /dev/null +++ b/module/core/proper_path_tools/tests/inc/transitive.rs @@ -0,0 +1,86 @@ +#[ allow( unused_imports ) ] +use super::*; + +#[ test ] +fn basic_from() +{ + use proper_path_tools::TransitiveTryFrom; + use std::convert::TryFrom; + + struct InitialType; + struct IntermediateType; + struct FinalType; + struct ConversionError; + + impl TryFrom< InitialType > for IntermediateType + { + type Error = ConversionError; + fn try_from( _value : InitialType ) -> Result< Self, Self::Error > + { + // Conversion logic here + Ok( IntermediateType ) + } + } + + impl TryFrom< IntermediateType > for FinalType + { + type Error = ConversionError; + fn try_from( _value : IntermediateType ) -> Result< Self, Self::Error > + { + // Conversion logic here + Ok( FinalType ) + } + } + + // impl TransitiveTryFrom< IntermediateType, ConversionError, InitialType > for FinalType {} + + let initial = InitialType; + let _final_result : Result< FinalType, ConversionError > = FinalType::transitive_try_from::< IntermediateType >( initial ); + +} + +#[ test ] +fn test_transitive_try_into() +{ + use proper_path_tools::TransitiveTryInto; + + // Define NewType1 wrapping a String + #[ derive( Debug, PartialEq ) ] + struct NewType1( String ); + + // Define NewType2 wrapping NewType1 + #[ derive( Debug, PartialEq ) ] + struct NewType2( NewType1 ); + + // Define an error type for conversion + #[ derive( Debug, PartialEq ) ] + struct ConversionError; + + // Implement TryInto for converting String to NewType1 + impl TryInto< NewType1 > for String + { + type Error = ConversionError; + fn try_into( self ) -> Result< NewType1, Self::Error > + { + Ok( NewType1( self ) ) + } + } + + // Implement TryInto for converting NewType1 to NewType2 + impl TryInto< NewType2 > for NewType1 + { + type Error = ConversionError; + fn try_into( self ) -> Result< NewType2, Self::Error > + { + Ok( NewType2( self ) ) + } + } + + let initial = String::from( "Hello, world!" ); + let final_result : Result< NewType2, ConversionError > = initial.transitive_try_into::< NewType1 >(); + assert_eq!( final_result, Ok( NewType2( NewType1( String::from( "Hello, world!" ) ) ) ) ); + + let initial = String::from( "Hello, world!" ); + let _final_result : NewType2 = initial.transitive_try_into::< NewType1 >().unwrap(); + +} diff --git a/module/core/proper_path_tools/tests/smoke_test.rs b/module/core/proper_path_tools/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/core/proper_path_tools/tests/smoke_test.rs +++ b/module/core/proper_path_tools/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/core/reflect_tools/Cargo.toml b/module/core/reflect_tools/Cargo.toml index b4ff98aff1..aafcdd3843 100644 --- a/module/core/reflect_tools/Cargo.toml +++ b/module/core/reflect_tools/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "reflect_tools" -version = "0.2.0" +version = "0.3.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", @@ -22,28 +22,30 @@ workspace = true [package.metadata.docs.rs] features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] + [features] default = [ "enabled", - "reflect_reflect", + "reflect_types", "reflect_newtype", ] full = [ - "enabled", - "reflect_reflect", - "reflect_newtype", + "default", +] +enabled = [ + "reflect_tools_meta/enabled", + "derive_tools/enabled" ] -enabled = [] -reflect_reflect = [] +reflect_types = [] reflect_newtype = [] [dependencies] -reflect_tools_meta = { workspace = true, features = [ "enabled" ] } -derive_tools = { workspace = true, features = [ "enabled", "derive_from", "derive_inner_from" ] } +reflect_tools_meta = { workspace = true, features = [] } +derive_tools = { workspace = true, features = ["derive_from", "derive_inner_from" ] } +# qqq : xxx : optimize features set [dev-dependencies] test_tools = { workspace = true } diff --git a/module/core/reflect_tools/src/lib.rs b/module/core/reflect_tools/src/lib.rs index 50f0a2231f..f4f71a2a2a 100644 --- a/module/core/reflect_tools/src/lib.rs +++ b/module/core/reflect_tools/src/lib.rs @@ -1,11 +1,11 @@ -#![ cfg_attr( feature = "no_std", no_std ) ] +// #![ cfg_attr( feature = "no_std", no_std ) ] #![ 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/reflect_tools/latest/reflect_tools/" ) ] #![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/", "Readme.md" ) ) ] #[ cfg( feature = "enabled" ) ] -#[ cfg( feature = "reflect_reflect" ) ] +#[ cfg( feature = "reflect_types" ) ] pub mod reflect; /// Namespace with dependencies. @@ -13,65 +13,66 @@ pub mod reflect; #[ cfg( feature = "enabled" ) ] pub mod dependency { - #[ cfg( any_derive ) ] + // #[ cfg( any_derive ) ] pub use ::reflect_tools_meta; } #[ cfg( feature = "enabled" ) ] #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. +/// Own namespace of the module. #[ cfg( feature = "enabled" ) ] -pub mod protected +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; - #[ cfg( feature = "reflect_reflect" ) ] + pub use orphan::*; + #[ cfg( feature = "reflect_types" ) ] #[ doc( inline ) ] - #[ allow( unused_imports ) ] pub use super::reflect::orphan::*; } /// Orphan namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; - #[ cfg( feature = "reflect_reflect" ) ] + #[ cfg( feature = "reflect_types" ) ] #[ doc( inline ) ] - #[ allow( unused_imports ) ] pub use super::reflect::exposed::*; // #[ cfg( any_derive ) ] #[ doc( inline ) ] - #[ allow( unused_imports ) ] pub use ::reflect_tools_meta::*; } /// Prelude to use essentials: `use my_module::prelude::*`. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; - #[ cfg( feature = "reflect_reflect" ) ] + #[ cfg( feature = "reflect_types" ) ] #[ doc( inline ) ] - #[ allow( unused_imports ) ] pub use super::reflect::prelude::*; } diff --git a/module/core/reflect_tools/src/reflect.rs b/module/core/reflect_tools/src/reflect.rs index aded0f2009..1d4f293585 100644 --- a/module/core/reflect_tools/src/reflect.rs +++ b/module/core/reflect_tools/src/reflect.rs @@ -65,16 +65,20 @@ pub mod entity_hashmap; pub mod entity_hashset; pub mod primitive; +pub mod fields; +pub mod wrapper; + #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::axiomatic::orphan::*; @@ -96,25 +100,36 @@ pub mod protected #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::primitive::orphan::*; - // pub use super::private:: + + // xxx : add features + #[ doc( inline ) ] + #[ allow( unused_imports ) ] + pub use super::fields::orphan::*; + #[ doc( inline ) ] + #[ allow( unused_imports ) ] + pub use super::wrapper::orphan::*; + + // pub use private:: // { // }; } /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::axiomatic::exposed::*; @@ -136,11 +151,22 @@ pub mod exposed #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::primitive::exposed::*; + + #[ doc( inline ) ] + #[ allow( unused_imports ) ] + pub use super::fields::exposed::*; + #[ doc( inline ) ] + #[ allow( unused_imports ) ] + pub use super::wrapper::exposed::*; + } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; + #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::axiomatic::prelude::*; @@ -162,4 +188,12 @@ pub mod prelude #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::primitive::prelude::*; + + #[ doc( inline ) ] + #[ allow( unused_imports ) ] + pub use super::fields::prelude::*; + #[ doc( inline ) ] + #[ allow( unused_imports ) ] + pub use super::wrapper::prelude::*; + } diff --git a/module/core/reflect_tools/src/reflect/axiomatic.rs b/module/core/reflect_tools/src/reflect/axiomatic.rs index df63730d59..1b3304846d 100644 --- a/module/core/reflect_tools/src/reflect/axiomatic.rs +++ b/module/core/reflect_tools/src/reflect/axiomatic.rs @@ -357,7 +357,7 @@ pub( crate ) mod private fn fmt( &self, f: &mut core::fmt::Formatter< '_ > ) -> core::fmt::Result { f - .write_str( &format!( "{}#{:?}", self.type_name(), self.type_id() ) ) + .write_str( &format!( "{}#{:?}", Entity::type_name( self ), self.type_id() ) ) } } @@ -369,7 +369,7 @@ pub( crate ) mod private fn fmt( &self, f: &mut core::fmt::Formatter< '_ > ) -> core::fmt::Result { f - .write_str( &format!( "{}#{:?}", self.type_name(), self.type_id() ) ) + .write_str( &format!( "{}#{:?}", Entity::type_name( self ), self.type_id() ) ) } } @@ -381,7 +381,7 @@ pub( crate ) mod private fn fmt( &self, f: &mut core::fmt::Formatter< '_ > ) -> core::fmt::Result { f - .write_str( &format!( "{}#{:?}", self.type_name(), self.type_id() ) ) + .write_str( &format!( "{}#{:?}", Entity::type_name( self ), self.type_id() ) ) } } @@ -493,25 +493,26 @@ pub( crate ) mod private #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { // reflect, IsContainer, @@ -527,14 +528,14 @@ pub mod orphan } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { reflect, }; @@ -545,6 +546,8 @@ pub mod exposed pub use exposed::*; /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; } diff --git a/module/core/reflect_tools/src/reflect/entity_array.rs b/module/core/reflect_tools/src/reflect/entity_array.rs index 5c171783e4..afe3363b7c 100644 --- a/module/core/reflect_tools/src/reflect/entity_array.rs +++ b/module/core/reflect_tools/src/reflect/entity_array.rs @@ -75,33 +75,36 @@ pub mod private #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; - // pub use super::private:: + pub use exposed::*; + // pub use private:: // { // }; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; } #[ doc( inline ) ] @@ -109,6 +112,8 @@ pub mod exposed pub use exposed::*; /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; } diff --git a/module/core/reflect_tools/src/reflect/entity_hashmap.rs b/module/core/reflect_tools/src/reflect/entity_hashmap.rs index 696f644db5..97d9a821c9 100644 --- a/module/core/reflect_tools/src/reflect/entity_hashmap.rs +++ b/module/core/reflect_tools/src/reflect/entity_hashmap.rs @@ -32,7 +32,7 @@ pub mod private KeyedCollectionDescriptor::< Self >::new( 0, Vec::new() ) } } - + impl< K, V > Entity for KeyedCollectionDescriptor< HashMap< K, V > > where K : 'static + Instance + IsScalar + Clone, @@ -69,7 +69,7 @@ pub mod private let mut result : Vec< KeyVal > = ( 0 .. self.len() ) .map( | k | KeyVal { key : Primitive::usize( k ), val : Box::new( < V as Instance >::Reflect() ) } ) .collect(); - + for i in 0..self.len() { result[ i ] = KeyVal { key : self.keys[ i ].clone(), val : Box::new( < V as Instance >::Reflect() ) } @@ -82,33 +82,36 @@ pub mod private #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; - // pub use super::private:: + pub use exposed::*; + // pub use private:: // { // }; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; } #[ doc( inline ) ] @@ -116,6 +119,8 @@ pub mod exposed pub use exposed::*; /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; } diff --git a/module/core/reflect_tools/src/reflect/entity_hashset.rs b/module/core/reflect_tools/src/reflect/entity_hashset.rs index d51fda1030..ba48a7a189 100644 --- a/module/core/reflect_tools/src/reflect/entity_hashset.rs +++ b/module/core/reflect_tools/src/reflect/entity_hashset.rs @@ -27,7 +27,7 @@ pub mod private CollectionDescriptor::< Self >::new( 0 ) } } - + impl< T > Entity for CollectionDescriptor< HashSet< T > > where T : 'static + Instance, @@ -71,33 +71,36 @@ pub mod private #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; - // pub use super::private:: + pub use exposed::*; + // pub use private:: // { // }; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; } #[ doc( inline ) ] @@ -105,6 +108,8 @@ pub mod exposed pub use exposed::*; /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; } diff --git a/module/core/reflect_tools/src/reflect/entity_slice.rs b/module/core/reflect_tools/src/reflect/entity_slice.rs index 90416afcbc..e396f8bcf9 100644 --- a/module/core/reflect_tools/src/reflect/entity_slice.rs +++ b/module/core/reflect_tools/src/reflect/entity_slice.rs @@ -37,33 +37,33 @@ pub mod private { true } - + #[ inline( always ) ] fn len( &self ) -> usize { self.len } - + #[ inline( always ) ] fn type_name( &self ) -> &'static str { core::any::type_name::< &'static [ T ] >() } - + #[ inline( always ) ] fn type_id( &self ) -> core::any::TypeId { core::any::TypeId::of::< &'static [ T ] >() } - + #[ inline( always ) ] fn elements( &self ) -> Box< dyn Iterator< Item = KeyVal > > { - + let result : Vec< KeyVal > = ( 0 .. self.len() ) .map( | k | KeyVal { key : Primitive::usize( k ), val : Box::new( < T as Instance >::Reflect() ) } ) .collect(); - + Box::new( result.into_iter() ) } } @@ -71,33 +71,36 @@ pub mod private #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; - // pub use super::private:: + pub use exposed::*; + // pub use private:: // { // }; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; } #[ doc( inline ) ] @@ -105,6 +108,8 @@ pub mod exposed pub use exposed::*; /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; } \ No newline at end of file diff --git a/module/core/reflect_tools/src/reflect/entity_vec.rs b/module/core/reflect_tools/src/reflect/entity_vec.rs index 997e32b18c..c559136729 100644 --- a/module/core/reflect_tools/src/reflect/entity_vec.rs +++ b/module/core/reflect_tools/src/reflect/entity_vec.rs @@ -26,7 +26,7 @@ pub mod private CollectionDescriptor::< Self >::new( 0 ) } } - + impl< T > Entity for CollectionDescriptor< Vec< T > > where T : 'static + Instance, @@ -70,33 +70,36 @@ pub mod private #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; - // pub use super::private:: + pub use exposed::*; + // pub use private:: // { // }; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; } #[ doc( inline ) ] @@ -104,6 +107,8 @@ pub mod exposed pub use exposed::*; /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; } diff --git a/module/core/reflect_tools/src/reflect/fields.rs b/module/core/reflect_tools/src/reflect/fields.rs new file mode 100644 index 0000000000..a90911ec2e --- /dev/null +++ b/module/core/reflect_tools/src/reflect/fields.rs @@ -0,0 +1,207 @@ +//! +//! Iterator over fields. +//! + +/// Internal namespace. +pub( crate ) mod private +{ + + // use core::fmt; + use std::borrow::Cow; + + /// A trait for iterators that are also `ExactSizeIterator`. + pub trait _IteratorTrait + where + Self : core::iter::Iterator + ExactSizeIterator + DoubleEndedIterator + { + } + + impl< T > _IteratorTrait for T + where + Self : core::iter::Iterator + ExactSizeIterator + DoubleEndedIterator + { + } + + /// A trait for iterators that implement `_IteratorTrait` and `Clone`. + pub trait IteratorTrait + where + Self : _IteratorTrait + Clone + { + } + + impl< T > IteratorTrait for T + where + Self : _IteratorTrait + Clone + { + } + + /// + /// A trait for iterating over fields convertible to a specified type within an entity. + /// + /// This trait provides a mechanism for accessing fields in collections or entities, converting + /// them into a desired type for iteration. + /// + /// # Type Parameters + /// + /// - `K`: The key type, typically representing the index or identifier of each field. + /// - `V`: The value type that fields are converted into during iteration. + /// + /// # Associated Types + /// + /// - `Value<'v>`: The type of value yielded by the iterator, parameterized by a lifetime `'v`. + /// This ensures the values' lifetimes are tied to the entity being iterated over. + /// + /// # Example + /// + /// ```rust + /// use reflect_tools::{ Fields, IteratorTrait }; + /// + /// struct MyCollection< T > + /// { + /// data : Vec< T >, + /// } + /// + /// impl< T > Fields< usize, & T > for MyCollection< T > + /// { + /// type Value< 'v > = & 'v T where Self : 'v; + /// + /// fn fields( & self ) -> impl IteratorTrait< Item = ( usize, Self::Value< '_ > ) > + /// { + /// self.data.iter().enumerate() + /// } + /// } + /// ``` + /// + /// This example shows `MyCollection` implementing `Fields`, allowing iteration over its elements + /// with both index and value. + pub trait Fields< K, V > + { + /// `Value<'v>`: The type of value yielded by the iterator, parameterized by a lifetime `'v`. + /// This ensures the values' lifetimes are tied to the entity being iterated over. + type Value< 'v > where Self : 'v; + + /// Returns an iterator over fields of the specified type within the entity. + fn fields( & self ) -> impl IteratorTrait< Item = ( K, Self::Value< '_ > ) >; + } + + /// Trait returning name of type of variable. + pub trait TypeName + { + /// Return name of type of variable. + fn type_name( &self ) -> &'static str; + } + + impl< T > TypeName for T + where + T : ?Sized, + { + #[ inline( always ) ] + fn type_name( &self ) -> &'static str + { + ::core::any::type_name_of_val( self ) + } + } + + // == implementations for collections + +// impl< T, Marker > Fields< usize, Marker > for Vec< T > +// where +// T : std::borrow::ToOwned, +// Marker : for< 'a > From< &'a T >, +// // T : Clone +// { +// type Value< 'v > = Marker +// where Self : 'v; +// +// fn fields( &self ) -> impl IteratorTrait< Item = ( usize, Self::Value< '_ > ) > +// // where +// // 'a : 'b, +// { +// self.iter().enumerate().map( move | ( key, val ) | ( key, Marker::from( val ) ) ) +// } +// } + + impl< T > Fields< usize, &'_ T > for Vec< T > + where + T : std::borrow::ToOwned, + { + type Value< 'v > = &'v T + where Self : 'v, T : 'v; + + fn fields( &self ) -> impl IteratorTrait< Item = ( usize, Self::Value< '_ > ) > + { + self.into_iter().enumerate().map( move | ( key, val ) | ( key, val ) ) + } + + } + + impl< T > Fields< usize, Option< Cow< '_, T > > > for Vec< T > + where + T : std::borrow::ToOwned, + { + type Value< 'v > = Option< Cow< 'v, T > > + where Self : 'v; + + fn fields( &self ) -> impl IteratorTrait< Item = ( usize, Self::Value< '_ > ) > + { + self.iter().enumerate().map( move | ( key, val ) | ( key, Some( Cow::Borrowed( val ) ) ) ) + } + } + + impl< T, Marker > Fields< usize, crate::MaybeAs< '_, T, Marker > > for Vec< T > + where + T : std::borrow::ToOwned, + Marker : Clone + Copy + 'static, + { + type Value< 'v > = crate::MaybeAs< 'v, T, Marker > + where Self : 'v; + + fn fields( &self ) -> impl IteratorTrait< Item = ( usize, Self::Value< '_ > ) > + { + self.iter().enumerate().map( move | ( key, val ) | ( key, crate::MaybeAs::from( Cow::Borrowed( val ) ) ) ) + } + } + +} + +#[ doc( inline ) ] +#[ allow( unused_imports ) ] +pub use own::*; + +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own +{ + use super::*; +} + +/// Orphan namespace of the module. +#[ allow( unused_imports ) ] +pub mod orphan +{ + use super::*; + #[ doc( inline ) ] + pub use exposed::*; +} + +/// Exposed namespace of the module. +#[ allow( unused_imports ) ] +pub mod exposed +{ + use super::*; + #[ doc( inline ) ] + pub use private:: + { + _IteratorTrait, + IteratorTrait, + Fields, + TypeName, + }; +} + +/// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] +pub mod prelude +{ + use super::*; +} diff --git a/module/core/reflect_tools/src/reflect/primitive.rs b/module/core/reflect_tools/src/reflect/primitive.rs index f696eccf75..f9e112db80 100644 --- a/module/core/reflect_tools/src/reflect/primitive.rs +++ b/module/core/reflect_tools/src/reflect/primitive.rs @@ -223,23 +223,25 @@ pub( crate ) mod private #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; - pub use super::private:: + pub use exposed::*; + pub use private:: { Primitive, // Data, @@ -247,11 +249,12 @@ pub mod orphan } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; } #[ doc( inline ) ] @@ -259,6 +262,8 @@ pub mod exposed pub use exposed::*; /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; } diff --git a/module/core/reflect_tools/src/reflect/wrapper.rs b/module/core/reflect_tools/src/reflect/wrapper.rs new file mode 100644 index 0000000000..e019b3dc23 --- /dev/null +++ b/module/core/reflect_tools/src/reflect/wrapper.rs @@ -0,0 +1,52 @@ +//! +//! Collection of wrappers. +//! + +/// Internal namespace. +pub( crate ) mod private +{ +} + +mod maybe_as; + +#[ doc( inline ) ] +#[ allow( unused_imports ) ] +pub use own::*; + +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own +{ + use super::*; + #[ doc( inline ) ] + pub use orphan::*; +} + +/// Orphan namespace of the module. +#[ allow( unused_imports ) ] +pub mod orphan +{ + use super::*; + #[ doc( inline ) ] + pub use exposed::*; +} + +/// Exposed namespace of the module. +#[ allow( unused_imports ) ] +pub mod exposed +{ + use super::*; + #[ doc( inline ) ] + #[ allow( unused_imports ) ] + pub use super:: + { + maybe_as::MaybeAs, + }; +} + +/// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] +pub mod prelude +{ + use super::*; +} diff --git a/module/core/reflect_tools/src/reflect/wrapper/maybe_as.rs b/module/core/reflect_tools/src/reflect/wrapper/maybe_as.rs new file mode 100644 index 0000000000..9b1a76e23f --- /dev/null +++ b/module/core/reflect_tools/src/reflect/wrapper/maybe_as.rs @@ -0,0 +1,214 @@ +//! +//! It's often necessary to wrap something inot a local structure and this file contains wrapper of `Option< Cow< 'a, T > >`. +//! + +use core::fmt; +use std::borrow::Cow; +use core::ops::{ Deref }; + +/// Universal wrapper with transparent option of copy on write reference emphasizing a specific aspect of identity of its internal type. +#[ repr( transparent ) ] +pub struct MaybeAs< 'a, T, Marker >( pub Option< Cow< 'a, T > >, ::core::marker::PhantomData< fn() -> Marker > ) +where + T : std::borrow::ToOwned + ?Sized, + Marker : Clone + Copy + 'static, +; + +impl< 'a, T, Marker > MaybeAs< 'a, T, Marker > +where + T : std::borrow::ToOwned + ?Sized, + Marker : Clone + Copy + 'static, +{ + + /// Check is it borrowed. + #[ inline( always ) ] + pub fn is_borrowed( &self ) -> bool + { + if self.0.is_none() + { + return false; + } + match self.0.as_ref().unwrap() + { + Cow::Borrowed( _ ) => true, + Cow::Owned( _ ) => false, + } + } + + /// Check does it have some value. + #[ inline( always ) ] + pub fn is_some( &self ) -> bool + { + return self.0.is_some() + } + + /// Constructor returning none. + #[ inline( always ) ] + pub fn none() -> Self + { + Self( None, ::core::marker::PhantomData ) + } + + /// Just a constructor. + #[ inline( always ) ] + pub fn new( src : < T as std::borrow::ToOwned >::Owned ) -> Self + { + Self( Some( Cow::Owned( src ) ), ::core::marker::PhantomData ) + } + + // xxx : review + /// Just a constructor. + #[ inline( always ) ] + pub fn new_with_ref( src : &'a T ) -> Self + { + Self( Some( Cow::Borrowed( src ) ), ::core::marker::PhantomData ) + } + + /// Just a constructor. + #[ inline( always ) ] + pub fn new_with_inner( src : Option< Cow< 'a, T > > ) -> Self + { + Self( src, ::core::marker::PhantomData ) + } + + /// Just a constructor. + #[ inline( always ) ] + pub fn inner( self ) -> Option< Cow< 'a, T > > + { + self.0 + } + +} + +// impl< 'a, T, Marker > std::borrow::ToOwned for MaybeAs< 'a, T, Marker > +// where +// T : std::borrow::ToOwned + ?Sized, +// { +// type Owned = MaybeAs< 'static, T::Owned, Marker >; +// +// fn to_owned( &self ) -> Self::Owned +// { +// MaybeAs +// ( +// self.0.as_ref().map( | cow | Cow::Owned( cow.to_owned() ) ), +// std::marker::PhantomData +// ) +// } +// } + +impl< 'a, T, Marker > Clone for MaybeAs< 'a, T, Marker > +where + T : std::borrow::ToOwned + ?Sized, + Marker : Clone + Copy + 'static, +{ + fn clone( &self ) -> Self + { + Self( self.0.clone(), ::core::marker::PhantomData ) + } +} + +impl< 'a, T, Marker > AsRef< Option< Cow< 'a, T > > > for MaybeAs< 'a, T, Marker > +where + T : std::borrow::ToOwned + ?Sized, + Marker : Clone + Copy + 'static, +{ + fn as_ref( &self ) -> &Option< Cow< 'a, T > > + { + &self.0 + } +} + +impl< 'a, T, Marker > Deref for MaybeAs< 'a, T, Marker > +where + T : std::borrow::ToOwned + ?Sized, + Marker : Clone + Copy + 'static, +{ + type Target = Option< Cow< 'a, T > >; + fn deref( &self ) -> &Option< Cow< 'a, T > > + { + self.as_ref() + } +} + +impl< 'a, T, Marker > From< Cow< 'a, T > > +for MaybeAs< 'a, T, Marker > +where + T : std::borrow::ToOwned + ?Sized, + Marker : Clone + Copy + 'static, +{ + fn from( src : Cow< 'a, T > ) -> Self + { + MaybeAs::new_with_inner( Some( src ) ) + } +} + +impl< 'a, T, Marker > From< Option< Cow< 'a, T > > > +for MaybeAs< 'a, T, Marker > +where + T : std::borrow::ToOwned + ?Sized, + Marker : Clone + Copy + 'static, +{ + fn from( src : Option< Cow< 'a, T > > ) -> Self + { + MaybeAs::new_with_inner( src ) + } +} + +impl< 'a, T, Marker > From< &'a T > +for MaybeAs< 'a, T, Marker > +where + T : std::borrow::ToOwned + ?Sized, + Marker : Clone + Copy + 'static, +{ + fn from( src : &'a T ) -> Self + { + MaybeAs::new_with_ref( src ) + } +} + +impl< 'a, T, Marker > Default for MaybeAs< 'a, T, Marker > +where + T : std::borrow::ToOwned + ?Sized, + < T as std::borrow::ToOwned >::Owned : Default, + Marker : Clone + Copy + 'static, +{ + fn default() -> Self + { + MaybeAs::new( < T as std::borrow::ToOwned >::Owned::default() ) + } +} + +impl< 'a, T, Marker > fmt::Debug for MaybeAs< 'a, T, Marker > +where + T : std::borrow::ToOwned + ?Sized, + < T as std::borrow::ToOwned >::Owned : fmt::Debug, + Marker : Clone + Copy + 'static, + T : fmt::Debug, +{ + fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> fmt::Result + { + f.debug_struct( "MaybeAs" ) + .field( "0", &self.0 ) + .finish() + } +} + +impl< 'a, T, Marker > PartialEq for MaybeAs< 'a, T, Marker > +where + T : std::borrow::ToOwned + ?Sized, + Marker : Clone + Copy + 'static, + T : PartialEq, +{ + fn eq( &self, other : &Self ) -> bool + { + self.as_ref() == other.as_ref() + } +} + +impl< 'a, T, Marker > Eq for MaybeAs< 'a, T, Marker > +where + T : std::borrow::ToOwned + ?Sized, + Marker : Clone + Copy + 'static, + T : Eq, +{ +} diff --git a/module/core/reflect_tools/tests/inc/fundamental/fields_test.rs b/module/core/reflect_tools/tests/inc/fundamental/fields_test.rs new file mode 100644 index 0000000000..24a561a6ea --- /dev/null +++ b/module/core/reflect_tools/tests/inc/fundamental/fields_test.rs @@ -0,0 +1,153 @@ +#[ allow( unused_imports ) ] +use super::*; + +use the_module:: +{ + Fields, + IteratorTrait, + MaybeAs, + // ToStringWith, + // WithDebug, +}; + +// xxx2 : check + +use std:: +{ + // fmt, + collections::HashMap, + borrow::Cow, +}; + +/// Struct representing a test object with various fields. +#[ derive( Clone, Debug ) ] +pub struct TestObject +{ + pub id : String, + pub created_at : i64, + pub file_ids : Vec< String >, + pub tools : Option< Vec< HashMap< String, String > > >, +} + +// impl< 'a > Fields< 'a, &'static str, MaybeAs< 'a, String, () > > +impl Fields< &'static str, MaybeAs< '_, String, () > > +for TestObject +{ + type Value< 'v > = MaybeAs< 'v, String, () >; + + // fn fields( &'a self ) -> impl IteratorTrait< Item = ( &'static str, MaybeAs< 'a, String, () > ) > + fn fields( &self ) -> impl IteratorTrait< Item = ( &'static str, MaybeAs< '_, String, () > ) > + { + let mut dst : Vec< ( &'static str, MaybeAs< '_, String, () > ) > = Vec::new(); + + dst.push( ( "id", Some( Cow::Borrowed( &self.id ) ).into() ) ); + dst.push( ( "created_at", Some( Cow::Owned( self.created_at.to_string() ) ).into() ) ); + dst.push( ( "file_ids", Some( Cow::Owned( format!( "{:?}", self.file_ids ) ) ).into() ) ); + + if let Some( tools ) = &self.tools + { + dst.push( ( "tools", Some( Cow::Owned( format!( "{:?}", tools ) ) ).into() ) ); + } + else + { + dst.push( ( "tools", None.into() ) ); + } + + dst.into_iter() + } +} + +// + +// #[ allow( dead_code ) ] +// fn is_borrowed< 'a, T : Clone >( src : &Option< Cow< 'a, T > > ) -> bool +// { +// if src.is_none() +// { +// return false; +// } +// match src.as_ref().unwrap() +// { +// Cow::Borrowed( _ ) => true, +// Cow::Owned( _ ) => false, +// } +// } + +// + +#[ test ] +fn basic() +{ + let test_object = TestObject + { + id : "12345".to_string(), + created_at : 1627845583, + file_ids : vec![ "file1".to_string(), "file2".to_string() ], + tools : Some + ( + vec! + [{ + let mut map = HashMap::new(); + map.insert( "tool1".to_string(), "value1".to_string() ); + map.insert( "tool2".to_string(), "value2".to_string() ); + map + }] + ), + }; + + let fields : Vec< ( &str, MaybeAs< '_, String, () > ) > = test_object.fields().collect(); + + assert_eq!( fields.len(), 4 ); + assert!( fields[ 0 ].1.is_borrowed() ); + assert!( !fields[ 1 ].1.is_borrowed() ); + assert!( !fields[ 2 ].1.is_borrowed() ); + assert!( !fields[ 3 ].1.is_borrowed() ); + assert_eq!( fields[ 0 ], ( "id", Some( Cow::Borrowed( &"12345".to_string() ) ).into() ) ); + assert_eq!( fields[ 1 ], ( "created_at", Some( Cow::Owned( "1627845583".to_string() ) ).into() ) ); + assert_eq!( fields[ 2 ], ( "file_ids", Some( Cow::Owned( "[\"file1\", \"file2\"]".to_string() ) ).into() ) ); + assert_eq!( fields[ 3 ].0, "tools" ); + +} + +// + +#[ test ] +fn test_vec_fields() +{ + let test_objects = vec! + [ + TestObject + { + id : "12345".to_string(), + created_at : 1627845583, + file_ids : vec![ "file1".to_string(), "file2".to_string() ], + tools : Some + ( + vec! + [{ + let mut map = HashMap::new(); + map.insert( "tool1".to_string(), "value1".to_string() ); + map.insert( "tool2".to_string(), "value2".to_string() ); + map + }] + ), + }, + TestObject + { + id : "67890".to_string(), + created_at : 13, + file_ids : vec![ "file3".to_string(), "file4".to_string() ], + tools : None, + }, + ]; + + // let fields : Vec< _ > = test_objects.fields().collect(); + // let fields : Vec< ( usize, Option< Cow< '_, TestObject > > ) > = test_objects.fields().collect(); + let fields : Vec< _ > = Fields::< usize, Option< _ > >::fields( &test_objects ).collect(); + assert_eq!( fields.len(), 2 ); + assert_eq!( fields[ 0 ].0, 0 ); + assert_eq!( fields[ 1 ].0, 1 ); + + // let x = Cow::Borrowed( ); + +} diff --git a/module/core/reflect_tools/tests/inc/reflect_array_test.rs b/module/core/reflect_tools/tests/inc/group1/array_test.rs similarity index 100% rename from module/core/reflect_tools/tests/inc/reflect_array_test.rs rename to module/core/reflect_tools/tests/inc/group1/array_test.rs diff --git a/module/core/reflect_tools/tests/inc/reflect_common_test.rs b/module/core/reflect_tools/tests/inc/group1/common_test.rs similarity index 100% rename from module/core/reflect_tools/tests/inc/reflect_common_test.rs rename to module/core/reflect_tools/tests/inc/group1/common_test.rs diff --git a/module/core/reflect_tools/tests/inc/reflect_hashmap_test.rs b/module/core/reflect_tools/tests/inc/group1/hashmap_test.rs similarity index 100% rename from module/core/reflect_tools/tests/inc/reflect_hashmap_test.rs rename to module/core/reflect_tools/tests/inc/group1/hashmap_test.rs diff --git a/module/core/reflect_tools/tests/inc/reflect_hashset_test.rs b/module/core/reflect_tools/tests/inc/group1/hashset_test.rs similarity index 100% rename from module/core/reflect_tools/tests/inc/reflect_hashset_test.rs rename to module/core/reflect_tools/tests/inc/group1/hashset_test.rs diff --git a/module/core/reflect_tools/tests/inc/newtype_experiment.rs b/module/core/reflect_tools/tests/inc/group1/newtype_experiment.rs similarity index 100% rename from module/core/reflect_tools/tests/inc/newtype_experiment.rs rename to module/core/reflect_tools/tests/inc/group1/newtype_experiment.rs diff --git a/module/core/reflect_tools/tests/inc/only_test/all.rs b/module/core/reflect_tools/tests/inc/group1/only_test/all.rs similarity index 100% rename from module/core/reflect_tools/tests/inc/only_test/all.rs rename to module/core/reflect_tools/tests/inc/group1/only_test/all.rs diff --git a/module/core/reflect_tools/tests/inc/only_test/reflect_struct.rs b/module/core/reflect_tools/tests/inc/group1/only_test/reflect_struct.rs similarity index 90% rename from module/core/reflect_tools/tests/inc/only_test/reflect_struct.rs rename to module/core/reflect_tools/tests/inc/group1/only_test/reflect_struct.rs index 482ad7bf84..9b7dddbb6c 100644 --- a/module/core/reflect_tools/tests/inc/only_test/reflect_struct.rs +++ b/module/core/reflect_tools/tests/inc/group1/only_test/reflect_struct.rs @@ -12,7 +12,7 @@ fn reflect_basic_test() a_id!( reflect::reflect( &ins ).is_container(), true ); a_id!( reflect::reflect( &ins ).len(), 3 ); - a_id!( reflect::reflect( &ins ).type_name(), "tests::inc::reflect_struct_manual_test::Struct1" ); + a_id!( reflect::reflect( &ins ).type_name(), "tests::inc::group1::struct_manual_test::Struct1" ); let names = reflect::reflect( &ins ).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 = reflect::reflect( &ins ).elements().map( | e | e.val.type_name() ).collect::< Vec< _ > >(); diff --git a/module/core/reflect_tools/tests/inc/only_test/reflect_struct_in_struct.rs b/module/core/reflect_tools/tests/inc/group1/only_test/reflect_struct_in_struct.rs similarity index 84% rename from module/core/reflect_tools/tests/inc/only_test/reflect_struct_in_struct.rs rename to module/core/reflect_tools/tests/inc/group1/only_test/reflect_struct_in_struct.rs index 999c924393..83f2cd53f0 100644 --- a/module/core/reflect_tools/tests/inc/only_test/reflect_struct_in_struct.rs +++ b/module/core/reflect_tools/tests/inc/group1/only_test/reflect_struct_in_struct.rs @@ -12,17 +12,17 @@ fn reflect_struct_in_struct() a_id!( reflect::reflect( &ins ).is_container(), true ); a_id!( reflect::reflect( &ins ).len(), 3 ); - a_id!( reflect::reflect( &ins ).type_name(), "tests::inc::reflect_struct_in_struct_manual_test::Struct1" ); + a_id!( reflect::reflect( &ins ).type_name(), "tests::inc::group1::struct_in_struct_manual_test::Struct1" ); let names = reflect::reflect( &ins ).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 = reflect::reflect( &ins ).elements().map( | e | e.val.type_name() ).collect::< Vec< _ > >(); - a_id!( types, vec![ "i32", "alloc::string::String", "tests::inc::reflect_struct_in_struct_manual_test::Struct2" ] ); + a_id!( types, vec![ "i32", "alloc::string::String", "tests::inc::group1::struct_in_struct_manual_test::Struct2" ] ); let f3 = reflect::reflect( &ins ).elements().skip( 2 ).next().unwrap(); 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(), "tests::inc::reflect_struct_in_struct_manual_test::Struct2" ); + a_id!( f3.val.type_name(), "tests::inc::group1::struct_in_struct_manual_test::Struct2" ); let names = f3.val.elements().map( | e | e.key ).collect::< Vec< _ > >(); 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< _ > >(); diff --git a/module/core/reflect_tools/tests/inc/only_test/reflect_struct_with_lifetime.rs b/module/core/reflect_tools/tests/inc/group1/only_test/reflect_struct_with_lifetime.rs similarity index 94% rename from module/core/reflect_tools/tests/inc/only_test/reflect_struct_with_lifetime.rs rename to module/core/reflect_tools/tests/inc/group1/only_test/reflect_struct_with_lifetime.rs index 64fb941938..7a61248a1f 100644 --- a/module/core/reflect_tools/tests/inc/only_test/reflect_struct_with_lifetime.rs +++ b/module/core/reflect_tools/tests/inc/group1/only_test/reflect_struct_with_lifetime.rs @@ -30,7 +30,7 @@ fn reflect_struct_with_lifetime() // inspection of structure a_id!( reflect::reflect( &ins ).is_container(), true ); a_id!( reflect::reflect( &ins ).len(), 3 ); - a_id!( reflect::reflect( &ins ).type_name(), "tests::inc::reflect_struct_with_lifetime_manual_test::Struct1" ); + a_id!( reflect::reflect( &ins ).type_name(), "tests::inc::group1::struct_with_lifetime_manual_test::Struct1" ); a_id!( reflect::reflect( &ins ).type_id(), core::any::TypeId::of::< Struct1< 'static, 'static > >() ); let names = reflect::reflect( &ins ).elements().map( | e | e.key ).collect::< Vec< _ > >(); a_id!( names, vec![ reflect::Primitive::str( "f1" ), reflect::Primitive::str( "f2" ), reflect::Primitive::str( "f3" ) ] ); diff --git a/module/core/reflect_tools/tests/inc/reflect_primitive_test.rs b/module/core/reflect_tools/tests/inc/group1/primitive_test.rs similarity index 100% rename from module/core/reflect_tools/tests/inc/reflect_primitive_test.rs rename to module/core/reflect_tools/tests/inc/group1/primitive_test.rs diff --git a/module/core/reflect_tools/tests/inc/reflect_slice_test.rs b/module/core/reflect_tools/tests/inc/group1/slice_test.rs similarity index 100% rename from module/core/reflect_tools/tests/inc/reflect_slice_test.rs rename to module/core/reflect_tools/tests/inc/group1/slice_test.rs diff --git a/module/core/reflect_tools/tests/inc/reflect_struct_in_struct_manual_test.rs b/module/core/reflect_tools/tests/inc/group1/struct_in_struct_manual_test.rs similarity index 100% rename from module/core/reflect_tools/tests/inc/reflect_struct_in_struct_manual_test.rs rename to module/core/reflect_tools/tests/inc/group1/struct_in_struct_manual_test.rs diff --git a/module/core/reflect_tools/tests/inc/reflect_struct_manual_test.rs b/module/core/reflect_tools/tests/inc/group1/struct_manual_test.rs similarity index 100% rename from module/core/reflect_tools/tests/inc/reflect_struct_manual_test.rs rename to module/core/reflect_tools/tests/inc/group1/struct_manual_test.rs diff --git a/module/core/reflect_tools/tests/inc/reflect_struct_with_lifetime_manual_test.rs b/module/core/reflect_tools/tests/inc/group1/struct_with_lifetime_manual_test.rs similarity index 100% rename from module/core/reflect_tools/tests/inc/reflect_struct_with_lifetime_manual_test.rs rename to module/core/reflect_tools/tests/inc/group1/struct_with_lifetime_manual_test.rs diff --git a/module/core/reflect_tools/tests/inc/reflect_vec_test.rs b/module/core/reflect_tools/tests/inc/group1/vec_test.rs similarity index 100% rename from module/core/reflect_tools/tests/inc/reflect_vec_test.rs rename to module/core/reflect_tools/tests/inc/group1/vec_test.rs diff --git a/module/core/reflect_tools/tests/inc/mod.rs b/module/core/reflect_tools/tests/inc/mod.rs index ba3f3136c9..e7531dff91 100644 --- a/module/core/reflect_tools/tests/inc/mod.rs +++ b/module/core/reflect_tools/tests/inc/mod.rs @@ -2,25 +2,37 @@ use super::*; #[ cfg( feature = "reflect_newtype" ) ] -mod newtype_experiment; +// #[ path = "fundamental" ] +mod fundamental +{ + #[ allow( unused_imports ) ] + use super::*; -#[ cfg( feature = "reflect_reflect" ) ] -mod reflect_common_test; -#[ cfg( feature = "reflect_reflect" ) ] -mod reflect_primitive_test; -#[ cfg( feature = "reflect_reflect" ) ] -mod reflect_struct_manual_test; -#[ cfg( feature = "reflect_reflect" ) ] -mod reflect_struct_in_struct_manual_test; -#[ cfg( feature = "reflect_reflect" ) ] -mod reflect_struct_with_lifetime_manual_test; -#[ cfg( feature = "reflect_reflect" ) ] -mod reflect_slice_test; -#[ cfg( feature = "reflect_reflect" ) ] -mod reflect_vec_test; -#[ cfg( feature = "reflect_reflect" ) ] -mod reflect_hashset_test; -#[ cfg( feature = "reflect_reflect" ) ] -mod reflect_hashmap_test; -#[ cfg( feature = "reflect_reflect" ) ] -mod reflect_array_test; + mod fields_test; + // mod to_string_test; + // mod to_string_example; + // mod to_string_with_fallback_test; + +} + +#[ cfg( feature = "reflect_newtype" ) ] +// #[ path = "group1" ] +mod group1 +{ + #[ allow( unused_imports ) ] + use super::*; + + mod newtype_experiment; + + mod common_test; + mod primitive_test; + mod struct_manual_test; + mod struct_in_struct_manual_test; + mod struct_with_lifetime_manual_test; + mod slice_test; + mod vec_test; + mod hashset_test; + mod hashmap_test; + mod array_test; + +} diff --git a/module/core/reflect_tools/tests/smoke_test.rs b/module/core/reflect_tools/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/core/reflect_tools/tests/smoke_test.rs +++ b/module/core/reflect_tools/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/core/reflect_tools_meta/Cargo.toml b/module/core/reflect_tools_meta/Cargo.toml index 75a842e9a1..bd525a2655 100644 --- a/module/core/reflect_tools_meta/Cargo.toml +++ b/module/core/reflect_tools_meta/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "reflect_tools_meta" -version = "0.2.0" +version = "0.3.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", @@ -22,7 +22,7 @@ workspace = true [package.metadata.docs.rs] features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] + [lib] proc-macro = true @@ -31,17 +31,17 @@ proc-macro = true default = [ "enabled", - "reflect_reflect", + "reflect_derive", ] full = [ - "enabled", - "reflect_reflect", + "default", ] enabled = [] -reflect_reflect = [] +reflect_derive = [] [dependencies] +macro_tools = { workspace = true, features = [ "default" ] } # iter_tools = { workspace = true, features = [ "full" ] } # xxx : qqq : optimize features set diff --git a/module/core/reflect_tools_meta/src/implementation/reflect.rs b/module/core/reflect_tools_meta/src/implementation/reflect.rs index 6016ff192a..34d239b8d9 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 super::*; -use macro_tools::{ Result, format_ident, attr, diag }; +use crate::*; +use macro_tools::{ Result, attr, diag }; // diff --git a/module/core/reflect_tools_meta/src/lib.rs b/module/core/reflect_tools_meta/src/lib.rs index c2efaadb8a..f6a8a78b64 100644 --- a/module/core/reflect_tools_meta/src/lib.rs +++ b/module/core/reflect_tools_meta/src/lib.rs @@ -5,20 +5,23 @@ // #![ allow( non_upper_case_globals ) ] #![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/", "Readme.md" ) ) ] -#[ cfg -( - any - ( - feature = "reflect_relfect", - ) -)] +// #[ cfg( feature = "enabled" ) ] +// use macro_tools::prelude::*; + #[ cfg( feature = "enabled" ) ] -mod implementation; +mod implementation +{ + #[ cfg( feature = "reflect_derive" ) ] + pub mod reflect; + #[ cfg( feature = "reflect_derive" ) ] + pub use reflect::*; +} + #[ cfg ( any ( - feature = "reflect_relfect", + feature = "reflect_derive", ) )] #[ cfg( feature = "enabled" ) ] @@ -33,7 +36,7 @@ use implementation::*; /// #[ cfg( feature = "enabled" ) ] -#[ cfg( feature = "derive_reflect" ) ] +#[ cfg( feature = "reflect_derive" ) ] #[ proc_macro_derive( Reflect, attributes( debug ) ) ] pub fn derive_reflect( input : proc_macro::TokenStream ) -> proc_macro::TokenStream { diff --git a/module/core/strs_tools/Cargo.toml b/module/core/strs_tools/Cargo.toml index 09308568ad..1e7af088ca 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.14.0" +version = "0.15.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", @@ -24,7 +24,7 @@ workspace = true features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] + [features] default = [ diff --git a/module/core/strs_tools/src/lib.rs b/module/core/strs_tools/src/lib.rs index 1c5bc9300e..72ff01c34c 100644 --- a/module/core/strs_tools/src/lib.rs +++ b/module/core/strs_tools/src/lib.rs @@ -11,35 +11,41 @@ pub mod string; #[ doc( inline ) ] #[ allow( unused_imports ) ] #[ cfg( feature = "enabled" ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. +/// Own namespace of the module. #[ cfg( feature = "enabled" ) ] -pub mod protected +#[ allow( unused_imports ) ] +pub mod own { - #[ allow( unused_imports ) ] - pub use super::orphan::*; + use super::*; + pub use orphan::*; pub use super::string::orphan::*; } /// Parented namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod orphan { - #[ allow( unused_imports ) ] - pub use super::exposed::*; + use super::*; + pub use exposed::*; } /// Exposed namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; pub use super::string::exposed::*; } /// Namespace of the module to include with `use module::*`. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; pub use super::string::prelude::*; } diff --git a/module/core/strs_tools/src/string/indentation.rs b/module/core/strs_tools/src/string/indentation.rs index 16f7208663..df0a4835cb 100644 --- a/module/core/strs_tools/src/string/indentation.rs +++ b/module/core/strs_tools/src/string/indentation.rs @@ -79,42 +79,46 @@ pub( crate ) mod private #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { - pub use super::orphan::*; - #[ allow( unused_imports ) ] - pub use super::private:: + use super::*; + pub use orphan::*; + pub use private:: { }; } /// Parented namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { - #[ allow( unused_imports ) ] - pub use super::exposed::*; - #[ allow( unused_imports ) ] - pub use super::private:: + use super::*; + pub use exposed::*; + pub use private:: { }; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { - pub use super::protected as indentation; + use super::*; + pub use super::own as indentation; - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { indentation, }; } /// Namespace of the module to include with `use module::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; } diff --git a/module/core/strs_tools/src/string/isolate.rs b/module/core/strs_tools/src/string/isolate.rs index 78d23f6658..d54e34d219 100644 --- a/module/core/strs_tools/src/string/isolate.rs +++ b/module/core/strs_tools/src/string/isolate.rs @@ -175,8 +175,10 @@ pub( crate ) mod private } /// Owned namespace of the module. -pub mod protected +#[ allow( unused_imports ) ] +pub mod own { + use super::*; use super::private as i; pub use i::IsolateOptions; @@ -186,18 +188,22 @@ pub mod protected pub use i::isolate_right; } -pub use protected::*; +pub use own::*; /// Parented namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { - pub use super::exposed::*; + use super::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { - pub use super::protected as isolate; + use super::*; + pub use super::own as isolate; use super::private as i; @@ -208,8 +214,10 @@ pub mod exposed } /// Namespace of the module to include with `use module::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; use super::private as i; pub use i::IsolateOptionsAdapter; diff --git a/module/core/strs_tools/src/string/mod.rs b/module/core/strs_tools/src/string/mod.rs index d15f35b69e..46552b8124 100644 --- a/module/core/strs_tools/src/string/mod.rs +++ b/module/core/strs_tools/src/string/mod.rs @@ -27,13 +27,14 @@ pub mod split; #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { - #[ allow( unused_imports ) ] - pub use super::orphan::*; + use super::*; + pub use orphan::*; #[ cfg( all( feature = "string_indentation", not( feature = "no_std" ) ) ) ] pub use super::indentation::orphan::*; #[ cfg( all( feature = "string_isolate", not( feature = "no_std" ) ) ) ] @@ -48,14 +49,18 @@ pub mod protected } /// Parented namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { - pub use super::exposed::*; + use super::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ cfg( all( feature = "string_indentation", not( feature = "no_std" ) ) ) ] #[ allow( unused_imports ) ] pub use super::indentation::exposed::*; @@ -71,8 +76,10 @@ pub mod exposed } /// Namespace of the module to include with `use module::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ cfg( all( feature = "string_indentation", not( feature = "no_std" ) ) ) ] #[ allow( unused_imports ) ] pub use super::indentation::prelude::*; diff --git a/module/core/strs_tools/src/string/number.rs b/module/core/strs_tools/src/string/number.rs index 29da7a5520..fcf486b796 100644 --- a/module/core/strs_tools/src/string/number.rs +++ b/module/core/strs_tools/src/string/number.rs @@ -5,15 +5,15 @@ pub( crate ) mod private #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { - #[ allow( unused_imports ) ] - pub use super::orphan::*; - #[ allow( unused_imports ) ] - pub use super::private:: + use super::*; + pub use orphan::*; + pub use private:: { }; #[ cfg( all( feature = "string_parse_number" ) ) ] @@ -23,28 +23,31 @@ pub mod protected } /// Parented namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { - #[ allow( unused_imports ) ] - pub use super::exposed::*; - #[ allow( unused_imports ) ] - pub use super::private:: + use super::*; + pub use exposed::*; + pub use private:: { }; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { - pub use super::protected as number; + use super::*; + pub use super::own as number; - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { }; } /// Namespace of the module to include with `use module::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; } diff --git a/module/core/strs_tools/src/string/parse_request.rs b/module/core/strs_tools/src/string/parse_request.rs index e3c68de8f9..9a0d896a2a 100644 --- a/module/core/strs_tools/src/string/parse_request.rs +++ b/module/core/strs_tools/src/string/parse_request.rs @@ -482,14 +482,15 @@ pub( crate ) mod private #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { - #[ allow( unused_imports ) ] - pub use super::orphan::*; - pub use super::private:: + use super::*; + pub use orphan::*; + pub use private:: { OpType, Request, @@ -500,17 +501,21 @@ pub mod protected } /// Parented namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { - pub use super::exposed::*; + use super::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { - pub use super::protected as parse_request; + use super::*; + pub use super::own as parse_request; - pub use super::private:: + pub use private:: { ParseOptionsAdapter, request_parse, @@ -518,7 +523,9 @@ pub mod exposed } /// Namespace of the module to include with `use module::*`. +#[ allow( unused_imports ) ] pub mod prelude { - pub use super::private::ParseOptionsAdapter; + use super::*; + pub use private::ParseOptionsAdapter; } diff --git a/module/core/strs_tools/src/string/split.rs b/module/core/strs_tools/src/string/split.rs index fc9135fdf5..2f2b078eea 100644 --- a/module/core/strs_tools/src/string/split.rs +++ b/module/core/strs_tools/src/string/split.rs @@ -645,14 +645,15 @@ pub( crate ) mod private #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { - #[ allow( unused_imports ) ] - pub use super::orphan::*; - pub use super::private:: + use super::*; + pub use orphan::*; + pub use private:: { Split, SplitType, @@ -664,17 +665,21 @@ pub mod protected } /// Parented namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { - pub use super::exposed::*; + use super::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { - pub use super::protected as split; + use super::*; + pub use super::own as split; - pub use super::private:: + pub use private:: { SplitOptionsAdapter, split, @@ -682,7 +687,9 @@ pub mod exposed } /// Namespace of the module to include with `use module::*`. +#[ allow( unused_imports ) ] pub mod prelude { - pub use super::private::SplitOptionsAdapter; + use super::*; + pub use private::SplitOptionsAdapter; } diff --git a/module/core/strs_tools/tests/smoke_test.rs b/module/core/strs_tools/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/core/strs_tools/tests/smoke_test.rs +++ b/module/core/strs_tools/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/core/test_tools/Cargo.toml b/module/core/test_tools/Cargo.toml index 18c79678fc..3c928e30e1 100644 --- a/module/core/test_tools/Cargo.toml +++ b/module/core/test_tools/Cargo.toml @@ -24,7 +24,7 @@ workspace = true features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] + # = features diff --git a/module/core/test_tools/build.rs b/module/core/test_tools/build.rs index 43860208a5..226b0dd147 100644 --- a/module/core/test_tools/build.rs +++ b/module/core/test_tools/build.rs @@ -13,18 +13,22 @@ fn main() Channel::Stable => { println!("cargo:rustc-cfg=RUSTC_IS_STABLE"); + println!("cargo:rustc-check-cfg=cfg(RUSTC_IS_STABLE)"); } Channel::Beta => { println!("cargo:rustc-cfg=RUSTC_IS_BETA"); + println!("cargo:rustc-check-cfg=cfg(RUSTC_IS_BETA)"); } Channel::Nightly => { println!("cargo:rustc-cfg=RUSTC_IS_NIGHTLY"); + println!("cargo:rustc-check-cfg=cfg(RUSTC_IS_NIGHTLY)"); } Channel::Dev => { println!("cargo:rustc-cfg=RUSTC_IS_DEV"); + println!("cargo:rustc-check-cfg=cfg(RUSTC_IS_DEV)"); } } diff --git a/module/core/test_tools/src/lib.rs b/module/core/test_tools/src/lib.rs index babcb96c49..a5e09fde70 100644 --- a/module/core/test_tools/src/lib.rs +++ b/module/core/test_tools/src/lib.rs @@ -55,7 +55,7 @@ pub mod dependency { // #![ debug ] - protected use super::dependency::*; + own use super::dependency::*; layer test; diff --git a/module/core/test_tools/src/test/asset.rs b/module/core/test_tools/src/test/asset.rs index 929ff1f382..9f4068709f 100644 --- a/module/core/test_tools/src/test/asset.rs +++ b/module/core/test_tools/src/test/asset.rs @@ -42,6 +42,6 @@ crate::mod_interface! // exposed use super; exposed use super::super::asset; - // protected use path_to_exe; + // own use path_to_exe; } diff --git a/module/core/test_tools/src/test/compiletime.rs b/module/core/test_tools/src/test/compiletime.rs index 6b32d232b4..82cde05a1d 100644 --- a/module/core/test_tools/src/test/compiletime.rs +++ b/module/core/test_tools/src/test/compiletime.rs @@ -17,7 +17,7 @@ crate::mod_interface! // xxx : make it working // exposed use super; exposed use super::super::compiletime; - protected use + own use { * }; diff --git a/module/core/test_tools/tests/inc/dynamic/namespace_does_not_exists.stderr b/module/core/test_tools/tests/inc/dynamic/namespace_does_not_exists.stderr index 2c127f9595..167994b68d 100644 --- a/module/core/test_tools/tests/inc/dynamic/namespace_does_not_exists.stderr +++ b/module/core/test_tools/tests/inc/dynamic/namespace_does_not_exists.stderr @@ -10,7 +10,7 @@ error: cannot find macro `tests_index` in this scope 15 | tests_index! | ^^^^^^^^^^^ | -help: consider importing one of these items +help: consider importing one of these macros | 1 + use meta_tools::tests_index; | @@ -23,7 +23,7 @@ error: cannot find macro `tests_impls` in this scope 5 | tests_impls! | ^^^^^^^^^^^ | -help: consider importing one of these items +help: consider importing one of these macros | 1 + use meta_tools::tests_impls; | diff --git a/module/core/test_tools/tests/smoke_test.rs b/module/core/test_tools/tests/smoke_test.rs index 8d83b8d34e..d05a55b089 100644 --- a/module/core/test_tools/tests/smoke_test.rs +++ b/module/core/test_tools/tests/smoke_test.rs @@ -1,5 +1,5 @@ -// #[ cfg( feature = "default" ) ] + #[ cfg( feature = "enabled" ) ] #[ cfg( not( feature = "no_std" ) ) ] #[ test ] @@ -8,7 +8,7 @@ fn local_smoke_test() ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ cfg( feature = "enabled" ) ] #[ cfg( not( feature = "no_std" ) ) ] #[ test ] diff --git a/module/core/time_tools/Cargo.toml b/module/core/time_tools/Cargo.toml index e12847049c..6625bd17ca 100644 --- a/module/core/time_tools/Cargo.toml +++ b/module/core/time_tools/Cargo.toml @@ -24,7 +24,7 @@ workspace = true features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] + # include = [ # "/rust/impl/time", # "/Cargo.toml", diff --git a/module/core/time_tools/src/lib.rs b/module/core/time_tools/src/lib.rs index 9af60e8522..afa8c3a1e7 100644 --- a/module/core/time_tools/src/lib.rs +++ b/module/core/time_tools/src/lib.rs @@ -25,36 +25,39 @@ pub mod dependency { } -/// Protected namespace of the module. +/// Own namespace of the module. #[ cfg( feature = "enabled" ) ] -pub mod protected +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } #[ doc( inline ) ] #[ allow( unused_imports ) ] #[ cfg( feature = "enabled" ) ] -pub use protected::*; +pub use own::*; /// Shared with parent namespace of the module #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ cfg( feature = "time_now" ) ] #[ doc( inline ) ] #[ allow( unused_imports ) ] @@ -63,6 +66,8 @@ pub mod exposed /// Prelude to use essentials: `use my_module::prelude::*`. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; } diff --git a/module/core/time_tools/tests/smoke_test.rs b/module/core/time_tools/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/core/time_tools/tests/smoke_test.rs +++ b/module/core/time_tools/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/core/typing_tools/Cargo.toml b/module/core/typing_tools/Cargo.toml index 22f2d3f982..5b128ba0e5 100644 --- a/module/core/typing_tools/Cargo.toml +++ b/module/core/typing_tools/Cargo.toml @@ -25,7 +25,7 @@ workspace = true features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] + [features] diff --git a/module/core/typing_tools/src/lib.rs b/module/core/typing_tools/src/lib.rs index 0b54e804ec..ce12c46568 100644 --- a/module/core/typing_tools/src/lib.rs +++ b/module/core/typing_tools/src/lib.rs @@ -32,15 +32,16 @@ pub mod dependency #[ doc( inline ) ] #[ allow( unused_imports ) ] #[ cfg( feature = "enabled" ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. +/// Own namespace of the module. #[ cfg( feature = "enabled" ) ] -pub mod protected +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::typing::orphan::*; @@ -48,20 +49,22 @@ pub mod protected /// Orphan namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::typing::exposed::*; @@ -69,8 +72,10 @@ pub mod exposed /// Prelude to use essentials: `use my_module::prelude::*`. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::typing::prelude::*; diff --git a/module/core/typing_tools/src/typing.rs b/module/core/typing_tools/src/typing.rs index 2e434594ae..afbd7973c3 100644 --- a/module/core/typing_tools/src/typing.rs +++ b/module/core/typing_tools/src/typing.rs @@ -1,14 +1,15 @@ #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; #[ cfg( feature = "typing_inspect_type" ) ] #[ doc( inline ) ] #[ allow( unused_imports ) ] @@ -24,19 +25,21 @@ pub mod protected } /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] #[ cfg( feature = "typing_inspect_type" ) ] @@ -52,8 +55,10 @@ pub mod exposed } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ cfg( feature = "typing_inspect_type" ) ] #[ doc( inline ) ] #[ allow( unused_imports ) ] diff --git a/module/core/typing_tools/tests/smoke_test.rs b/module/core/typing_tools/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/core/typing_tools/tests/smoke_test.rs +++ b/module/core/typing_tools/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/core/variadic_from/Cargo.toml b/module/core/variadic_from/Cargo.toml index 3f41686cfe..b09bc75c60 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.19.0" +version = "0.21.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", @@ -24,7 +24,7 @@ workspace = true features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] + [features] diff --git a/module/core/variadic_from/Readme.md b/module/core/variadic_from/Readme.md index c06be02938..1389bf6828 100644 --- a/module/core/variadic_from/Readme.md +++ b/module/core/variadic_from/Readme.md @@ -60,8 +60,8 @@ fn main() dbg!( exp ); //> MyStruct { - //> a: 13, - //> b: 14, + //> a : 13, + //> b : 14, //> } } @@ -127,8 +127,8 @@ fn main() dbg!( exp ); //> MyStruct { - //> a: 13, - //> b: 14, + //> a : 13, + //> b : 14, //> } } diff --git a/module/core/variadic_from/examples/variadic_from_trivial.rs b/module/core/variadic_from/examples/variadic_from_trivial.rs index a1c68018ec..bccf54bacf 100644 --- a/module/core/variadic_from/examples/variadic_from_trivial.rs +++ b/module/core/variadic_from/examples/variadic_from_trivial.rs @@ -45,8 +45,8 @@ fn main() dbg!( exp ); //> MyStruct { - //> a: 13, - //> b: 14, + //> a : 13, + //> b : 14, //> } } diff --git a/module/core/variadic_from/examples/variadic_from_trivial_expanded.rs b/module/core/variadic_from/examples/variadic_from_trivial_expanded.rs index 3f32182add..4ca52fcb56 100644 --- a/module/core/variadic_from/examples/variadic_from_trivial_expanded.rs +++ b/module/core/variadic_from/examples/variadic_from_trivial_expanded.rs @@ -59,8 +59,8 @@ fn main() dbg!( exp ); //> MyStruct { - //> a: 13, - //> b: 14, + //> a : 13, + //> b : 14, //> } } diff --git a/module/core/variadic_from/src/lib.rs b/module/core/variadic_from/src/lib.rs index e05fa1bee2..872ee6acc1 100644 --- a/module/core/variadic_from/src/lib.rs +++ b/module/core/variadic_from/src/lib.rs @@ -12,22 +12,22 @@ pub mod variadic; #[ cfg( feature = "enabled" ) ] pub mod dependency { - #[ cfg( derive_variadic_from ) ] pub use ::derive_tools_meta; } #[ cfg( feature = "enabled" ) ] #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. +/// Own namespace of the module. #[ cfg( feature = "enabled" ) ] -pub mod protected +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::variadic::orphan::*; @@ -35,33 +35,35 @@ pub mod protected /// Orphan namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; - // #[ cfg( any_derive ) ] #[ doc( inline ) ] - #[ allow( unused_imports ) ] pub use ::derive_tools_meta::*; } /// Prelude to use essentials: `use my_module::prelude::*`. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] diff --git a/module/core/variadic_from/src/variadic.rs b/module/core/variadic_from/src/variadic.rs index ed30e42677..0b012b9d22 100644 --- a/module/core/variadic_from/src/variadic.rs +++ b/module/core/variadic_from/src/variadic.rs @@ -373,48 +373,51 @@ pub( crate ) mod private pub use from; } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { }; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { // From_0, diff --git a/module/core/variadic_from/tests/smoke_test.rs b/module/core/variadic_from/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/core/variadic_from/tests/smoke_test.rs +++ b/module/core/variadic_from/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/core/wtools/Cargo.toml b/module/core/wtools/Cargo.toml index 3d2ec71314..8488ccd02b 100644 --- a/module/core/wtools/Cargo.toml +++ b/module/core/wtools/Cargo.toml @@ -25,7 +25,7 @@ features = [ "full" ] all-features = false # rustdoc-args = [] -# exclude = [ "/tests", "/examples", "-*" ] + # = features @@ -173,22 +173,22 @@ string_split = [ "string", "strs_tools/string_split", "strs_tools/string_parse_r error = [ "error_tools" ] error_default = [ "error", - "error_for_lib", - "error_for_app", + "error_typed", + "error_untyped", # "error_use_std", ] error_full = [ "error", - "error_for_lib", - "error_for_app", + "error_typed", + "error_untyped", # "error_use_std", ] # error_use_std = [ "error", "error_tools/use_std" ] error_no_std = [ "error", "error_tools/no_std" ] #error_use_alloc = [ "error", "error_tools/use_alloc" ] -error_for_lib = [ "error", "error_tools/error_for_lib" ] -error_for_app = [ "error", "error_tools/error_for_app" ] +error_typed = [ "error", "error_tools/error_typed" ] +error_untyped = [ "error", "error_tools/error_untyped" ] # derive diff --git a/module/core/wtools/src/lib.rs b/module/core/wtools/src/lib.rs index 6f8412f139..3ea359658d 100644 --- a/module/core/wtools/src/lib.rs +++ b/module/core/wtools/src/lib.rs @@ -50,12 +50,13 @@ pub mod dependency } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; #[ cfg( feature = "iter" ) ] #[ doc( inline ) ] @@ -110,22 +111,24 @@ pub mod protected #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ cfg( feature = "iter" ) ] pub use super::iter::exposed::*; #[ cfg( feature = "meta" ) ] @@ -155,8 +158,10 @@ pub mod exposed } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ cfg( feature = "iter" ) ] #[ doc( inline ) ] #[ allow( unused_imports ) ] diff --git a/module/core/wtools/tests/smoke_test.rs b/module/core/wtools/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/core/wtools/tests/smoke_test.rs +++ b/module/core/wtools/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/move/assistant/Cargo.toml b/module/move/assistant/Cargo.toml new file mode 100644 index 0000000000..6e2af1a870 --- /dev/null +++ b/module/move/assistant/Cargo.toml @@ -0,0 +1,45 @@ +[package] +name = "assistant" +version = "0.1.0" +edition = "2021" +authors = [ + "Kostiantyn Wandalen ", +] +license = "MIT" +readme = "Readme.md" +documentation = "https://docs.rs/assistant" +repository = "https://github.com/Wandalen/wTools/tree/master/module/core/assistant" +homepage = "https://github.com/Wandalen/wTools/tree/master/module/core/assistant" +description = """ +Assist AI in writing code. +""" +categories = [ "algorithms", "development-tools" ] +keywords = [ "fundamental", "general-purpose" ] + +[lints] +workspace = true + +[package.metadata.docs.rs] +features = [ "full" ] +all-features = false + +[features] +default = [ "enabled" ] +full = [ "enabled" ] +enabled = [ + "former/enabled", + "format_tools/enabled", + "reflect_tools/enabled", +] + +[dependencies] +# xxx : qqq : optimze features +former = { workspace = true, features = [ "full" ] } +format_tools = { workspace = true, features = [ "full" ] } +reflect_tools = { workspace = true, features = [ "full" ] } +openai-api-rs = { version = "4.0.9" } +tokio = { version = "1", features = ["full"] } +dotenv = "0.15" + +[dev-dependencies] +test_tools = { workspace = true } diff --git a/module/move/assistant/License b/module/move/assistant/License new file mode 100644 index 0000000000..6d5ef8559f --- /dev/null +++ b/module/move/assistant/License @@ -0,0 +1,22 @@ +Copyright Kostiantyn W and Out of the Box Systems (c) 2013-2024 + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/module/move/assistant/Readme.md b/module/move/assistant/Readme.md new file mode 100644 index 0000000000..0e9402c634 --- /dev/null +++ b/module/move/assistant/Readme.md @@ -0,0 +1,33 @@ + + +# Module :: assistant +[![experimental](https://raster.shields.io/static/v1?label=stability&message=experimental&color=orange&logoColor=eee)](https://github.com/emersion/stability-badges#experimental) [![rust-status](https://github.com/Wandalen/wTools/actions/workflows/ModuleassistantPush.yml/badge.svg)](https://github.com/Wandalen/wTools/actions/workflows/ModuleassistantPush.yml) [![docs.rs](https://img.shields.io/docsrs/assistant?color=e3e8f0&logo=docs.rs)](https://docs.rs/assistant) [![discord](https://img.shields.io/discord/872391416519737405?color=eee&logo=discord&logoColor=eee&label=ask)](https://discord.gg/m3YfbXpUUY) + +Assist AI in writing code. + + diff --git a/module/move/assistant/api/list.http b/module/move/assistant/api/list.http new file mode 100644 index 0000000000..32a3263f5a --- /dev/null +++ b/module/move/assistant/api/list.http @@ -0,0 +1,3 @@ +get https://api.openai.com/v1/models +Authorization: Bearer {{openai_token}} +# Content-Type: application/json diff --git a/module/move/assistant/src/client.rs b/module/move/assistant/src/client.rs new file mode 100644 index 0000000000..03487420dc --- /dev/null +++ b/module/move/assistant/src/client.rs @@ -0,0 +1,96 @@ +//! +//! Client of API. +//! + +/// Internal namespace. +pub( crate ) mod private +{ + + pub use openai_api_rs::v1:: + { + api::Client, + assistant::AssistantObject, + }; + + use std:: + { + env, + error::Error, + }; + + use former::Former; + + /// Options for configuring the OpenAI API client. + #[ derive( Former, Debug ) ] + pub struct ClientOptions + { + /// The API key for authenticating with the OpenAI API. + pub api_key : Option< String >, + } + + /// Creates a new OpenAI API client using the API key from the environment variable `OPENAI_API_KEY`. + pub fn client() -> Result< Client, Box< dyn Error > > + { + let api_key = env::var( "OPENAI_API_KEY" )?; + Ok( Client::new( api_key ) ) + } + + +} + +#[ allow( unused_imports ) ] +pub use own::*; + +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own +{ + use super::*; + + #[ doc( inline ) ] + #[ allow( unused_imports ) ] + pub use orphan::*; + +} + +/// Orphan namespace of the module. +#[ allow( unused_imports ) ] +pub mod orphan +{ + use super::*; + #[ doc( inline ) ] + #[ allow( unused_imports ) ] + pub use exposed::*; +} + +/// Exposed namespace of the module. +#[ allow( unused_imports ) ] +pub mod exposed +{ + use super::*; + + #[ doc( inline ) ] + pub use private:: + { + ClientOptions, + client, + AssistantObject, + }; + + // #[ doc( inline ) ] + // #[ allow( unused_imports ) ] + // pub use reflect_tools:: + // { + // Fields, + // _IteratorTrait, + // IteratorTrait, + // }; + +} + +/// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] +pub mod prelude +{ + use super::*; +} diff --git a/module/move/assistant/src/lib.rs b/module/move/assistant/src/lib.rs new file mode 100644 index 0000000000..8f1345c5aa --- /dev/null +++ b/module/move/assistant/src/lib.rs @@ -0,0 +1,84 @@ +#![ cfg_attr( feature = "no_std", no_std ) ] +#![ 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/assistant/latest/assistant/" ) ] +#![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/", "Readme.md" ) ) ] + + +/// Internal namespace. +pub( crate ) mod private +{ +} + +pub mod client; + +#[ allow( unused_imports ) ] +pub use own::*; + +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own +{ + use super::*; + + #[ doc( inline ) ] + #[ allow( unused_imports ) ] + pub use super:: + { + client::orphan::*, + }; + + #[ doc( inline ) ] + #[ allow( unused_imports ) ] + pub use orphan::*; + +} + +/// Orphan namespace of the module. +#[ allow( unused_imports ) ] +pub mod orphan +{ + use super::*; + #[ doc( inline ) ] + #[ allow( unused_imports ) ] + pub use exposed::*; +} + +/// Exposed namespace of the module. +#[ allow( unused_imports ) ] +pub mod exposed +{ + use super::*; + + #[ doc( inline ) ] + #[ allow( unused_imports ) ] + pub use super:: + { + client::exposed::*, + }; + + #[ doc( inline ) ] + #[ allow( unused_imports ) ] + pub use reflect_tools:: + { + Fields, + _IteratorTrait, + IteratorTrait, + }; + +} + +/// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] +pub mod prelude +{ + use super::*; + + #[ doc( inline ) ] + #[ allow( unused_imports ) ] + pub use super:: + { + client::prelude::*, + }; + +} diff --git a/module/move/assistant/src/main.rs b/module/move/assistant/src/main.rs new file mode 100644 index 0000000000..ad03e3549a --- /dev/null +++ b/module/move/assistant/src/main.rs @@ -0,0 +1,28 @@ +#![ cfg_attr( feature = "no_std", no_std ) ] +#![ 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/assistant/latest/assistant/" ) ] +#![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/", "Readme.md" ) ) ] + +use std:: +{ + env, + error::Error, +}; + +use dotenv::dotenv; + +use assistant:: +{ + client, +}; + +#[ tokio::main ] +async fn main() -> Result< (), Box< dyn Error > > +{ + dotenv().ok(); + let client = client()?; + let assistants = client.list_assistant( None, None, None, None )?; + println!( "Assistants: {:?}", assistants.data ); + Ok( () ) +} diff --git a/module/move/assistant/tests/inc/basic_test.rs b/module/move/assistant/tests/inc/basic_test.rs new file mode 100644 index 0000000000..60c9a81cfb --- /dev/null +++ b/module/move/assistant/tests/inc/basic_test.rs @@ -0,0 +1,7 @@ +#[ allow( unused_imports ) ] +use super::*; + +#[ test ] +fn basic() +{ +} diff --git a/module/blank/willbe_old/tests/willbe_old/_asset/package/License b/module/move/assistant/tests/inc/experiment.rs similarity index 100% rename from module/blank/willbe_old/tests/willbe_old/_asset/package/License rename to module/move/assistant/tests/inc/experiment.rs diff --git a/module/move/assistant/tests/inc/mod.rs b/module/move/assistant/tests/inc/mod.rs new file mode 100644 index 0000000000..0706620c6e --- /dev/null +++ b/module/move/assistant/tests/inc/mod.rs @@ -0,0 +1,6 @@ +#[ allow( unused_imports ) ] +use super::*; + +mod basic_test; + +mod experiment; diff --git a/module/move/assistant/tests/smoke_test.rs b/module/move/assistant/tests/smoke_test.rs new file mode 100644 index 0000000000..663dd6fb9f --- /dev/null +++ b/module/move/assistant/tests/smoke_test.rs @@ -0,0 +1,12 @@ + +#[ test ] +fn local_smoke_test() +{ + ::test_tools::smoke_test_for_local_run(); +} + +#[ test ] +fn published_smoke_test() +{ + ::test_tools::smoke_test_for_published_run(); +} diff --git a/module/move/assistant/tests/tests.rs b/module/move/assistant/tests/tests.rs new file mode 100644 index 0000000000..c94c4d074f --- /dev/null +++ b/module/move/assistant/tests/tests.rs @@ -0,0 +1,10 @@ + +include!( "../../../../module/step/meta/src/module/terminal.rs" ); + +#[ allow( unused_imports ) ] +use assistant as the_module; +#[ allow( unused_imports ) ] +use test_tools::exposed::*; + +#[ cfg( feature = "enabled" ) ] +mod inc; diff --git a/module/move/crates_tools/Cargo.toml b/module/move/crates_tools/Cargo.toml index 4120a358df..fc30f6d9ad 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.10.0" +version = "0.11.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", diff --git a/module/move/crates_tools/src/lib.rs b/module/move/crates_tools/src/lib.rs index 20a89cd7cf..8456839b4f 100644 --- a/module/move/crates_tools/src/lib.rs +++ b/module/move/crates_tools/src/lib.rs @@ -127,40 +127,48 @@ pub( crate ) mod private #[ cfg( feature = "enabled" ) ] #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. +/// Own namespace of the module. #[ cfg( feature = "enabled" ) ] -pub mod protected +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } /// Orphan namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; } /// Prelude to use essentials: `use my_module::prelude::*`. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::private::CrateArchive; + pub use private::CrateArchive; } diff --git a/module/move/crates_tools/tests/smoke_test.rs b/module/move/crates_tools/tests/smoke_test.rs index 781e173398..7827ff5737 100644 --- a/module/move/crates_tools/tests/smoke_test.rs +++ b/module/move/crates_tools/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ ignore ] #[ test ] fn published_smoke_test() diff --git a/module/move/deterministic_rand/Cargo.toml b/module/move/deterministic_rand/Cargo.toml index d0cc6d1fe5..1a469f1249 100644 --- a/module/move/deterministic_rand/Cargo.toml +++ b/module/move/deterministic_rand/Cargo.toml @@ -23,7 +23,7 @@ workspace = true [package.metadata.docs.rs] features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] + [features] default = [ "enabled", "determinism" ] diff --git a/module/move/deterministic_rand/src/lib.rs b/module/move/deterministic_rand/src/lib.rs index bb9a097fe9..b41e465453 100644 --- a/module/move/deterministic_rand/src/lib.rs +++ b/module/move/deterministic_rand/src/lib.rs @@ -21,7 +21,7 @@ pub use hrng_non_deterministic as hrng; mod_interface! { - protected use ::rand::*; + own use ::rand::*; use super::hrng; diff --git a/module/move/graphs_tools/Cargo.toml b/module/move/graphs_tools/Cargo.toml index 64e17ebbd0..f0eeb97831 100644 --- a/module/move/graphs_tools/Cargo.toml +++ b/module/move/graphs_tools/Cargo.toml @@ -23,7 +23,7 @@ workspace = true [package.metadata.docs.rs] features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] + [features] default = [ diff --git a/module/move/graphs_tools/src/lib.rs b/module/move/graphs_tools/src/lib.rs index 0fbf24553d..e171ce3821 100644 --- a/module/move/graphs_tools/src/lib.rs +++ b/module/move/graphs_tools/src/lib.rs @@ -36,7 +36,7 @@ mod_interface! #[ cfg( not( feature = "no_std" ) ) ] layer algo; - protected( crate ) use ::meta_tools::prelude::*; + own use ::meta_tools::prelude::*; } // zzz : implement checks diff --git a/module/move/graphs_tools/tests/smoke_test.rs b/module/move/graphs_tools/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/move/graphs_tools/tests/smoke_test.rs +++ b/module/move/graphs_tools/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/move/optimization_tools/.cargo/config.toml b/module/move/optimization_tools/.cargo/config.toml index ce93c42ac4..ce0792da39 100644 --- a/module/move/optimization_tools/.cargo/config.toml +++ b/module/move/optimization_tools/.cargo/config.toml @@ -1,3 +1,3 @@ [patch.crates-io] -pathfinder_geometry = { git = "https://github.com/servo/pathfinder.git" } -pathfinder_simd = { git = "https://github.com/servo/pathfinder.git" } \ No newline at end of file +pathfinder_geometry = { git = 'https://github.com/pbdeuchler/pathfinder.git', rev = "bd7270b" } +pathfinder_simd = { git = 'https://github.com/pbdeuchler/pathfinder.git', rev = "bd7270b" } \ No newline at end of file diff --git a/module/move/optimization_tools/src/problems/traveling_salesman.rs b/module/move/optimization_tools/src/problems/traveling_salesman.rs index 2eab112158..ec00937ab5 100644 --- a/module/move/optimization_tools/src/problems/traveling_salesman.rs +++ b/module/move/optimization_tools/src/problems/traveling_salesman.rs @@ -98,11 +98,21 @@ pub struct Edge( NodeIndex, NodeIndex, EdgeWeight ); impl Edge { + /// Create new Edge + pub fn new( node1 : NodeIndex, node2 : NodeIndex, weight : EdgeWeight ) -> Self + { + Edge( node1, node2, weight ) + } /// Get weight of the edge. pub fn weight( &self ) -> EdgeWeight { self.2 } + /// Get nodes of the edge + pub fn nodes( &self ) -> ( NodeIndex, NodeIndex ) + { + ( self.0, self.1 ) + } } impl Graph for TSPGraph @@ -127,7 +137,7 @@ impl Graph for TSPGraph { if let Some( ( _, weight ) ) = node_vec.iter().find( | ( n, _ ) | n == node2 ) { - return Some( Edge( *node1, *node2, *weight ) ); + return Some( Edge::new( *node1, *node2, *weight ) ); } } None diff --git a/module/move/optimization_tools/tests/optimization.rs b/module/move/optimization_tools/tests/optimization.rs index 329cfbe213..3f631aced2 100644 --- a/module/move/optimization_tools/tests/optimization.rs +++ b/module/move/optimization_tools/tests/optimization.rs @@ -79,7 +79,6 @@ fn solve_with_sa() 000000013 "#; - let seed : Seed = "seed3".into(); let initial = SudokuInitial::new( Board::from( input ) ); let problem = Problem::new( initial, BestRowsColumnsCrossover, RandomPairInBlockMutation ); let optimizer = HybridOptimizer::new( Config::default(), problem ); diff --git a/module/move/plot_interface/Cargo.toml b/module/move/plot_interface/Cargo.toml index 39ad1ab4f8..655513f31d 100644 --- a/module/move/plot_interface/Cargo.toml +++ b/module/move/plot_interface/Cargo.toml @@ -23,7 +23,7 @@ workspace = true [package.metadata.docs.rs] features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] + include = [ "/rust/impl/_blank", "/Cargo.toml", diff --git a/module/move/plot_interface/src/plot/abs/change.rs b/module/move/plot_interface/src/plot/abs/change.rs index c4ed6fba10..75087410e6 100644 --- a/module/move/plot_interface/src/plot/abs/change.rs +++ b/module/move/plot_interface/src/plot/abs/change.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - use crate::protected::*; + use crate::own::*; /// Context. #[ clone_dyn ] diff --git a/module/move/plot_interface/src/plot/abs/changer.rs b/module/move/plot_interface/src/plot/abs/changer.rs index b3db57d644..b08fab234b 100644 --- a/module/move/plot_interface/src/plot/abs/changer.rs +++ b/module/move/plot_interface/src/plot/abs/changer.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - use crate::protected::*; + use crate::own::*; /// Context. pub trait ChangerInterface diff --git a/module/move/plot_interface/src/plot/abs/context.rs b/module/move/plot_interface/src/plot/abs/context.rs index a168563487..821b2fb123 100644 --- a/module/move/plot_interface/src/plot/abs/context.rs +++ b/module/move/plot_interface/src/plot/abs/context.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - use crate::protected::*; + use crate::own::*; // use crate::abs::*; // use once_cell::sync::Lazy; // use std::sync::Mutex; diff --git a/module/move/plot_interface/src/plot/abs/identity.rs b/module/move/plot_interface/src/plot/abs/identity.rs index 9c44106555..e9fe2b4ab6 100644 --- a/module/move/plot_interface/src/plot/abs/identity.rs +++ b/module/move/plot_interface/src/plot/abs/identity.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - use crate::protected::*; + use crate::own::*; use once_cell::sync::Lazy; use std::sync::Mutex; use core::hash::Hash; diff --git a/module/move/plot_interface/src/plot/abs/registry.rs b/module/move/plot_interface/src/plot/abs/registry.rs index 82a18645a4..a3c640cdd2 100644 --- a/module/move/plot_interface/src/plot/abs/registry.rs +++ b/module/move/plot_interface/src/plot/abs/registry.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - use crate::protected::*; + use crate::own::*; // use crate::abs::*; use once_cell::sync::Lazy; use std::sync::Mutex; diff --git a/module/move/plot_interface/src/plot/color.rs b/module/move/plot_interface/src/plot/color.rs index b41399f253..18bd1c0733 100644 --- a/module/move/plot_interface/src/plot/color.rs +++ b/module/move/plot_interface/src/plot/color.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - use crate::protected::*; + use crate::own::*; use num_traits::{ Zero }; /* zzz : consider as submodule for wtools */ /// Convertable into RGBA. @@ -92,7 +92,7 @@ pub( crate ) mod private crate::mod_interface! { - protected use ::rgb::*; + own use ::rgb::*; #[ cfg( not( feature = "no_std" ) ) ] exposed use Rgba; diff --git a/module/move/plot_interface/src/plot/sys/context.rs b/module/move/plot_interface/src/plot/sys/context.rs index 9b11a3f80a..c47566d47d 100644 --- a/module/move/plot_interface/src/plot/sys/context.rs +++ b/module/move/plot_interface/src/plot/sys/context.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - use crate::protected::*; + use crate::own::*; use crate::abs::*; use once_cell::sync::Lazy; @@ -85,6 +85,6 @@ pub( crate ) mod private crate::mod_interface! { - protected use { REGISTRY, current }; + own use { REGISTRY, current }; exposed use { Context, current as context }; } diff --git a/module/move/plot_interface/src/plot/sys/context_changer.rs b/module/move/plot_interface/src/plot/sys/context_changer.rs index e32452adf9..fe06c75c67 100644 --- a/module/move/plot_interface/src/plot/sys/context_changer.rs +++ b/module/move/plot_interface/src/plot/sys/context_changer.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - use crate::protected::*; + use crate::own::*; /// Context. #[ allow( dead_code ) ] diff --git a/module/move/plot_interface/src/plot/sys/drawing.rs b/module/move/plot_interface/src/plot/sys/drawing.rs index 2efa4e8eaa..20aa9bf26e 100644 --- a/module/move/plot_interface/src/plot/sys/drawing.rs +++ b/module/move/plot_interface/src/plot/sys/drawing.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - use crate::protected::*; + use crate::own::*; /// Drawing. #[ derive( Debug, Clone ) ] diff --git a/module/move/plot_interface/src/plot/sys/drawing/change_new.rs b/module/move/plot_interface/src/plot/sys/drawing/change_new.rs index 08b0125b77..e7d72be5b5 100644 --- a/module/move/plot_interface/src/plot/sys/drawing/change_new.rs +++ b/module/move/plot_interface/src/plot/sys/drawing/change_new.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - use crate::protected::*; + use crate::own::*; /// ChangerInterface of brush stroke. #[ allow( dead_code ) ] diff --git a/module/move/plot_interface/src/plot/sys/drawing/changer.rs b/module/move/plot_interface/src/plot/sys/drawing/changer.rs index eaa2d0c76f..2400ac77a2 100644 --- a/module/move/plot_interface/src/plot/sys/drawing/changer.rs +++ b/module/move/plot_interface/src/plot/sys/drawing/changer.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - use crate::protected::*; + use crate::own::*; /// ChangerInterface of brush stroke. #[ allow( dead_code ) ] diff --git a/module/move/plot_interface/src/plot/sys/drawing/command.rs b/module/move/plot_interface/src/plot/sys/drawing/command.rs index 8108cbcf17..e10b140493 100644 --- a/module/move/plot_interface/src/plot/sys/drawing/command.rs +++ b/module/move/plot_interface/src/plot/sys/drawing/command.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - // use crate::protected::*; + // use crate::own::*; // /// Interface of command to draw something. // pub trait DrawCommandInterface diff --git a/module/move/plot_interface/src/plot/sys/drawing/queue.rs b/module/move/plot_interface/src/plot/sys/drawing/queue.rs index 6b9ba83b3c..06367a519a 100644 --- a/module/move/plot_interface/src/plot/sys/drawing/queue.rs +++ b/module/move/plot_interface/src/plot/sys/drawing/queue.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - // use crate::protected::*; + // use crate::own::*; // use crate::drawing_changer::*; // // /// Queue of draw commands. diff --git a/module/move/plot_interface/src/plot/sys/drawing/rect_change_new.rs b/module/move/plot_interface/src/plot/sys/drawing/rect_change_new.rs index f3ce04bca6..b021be8e07 100644 --- a/module/move/plot_interface/src/plot/sys/drawing/rect_change_new.rs +++ b/module/move/plot_interface/src/plot/sys/drawing/rect_change_new.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - use crate::protected::*; + use crate::own::*; /// Command to draw rectangle. #[ allow( dead_code ) ] diff --git a/module/move/plot_interface/src/plot/sys/drawing/rect_change_region.rs b/module/move/plot_interface/src/plot/sys/drawing/rect_change_region.rs index 163a8309ea..9f3fdc07df 100644 --- a/module/move/plot_interface/src/plot/sys/drawing/rect_change_region.rs +++ b/module/move/plot_interface/src/plot/sys/drawing/rect_change_region.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - use crate::protected::*; + use crate::own::*; /// Command to draw rectangle. #[ allow( dead_code ) ] diff --git a/module/move/plot_interface/src/plot/sys/drawing/rect_changer.rs b/module/move/plot_interface/src/plot/sys/drawing/rect_changer.rs index 3550c4153c..6f7afe8caf 100644 --- a/module/move/plot_interface/src/plot/sys/drawing/rect_changer.rs +++ b/module/move/plot_interface/src/plot/sys/drawing/rect_changer.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - use crate::protected::*; + use crate::own::*; /// Command to draw rectangle. #[ allow( dead_code ) ] diff --git a/module/move/plot_interface/src/plot/sys/stroke_brush.rs b/module/move/plot_interface/src/plot/sys/stroke_brush.rs index 28a88e7aee..d7e451dc95 100644 --- a/module/move/plot_interface/src/plot/sys/stroke_brush.rs +++ b/module/move/plot_interface/src/plot/sys/stroke_brush.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - use crate::protected::*; + use crate::own::*; /// StrokeBrush. #[ derive( Debug, Clone ) ] diff --git a/module/move/plot_interface/src/plot/sys/stroke_brush/change_color.rs b/module/move/plot_interface/src/plot/sys/stroke_brush/change_color.rs index 98d55ffbaa..42a2e6f486 100644 --- a/module/move/plot_interface/src/plot/sys/stroke_brush/change_color.rs +++ b/module/move/plot_interface/src/plot/sys/stroke_brush/change_color.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - use crate::protected::*; + use crate::own::*; /// ChangerInterface of brush stroke. #[ allow( dead_code ) ] diff --git a/module/move/plot_interface/src/plot/sys/stroke_brush/change_new.rs b/module/move/plot_interface/src/plot/sys/stroke_brush/change_new.rs index 86f5ae3914..1ffe548ae5 100644 --- a/module/move/plot_interface/src/plot/sys/stroke_brush/change_new.rs +++ b/module/move/plot_interface/src/plot/sys/stroke_brush/change_new.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - use crate::protected::*; + use crate::own::*; /// ChangerInterface of brush stroke. #[ allow( dead_code ) ] diff --git a/module/move/plot_interface/src/plot/sys/stroke_brush/change_width.rs b/module/move/plot_interface/src/plot/sys/stroke_brush/change_width.rs index 41c86c90e3..991aa2092c 100644 --- a/module/move/plot_interface/src/plot/sys/stroke_brush/change_width.rs +++ b/module/move/plot_interface/src/plot/sys/stroke_brush/change_width.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - use crate::protected::*; + use crate::own::*; /// ChangerInterface of brush stroke. #[ allow( dead_code ) ] diff --git a/module/move/plot_interface/src/plot/sys/stroke_brush/changer.rs b/module/move/plot_interface/src/plot/sys/stroke_brush/changer.rs index c18ebbd4f7..3fdd638da2 100644 --- a/module/move/plot_interface/src/plot/sys/stroke_brush/changer.rs +++ b/module/move/plot_interface/src/plot/sys/stroke_brush/changer.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - use crate::protected::*; + use crate::own::*; /// ChangerInterface of brush stroke. #[ allow( dead_code ) ] diff --git a/module/move/plot_interface/src/plot/wplot_lib.rs b/module/move/plot_interface/src/plot/wplot_lib.rs index 13e61e7dfd..b1d6d6211b 100644 --- a/module/move/plot_interface/src/plot/wplot_lib.rs +++ b/module/move/plot_interface/src/plot/wplot_lib.rs @@ -42,7 +42,7 @@ crate::mod_interface! layer sys; use super::math; - protected use ::wmath as math; + own use ::wmath as math; protected( crate ) use ::wtools::prelude::*; } diff --git a/module/move/plot_interface/tests/smoke_test.rs b/module/move/plot_interface/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/move/plot_interface/tests/smoke_test.rs +++ b/module/move/plot_interface/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/move/refiner/tests/smoke_test.rs b/module/move/refiner/tests/smoke_test.rs index 7853994b3a..3499e82321 100644 --- a/module/move/refiner/tests/smoke_test.rs +++ b/module/move/refiner/tests/smoke_test.rs @@ -1,5 +1,5 @@ -// #[ cfg( feature = "default" ) ] + #[ ignore ] #[ test ] fn local_smoke_test() @@ -7,7 +7,7 @@ fn local_smoke_test() ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/move/sqlx_query/Cargo.toml b/module/move/sqlx_query/Cargo.toml index 08a3ff8a98..fbccba1f74 100644 --- a/module/move/sqlx_query/Cargo.toml +++ b/module/move/sqlx_query/Cargo.toml @@ -21,7 +21,7 @@ workspace = true [package.metadata.docs.rs] features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] + [features] default = [ "enabled" ] diff --git a/module/move/sqlx_query/src/lib.rs b/module/move/sqlx_query/src/lib.rs index 1285b5a3de..46aeccb400 100644 --- a/module/move/sqlx_query/src/lib.rs +++ b/module/move/sqlx_query/src/lib.rs @@ -92,39 +92,47 @@ pub( crate ) mod private #[ cfg( feature = "enabled" ) ] #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. +/// Own namespace of the module. #[ cfg( feature = "enabled" ) ] -pub mod protected +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } /// Orphan namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; } /// Prelude to use essentials: `use my_module::prelude::*`. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::query; diff --git a/module/move/sqlx_query/tests/smoke_test.rs b/module/move/sqlx_query/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/move/sqlx_query/tests/smoke_test.rs +++ b/module/move/sqlx_query/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/move/unitore/src/action/config.rs b/module/move/unitore/src/action/config.rs index fae3bcf67d..9dfc356fe0 100644 --- a/module/move/unitore/src/action/config.rs +++ b/module/move/unitore/src/action/config.rs @@ -3,7 +3,7 @@ use std::path::PathBuf; use crate::*; -use error_tools::{ for_app::Context, Result }; +use error_tools::{ untyped::Context, untyped::Result }; use sled_adapter::FeedStorage; use entity:: { @@ -37,7 +37,7 @@ pub async fn config_add( mut storage : FeedStorage< SledStorage >, path : &PathB if !path.exists() { - return Err( error_tools::for_app::Error::msg( err_str ) ); + return Err( error_tools::untyped::Error::msg( err_str ) ); } let abs_path = path.canonicalize()?; diff --git a/module/move/unitore/src/action/feed.rs b/module/move/unitore/src/action/feed.rs index 70063de854..6ef23cc1ab 100644 --- a/module/move/unitore/src/action/feed.rs +++ b/module/move/unitore/src/action/feed.rs @@ -4,7 +4,7 @@ use crate::*; use action::{ Report, frame::SelectedEntries }; use sled_adapter::FeedStorage; use entity::feed::FeedStore; -use error_tools::Result; +use error_tools::untyped::Result; /// List all feeds from storage. pub async fn feeds_list( mut storage : FeedStorage< gluesql::sled_storage::SledStorage > ) -> Result< impl Report > diff --git a/module/move/unitore/src/action/frame.rs b/module/move/unitore/src/action/frame.rs index 2acb4cd168..fc23b10683 100644 --- a/module/move/unitore/src/action/frame.rs +++ b/module/move/unitore/src/action/frame.rs @@ -10,7 +10,7 @@ use entity:: }; use gluesql::prelude::{ Payload, Value, SledStorage }; use feed_config; -use error_tools::{ err, Result }; +use error_tools::{ err, untyped::Result }; use action::Report; // qqq : review the whole project and make sure all names are consitant: actions, commands, its tests diff --git a/module/move/unitore/src/action/query.rs b/module/move/unitore/src/action/query.rs index d9f4180384..f3de3beefe 100644 --- a/module/move/unitore/src/action/query.rs +++ b/module/move/unitore/src/action/query.rs @@ -6,7 +6,7 @@ use crate::*; use gluesql::core::executor::Payload; use sled_adapter::Store; use action::Report; -use error_tools::Result; +use error_tools::untyped::Result; /// Execute query specified in query string. pub async fn query_execute diff --git a/module/move/unitore/src/action/table.rs b/module/move/unitore/src/action/table.rs index ce9a4e756f..03a4b0da06 100644 --- a/module/move/unitore/src/action/table.rs +++ b/module/move/unitore/src/action/table.rs @@ -6,7 +6,7 @@ use std::collections::HashMap; use action::Report; use sled_adapter::FeedStorage; use entity::table::TableStore; -use error_tools::Result; +use error_tools::untyped::Result; /// Get labels of column for specified table. pub async fn table_list diff --git a/module/move/unitore/src/command/config.rs b/module/move/unitore/src/command/config.rs index 72eb063007..bbd436ccb9 100644 --- a/module/move/unitore/src/command/config.rs +++ b/module/move/unitore/src/command/config.rs @@ -7,7 +7,7 @@ use gluesql::sled_storage::sled::Config; use wca::{ Command, Type, VerifiedCommand }; use sled_adapter::FeedStorage; use action::{ Report, config::{ config_add, config_delete, config_list } }; -use error_tools::Result; +use error_tools::untyped::Result; /// Struct that provides commands for config files. #[ derive( Debug ) ] diff --git a/module/move/unitore/src/command/feed.rs b/module/move/unitore/src/command/feed.rs index 148d404952..b6aeaccd0a 100644 --- a/module/move/unitore/src/command/feed.rs +++ b/module/move/unitore/src/command/feed.rs @@ -5,7 +5,7 @@ use gluesql::sled_storage::sled::Config; use wca::{ Command, VerifiedCommand }; use sled_adapter::FeedStorage; use action::{ Report, feed::feeds_list }; -use error_tools::Result; +use error_tools::untyped::Result; /// Struct that provides commands for feed. #[ derive( Debug ) ] diff --git a/module/move/unitore/src/command/frame.rs b/module/move/unitore/src/command/frame.rs index 8a4f18a756..230a704cfa 100644 --- a/module/move/unitore/src/command/frame.rs +++ b/module/move/unitore/src/command/frame.rs @@ -5,7 +5,7 @@ use gluesql::sled_storage::sled::Config; use wca::{ Command, VerifiedCommand }; use sled_adapter::FeedStorage; use action::{ Report, frame::{ frames_list, frames_download } }; -use error_tools::Result; +use error_tools::untyped::Result; /// Struct that provides commands for frames. #[ derive( Debug ) ] diff --git a/module/move/unitore/src/command/query.rs b/module/move/unitore/src/command/query.rs index 24519e1a86..67a76dffed 100644 --- a/module/move/unitore/src/command/query.rs +++ b/module/move/unitore/src/command/query.rs @@ -5,7 +5,7 @@ use gluesql::sled_storage::sled::Config; use wca::{ Command, Type, VerifiedCommand }; use sled_adapter::FeedStorage; use action::{ Report, query::query_execute }; -use error_tools::Result; +use error_tools::untyped::Result; /// Struct that provides commands for queries. #[ derive( Debug ) ] diff --git a/module/move/unitore/src/command/table.rs b/module/move/unitore/src/command/table.rs index 67c82f23a0..29f971695b 100644 --- a/module/move/unitore/src/command/table.rs +++ b/module/move/unitore/src/command/table.rs @@ -5,7 +5,7 @@ use gluesql::sled_storage::sled::Config; use wca::{ Command, Type, VerifiedCommand }; use sled_adapter::FeedStorage; use action::{ Report, table::{ table_list, tables_list } }; -use error_tools::Result; +use error_tools::untyped::Result; /// Struct that provides commands for table information. #[ derive( Debug ) ] diff --git a/module/move/unitore/src/entity/config.rs b/module/move/unitore/src/entity/config.rs index b28a90a1dc..92f9f550d6 100644 --- a/module/move/unitore/src/entity/config.rs +++ b/module/move/unitore/src/entity/config.rs @@ -1,6 +1,6 @@ //! Functionality for storing and retrieving config files. -use error_tools::Result; +use error_tools::untyped::Result; use gluesql::core::executor::Payload; /// Config file path. diff --git a/module/move/unitore/src/entity/feed.rs b/module/move/unitore/src/entity/feed.rs index 7084e841dd..449627e7ff 100644 --- a/module/move/unitore/src/entity/feed.rs +++ b/module/move/unitore/src/entity/feed.rs @@ -2,7 +2,7 @@ use crate::*; use std::time::Duration; -use error_tools::Result; +use error_tools::untyped::Result; use gluesql::core:: { ast_builder::{ null, text, timestamp, ExprNode }, diff --git a/module/move/unitore/src/entity/frame.rs b/module/move/unitore/src/entity/frame.rs index 8fb522ad58..23bc76718d 100644 --- a/module/move/unitore/src/entity/frame.rs +++ b/module/move/unitore/src/entity/frame.rs @@ -1,7 +1,7 @@ //! Frame storing and retrieving functionality. use crate::*; -use error_tools::Result; +use error_tools::untyped::Result; use gluesql::core:: { ast_builder::{ null, text, timestamp, ExprNode }, chrono::{ DateTime, SecondsFormat, Utc }, executor::Payload diff --git a/module/move/unitore/src/entity/table.rs b/module/move/unitore/src/entity/table.rs index b177c3c934..c0e5eb62b2 100644 --- a/module/move/unitore/src/entity/table.rs +++ b/module/move/unitore/src/entity/table.rs @@ -1,7 +1,7 @@ //! Functionality for storage tables information. use crate::*; -use error_tools::Result; +use error_tools::untyped::Result; use gluesql::prelude::Payload; use action::table::TablesReport; diff --git a/module/move/unitore/src/executor.rs b/module/move/unitore/src/executor.rs index 8010dbd9cc..c3cb899854 100644 --- a/module/move/unitore/src/executor.rs +++ b/module/move/unitore/src/executor.rs @@ -2,7 +2,7 @@ use crate::*; use wca::{ Dictionary, Executor, Parser, Verifier }; -use error_tools::Result; +use error_tools::untyped::Result; /// Run feed updates. pub fn execute() -> Result< (), Box< dyn std::error::Error + Send + Sync > > diff --git a/module/move/unitore/src/feed_config.rs b/module/move/unitore/src/feed_config.rs index 88b5f8a791..d792c96fc1 100644 --- a/module/move/unitore/src/feed_config.rs +++ b/module/move/unitore/src/feed_config.rs @@ -1,7 +1,7 @@ //! Reading and parsing of subscription configuration file. use std::{ fs::OpenOptions, io::{ BufReader, Read } }; -use error_tools::{ for_app::Context, Result }; +use error_tools::{ untyped::Context, untyped::Result }; use serde::Deserialize; /// Configuration for subscription to feed resource. diff --git a/module/move/unitore/src/retriever.rs b/module/move/unitore/src/retriever.rs index ac4e94be11..203789ca5b 100644 --- a/module/move/unitore/src/retriever.rs +++ b/module/move/unitore/src/retriever.rs @@ -9,7 +9,7 @@ use hyper_util:: use http_body_util::{ Empty, BodyExt }; use hyper::body::Bytes; use feed_rs::parser as feed_parser; -use error_tools::{ Result, for_app::Context }; +use error_tools::{ untyped::Result, untyped::Context }; // qqq : purpose of trait if any? // aaa : removed unnecessary trait diff --git a/module/move/unitore/src/sled_adapter/config.rs b/module/move/unitore/src/sled_adapter/config.rs index a3b0cc73d8..a873c229df 100644 --- a/module/move/unitore/src/sled_adapter/config.rs +++ b/module/move/unitore/src/sled_adapter/config.rs @@ -1,7 +1,7 @@ //! Config file operation with Sled storage. use crate::*; -use error_tools::{ err, Result }; +use error_tools::{ err, untyped::Result }; use gluesql:: { core:: diff --git a/module/move/unitore/src/sled_adapter/feed.rs b/module/move/unitore/src/sled_adapter/feed.rs index fb38e02075..fda59782bb 100644 --- a/module/move/unitore/src/sled_adapter/feed.rs +++ b/module/move/unitore/src/sled_adapter/feed.rs @@ -2,7 +2,7 @@ use crate::*; use std::time::Duration; -use error_tools::{ Result, for_app::Context }; +use error_tools::{ untyped::Result, untyped::Context }; use gluesql:: { core:: @@ -25,7 +25,7 @@ use action:: frame::{ UpdateReport, SelectedEntries, FramesReport }, }; use sled_adapter::FeedStorage; -use wca::wtools::Itertools; +use wca::iter_tools::Itertools; #[ async_trait::async_trait( ?Send ) ] impl FeedStore for FeedStorage< SledStorage > @@ -38,7 +38,7 @@ impl FeedStore for FeedStorage< SledStorage > .execute( &mut *self.0.lock().await ) .await? ; - + let mut report = FeedsReport::new(); match res { diff --git a/module/move/unitore/src/sled_adapter/frame.rs b/module/move/unitore/src/sled_adapter/frame.rs index 84d4687bf4..9bdaf2792d 100644 --- a/module/move/unitore/src/sled_adapter/frame.rs +++ b/module/move/unitore/src/sled_adapter/frame.rs @@ -2,7 +2,7 @@ use crate::*; use std::collections::HashMap; -use error_tools::{ Result, for_app::Context }; +use error_tools::{ untyped::Result, untyped::Context }; use gluesql:: { core:: @@ -16,7 +16,7 @@ use gluesql:: use entity::frame::{ FrameStore, Frame }; use action::frame::{ SelectedEntries, FramesReport, ListReport }; use sled_adapter::FeedStorage; -use wca::wtools::Itertools; +use wca::iter_tools::Itertools; #[ async_trait::async_trait( ?Send ) ] impl FrameStore for FeedStorage< SledStorage > @@ -26,7 +26,7 @@ impl FrameStore for FeedStorage< SledStorage > let res = table( "frame" ).select().execute( &mut *self.0.lock().await ).await?; let mut reports = Vec::new(); - let all_frames = + let all_frames = if let Payload::Select { labels: label_vec, rows: rows_vec } = res { SelectedEntries @@ -39,7 +39,7 @@ impl FrameStore for FeedStorage< SledStorage > { SelectedEntries::new() }; - + let mut feeds_map = HashMap::new(); for row in all_frames.selected_rows diff --git a/module/move/unitore/src/sled_adapter/mod.rs b/module/move/unitore/src/sled_adapter/mod.rs index ac4780a6f1..9c63972e9e 100644 --- a/module/move/unitore/src/sled_adapter/mod.rs +++ b/module/move/unitore/src/sled_adapter/mod.rs @@ -2,7 +2,7 @@ use crate::*; use std::sync::Arc; -use error_tools::{ for_app::Context, Result }; +use error_tools::{ untyped::Context, untyped::Result }; use tokio::sync::Mutex; use gluesql:: { diff --git a/module/move/unitore/src/sled_adapter/table.rs b/module/move/unitore/src/sled_adapter/table.rs index 71763918ee..8acfd1001e 100644 --- a/module/move/unitore/src/sled_adapter/table.rs +++ b/module/move/unitore/src/sled_adapter/table.rs @@ -1,7 +1,7 @@ //! Table and columns info operations from Sled storage. use crate::*; -use error_tools::Result; +use error_tools::untyped::Result; use gluesql:: { core::executor::Payload, diff --git a/module/move/unitore/tests/basic.rs b/module/move/unitore/tests/basic.rs index 6e5df1ad4d..c14f8f278b 100644 --- a/module/move/unitore/tests/basic.rs +++ b/module/move/unitore/tests/basic.rs @@ -1,5 +1,5 @@ use feed_rs::parser as feed_parser; -use error_tools::Result; +use error_tools::untyped::Result; #[ tokio::test ] async fn frame() -> Result< () > diff --git a/module/move/unitore/tests/config_add.rs b/module/move/unitore/tests/config_add.rs index 455a77dbd4..7f080622b8 100644 --- a/module/move/unitore/tests/config_add.rs +++ b/module/move/unitore/tests/config_add.rs @@ -6,7 +6,7 @@ use unitore:: entity::feed::FeedStore, action::config, }; -use error_tools::Result; +use error_tools::untyped::Result; #[ tokio::test ] async fn config_add() -> Result< () > diff --git a/module/move/unitore/tests/config_delete.rs b/module/move/unitore/tests/config_delete.rs index 63a792725e..9a7ffdf10a 100644 --- a/module/move/unitore/tests/config_delete.rs +++ b/module/move/unitore/tests/config_delete.rs @@ -9,7 +9,7 @@ use unitore:: entity::config::ConfigStore, action::config, }; -use error_tools::Result; +use error_tools::untyped::Result; #[ tokio::test ] async fn config_delete() -> Result< () > diff --git a/module/move/unitore/tests/frames_download.rs b/module/move/unitore/tests/frames_download.rs index ae8119a71d..11494838f9 100644 --- a/module/move/unitore/tests/frames_download.rs +++ b/module/move/unitore/tests/frames_download.rs @@ -8,14 +8,14 @@ use gluesql:: }, sled_storage::sled::Config, }; -use wca::wtools::Itertools; +use wca::iter_tools::Itertools; use unitore:: { feed_config::SubscriptionConfig, sled_adapter::FeedStorage, entity::{ frame::FrameStore, feed::FeedStore }, }; -use error_tools::Result; +use error_tools::untyped::Result; #[ tokio::test ] async fn test_save() -> Result< () > diff --git a/module/move/unitore/tests/query_execute.rs b/module/move/unitore/tests/query_execute.rs index 7741575322..4215971781 100644 --- a/module/move/unitore/tests/query_execute.rs +++ b/module/move/unitore/tests/query_execute.rs @@ -14,7 +14,7 @@ use gluesql:: sled_storage::sled, }; use wca::{ VerifiedCommand, CommandsAggregator, Type, Parser, Dictionary, Verifier, Executor }; -use error_tools::Result; +use error_tools::untyped::Result; use mockall::predicate; use std::path::PathBuf; diff --git a/module/move/unitore/tests/table_list.rs b/module/move/unitore/tests/table_list.rs index 188d1a3131..ff06deae00 100644 --- a/module/move/unitore/tests/table_list.rs +++ b/module/move/unitore/tests/table_list.rs @@ -8,7 +8,7 @@ use unitore:: sled_adapter::FeedStorage, entity::table::TableStore, }; -use error_tools::Result; +use error_tools::untyped::Result; #[ tokio::test ] async fn table_list() -> Result< () > diff --git a/module/move/unitore/tests/tables_list.rs b/module/move/unitore/tests/tables_list.rs index 0972041704..f740e94b08 100644 --- a/module/move/unitore/tests/tables_list.rs +++ b/module/move/unitore/tests/tables_list.rs @@ -4,7 +4,7 @@ use unitore:: sled_adapter::FeedStorage, entity::table::TableStore, }; -use error_tools::Result; +use error_tools::untyped::Result; #[ tokio::test ] async fn tables_list() -> Result< () > diff --git a/module/move/wca/Cargo.toml b/module/move/wca/Cargo.toml index 7489b66fbb..9a109310a0 100644 --- a/module/move/wca/Cargo.toml +++ b/module/move/wca/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wca" -version = "0.18.0" +version = "0.19.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", @@ -45,6 +45,7 @@ strs_tools = { workspace = true, features = [ "default" ] } mod_interface = { workspace = true, features = [ "default" ] } iter_tools = { workspace = true, features = [ "default" ] } former = { workspace = true, features = [ "default" ] } +# xxx : qqq : optimize set of features ## external log = "0.4" diff --git a/module/move/wca/examples/wca_fluent.rs b/module/move/wca/examples/wca_fluent.rs index cf60d4000c..487d6ee97d 100644 --- a/module/move/wca/examples/wca_fluent.rs +++ b/module/move/wca/examples/wca_fluent.rs @@ -7,7 +7,7 @@ //! -use wca::{ Context, Type, VerifiedCommand }; +use wca::{ Context, Handler, Type, VerifiedCommand }; use std::sync::{ Arc, Mutex }; fn main() @@ -38,7 +38,10 @@ fn main() .end() .command( "exit" ) .hint( "just exit" ) - .routine( || { println!( "exit" ); std::process::exit( 0 ) } ) + .routine( Handler::< _, std::convert::Infallible >::from + ( + || { println!( "exit" ); std::process::exit( 0 ) } + ) ) .end() .perform(); diff --git a/module/move/wca/src/ca/aggregator.rs b/module/move/wca/src/ca/aggregator.rs index 1d81a4e945..7f9c92e287 100644 --- a/module/move/wca/src/ca/aggregator.rs +++ b/module/move/wca/src/ca/aggregator.rs @@ -15,17 +15,21 @@ pub( crate ) mod private help::{ HelpGeneratorFn, HelpGeneratorOptions, HelpVariants }, }; + // qqq : group uses use std::collections::HashSet; use std::fmt; use former::StoragePreform; - use wtools::thiserror; - use wtools::error:: + // use wtools:: + // { + // }; + // use wtools::thiserror; + use error:: { - Result, - for_app::Error as wError, + // Result, + untyped::Error as wError, // xxx for_lib::*, }; - use wtools::Itertools; + use iter_tools::Itertools; /// Order of commands and properties. #[ derive( Debug, Default, Clone, Copy, Eq, PartialOrd, PartialEq ) ] diff --git a/module/move/wca/src/ca/executor/executor.rs b/module/move/wca/src/ca/executor/executor.rs index 1ba7ce66a4..ca491a3fc3 100644 --- a/module/move/wca/src/ca/executor/executor.rs +++ b/module/move/wca/src/ca/executor/executor.rs @@ -2,8 +2,8 @@ pub( crate ) mod private { use crate::*; - use wtools::error::Result; - use error_tools::return_err; + // use wtools::error::Result; + use error::return_err; use ca::help::private::{ HelpGeneratorOptions, LevelOfDetail, generate_help_content }; // aaa : for Bohdan : how is it useful? where is it used? @@ -34,9 +34,11 @@ pub( crate ) mod private /// /// # Returns /// - /// A `Result` with `Ok(())` if the execution was successful, or an `Err` containing an error message if an error occurred. + /// A `Result` with `Ok( () )` if the execution was successful, or an `Err` containing an error message if an error occurred. /// - pub fn program( &self, dictionary : &Dictionary, program : Program< VerifiedCommand > ) -> Result< () > + // qqq : use typed error + pub fn program( &self, dictionary : &Dictionary, program : Program< VerifiedCommand > ) + -> error::untyped::Result< () > { for command in program.commands { @@ -58,7 +60,9 @@ pub( crate ) mod private /// # Returns /// /// Returns a Result indicating success or failure. If successful, returns `Ok(())`, otherwise returns an error. - pub fn command( &self, dictionary : &Dictionary, command : VerifiedCommand ) -> Result< () > + // qqq : use typed error + pub fn command( &self, dictionary : &Dictionary, command : VerifiedCommand ) + -> error::untyped::Result< () > { if command.internal_command { @@ -70,12 +74,14 @@ pub( crate ) mod private _exec_command( command, routine, self.context.clone() ) } } - + // aaa : for Bohdan : probably redundant // aaa : removed `parallel_execution_loop` } - - fn _exec_command( command : VerifiedCommand, routine : Routine, ctx : Context ) -> Result< () > + + // qqq : use typed error + fn _exec_command( command : VerifiedCommand, routine : Routine, ctx : Context ) + -> error::untyped::Result< () > { match routine { @@ -83,8 +89,10 @@ pub( crate ) mod private Routine::WithContext( routine ) => routine( ctx, command ), } } - - fn _exec_internal_command( dictionary : &Dictionary, command : VerifiedCommand ) -> Result< () > + + // qqq : use typed error + fn _exec_internal_command( dictionary : &Dictionary, command : VerifiedCommand ) + -> error::untyped::Result< () > { match command.phrase.as_str() { @@ -93,7 +101,7 @@ pub( crate ) mod private let generator_args = HelpGeneratorOptions::former() .command_prefix( "." ) .form(); - + let content = generate_help_content( dictionary, generator_args ); println!( "{content}" ); } @@ -104,7 +112,7 @@ pub( crate ) mod private .subject_detailing( LevelOfDetail::Simple ) .property_detailing( LevelOfDetail::Simple ) .form(); - + let content = generate_help_content( dictionary, generator_args ); println!( "{content}" ); } @@ -137,7 +145,7 @@ pub( crate ) mod private .property_detailing( LevelOfDetail::Simple ) .with_footer( true ) .form(); - + let content = generate_help_content( dictionary, generator_args ); println!( "{content}" ); } @@ -148,7 +156,7 @@ pub( crate ) mod private } unexpected => return_err!( "Encountered an unrecognized internal command: `.{}`.", unexpected ), } - + Ok( () ) } } diff --git a/module/move/wca/src/ca/executor/routine.rs b/module/move/wca/src/ca/executor/routine.rs index 9165c4486a..1435910138 100644 --- a/module/move/wca/src/ca/executor/routine.rs +++ b/module/move/wca/src/ca/executor/routine.rs @@ -2,11 +2,13 @@ pub( crate ) mod private { use crate::*; + // qqq : group + use std::collections::HashMap; - use wtools::error::Result; + // use wtools::error::Result; use std::{ fmt::Formatter, rc::Rc }; - use wtools::anyhow::anyhow; + // use wtools::anyhow::anyhow; /// Command Args /// @@ -129,13 +131,14 @@ pub( crate ) mod private // aaa : make 0-arguments, 1-argument, 2-arguments, 3 arguments versions // aaa : done. now it works with the following variants: // fn(), fn(args), fn(props), fn(args, props), fn(context), fn(context, args), fn(context, props), fn(context, args, props) - - type RoutineWithoutContextFn = dyn Fn( VerifiedCommand ) -> Result< () >; - type RoutineWithContextFn = dyn Fn( Context, VerifiedCommand ) -> Result< () >; + + // qqq : why not public? + type RoutineWithoutContextFn = dyn Fn( VerifiedCommand ) -> error::untyped::Result< () >; + type RoutineWithContextFn = dyn Fn( Context, VerifiedCommand ) -> error::untyped::Result< () >; /// /// Routine handle. - /// + /// /// ``` /// # use wca::{ Handler, Routine }; /// let routine = Routine::from( Handler::from @@ -228,7 +231,7 @@ pub( crate ) mod private where I : 'static, O : IntoResult + 'static, - Routine : From< Box< dyn Fn( I ) -> Result< () > > >, + Routine : From< Box< dyn Fn( I ) -> error::untyped::Result< () > > >, { fn from( value : Handler< I, O > ) -> Self { @@ -264,34 +267,34 @@ pub( crate ) mod private } // without context - impl From< Box< dyn Fn( () ) -> Result< () > > > for Routine + impl From< Box< dyn Fn( () ) -> error::untyped::Result< () > > > for Routine { - fn from( value : Box< dyn Fn( () ) -> Result< () > > ) -> Self + fn from( value : Box< dyn Fn( () ) -> error::untyped::Result< () > > ) -> Self { Self::WithoutContext( Rc::new( move | _ | { value( () )?; Ok( () ) } ) ) } } - - impl From< Box< dyn Fn( VerifiedCommand ) -> Result< () > > > for Routine + + impl From< Box< dyn Fn( VerifiedCommand ) -> error::untyped::Result< () > > > for Routine { - fn from( value : Box< dyn Fn( VerifiedCommand ) -> Result< () > > ) -> Self + fn from( value : Box< dyn Fn( VerifiedCommand ) -> error::untyped::Result< () > > ) -> Self { Self::WithoutContext( Rc::new( move | a | { value( a )?; Ok( () ) } ) ) } } // with context - impl From< Box< dyn Fn( Context ) -> Result< () > > > for Routine + impl From< Box< dyn Fn( Context ) -> error::untyped::Result< () > > > for Routine { - fn from( value : Box< dyn Fn( Context ) -> Result< () > > ) -> Self + fn from( value : Box< dyn Fn( Context ) -> error::untyped::Result< () > > ) -> Self { Self::WithContext( Rc::new( move | ctx, _ | { value( ctx )?; Ok( () ) } ) ) } } - impl From< Box< dyn Fn(( Context, VerifiedCommand )) -> Result< () > > > for Routine + impl From< Box< dyn Fn(( Context, VerifiedCommand )) -> error::untyped::Result< () > > > for Routine { - fn from( value : Box< dyn Fn(( Context, VerifiedCommand )) -> Result< () > > ) -> Self + fn from( value : Box< dyn Fn(( Context, VerifiedCommand )) -> error::untyped::Result< () > > ) -> Self { Self::WithContext( Rc::new( move | ctx, a | { value(( ctx, a ))?; Ok( () ) } ) ) } @@ -320,12 +323,21 @@ pub( crate ) mod private trait IntoResult { - fn into_result( self ) -> Result< () >; + fn into_result( self ) -> error::untyped::Result< () >; } - impl IntoResult for std::convert::Infallible { fn into_result( self ) -> Result< () > { Ok( () ) } } - impl IntoResult for () { fn into_result( self ) -> Result< () > { Ok( () ) } } - impl< E : std::fmt::Debug > IntoResult for Result< (), E > { fn into_result( self ) -> Result< () > { self.map_err( | e | anyhow!( "{e:?}" )) } } + // xxx + impl IntoResult for std::convert::Infallible { fn into_result( self ) -> error::untyped::Result< () > { Ok( () ) } } + impl IntoResult for () { fn into_result( self ) -> error::untyped::Result< () > { Ok( () ) } } + impl< E : std::fmt::Debug > IntoResult + for error::untyped::Result< (), E > + { + fn into_result( self ) -> error::untyped::Result< () > + { + self.map_err( | e | error::untyped::format_err!( "{e:?}" )) + // xxx : qqq : ? + } + } } // diff --git a/module/move/wca/src/ca/facade.rs b/module/move/wca/src/ca/facade.rs index cdc9edb599..e63158f59f 100644 --- a/module/move/wca/src/ca/facade.rs +++ b/module/move/wca/src/ca/facade.rs @@ -1,345 +1,345 @@ -pub( crate ) mod private -{ - use crate::*; - use core::fmt; - use ca::grammar; - - /// Macro for parsing WCA arguments. - /// - /// # Examples - /// ```rust - /// use wca::Value; - /// - /// let mut args = vec![ Value::Number( 42. ), Value::String( "Rust".into() ) ].into_iter(); - /// wca::parse_args!( args, n : f64, name : String ); - /// - /// assert_eq!( n, 42. ); - /// assert_eq!( name, "Rust" ); - /// ``` - #[macro_export] - macro_rules! parse_args - { - ( $args : ident, mut $b : ident : $ty : ident $( $rest : tt )* ) => - { - let mut $b : $ty = std::convert::TryFrom::try_from( $args.next().unwrap() ).unwrap(); - $crate::parse_args!( $args $( $rest )* ) - }; - ( $args : ident, $b : ident : $ty : ident $( $rest : tt )* ) => - { - let $b : $ty = std::convert::TryFrom::try_from( $args.next().unwrap() ).unwrap(); - $crate::parse_args!( $args $( $rest )* ) - }; - ( $args : ident, $b : ident $( $rest : tt )* ) => - { - let $b = $args.next().unwrap(); - $crate::parse_args!( $args $( $rest )* ) - }; - ( $args : ident, mut $b : ident $( $rest : tt )* ) => - { - let mut $b = $args.next().unwrap(); - $crate::parse_args!( $args $( $rest )* ) - }; - ( $args : ident ) => - { - assert!( $args.next().is_none() ); - }; - ( $args : ident, ) => - { - $crate::parse_args!( $args ) - }; - } - - /// Creates a command-line interface (CLI) builder with the given initial state. - /// - /// This function initializes a `CommandBuilder` with the provided `state` and - /// returns it for further configuration of the CLI. - pub fn cui< T >( state : T ) -> CommandBuilder< T > - { - CommandBuilder::with_state( state ) - } - - /// A struct representing a property. - #[ derive( Debug, Clone ) ] - pub struct Property< 'a > - { - /// The name of the property. - pub name : &'a str, - /// The hint for the property. - pub debug : &'a str, - /// The tag representing the property's type. - pub tag : Type, - } - - impl< 'a > Property< 'a > - { - /// Constructor of a property. - pub fn new( name : &'a str, hint : &'a str, tag : Type ) -> Self { Self { name, hint, tag } } - } - - /// A builder struct for constructing commands. - #[ derive( Debug ) ] - pub struct CommandBuilder< T > - { - state : T, - commands : Vec< Command >, - handlers : std::collections::HashMap< String, Routine >, - } - - impl< T > CommandBuilder< T > - { - /// Constructs a `CommandBuilder` with the given state. - pub fn with_state( state : T ) -> Self - { - Self { state, handlers : < _ >::default(), commands : vec![] } - } - } - - #[ derive( Debug ) ] - pub struct Builder< F > - { - handler : F, - command : Command, - } - - impl< F > Builder< F > - { - /// Creates a new instance of the command with the provided handler function. - /// - /// This method takes in a handler function `handler` and creates a new instance of the command. - /// The `handler` function is used to handle the execution logic associated with the command. - /// - /// # Arguments - /// - /// * `handler` - The handler function that will be invoked when the command is executed. - /// - /// # Returns - /// - /// A new instance of the command with the specified `handler`. - /// - #[ inline ] - pub fn new( handler: F ) -> Self - { - let name = - { - use wtools::Itertools as _; - - let name = std::any::type_name::< F >(); - let name = name.split("::").last().unwrap(); - name.split( '_' ).join( "." ) - }; - - Self { handler, command : Command::former().phrase( name ).form() } - } - - /// Adds an argument to the command. - /// - /// This method takes in the `hint` and `tag` parameters to create a `ValueDescription` object - /// representing an argument. The `ValueDescription` object is then appended to the command's - /// `subjects` collection. - /// - /// # Arguments - /// - /// * `hint` - The hint for the argument, represented as a string slice (`&str`). - /// * `tag` - The type of the argument, represented by a `Type` object from the `Type` module. - /// - /// # Returns - /// - /// The modified command instance with the argument added. - /// - #[ inline ] - pub fn arg( mut self, hint : &str, tag : Type ) -> Self - { - self.command.subjects.push( grammar::command::ValueDescription - { - hint : hint.into(), - kind : tag, - optional : false, - }); - - self - } - - /// Adds a property to the command. - /// - /// This method takes in the `name`, `hint`, and `kind` parameters to create a `ValueDescription` - /// object representing a property. The `ValueDescription` object is then inserted into the - /// command's properties collection using the `name` as the key. - /// - /// # Example - /// ```no_rust - /// let ca = cui(()) - /// .command(user.property("name", "Name property", Type::String)) - /// .build(); - /// ``` - /// - /// # Arguments - /// - /// * `name` - The name of the property. It should implement the `ToString` trait. - /// * `hint` - The hint for the property. It should implement the `ToString` trait. - /// * `kind` - The type of the property, represented by a `Type` object from the `Type` module. - /// - /// # Returns - /// - /// The modified command instance with the property added. - /// - #[ inline ] - pub fn property( mut self, name : impl ToString , hint : impl ToString, kind : Type ) -> Self - { - self.command.properties.insert - ( - name.to_string(), - grammar::command::ValueDescription - { - hint : hint.to_string(), - kind, - optional : false, - } - ); - - self - } - - /// Adds multiple properties to the command. - /// - /// This method takes in an array of `Property` objects and adds them to the command's properties. - /// The properties are provided in the `properties` parameter as an array of length `N`. - /// - /// ```without_std - /// let ca = cui(()) - /// .properties([ - /// Property::new("name", "Name property", Type::String), - /// Property::new("age", "Age property", Type::Integer), - /// ]).build(); - /// ``` - /// - /// # Arguments - /// - /// * `properties` - An array of `Property` objects representing the properties to be added. - /// - /// # Returns - /// - /// The modified command instance with the properties added. - /// - #[ inline ] - pub fn properties< const N: usize >( mut self, properties : [ Property< '_ >; N ] ) -> Self - { - self.command.properties.reserve( properties.len() ); - - for Property { name, hint, tag } in properties - { - self = self.property(name, hint, tag); - } - - self - } - } - - impl< T: Clone + 'static > CommandBuilder< T > - { - /// Adds a command to the `CommandBuilder`. - /// ```no_rust - /// let ca = cui( () ) // Add commands using the builder pattern - /// .command( command ) - /// .command( command2 ) - /// .command( echo.arg("string", Type::String ) ) // Customize your commands by chaining methods such as properties - /// // property, and arg to add properties and arguments. - /// .build(); - /// - /// ``` - pub fn command< F, E > - ( - mut self, - command : impl IntoBuilder< F, T >, - ) -> Self - where - F : Fn( T, Args, Props ) -> Result< (), E > + 'static + Copy, - E : fmt::Debug, - { - let Builder { handler, command } = command.into_builder(); - let state = self.state.clone(); - - let closure = closure::closure!( | ( args, props ) | - { - handler( state.clone(), args, props ) - .map_err( | report | BasicError::new( format!( "{report:?}" ) ).into() ) - }); - - let handler = Routine::new( closure ); - - self.handlers.insert( command.phrase.clone(), handler ); - self.commands.push( command ); - - self - } - - /// Builds and returns a `wca::CommandsAggregator` instance. - /// - /// This method finalizes the construction of the `CommandBuilder` by - /// creating a `wca::CommandsAggregator` instance with the accumulated - /// commands and handlers. - pub fn build( self ) -> CommandsAggregator - { - CommandsAggregator::former().grammar( self.commands ).executor( self.handlers ).perform() - } - } - - /// An extension trait for commands. - /// - /// This trait provides additional methods for enhancing commands, such as - /// adding arguments and properties. - pub trait CommandExt< T > : Sized - { - /// Adds an argument to the command. - fn arg( self, hint : &str, tag : Type ) -> Builder< Self > - { - Builder::new( self ).arg( hint, tag ) - } - - /// Adds property to the command. - fn property< const N: usize >( self, name : impl ToString , hint : impl ToString, kind : Type ) -> Builder< Self > - { - Builder::new( self ).property( name, hint, kind ) - } - - /// Adds properties to the command. - fn properties< const N: usize >( self, properties: [ Property< '_ >; N ] ) -> Builder< Self > - { - Builder::new( self ).properties( properties ) - } - } - - impl< F: Fn( T, Args, Props ) -> Result< (), E>, T, E > CommandExt< T > for F {} - - /// A trait for converting a type into a `Builder`. - pub trait IntoBuilder< F, T > : Sized - { - /// Converts the type into a `Builder` instance. - fn into_builder( self ) -> Builder< F >; - } - - impl< F, T > IntoBuilder< F, T > for Builder< F > - { - fn into_builder( self ) -> Self - { - self - } - } - - impl< F: Fn( T, Args, Props ) -> Result< (), E >, T, E > IntoBuilder< F, T > for F - { - fn into_builder( self ) -> Builder< F > - { - Builder::new( self ) - } - } - -} - -crate::mod_interface! -{ - exposed use cui; - exposed use CommandBuilder; - exposed use Property; - prelude use IntoBuilder; - prelude use CommandExt; -} +// pub( crate ) mod private +// { +// use crate::*; +// use core::fmt; +// use ca::grammar; +// +// /// Macro for parsing WCA arguments. +// /// +// /// # Examples +// /// ```rust +// /// use wca::Value; +// /// +// /// let mut args = vec![ Value::Number( 42. ), Value::String( "Rust".into() ) ].into_iter(); +// /// wca::parse_args!( args, n : f64, name : String ); +// /// +// /// assert_eq!( n, 42. ); +// /// assert_eq!( name, "Rust" ); +// /// ``` +// #[macro_export] +// macro_rules! parse_args +// { +// ( $args : ident, mut $b : ident : $ty : ident $( $rest : tt )* ) => +// { +// let mut $b : $ty = std::convert::TryFrom::try_from( $args.next().unwrap() ).unwrap(); +// $crate::parse_args!( $args $( $rest )* ) +// }; +// ( $args : ident, $b : ident : $ty : ident $( $rest : tt )* ) => +// { +// let $b : $ty = std::convert::TryFrom::try_from( $args.next().unwrap() ).unwrap(); +// $crate::parse_args!( $args $( $rest )* ) +// }; +// ( $args : ident, $b : ident $( $rest : tt )* ) => +// { +// let $b = $args.next().unwrap(); +// $crate::parse_args!( $args $( $rest )* ) +// }; +// ( $args : ident, mut $b : ident $( $rest : tt )* ) => +// { +// let mut $b = $args.next().unwrap(); +// $crate::parse_args!( $args $( $rest )* ) +// }; +// ( $args : ident ) => +// { +// assert!( $args.next().is_none() ); +// }; +// ( $args : ident, ) => +// { +// $crate::parse_args!( $args ) +// }; +// } +// +// /// Creates a command-line interface (CLI) builder with the given initial state. +// /// +// /// This function initializes a `CommandBuilder` with the provided `state` and +// /// returns it for further configuration of the CLI. +// pub fn cui< T >( state : T ) -> CommandBuilder< T > +// { +// CommandBuilder::with_state( state ) +// } +// +// /// A struct representing a property. +// #[ derive( Debug, Clone ) ] +// pub struct Property< 'a > +// { +// /// The name of the property. +// pub name : &'a str, +// /// The hint for the property. +// pub debug : &'a str, +// /// The tag representing the property's type. +// pub tag : Type, +// } +// +// impl< 'a > Property< 'a > +// { +// /// Constructor of a property. +// pub fn new( name : &'a str, hint : &'a str, tag : Type ) -> Self { Self { name, hint, tag } } +// } +// +// /// A builder struct for constructing commands. +// #[ derive( Debug ) ] +// pub struct CommandBuilder< T > +// { +// state : T, +// commands : Vec< Command >, +// handlers : std::collections::HashMap< String, Routine >, +// } +// +// impl< T > CommandBuilder< T > +// { +// /// Constructs a `CommandBuilder` with the given state. +// pub fn with_state( state : T ) -> Self +// { +// Self { state, handlers : < _ >::default(), commands : vec![] } +// } +// } +// +// #[ derive( Debug ) ] +// pub struct Builder< F > +// { +// handler : F, +// command : Command, +// } +// +// impl< F > Builder< F > +// { +// /// Creates a new instance of the command with the provided handler function. +// /// +// /// This method takes in a handler function `handler` and creates a new instance of the command. +// /// The `handler` function is used to handle the execution logic associated with the command. +// /// +// /// # Arguments +// /// +// /// * `handler` - The handler function that will be invoked when the command is executed. +// /// +// /// # Returns +// /// +// /// A new instance of the command with the specified `handler`. +// /// +// #[ inline ] +// pub fn new( handler: F ) -> Self +// { +// let name = +// { +// use iter_tools::Itertools as _; +// +// let name = std::any::type_name::< F >(); +// let name = name.split("::").last().unwrap(); +// name.split( '_' ).join( "." ) +// }; +// +// Self { handler, command : Command::former().phrase( name ).form() } +// } +// +// /// Adds an argument to the command. +// /// +// /// This method takes in the `hint` and `tag` parameters to create a `ValueDescription` object +// /// representing an argument. The `ValueDescription` object is then appended to the command's +// /// `subjects` collection. +// /// +// /// # Arguments +// /// +// /// * `hint` - The hint for the argument, represented as a string slice (`&str`). +// /// * `tag` - The type of the argument, represented by a `Type` object from the `Type` module. +// /// +// /// # Returns +// /// +// /// The modified command instance with the argument added. +// /// +// #[ inline ] +// pub fn arg( mut self, hint : &str, tag : Type ) -> Self +// { +// self.command.subjects.push( grammar::command::ValueDescription +// { +// hint : hint.into(), +// kind : tag, +// optional : false, +// }); +// +// self +// } +// +// /// Adds a property to the command. +// /// +// /// This method takes in the `name`, `hint`, and `kind` parameters to create a `ValueDescription` +// /// object representing a property. The `ValueDescription` object is then inserted into the +// /// command's properties collection using the `name` as the key. +// /// +// /// # Example +// /// ```no_rust +// /// let ca = cui(()) +// /// .command(user.property("name", "Name property", Type::String)) +// /// .build(); +// /// ``` +// /// +// /// # Arguments +// /// +// /// * `name` - The name of the property. It should implement the `ToString` trait. +// /// * `hint` - The hint for the property. It should implement the `ToString` trait. +// /// * `kind` - The type of the property, represented by a `Type` object from the `Type` module. +// /// +// /// # Returns +// /// +// /// The modified command instance with the property added. +// /// +// #[ inline ] +// pub fn property( mut self, name : impl ToString , hint : impl ToString, kind : Type ) -> Self +// { +// self.command.properties.insert +// ( +// name.to_string(), +// grammar::command::ValueDescription +// { +// hint : hint.to_string(), +// kind, +// optional : false, +// } +// ); +// +// self +// } +// +// /// Adds multiple properties to the command. +// /// +// /// This method takes in an array of `Property` objects and adds them to the command's properties. +// /// The properties are provided in the `properties` parameter as an array of length `N`. +// /// +// /// ```without_std +// /// let ca = cui(()) +// /// .properties([ +// /// Property::new("name", "Name property", Type::String), +// /// Property::new("age", "Age property", Type::Integer), +// /// ]).build(); +// /// ``` +// /// +// /// # Arguments +// /// +// /// * `properties` - An array of `Property` objects representing the properties to be added. +// /// +// /// # Returns +// /// +// /// The modified command instance with the properties added. +// /// +// #[ inline ] +// pub fn properties< const N: usize >( mut self, properties : [ Property< '_ >; N ] ) -> Self +// { +// self.command.properties.reserve( properties.len() ); +// +// for Property { name, hint, tag } in properties +// { +// self = self.property(name, hint, tag); +// } +// +// self +// } +// } +// +// impl< T: Clone + 'static > CommandBuilder< T > +// { +// /// Adds a command to the `CommandBuilder`. +// /// ```no_rust +// /// let ca = cui( () ) // Add commands using the builder pattern +// /// .command( command ) +// /// .command( command2 ) +// /// .command( echo.arg("string", Type::String ) ) // Customize your commands by chaining methods such as properties +// /// // property, and arg to add properties and arguments. +// /// .build(); +// /// +// /// ``` +// pub fn command< F, E > +// ( +// mut self, +// command : impl IntoBuilder< F, T >, +// ) -> Self +// where +// F : Fn( T, Args, Props ) -> Result< (), E > + 'static + Copy, +// E : fmt::Debug, +// { +// let Builder { handler, command } = command.into_builder(); +// let state = self.state.clone(); +// +// let closure = closure::closure!( | ( args, props ) | +// { +// handler( state.clone(), args, props ) +// .map_err( | report | BasicError::new( format!( "{report:?}" ) ).into() ) +// }); +// +// let handler = Routine::new( closure ); +// +// self.handlers.insert( command.phrase.clone(), handler ); +// self.commands.push( command ); +// +// self +// } +// +// /// Builds and returns a `wca::CommandsAggregator` instance. +// /// +// /// This method finalizes the construction of the `CommandBuilder` by +// /// creating a `wca::CommandsAggregator` instance with the accumulated +// /// commands and handlers. +// pub fn build( self ) -> CommandsAggregator +// { +// CommandsAggregator::former().grammar( self.commands ).executor( self.handlers ).perform() +// } +// } +// +// /// An extension trait for commands. +// /// +// /// This trait provides additional methods for enhancing commands, such as +// /// adding arguments and properties. +// pub trait CommandExt< T > : Sized +// { +// /// Adds an argument to the command. +// fn arg( self, hint : &str, tag : Type ) -> Builder< Self > +// { +// Builder::new( self ).arg( hint, tag ) +// } +// +// /// Adds property to the command. +// fn property< const N: usize >( self, name : impl ToString , hint : impl ToString, kind : Type ) -> Builder< Self > +// { +// Builder::new( self ).property( name, hint, kind ) +// } +// +// /// Adds properties to the command. +// fn properties< const N: usize >( self, properties: [ Property< '_ >; N ] ) -> Builder< Self > +// { +// Builder::new( self ).properties( properties ) +// } +// } +// +// impl< F: Fn( T, Args, Props ) -> Result< (), E>, T, E > CommandExt< T > for F {} +// +// /// A trait for converting a type into a `Builder`. +// pub trait IntoBuilder< F, T > : Sized +// { +// /// Converts the type into a `Builder` instance. +// fn into_builder( self ) -> Builder< F >; +// } +// +// impl< F, T > IntoBuilder< F, T > for Builder< F > +// { +// fn into_builder( self ) -> Self +// { +// self +// } +// } +// +// impl< F: Fn( T, Args, Props ) -> Result< (), E >, T, E > IntoBuilder< F, T > for F +// { +// fn into_builder( self ) -> Builder< F > +// { +// Builder::new( self ) +// } +// } +// +// } +// +// crate::mod_interface! +// { +// exposed use cui; +// exposed use CommandBuilder; +// exposed use Property; +// prelude use IntoBuilder; +// prelude use CommandExt; +// } diff --git a/module/move/wca/src/ca/formatter.rs b/module/move/wca/src/ca/formatter.rs index 368ec8e88f..37cccbc5a9 100644 --- a/module/move/wca/src/ca/formatter.rs +++ b/module/move/wca/src/ca/formatter.rs @@ -2,7 +2,7 @@ pub( crate ) mod private { use crate::*; - use wtools::Itertools; + use iter_tools::Itertools; use ca::aggregator::private::Order; /// - diff --git a/module/move/wca/src/ca/grammar/command.rs b/module/move/wca/src/ca/grammar/command.rs index 38a02583a4..383cca9448 100644 --- a/module/move/wca/src/ca/grammar/command.rs +++ b/module/move/wca/src/ca/grammar/command.rs @@ -5,7 +5,7 @@ pub( crate ) mod private use std::collections::{ HashMap }; use indexmap::IndexMap; use former::{ Former, StoragePreform }; - use wtools::Itertools; + use iter_tools::Itertools; /// A description of a Value in a command. Used to specify the expected type and provide a hint for the Value. /// @@ -103,12 +103,10 @@ pub( crate ) mod private /// Map of aliases. // Aliased key -> Original key pub properties_aliases : HashMap< String, String >, - // aaa : for Bohdan : routine should also be here - // aaa : here it is // qqq : make it usable and remove default(?) /// The type `Routine` represents the specific implementation of the routine. #[ scalar( setter = false ) ] - #[ former( default = Routine::from( Handler::from( || { panic!( "No routine available: A handler function for the command is missing" ) } ) ) ) ] + #[ former( default = Routine::from( Handler::< _, std::convert::Infallible >::from( || { panic!( "No routine available: A handler function for the command is missing" ) } ) ) ) ] pub routine : Routine, } @@ -250,7 +248,7 @@ crate::mod_interface! { exposed use Command; exposed use CommandFormer; - protected use ValueDescription; + own use ValueDescription; } // 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/grammar/dictionary.rs b/module/move/wca/src/ca/grammar/dictionary.rs index 06c8479f8b..91beec9329 100644 --- a/module/move/wca/src/ca/grammar/dictionary.rs +++ b/module/move/wca/src/ca/grammar/dictionary.rs @@ -3,7 +3,7 @@ pub( crate ) mod private use crate::*; use former::Former; use indexmap::IndexMap; - use wtools::Itertools; + use iter_tools::Itertools; // qqq : `Former` does not handle this situation well diff --git a/module/move/wca/src/ca/grammar/types.rs b/module/move/wca/src/ca/grammar/types.rs index 1ee53a654e..6d045ad4a2 100644 --- a/module/move/wca/src/ca/grammar/types.rs +++ b/module/move/wca/src/ca/grammar/types.rs @@ -2,13 +2,14 @@ pub( crate ) mod private { use crate::*; use std::fmt:: - { - Display, - Formatter + { + Display, + Formatter }; - use wtools; - use wtools::{ error::Result, err }; - use wtools::Itertools; + // use wtools; + // use wtools::{ error::Result, err }; + use error::err; + use iter_tools::Itertools; /// Available types that can be converted to a `Value` /// @@ -46,7 +47,7 @@ pub( crate ) mod private pub trait TryCast< T > { /// return casted value - fn try_cast( &self, value : String ) -> Result< T >; + fn try_cast( &self, value : String ) -> error::untyped::Result< T >; } /// Container for a `Value` of a specific type @@ -180,7 +181,7 @@ pub( crate ) mod private impl TryCast< Value > for Type { - fn try_cast( &self, value : String ) -> Result< Value > + fn try_cast( &self, value : String ) -> error::untyped::Result< Value > { match self { @@ -193,7 +194,8 @@ pub( crate ) mod private let values = value .split( *delimeter ) .map( | val | kind.try_cast( val.into() ) ) - .collect::< Result< Vec< Value > > >()?; + .collect::< error::untyped::Result< Vec< Value > > >()?; + // qqq : avoid using fish notation whenever possible. review whole crate Ok( Value::List( values ) ) }, } diff --git a/module/move/wca/src/ca/help.rs b/module/move/wca/src/ca/help.rs index cc8c897b70..3cf65c4633 100644 --- a/module/move/wca/src/ca/help.rs +++ b/module/move/wca/src/ca/help.rs @@ -4,19 +4,19 @@ pub( crate ) mod private use ca:: { Command, - Routine, - Type, + Routine, + Type, formatter::private:: - { - HelpFormat, - md_generator + { + HelpFormat, + md_generator }, tool::table::format_table, }; - use wtools::Itertools; + use iter_tools::Itertools; use std::rc::Rc; - use error_tools::for_app::anyhow; + use error::untyped::format_err; use former::Former; // qqq : for Bohdan : it should transparent mechanist which patch list of commands, not a stand-alone mechanism @@ -105,7 +105,7 @@ pub( crate ) mod private { let full_subjects = command.subjects.iter().map( | subj | format!( "- {} [{}{:?}]", subj.hint, if subj.optional { "?" } else { "" }, subj.kind ) ).join( "\n\t" ); let full_properties = format_table( command.properties( dictionary.order ).into_iter().map( | ( name, value ) | [ name.clone(), format!( "- {} [{}{:?}]", value.hint, if value.optional { "?" } else { "" }, value.kind ) ] ) ).unwrap().replace( '\n', "\n\t" ); - + format! ( "{}{}", @@ -230,7 +230,7 @@ pub( crate ) mod private } } - Ok::< _, error_tools::for_app::Error >( () ) + Ok::< _, error_tools::untyped::Error >( () ) }; let help = Command::former() .hint( "prints information about existing commands" ) @@ -265,7 +265,9 @@ pub( crate ) mod private _ => { let command = o.args.get_owned::< String >( 0 ).unwrap(); - let cmd = grammar.commands.get( &command ).ok_or_else( || anyhow!( "Can not found help for command `{command}`" ) )?; + let cmd = grammar.commands + .get( &command ) + .ok_or_else( || format_err!( "Can not found help for command `{command}`" ) )?; let args = HelpGeneratorOptions::former() .command_prefix( "." ) @@ -281,7 +283,7 @@ pub( crate ) mod private } }; - Ok::< _, error_tools::for_app::Error >( () ) + Ok::< _, error_tools::untyped::Error >( () ) }; let help = Command::former() @@ -414,7 +416,7 @@ pub( crate ) mod private crate::mod_interface! { - protected use HelpGeneratorFn; - protected use HelpGeneratorOptions; + own use HelpGeneratorFn; + own use HelpGeneratorOptions; prelude use HelpVariants; } diff --git a/module/move/wca/src/ca/mod.rs b/module/move/wca/src/ca/mod.rs index 9333e5ac5b..3526d2c8fa 100644 --- a/module/move/wca/src/ca/mod.rs +++ b/module/move/wca/src/ca/mod.rs @@ -1,3 +1,6 @@ +//! +//! Commands aggregator library. +//! crate::mod_interface! { @@ -13,9 +16,7 @@ crate::mod_interface! /// Provides functionality for working with input data, including asking user questions and converting various string representations into a uniform `Input` struct. layer input; - - // /// The missing batteries of WCA. - // layer facade; + /// Genera-purpose tools which might be moved out one day. layer tool; @@ -25,7 +26,5 @@ crate::mod_interface! layer help; /// Responsible for generating Markdown formatted documentation for commands layer formatter; - // aaa : for Bohdan : write concise documentations - // aaa : Is this enough or is more needed? } diff --git a/module/move/wca/src/ca/parser/parser.rs b/module/move/wca/src/ca/parser/parser.rs index a952e6427e..1efe959495 100644 --- a/module/move/wca/src/ca/parser/parser.rs +++ b/module/move/wca/src/ca/parser/parser.rs @@ -3,9 +3,9 @@ mod private use crate::*; use std::collections::HashMap; - - use error_tools::{ Result, return_err }; - + + use error::{ return_err }; + /// `Parser` is a struct used for parsing data. #[ derive( Debug ) ] pub struct Parser; @@ -21,7 +21,8 @@ mod private /// # Returns /// /// Returns a `Result` with a `Program` containing the parsed commands if successful, or an error if parsing fails. - pub fn parse< As, A >( &self, args : As ) -> Result< Program< ParsedCommand > > + // qqq : use typed error + pub fn parse< As, A >( &self, args : As ) -> error::untyped::Result< Program< ParsedCommand > > where As : IntoIterator< Item = A >, A : Into< String >, @@ -38,7 +39,7 @@ mod private Ok( Program { commands } ) } - + // with dot at the beginning fn valid_command_name( input : &str ) -> bool { @@ -53,14 +54,15 @@ mod private } // returns ParsedCommand and relative position of the last parsed item - fn parse_command( args : &[ String ] ) -> Result< ( ParsedCommand, usize ) > + // qqq : use typed error + fn parse_command( args : &[ String ] ) -> error::untyped::Result< ( ParsedCommand, usize ) > { if args.is_empty() { return_err!( "Unexpected behaviour: Try to parse command without input" ); } let mut i = 0; - + if !Self::valid_command_name( &args[ i ] ) { return_err!( "Unexpected input: Expected a command, found: `{}`", args[ i ] ); @@ -73,7 +75,7 @@ mod private }; i += 1; let ( subjects, properties, relative_pos ) = Self::parse_command_args( &args[ i .. ] )?; - + i += relative_pos; return Ok( @@ -87,12 +89,13 @@ mod private i, )) } - + // returns ( subjects, properties, relative_end_pos ) - fn parse_command_args( args : &[ String ] ) -> Result< ( Vec< String >, HashMap< String, String >, usize ) > + // qqq : use typed error + fn parse_command_args( args : &[ String ] ) -> error::untyped::Result< ( Vec< String >, HashMap< String, String >, usize ) > { let mut i = 0; - + let mut subjects = vec![]; let mut properties = HashMap::new(); @@ -146,13 +149,13 @@ mod private return_err!( "Unexpected input '{} :': Detected a possible property key preceding the ':' character. However, no corresponding value was found.", item ); } } - + else if !properties_turn { subjects.push( item.to_string() ); } - + else { return_err!( "Unexpected input: Expected `command` or `property`, found: `{}`", item ); } i += 1; } - + Ok(( subjects, properties, i )) } } diff --git a/module/move/wca/src/ca/tool/mod.rs b/module/move/wca/src/ca/tool/mod.rs index 637dcae457..116804b97d 100644 --- a/module/move/wca/src/ca/tool/mod.rs +++ b/module/move/wca/src/ca/tool/mod.rs @@ -4,4 +4,12 @@ crate::mod_interface! /// It takes a table of data and format it into a human-readable string layer table; + orphan use super::super::tool; + orphan use ::error_tools as error; + orphan use ::iter_tools; + + // use ::strs_tools as string; // xxx : check + // use ::error_tools as error; + // use ::mod_interface; + } diff --git a/module/move/wca/src/ca/tool/table.rs b/module/move/wca/src/ca/tool/table.rs index 7c62d76d3a..192caa0396 100644 --- a/module/move/wca/src/ca/tool/table.rs +++ b/module/move/wca/src/ca/tool/table.rs @@ -1,9 +1,10 @@ mod private { use crate::*; - - use wtools::error::{ Result, err }; - + + // use wtools::error::{ Result, err }; + use error::err; + /// Represents a table composed of multiple rows. /// /// The `Table` struct is a simple container that holds multiple `Row` objects. @@ -20,7 +21,7 @@ mod private Self( value.into_iter().map( Into::into ).collect() ) } } - + impl Table { /// Validates the structure of the given `self` object. @@ -44,7 +45,7 @@ mod private return false; } } - + true } } @@ -54,7 +55,7 @@ mod private /// The `Row` struct is a container that holds multiple `String` objects representing the values in a table row. #[ derive( Debug ) ] pub struct Row( Vec< String > ); - + impl< R, V > From< R > for Row where R : IntoIterator< Item = V >, @@ -65,7 +66,7 @@ mod private Self( value.into_iter().map( Into::into ).collect() ) } } - + fn max_column_lengths( table : &Table ) -> Vec< usize > { let num_columns = table.0.get( 0 ).map_or( 0, | row | row.0.len() ); @@ -79,7 +80,7 @@ mod private }) .collect() } - + /// Formats a table into a readable string representation. /// /// # Arguments @@ -88,8 +89,9 @@ mod private /// /// # Returns /// - /// * `Result` - A `Result` containing the formatted table as a `String`, or an `Error` if the table is invalid. - pub fn format_table< IntoTable >( table : IntoTable ) -> Result< String > + /// * `error::untyped::Result` - A `error::untyped::Result` containing the formatted table as a `String`, or an `Error` if the table is invalid. + // qqq : use typed error + pub fn format_table< IntoTable >( table : IntoTable ) -> error::untyped::Result< String > where IntoTable : Into< Table >, { @@ -98,9 +100,9 @@ mod private { return Err( err!( "Invalid table" ) ); } - + let max_lengths = max_column_lengths( &table ); - + let mut formatted_table = String::new(); for row in table.0 { @@ -113,7 +115,7 @@ mod private formatted_table.push( '\n' ); } formatted_table.pop(); // trailing end of line - + Ok( formatted_table ) } } @@ -122,5 +124,5 @@ mod private crate::mod_interface! { - protected use format_table; + own use format_table; } diff --git a/module/move/wca/src/ca/verifier/verifier.rs b/module/move/wca/src/ca/verifier/verifier.rs index b443000f7d..94caf94d5f 100644 --- a/module/move/wca/src/ca/verifier/verifier.rs +++ b/module/move/wca/src/ca/verifier/verifier.rs @@ -6,8 +6,10 @@ pub( crate ) mod private // use former::Former; use std::collections::HashMap; use indexmap::IndexMap; - use wtools::{ error, error::Result, err }; + // use wtools::{ error, error::Result, err }; + use error::err; use ca::help::private::{ HelpGeneratorOptions, LevelOfDetail, generate_help_content }; + // xxx /// Converts a `ParsedCommand` to a `VerifiedCommand` by performing validation and type casting on values. /// @@ -46,12 +48,13 @@ pub( crate ) mod private dictionary : &Dictionary, raw_program : Program< ParsedCommand > ) - -> Result< Program< VerifiedCommand > > + -> error::untyped::Result< Program< VerifiedCommand > > + // qqq : use typed error { let commands = raw_program.commands .into_iter() .map( | n | self.to_command( dictionary, n ) ) - .collect::< Result< Vec< VerifiedCommand > > >()?; + .collect::< error::untyped::Result< Vec< VerifiedCommand > > >()?; Ok( Program { commands } ) } @@ -106,210 +109,10 @@ pub( crate ) mod private if Self::is_valid_command_variant( expected_subjects_count, raw_subjects_count, possible_subjects_count ) { Some( variant ) } else { None } } - // qqq : for Barsik : - // Problem with separating properties and subjects: - // if we pass to wca a command that has an incorrectly named property, it defines this property as part of an subject. - // You can simulate this problem by running the code from https://github.com/Wandalen/wTools/blob/alpha/module/move/wca/examples/wca_trivial.rs in this form `cargo r .echo propertyf:123` - // where the console shows that the subject is `propertyf:123` and the property is empty. - // - // I would like to get an error in this case. - // - // A real example of the problem can be seen in the `.test` command in willbe where if you don't specify the option and make a mistake in the name of the properties when running it, - // the option will be an incorrectly written property that will produce an error with unobvious output. - // log: - // kosli@kos-msi-creator MINGW64 /c/pro/rust/lib/wTools/module/move/willbe (alpha) - // $ RUST_BACKTRACE=1 cargo run .test enabled_features:enabled power:1 dry:0 - // warning: usage of an `unsafe` block - // --> module\move\wca\src\ca\executor\context.rs:88:7 - // | - // 88 | unsafe{ self.inner.as_ptr().as_ref()?.get() } - // | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - // | - // = note: requested on the command line with `-W unsafe-code` - // - // warning: usage of an `unsafe` block - // --> module\move\wca\src\ca\executor\context.rs:94:7 - // | - // 94 | unsafe { self.inner.as_ptr().as_mut()?.get_mut() } - // | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - // - // warning: method `deep_clone` is never used - // --> module\move\wca\src\ca\executor\context.rs:120:21 - // | - // 70 | impl Context - // | ------------ method in this implementation - // ... - // 120 | pub( crate ) fn deep_clone( &self ) -> Self - // | ^^^^^^^^^^ - // | - // = note: `#[warn(dead_code)]` on by default - // - // warning: `wca` (lib) generated 3 warnings - // Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.32s - // Running `C:\pro\rust\lib\wTools\target\debug\will.exe .test 'enabled_features:enabled' 'power:1' 'dry:0'` - // Error: Execution failed. The system cannot find the file specified. (os error 2) - // - // Stack backtrace: - // 0: std::backtrace_rs::backtrace::dbghelp64::trace - // at /rustc/3c85e56249b0b1942339a6a989a971bf6f1c9e0f/library\std\src\..\..\backtrace\src\backtrace\dbghelp64.rs:99 - // 1: std::backtrace_rs::backtrace::trace_unsynchronized - // at /rustc/3c85e56249b0b1942339a6a989a971bf6f1c9e0f/library\std\src\..\..\backtrace\src\backtrace\mod.rs:66 - // 2: std::backtrace::Backtrace::create - // at /rustc/3c85e56249b0b1942339a6a989a971bf6f1c9e0f/library\std\src\backtrace.rs:331 - // 3: std::backtrace::Backtrace::capture - // at /rustc/3c85e56249b0b1942339a6a989a971bf6f1c9e0f/library\std\src\backtrace.rs:296 - // 4: anyhow::error::impl$1::from - // at C:\Users\kosli\.cargo\registry\src\index.crates.io-6f17d22bba15001f\anyhow-1.0.81\src\error.rs:565 - // 5: core::result::impl$27::from_residual,std::io::error::Error,anyhow::Error> - // at /rustc/3c85e56249b0b1942339a6a989a971bf6f1c9e0f\library\core\src\result.rs:1964 - // 6: willbe::command::test::private::test - // at .\src\command\test.rs:50 - // 7: core::ops::function::Fn::call,anyhow::Error> > (*)(wca::ca::executor::routine::private::Args,wca::ca::executor::routine::private::Props),tuple$,anyhow::Error> > (*)(wca::ca::executor::routine::private::Args,wca::ca::executor::routine::private::Props),enum2$,anyhow::Error - // at C:\pro\rust\lib\wTools\module\move\wca\src\ca\executor\routine.rs:218 - // 9: alloc::boxed::impl$49::call >,dyn$,enum2$,anyhow::Error> > > - // at C:\pro\rust\lib\wTools\module\move\wca\src\ca\executor\routine.rs:275 - // 11: alloc::boxed::impl$49::call >,dyn$,anyhow::Error> >::and_then,anyhow::Error,tuple$<>,wca::ca::executor::runtime::private::impl$0::do::closure_en - // at /rustc/3c85e56249b0b1942339a6a989a971bf6f1c9e0f\library\core\src\result.rs:1321 - // 16: wca::ca::executor::runtime::private::Runtime::do - // at C:\pro\rust\lib\wTools\module\move\wca\src\ca\executor\runtime.rs:73 - // 17: wca::ca::executor::executor::private::Executor::sequential_execution_loop - // at C:\pro\rust\lib\wTools\module\move\wca\src\ca\executor\executor.rs:60 - // 18: wca::ca::executor::executor::private::Executor::program - // at C:\pro\rust\lib\wTools\module\move\wca\src\ca\executor\executor.rs:37 - // 19: wca::ca::aggregator::private::CommandsAggregator::perform > - // at C:\pro\rust\lib\wTools\module\move\wca\src\ca\aggregator.rs:276 - // 20: willbe::private::run - // at .\src\lib.rs:42 - // 21: will::main - // at .\src\bin\will.rs:14 - // 22: core::ops::function::FnOnce::call_once,anyhow::Error> > (*)(),tuple$<> > - // at /rustc/3c85e56249b0b1942339a6a989a971bf6f1c9e0f\library\core\src\ops\function.rs:250 - // 23: std::sys_common::backtrace::__rust_begin_short_backtrace,anyhow::Error> > (*)(),enum2$,anyhow::Error> > > - // at /rustc/3c85e56249b0b1942339a6a989a971bf6f1c9e0f\library\std\src\sys_common\backtrace.rs:155 - // 24: std::rt::lang_start::closure$0,anyhow::Error> > > - // at /rustc/3c85e56249b0b1942339a6a989a971bf6f1c9e0f\library\std\src\rt.rs:166 - // 25: std::rt::lang_start_internal - // at /rustc/3c85e56249b0b1942339a6a989a971bf6f1c9e0f/library\std\src\rt.rs:148 - // 26: std::rt::lang_start,anyhow::Error> > > - // at /rustc/3c85e56249b0b1942339a6a989a971bf6f1c9e0f\library\std\src\rt.rs:165 - // 27: main - // 28: invoke_main - // at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:78 - // 29: __scrt_common_main_seh - // at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288 - // 30: BaseThreadInitThunk - // 31: RtlUserThreadStart - // - // Stack backtrace: - // 0: std::backtrace_rs::backtrace::dbghelp64::trace - // at /rustc/3c85e56249b0b1942339a6a989a971bf6f1c9e0f/library\std\src\..\..\backtrace\src\backtrace\dbghelp64.rs:99 - // 1: std::backtrace_rs::backtrace::trace_unsynchronized - // at /rustc/3c85e56249b0b1942339a6a989a971bf6f1c9e0f/library\std\src\..\..\backtrace\src\backtrace\mod.rs:66 - // 2: std::backtrace::Backtrace::create - // at /rustc/3c85e56249b0b1942339a6a989a971bf6f1c9e0f/library\std\src\backtrace.rs:331 - // 3: std::backtrace::Backtrace::capture - // at /rustc/3c85e56249b0b1942339a6a989a971bf6f1c9e0f/library\std\src\backtrace.rs:296 - // 4: anyhow::Error::msg - // at C:\Users\kosli\.cargo\registry\src\index.crates.io-6f17d22bba15001f\anyhow-1.0.81\src\error.rs:83 - // 5: anyhow::__private::format_err - // at C:\Users\kosli\.cargo\registry\src\index.crates.io-6f17d22bba15001f\anyhow-1.0.81\src\lib.rs:691 - // 6: wca::ca::executor::routine::private::impl$28::into_result::closure$0 - // at C:\pro\rust\lib\wTools\module\move\wca\src\ca\executor\routine.rs:450 - // 7: enum2$,anyhow::Error> >::map_err,anyhow::Error,anyhow::Error,wca::ca::executor::routine::private::impl$28::into_result::closure_env$0 > - // at /rustc/3c85e56249b0b1942339a6a989a971bf6f1c9e0f\library\core\src\result.rs:829 - // 8: wca::ca::executor::routine::private::impl$28::into_result - // at C:\pro\rust\lib\wTools\module\move\wca\src\ca\executor\routine.rs:450 - // 9: wca::ca::executor::routine::private::impl$13::from::closure$0,enum2$,anyhow::Error> > > - // at C:\pro\rust\lib\wTools\module\move\wca\src\ca\executor\routine.rs:275 - // 10: alloc::boxed::impl$49::call >,dyn$,anyhow::Error> >::and_then,anyhow::Error,tuple$<>,wca::ca::executor::runtime::private::impl$0::do::closure_en - // at /rustc/3c85e56249b0b1942339a6a989a971bf6f1c9e0f\library\core\src\result.rs:1321 - // 15: wca::ca::executor::runtime::private::Runtime::do - // at C:\pro\rust\lib\wTools\module\move\wca\src\ca\executor\runtime.rs:73 - // 16: wca::ca::executor::executor::private::Executor::sequential_execution_loop - // at C:\pro\rust\lib\wTools\module\move\wca\src\ca\executor\executor.rs:60 - // 17: wca::ca::executor::executor::private::Executor::program - // at C:\pro\rust\lib\wTools\module\move\wca\src\ca\executor\executor.rs:37 - // 18: wca::ca::aggregator::private::CommandsAggregator::perform > - // at C:\pro\rust\lib\wTools\module\move\wca\src\ca\aggregator.rs:276 - // 19: willbe::private::run - // at .\src\lib.rs:42 - // 20: will::main - // at .\src\bin\will.rs:14 - // 21: core::ops::function::FnOnce::call_once,anyhow::Error> > (*)(),tuple$<> > - // at /rustc/3c85e56249b0b1942339a6a989a971bf6f1c9e0f\library\core\src\ops\function.rs:250 - // 22: std::sys_common::backtrace::__rust_begin_short_backtrace,anyhow::Error> > (*)(),enum2$,anyhow::Error> > > - // at /rustc/3c85e56249b0b1942339a6a989a971bf6f1c9e0f\library\std\src\sys_common\backtrace.rs:155 - // 23: std::rt::lang_start::closure$0,anyhow::Error> > > - // at /rustc/3c85e56249b0b1942339a6a989a971bf6f1c9e0f\library\std\src\rt.rs:166 - // 24: std::rt::lang_start_internal - // at /rustc/3c85e56249b0b1942339a6a989a971bf6f1c9e0f/library\std\src\rt.rs:148 - // 25: std::rt::lang_start,anyhow::Error> > > - // at /rustc/3c85e56249b0b1942339a6a989a971bf6f1c9e0f\library\std\src\rt.rs:165 - // 26: main - // 27: invoke_main - // at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:78 - // 28: __scrt_common_main_seh - // at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288 - // 29: BaseThreadInitThunk - // 30: RtlUserThreadStart - // - // Stack backtrace: - // 0: std::backtrace_rs::backtrace::dbghelp64::trace - // at /rustc/3c85e56249b0b1942339a6a989a971bf6f1c9e0f/library\std\src\..\..\backtrace\src\backtrace\dbghelp64.rs:99 - // 1: std::backtrace_rs::backtrace::trace_unsynchronized - // at /rustc/3c85e56249b0b1942339a6a989a971bf6f1c9e0f/library\std\src\..\..\backtrace\src\backtrace\mod.rs:66 - // 2: std::backtrace::Backtrace::create - // at /rustc/3c85e56249b0b1942339a6a989a971bf6f1c9e0f/library\std\src\backtrace.rs:331 - // 3: std::backtrace::Backtrace::capture - // at /rustc/3c85e56249b0b1942339a6a989a971bf6f1c9e0f/library\std\src\backtrace.rs:296 - // 4: anyhow::error::impl$1::from > - // at C:\Users\kosli\.cargo\registry\src\index.crates.io-6f17d22bba15001f\anyhow-1.0.81\src\error.rs:565 - // 5: core::result::impl$27::from_residual,enum2$,anyhow::Error> - // at /rustc/3c85e56249b0b1942339a6a989a971bf6f1c9e0f\library\core\src\result.rs:1964 - // 6: willbe::private::run - // at .\src\lib.rs:42 - // 7: will::main - // at .\src\bin\will.rs:14 - // 8: core::ops::function::FnOnce::call_once,anyhow::Error> > (*)(),tuple$<> > - // at /rustc/3c85e56249b0b1942339a6a989a971bf6f1c9e0f\library\core\src\ops\function.rs:250 - // 9: std::sys_common::backtrace::__rust_begin_short_backtrace,anyhow::Error> > (*)(),enum2$,anyhow::Error> > > - // at /rustc/3c85e56249b0b1942339a6a989a971bf6f1c9e0f\library\std\src\sys_common\backtrace.rs:155 - // 10: std::rt::lang_start::closure$0,anyhow::Error> > > - // at /rustc/3c85e56249b0b1942339a6a989a971bf6f1c9e0f\library\std\src\rt.rs:166 - // 11: std::rt::lang_start_internal - // at /rustc/3c85e56249b0b1942339a6a989a971bf6f1c9e0f/library\std\src\rt.rs:148 - // 12: std::rt::lang_start,anyhow::Error> > > - // at /rustc/3c85e56249b0b1942339a6a989a971bf6f1c9e0f\library\std\src\rt.rs:165 - // 13: main - // 14: invoke_main - // at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:78 - // 15: __scrt_common_main_seh - // at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288 - // 16: BaseThreadInitThunk - // 17: RtlUserThreadStart - // error: process didn't exit successfully: `C:\pro\rust\lib\wTools\target\debug\will.exe .test 'enabled_features:enabled' 'power:1' 'dry:0'` (exit code: 1) - - fn extract_subjects( command : &Command, raw_command : &ParsedCommand, used_properties : &[ &String ] ) -> Result< Vec< Value > > + // qqq : use typed error + fn extract_subjects( command : &Command, raw_command : &ParsedCommand, used_properties : &[ &String ] ) + -> + error::untyped::Result< Vec< Value > > { let mut subjects = vec![]; @@ -341,7 +144,10 @@ pub( crate ) mod private Ok( subjects ) } - fn extract_properties( command: &Command, raw_command : HashMap< String, String > ) -> Result< HashMap< String, Value > > + // qqq : use typed error + fn extract_properties( command: &Command, raw_command : HashMap< String, String > ) + -> + error::untyped::Result< HashMap< String, Value > > { raw_command.into_iter() .filter_map @@ -359,7 +165,7 @@ pub( crate ) mod private |( value_description, key, value )| value_description.kind.try_cast( value ).map( | v | ( key.clone(), v ) ) ) - .collect::< Result< HashMap< _, _ > > >() + .collect::< error::untyped::Result< HashMap< _, _ > > >() } fn group_properties_and_their_aliases< 'a, Ks >( aliases : &'a HashMap< String, String >, used_keys : Ks ) -> Vec< &String > @@ -386,7 +192,10 @@ pub( crate ) mod private /// Converts raw command to grammatically correct /// /// Make sure that this command is described in the grammar and matches it(command itself and all it options too). - pub fn to_command( &self, dictionary : &Dictionary, raw_command : ParsedCommand ) -> Result< VerifiedCommand > + // qqq : use typed error + pub fn to_command( &self, dictionary : &Dictionary, raw_command : ParsedCommand ) + -> + error::untyped::Result< VerifiedCommand > { if raw_command.name.ends_with( '.' ) | raw_command.name.ends_with( ".?" ) { @@ -399,7 +208,7 @@ pub( crate ) mod private }); } let command = dictionary.command( &raw_command.name ) - .ok_or_else::< error::for_app::Error, _ > + .ok_or_else::< error::untyped::Error, _ > ( || { @@ -412,7 +221,7 @@ pub( crate ) mod private let Some( cmd ) = Self::check_command( command, &raw_command ) else { - error::for_app::bail! + error::untyped::bail! ( "`{}` command with specified subjects not found. Command info: `{}`", &raw_command.name, diff --git a/module/move/wca/src/lib.rs b/module/move/wca/src/lib.rs index acfd31609c..c318aa58fd 100644 --- a/module/move/wca/src/lib.rs +++ b/module/move/wca/src/lib.rs @@ -1,4 +1,3 @@ -#![ cfg_attr( feature = "no_std", no_std ) ] #![ 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/wca/latest/wca/" ) ] @@ -6,20 +5,14 @@ #![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/", "doc/", "wca.md" ) ) ] #![ allow( where_clauses_object_safety ) ] // https://github.com/chris-morgan/anymap/issues/31 +// qqq : xxx : is it neccessary? use mod_interface::mod_interface; -/// Tools -pub mod wtools; -// qqq : maybe remove this? -// /// Errors. -// #[ cfg( not( feature = "no_std" ) ) ] -// use wtools::error::BasicError; -// xxx : check +pub mod ca; crate::mod_interface! { - /// Commands aggregator library. - #[ cfg( not( feature = "no_std" ) ) ] - layer ca; + use super::ca; + own use super::ca::own::*; } diff --git a/module/move/wca/src/wtools.rs b/module/move/wca/src/wtools.rs index a5bf769f74..1df4db86e7 100644 --- a/module/move/wca/src/wtools.rs +++ b/module/move/wca/src/wtools.rs @@ -1,17 +1,22 @@ - -crate::mod_interface! -{ - protected use ::iter_tools::Itertools; - protected use ::error_tools::err; - protected use ::error_tools::dependency::*; - use ::strs_tools as string; - use ::error_tools as error; - use ::mod_interface; -} - -// /// Requests parser. -// #[ cfg( not( feature = "no_std" ) ) ] -// pub mod string +// // xxx : review +// +// crate::mod_interface! // { -// pub use strs_tools::string::*; +// own use ::iter_tools::Itertools; +// +// // own use ::error_tools::err; +// // own use ::error_tools::dependency::*; +// +// own use error_tools; +// +// use ::strs_tools as string; +// // use ::error_tools as error; +// use ::mod_interface; // } +// +// // /// Requests parser. +// // #[ cfg( not( feature = "no_std" ) ) ] +// // pub mod string +// // { +// // pub use strs_tools::string::*; +// // } diff --git a/module/move/wca/tests/inc/executor/mod.rs b/module/move/wca/tests/inc/executor/mod.rs index 6b2906031a..7c84cbf8a3 100644 --- a/module/move/wca/tests/inc/executor/mod.rs +++ b/module/move/wca/tests/inc/executor/mod.rs @@ -1,4 +1,6 @@ use super::*; + +// qqq : rid of global uses in tests use the_module:: { Parser, @@ -8,7 +10,7 @@ use the_module:: Verifier, Executor, - wtools + // wtools }; mod command; diff --git a/module/move/wca/tests/inc/executor/program.rs b/module/move/wca/tests/inc/executor/program.rs index 885d2e017e..de33330259 100644 --- a/module/move/wca/tests/inc/executor/program.rs +++ b/module/move/wca/tests/inc/executor/program.rs @@ -38,7 +38,7 @@ tests_impls! fn with_context() { use std::sync::{ Arc, Mutex }; - use wtools::error::for_app::Error; + use error::untyped::Error; // init parser let parser = Parser; diff --git a/module/move/wca/tests/inc/mod.rs b/module/move/wca/tests/inc/mod.rs index e07349dc81..c2617e9035 100644 --- a/module/move/wca/tests/inc/mod.rs +++ b/module/move/wca/tests/inc/mod.rs @@ -1,6 +1,8 @@ #[ allow( unused_imports ) ] use super::*; +#[ allow( unused_imports ) ] +use the_module::tool::*; #[ allow( unused_imports ) ] use std::collections::HashMap; @@ -12,5 +14,7 @@ mod grammar; mod executor; #[ cfg( not( feature = "no_std" ) ) ] mod commands_aggregator; + +// qqq : for Bohdan : why commented out? resolve // #[ cfg( not( feature = "no_std" ) ) ] // mod adapter; diff --git a/module/move/wca/tests/smoke_test.rs b/module/move/wca/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/move/wca/tests/smoke_test.rs +++ b/module/move/wca/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/move/wca/tests/wca_tests.rs b/module/move/wca/tests/wca_tests.rs index 85a4f35ea3..ac2fbf9612 100644 --- a/module/move/wca/tests/wca_tests.rs +++ b/module/move/wca/tests/wca_tests.rs @@ -6,7 +6,7 @@ use wca as the_module; #[ allow( unused_imports ) ] use test_tools::exposed::*; -#[ allow( unused_imports ) ] -use wca::wtools::*; +// #[ allow( unused_imports ) ] +// use wca::wtools::*; mod inc; diff --git a/module/move/willbe/Cargo.toml b/module/move/willbe/Cargo.toml index 63c66bd6c0..42a2595064 100644 --- a/module/move/willbe/Cargo.toml +++ b/module/move/willbe/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "willbe" -version = "0.12.0" +version = "0.13.0" edition = "2021" authors = [ "Kostiantyn Wandalen ", @@ -24,16 +24,37 @@ workspace = true [package.metadata.docs.rs] features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] + [features] -default = [ "enabled", "progress_bar" ] -full = [ "enabled", "progress_bar" ] -enabled = [] +default = [ + "enabled", + "progress_bar", +] +full = [ + "default" +] +enabled = [ + "crates_tools/enabled", + "error_tools/enabled", + "former/enabled", + "iter_tools/enabled", + "mod_interface/enabled", + "wca/enabled", + "proper_path_tools/enabled", + "process_tools/enabled", + "derive_tools/enabled", + "data_type/enabled", + "collection_tools/enabled", + "macro_tools/enabled", +] + tracing = [ "dep:tracing", "dep:tracing-subscriber" ] progress_bar = [ "dep:indicatif" ] [dependencies] + +## external cargo_metadata = "~0.18.1" convert_case = "0.6.0" flate2 = "~1.0" @@ -57,6 +78,8 @@ indicatif = { version = "0.17", optional = true } prettytable-rs = "0.10" serde_json = "1.0" # for CargoMetadata::Package::metadata (need serde_json::Value) serde = "1.0" # for CargoMetadata::Package +parse-display = "0.9" # need because derive_tools don't reexport this correctly +walkdir = "2.3" ## internal crates_tools = { workspace = true } @@ -65,8 +88,12 @@ former = { workspace = true, features = [ "default" ] } iter_tools = { workspace = true, features = [ "default" ] } mod_interface = { workspace = true, features = [ "default" ] } wca = { workspace = true, features = [ "default" ] } -proper_path_tools = { workspace = true, features = [ "default" ] } +proper_path_tools = { workspace = true, features = [ "default", "path_utf8" ] } process_tools = { workspace = true, features = [ "default" ] } +derive_tools = { workspace = true, features = [ "derive_display", "derive_from_str", "derive_deref", "derive_from", "derive_as_ref" ] } +data_type = { workspace = true, features = [ "either" ] } +collection_tools = { workspace = true, features = [ "collection_constructors", "collection_into_constructors" ] } +macro_tools = { workspace = true, features = [ "default" ] } [dev-dependencies] test_tools = { workspace = true } diff --git a/module/move/willbe/src/description.md b/module/move/willbe/src/Readme.md similarity index 100% rename from module/move/willbe/src/description.md rename to module/move/willbe/src/Readme.md diff --git a/module/move/willbe/src/action/cicd_renew.rs b/module/move/willbe/src/action/cicd_renew.rs index 573a2a13bc..fdf14a1216 100644 --- a/module/move/willbe/src/action/cicd_renew.rs +++ b/module/move/willbe/src/action/cicd_renew.rs @@ -4,39 +4,36 @@ mod private use std:: { - path::Path, fs::File, io::{ Write, Read }, - collections::BTreeMap }; - // aaa : for Petro : don't use cargo_metadata and Package directly, use facade - // aaa : ✅ + use path::{ Path }; + use collection::BTreeMap; use convert_case::{ Casing, Case }; use handlebars::{ RenderError, TemplateError }; use toml_edit::Document; - use _path::AbsolutePath; - use crate::manifest::private::CrateDirError; - use error_tools::for_lib::Error; - use error_tools::dependency::*; - use workspace::WorkspacePackage; + use entity::{ PathError, WorkspaceInitError }; - use wtools::error::for_app::{ Result, Error as wError }; - use entity::WorkspaceError; - use error_tools::err; + use error:: + { + typed::Error, + err, + }; #[ derive( Debug, Error ) ] pub enum CiCdGenerateError { + // qqq : rid of the branch #[ error( "Common error: {0}" ) ] - Common(#[ from ] wError ), + Common( #[ from ] error::untyped::Error ), #[ error( "I/O error: {0}" ) ] IO( #[ from ] std::io::Error ), #[ error( "Crate directory error: {0}" ) ] - CrateDir( #[ from ] CrateDirError ), + CrateDir( #[ from ] PathError ), #[ error( "Workspace error: {0}" ) ] - Workspace( #[ from ] WorkspaceError), + Workspace( #[ from ] WorkspaceInitError ), #[ error( "Template error: {0}" ) ] Template( #[ from ] TemplateError ), #[ error( "Render error: {0}" ) ] @@ -47,69 +44,155 @@ mod private /// Generate workflows for modules in .github/workflows directory. pub fn cicd_renew( base_path : &Path ) -> Result< (), CiCdGenerateError > { - let workspace_cache = Workspace::with_crate_dir( AbsolutePath::try_from( base_path )?.try_into()? )?; - let packages = workspace_cache.packages()?; - let username_and_repository = &username_and_repository( &workspace_cache.workspace_root()?.join( "Cargo.toml" ).try_into()?, packages.as_slice() )?; - let workspace_root = workspace_cache.workspace_root()?; + let workspace_cache = Workspace::try_from( CrateDir::try_from( base_path )? )?; + let packages = workspace_cache.packages(); + let username_and_repository = &username_and_repository + ( + &workspace_cache.workspace_root().join( "Cargo.toml" ).to_path_buf().try_into()?, // qqq + packages.clone(), + // packages.as_slice(), + )?; + let workspace_root : &Path = &workspace_cache.workspace_root(); // find directory for workflows let workflow_root = workspace_root.join( ".github" ).join( "workflows" ); // map packages name's to naming standard - // aaa : for Petro : avoid calling packages_get twice - // aaa : remove it - let names = packages.iter().map( | p | p.name() ).collect::< Vec< _ > >(); - // map packages path to relative paths fom workspace root, for example D :/work/wTools/module/core/iter_tools => module/core/iter_tools - let relative_paths = - packages - .iter() - .map( | p | p.manifest_path() ) - .filter_map( | p | p.strip_prefix( workspace_root ).ok() ) - .map( | p | p.with_file_name( "" ) ) - .collect::< Vec< _ > >(); + // let names = packages.map( | p | p.name() ).collect::< Vec< _ > >(); + let names = packages.clone().map( | p | p.name().to_string() ); + + // dbg!( &workflow_root ); + + // map packages path to relative paths fom workspace root, + // for example D:/work/wTools/module/core/iter_tools => module/core/iter_tools + let relative_paths = packages + .map( | p | p.manifest_file().ok() ) // aaa : rid of unwrap : removed + .filter_map( | p | + { + // dbg!( &workspace_root ); + Some( path::normalize( workspace_root ) ).and_then( | root_str | + { + + dbg!( &root_str ); + dbg!( &p ); + + Some( p?.strip_prefix( root_str ).ok()?.to_path_buf() ) + //.map( | s | s.display().to_string() ).ok() + }) + }) + .map( | p | + { + path::normalize( p.parent().unwrap() ) + // dbg!( &p ); + // let mut path = PathBuf::from( p ); + // path.set_file_name( "" ); + // path + }); // preparing templates let mut handlebars = handlebars::Handlebars::new(); - handlebars.register_template_string( "auto_pr_to", include_str!( "../../template/workflow/auto_pr_to.hbs" ) )?; - handlebars.register_template_string( "appropraite_branch_for", include_str!( "../../template/workflow/appropraite_branch_for.hbs" ) )?; - handlebars.register_template_string( "auto_merge_to", include_str!( "../../template/workflow/auto_merge_to.hbs" ) )?; - handlebars.register_template_string( "standard_rust_pull_request", include_str!( "../../template/workflow/standard_rust_pull_request.hbs" ) )?; - handlebars.register_template_string( "module_push", include_str!( "../../template/workflow/module_push.hbs" ) )?; - + handlebars.register_template_string + ( + "auto_pr_to", + include_str!( "../../template/workflow/auto_pr_to.hbs" ) + )?; + handlebars.register_template_string + ( + "appropraite_branch_for", + include_str!( "../../template/workflow/appropraite_branch_for.hbs" ) + )?; + handlebars.register_template_string + ( + "auto_merge_to", + include_str!( "../../template/workflow/auto_merge_to.hbs" ) + )?; + handlebars.register_template_string + ( + "standard_rust_pull_request", + include_str!( "../../template/workflow/standard_rust_pull_request.hbs" ) + )?; + handlebars.register_template_string + ( + "module_push", + include_str!( "../../template/workflow/module_push.hbs" ) + )?; // qqq : for Petro : instead of iterating each file manually, iterate each file in loop + // use similar::DiffableStr; + // creating workflow for each module - for ( name, relative_path ) in names.iter().zip( relative_paths.iter() ) + for ( name, relative_path ) in names.zip( relative_paths ) { // generate file names - let workflow_file_name = workflow_root.join( format!( "module_{}_push.yml", name.to_case( Case::Snake ) ) ); - let path = relative_path.join( "Cargo.toml" ); - let mut data = BTreeMap::new(); + let workflow_file_name = workflow_root + .join( format!( "module_{}_push.yml", name.to_case( Case::Snake ) ) ); + let manifest_file = relative_path.join( "Cargo.toml" ); + let mut data : BTreeMap< &str, &str > = BTreeMap::new(); data.insert( "name", name.as_str() ); data.insert( "username_and_repository", username_and_repository.0.as_str() ); data.insert( "branch", "alpha" ); - let path = path.as_str().replace( "\\", "/" ); - data.insert( "manifest_path", path.as_str() ); + let manifest_file = manifest_file.to_string_lossy().replace( "\\", "/" ); + let manifest_file = manifest_file.trim_start_matches( '/' ); + data.insert( "manifest_path", manifest_file ); let content = handlebars.render( "module_push", &data )?; file_write( &workflow_file_name, &content )?; + + println!( "file_write : {:?}", &workflow_file_name ) } - file_write( &workflow_root.join( "appropriate_branch.yml" ), include_str!( "../../template/workflow/appropriate_branch.yml" ) )?; + dbg!( &workflow_root ); + + file_write + ( + &workflow_root + .join("appropriate_branch.yml" ), + include_str!( "../../template/workflow/appropriate_branch.yml" ) + )?; + + let data = map_prepare_for_appropriative_branch + ( + "- beta", + username_and_repository.0.as_str(), + "alpha", + "alpha", + "beta" + ); + file_write + ( + &workflow_root.join( "appropriate_branch_beta.yml" ), + &handlebars.render( "appropraite_branch_for", &data )? + )?; - let data = map_prepare_for_appropriative_branch( "- beta", username_and_repository.0.as_str(), "alpha", "alpha", "beta" ); - file_write( &workflow_root.join( "appropriate_branch_beta.yml" ), &handlebars.render( "appropraite_branch_for", &data )? )?; + let data = map_prepare_for_appropriative_branch + ( + "- main\n - master", + username_and_repository.0.as_str(), + "alpha", + "beta", + "master" + ); - let data = map_prepare_for_appropriative_branch( "- main\n - master", username_and_repository.0.as_str(), "alpha", "beta", "master" ); - file_write( &workflow_root.join( "appropriate_branch_master.yml" ), &handlebars.render( "appropraite_branch_for", &data )? )?; + file_write + ( + &workflow_root.join( "appropriate_branch_master.yml" ), + &handlebars.render( "appropraite_branch_for", &data )? + )?; let mut data = BTreeMap::new(); data.insert( "name", "beta" ); data.insert( "group_branch", "beta" ); data.insert( "branch", "alpha" ); - file_write( &workflow_root.join( "auto_merge_to_beta.yml" ), &handlebars.render( "auto_merge_to", &data )? )?; - - file_write( &workflow_root.join( "auto_pr.yml" ), include_str!( "../../template/workflow/auto_pr.yml" ) )?; + file_write + ( + &workflow_root.join( "auto_merge_to_beta.yml" ), + &handlebars.render( "auto_merge_to", &data )? + )?; + file_write + ( + &workflow_root.join( "auto_pr.yml" ), + include_str!( "../../template/workflow/auto_pr.yml" ) + )?; let mut data = BTreeMap::new(); data.insert( "name", "alpha" ); @@ -135,7 +218,11 @@ mod private data.insert( "src_branch", "${{ github.ref_name }}" ); data.insert( "dest_branch", "alpha" ); - file_write( &workflow_root.join( "auto_pr_to_alpha.yml" ), &handlebars.render( "auto_pr_to", &data )? )?; + file_write + ( + &workflow_root.join( "auto_pr_to_alpha.yml" ), + &handlebars.render( "auto_pr_to", &data )? + )?; let mut data = BTreeMap::new(); data.insert( "name", "beta" ); @@ -145,7 +232,11 @@ mod private data.insert( "src_branch", "alpha" ); data.insert( "dest_branch", "beta" ); - file_write( &workflow_root.join( "auto_pr_to_beta.yml" ), &handlebars.render( "auto_pr_to", &data )? )?; + file_write + ( + &workflow_root.join( "auto_pr_to_beta.yml" ), + &handlebars.render( "auto_pr_to", &data )? + )?; let mut data = BTreeMap::new(); data.insert( "name", "master" ); @@ -155,27 +246,63 @@ mod private data.insert( "src_branch", "beta" ); data.insert( "dest_branch", "master" ); - file_write( &workflow_root.join( "auto_pr_to_master.yml" ), &handlebars.render( "auto_pr_to", &data )? )?; + file_write + ( + &workflow_root.join( "auto_pr_to_master.yml" ), + &handlebars.render( "auto_pr_to", &data )? + )?; - file_write( &workflow_root.join( "runs_clean.yml" ), include_str!( "../../template/workflow/rust_clean.yml" ) )?; + file_write + ( + &workflow_root.join( "runs_clean.yml" ), + include_str!( "../../template/workflow/rust_clean.yml" ) + )?; let mut data = BTreeMap::new(); data.insert( "username_and_repository", username_and_repository.0.as_str() ); - file_write( &workflow_root.join( "standard_rust_pull_request.yml" ), &handlebars.render( "standard_rust_pull_request", &data )? )?; + file_write + ( + &workflow_root.join( "standard_rust_pull_request.yml" ), + &handlebars.render( "standard_rust_pull_request", &data )? + )?; - file_write( &workflow_root.join( "standard_rust_push.yml" ), include_str!( "../../template/workflow/standard_rust_push.yml" ) )?; + file_write + ( + &workflow_root.join( "standard_rust_push.yml" ), + include_str!( "../../template/workflow/standard_rust_push.yml" ) + )?; - file_write( &workflow_root.join( "for_pr_rust_push.yml" ), include_str!( "../../template/workflow/for_pr_rust_push.yml" ) )?; + file_write + ( + &workflow_root.join( "for_pr_rust_push.yml" ), + include_str!( "../../template/workflow/for_pr_rust_push.yml" ) + )?; - file_write( &workflow_root.join( "standard_rust_scheduled.yml" ), include_str!( "../../template/workflow/standard_rust_scheduled.yml" ) )?; + file_write + ( + &workflow_root.join( "standard_rust_scheduled.yml" ), + include_str!( "../../template/workflow/standard_rust_scheduled.yml" ) + )?; - file_write( &workflow_root.join( "standard_rust_status.yml" ), include_str!( "../../template/workflow/standard_rust_status.yml" ) )?; + file_write + ( + &workflow_root.join( "standard_rust_status.yml" ), + include_str!( "../../template/workflow/standard_rust_status.yml" ) + )?; - file_write( &workflow_root.join( "status_checks_rules_update.yml" ), include_str!( "../../template/workflow/status_checks_rules_update.yml" ) )?; + file_write + ( + &workflow_root.join( "status_checks_rules_update.yml" ), + include_str!( "../../template/workflow/status_checks_rules_update.yml" ) + )?; + + file_write + ( + &workflow_root.join( "Readme.md" ), + include_str!( "../../template/workflow/Readme.md" ) + )?; - file_write( &workflow_root.join( "Readme.md" ), include_str!( "../../template/workflow/Readme.md" ) )?; - Ok( () ) } @@ -200,7 +327,7 @@ mod private } /// Create and write or rewrite content in file. - pub fn file_write( filename : &Path, content : &str ) -> Result< () > + pub fn file_write( filename : &Path, content : &str ) -> error::untyped::Result< () > // qqq : use typed error { if let Some( folder ) = filename.parent() { @@ -220,18 +347,18 @@ mod private #[derive( Debug ) ] struct UsernameAndRepository( String ); - // aaa : for Petro : not clear how output should look - // aaa : add to documentation - // aaa : for Petro : newtype? - // aaa : replace to AbsolutePath - // aaa : for Petro : why mut? - // aaa : change signature /// Searches and extracts the username and repository name from the repository URL. /// The repository URL is first sought in the Cargo.toml file of the workspace; /// if not found there, it is then searched in the Cargo.toml file of the module. /// If it is still not found, the search continues in the GitHub remotes. /// Result looks like this: `Wandalen/wTools` - fn username_and_repository( cargo_toml_path : &AbsolutePath, packages : &[ WorkspacePackage ] ) -> Result< UsernameAndRepository > + fn username_and_repository< 'a > + ( + cargo_toml_path : &AbsolutePath, + packages : impl Iterator< Item = WorkspacePackageRef< 'a > >, + ) + -> error::untyped::Result< UsernameAndRepository > + // qqq : use typed error { let mut contents = String::new(); File::open( cargo_toml_path )?.read_to_string( &mut contents )?; @@ -245,7 +372,7 @@ mod private .map( String::from ); if let Some( url ) = url { - return url::extract_repo_url( &url ) + return url::repo_url_extract( &url ) .and_then( | url | url::git_info_extract( &url ).ok() ) .map( UsernameAndRepository ) .ok_or_else( || err!( "Fail to parse repository url from workspace Cargo.toml")) @@ -255,14 +382,15 @@ mod private let mut url = None; for package in packages { - if let Ok( wu ) = manifest::private::repo_url( package.manifest_path().parent().unwrap().as_std_path() ) + // if let Ok( wu ) = manifest::private::repo_url( package.manifest_file().parent().unwrap().as_std_path() ) + if let Ok( wu ) = manifest::repo_url( &package.crate_dir()? ) { url = Some( wu ); break; } } return url - .and_then( | url | url::extract_repo_url( &url ) ) + .and_then( | url | url::repo_url_extract( &url ) ) .and_then( | url | url::git_info_extract( &url ).ok() ) .map( UsernameAndRepository ) .ok_or_else( || err!( "Fail to extract repository url") ) diff --git a/module/move/willbe/src/action/deploy_renew.rs b/module/move/willbe/src/action/deploy_renew.rs index 2bd04f640c..2a6d3b52fd 100644 --- a/module/move/willbe/src/action/deploy_renew.rs +++ b/module/move/willbe/src/action/deploy_renew.rs @@ -2,153 +2,149 @@ mod private { use crate::*; use std::path::Path; - use error_tools::{for_app::Context, Result}; + use error::{ untyped::Context }; use tool::template::*; - /// Template for creating deploy files. - /// - /// Includes terraform deploy options to GCP, and Hetzner, - /// a Makefile for useful commands, and a key directory. - #[ derive( Debug ) ] - pub struct DeployTemplate - { - files : DeployTemplateFiles, - parameters : TemplateParameters, - values : TemplateValues, - } - - // qqq : for Viktor : why DeployTemplate can't be part of template.rs? - - impl Template< DeployTemplateFiles > for DeployTemplate - { - fn create_all( self, path : &Path ) -> Result< () > - { - self.files.create_all( path, &self.values ) - } - - fn parameters( &self ) -> &TemplateParameters - { - &self.parameters - } - - fn set_values( &mut self, values : TemplateValues ) - { - self.values = values - } - - fn get_values( &self ) -> &TemplateValues - { - &self.values - } - - fn get_values_mut( &mut self ) -> &mut TemplateValues - { - &mut self.values - } - - fn parameter_storage( &self ) -> &Path { - "./.deploy_template.toml".as_ref() - } - - fn template_name( &self ) -> &'static str { - "deploy" - } - } - - impl Default for DeployTemplate - { - fn default() -> Self - { - let parameters = TemplateParameters::former() - .parameter( "gcp_project_id" ).is_mandatory( true ).end() - .parameter( "gcp_region" ).end() - .parameter( "gcp_artifact_repo_name" ).end() - .parameter( "docker_image_name" ).end() - .form(); - - Self - { - files : Default::default(), - parameters, - values : Default::default(), - } - } - } - - // qqq : for Viktor : is that structure required? - /// Files for the deploy template. - /// - /// Default implementation contains all required files. - #[ derive( Debug ) ] - pub struct DeployTemplateFiles( Vec< TemplateFileDescriptor > ); - - impl Default for DeployTemplateFiles - { - fn default() -> Self - { - let formed = TemplateFilesBuilder::former() - // root - .file().data( include_str!( "../../template/deploy/.deploy_template.toml.hbs" ) ).path( "./.deploy_template.toml" ).mode( WriteMode::TomlExtend ).is_template( true ).end() - .file().data( include_str!( "../../template/deploy/Makefile.hbs" ) ).path( "./Makefile" ).is_template( true ).end() - // /key - .file().data( include_str!( "../../template/deploy/key/pack.sh" ) ).path( "./key/pack.sh" ).end() - .file().data( include_str!( "../../template/deploy/key/Readme.md" ) ).path( "./key/Readme.md" ).end() - // /deploy/ - .file().data( include_str!( "../../template/deploy/deploy/Dockerfile" ) ).path( "./deploy/Dockerfile" ).end() - .file().data( include_str!( "../../template/deploy/deploy/Readme.md" ) ).path( "./deploy/Readme.md" ).end() - // /deploy/gar - .file().data( include_str!( "../../template/deploy/deploy/gar/Readme.md" ) ).path( "./deploy/gar/Readme.md" ).end() - .file().data( include_str!( "../../template/deploy/deploy/gar/main.tf" ) ).path( "./deploy/gar/main.tf" ).end() - .file().data( include_str!( "../../template/deploy/deploy/gar/outputs.tf" ) ).path( "./deploy/gar/outputs.tf" ).end() - .file().data( include_str!( "../../template/deploy/deploy/gar/variables.tf" ) ).path( "./deploy/gar/variables.tf" ).end() - // /deploy/gce - .file().data( include_str!( "../../template/deploy/deploy/gce/Readme.md" ) ).path( "./deploy/gce/Readme.md" ).end() - .file().data( include_str!( "../../template/deploy/deploy/gce/main.tf" ) ).path( "./deploy/gce/main.tf" ).end() - .file().data( include_str!( "../../template/deploy/deploy/gce/outputs.tf" ) ).path( "./deploy/gce/outputs.tf" ).end() - .file().data( include_str!( "../../template/deploy/deploy/gce/variables.tf" ) ).path( "./deploy/gce/variables.tf" ).end() - // /deploy/gce/templates - .file().data( include_str!( "../../template/deploy/deploy/gce/templates/cloud-init.tpl" ) ).path( "./deploy/gce/templates/cloud-init.tpl" ).end() - // /deploy/gcs - .file().data( include_str!( "../../template/deploy/deploy/gcs/main.tf" ) ).path( "./deploy/gcs/main.tf" ).end() - // /deploy/hetzner - .file().data( include_str!( "../../template/deploy/deploy/hetzner/main.tf" ) ).path( "./deploy/hetzner/main.tf" ).end() - .file().data( include_str!( "../../template/deploy/deploy/hetzner/outputs.tf" ) ).path( "./deploy/hetzner/outputs.tf" ).end() - .file().data( include_str!( "../../template/deploy/deploy/hetzner/variables.tf" ) ).path( "./deploy/hetzner/variables.tf" ).end() - // /deploy/hetzner/templates - .file().data( include_str!( "../../template/deploy/deploy/hetzner/templates/cloud-init.tpl" ) ).path( "./deploy/hetzner/templates/cloud-init.tpl" ).end() - // /deploy/aws - .file().data( include_str!( "../../template/deploy/deploy/aws/main.tf" ) ).path( "./deploy/aws/main.tf" ).end() - .file().data( include_str!( "../../template/deploy/deploy/aws/outputs.tf" ) ).path( "./deploy/aws/outputs.tf" ).end() - .file().data( include_str!( "../../template/deploy/deploy/aws/variables.tf" ) ).path( "./deploy/aws/variables.tf" ).end() - // /deploy/aws/templates - .file().data( include_str!( "../../template/deploy/deploy/aws/templates/cloud-init.tpl" ) ).path( "./deploy/aws/templates/cloud-init.tpl" ).end() - .form(); - - Self( formed.files ) - } - } - - // qqq : for Viktor : should not be required - impl TemplateFiles for DeployTemplateFiles {} - // qqq : for Viktor : should not be required - impl IntoIterator for DeployTemplateFiles - { - type Item = TemplateFileDescriptor; - - type IntoIter = std::vec::IntoIter< Self::Item >; - - fn into_iter( self ) -> Self::IntoIter - { - self.0.into_iter() - } - } - - fn get_dir_name() -> Result< String > - { - let current_dir = std::env::current_dir()?; - let current_dir = current_dir.components().last().context( "Invalid current directory" )?; - Ok( current_dir.as_os_str().to_string_lossy().into() ) - } + // /// Template for creating deploy files. + // /// + // /// Includes terraform deploy options to GCP, and Hetzner, + // /// a Makefile for useful commands, and a key directory. + // #[ derive( Debug ) ] + // pub struct DeployTemplate + // { + // files : DeployTemplateFiles, + // parameters : TemplateParameters, + // values : TemplateValues, + // } + + // // qqq : for Viktor : why DeployTemplate can't be part of template.rs? + + // impl Template< DeployTemplateFiles > for DeployTemplate + // { + // fn create_all( self, path : &Path ) -> error::untyped::Result< () > + // { + // self.files.create_all( path, &self.values ) + // } + + // fn parameters( &self ) -> &TemplateParameters + // { + // &self.parameters + // } + + // fn set_values( &mut self, values : TemplateValues ) + // { + // self.values = values + // } + + // fn get_values( &self ) -> &TemplateValues + // { + // &self.values + // } + + // fn get_values_mut( &mut self ) -> &mut TemplateValues + // { + // &mut self.values + // } + + // fn parameter_storage( &self ) -> &Path { + // "./.deploy_template.toml".as_ref() + // } + + // fn template_name( &self ) -> &'static str { + // "deploy" + // } + // } + + // impl Default for DeployTemplate + // { + // fn default() -> Self + // { + // let parameters = TemplateParameters::former() + // .parameter( "gcp_project_id" ).is_mandatory( true ).end() + // .parameter( "gcp_region" ).end() + // .parameter( "gcp_artifact_repo_name" ).end() + // .parameter( "docker_image_name" ).end() + // .form(); + + // Self + // { + // files : Default::default(), + // parameters, + // values : Default::default(), + // } + // } + // } + + // // qqq : for Viktor : is that structure required? + // /// Files for the deploy template. + // /// + // /// Default implementation contains all required files. + // #[ derive( Debug ) ] + // pub struct DeployTemplateFiles( Vec< TemplateFileDescriptor > ); + + // impl Default for DeployTemplateFiles + // { + // fn default() -> Self + // { + // let formed = TemplateFilesBuilder::former() + // // root + // .file().data( include_str!( "../../template/deploy/.deploy_template.toml.hbs" ) ).path( "./.deploy_template.toml" ).mode( WriteMode::TomlExtend ).is_template( true ).end() + // .file().data( include_str!( "../../template/deploy/Makefile.hbs" ) ).path( "./Makefile" ).is_template( true ).end() + // // /key + // .file().data( include_str!( "../../template/deploy/key/pack.sh" ) ).path( "./key/pack.sh" ).end() + // .file().data( include_str!( "../../template/deploy/key/Readme.md" ) ).path( "./key/Readme.md" ).end() + // // /deploy/ + // .file().data( include_str!( "../../template/deploy/deploy/Dockerfile" ) ).path( "./deploy/Dockerfile" ).end() + // .file().data( include_str!( "../../template/deploy/deploy/Readme.md" ) ).path( "./deploy/Readme.md" ).end() + // // /deploy/gar + // .file().data( include_str!( "../../template/deploy/deploy/gar/Readme.md" ) ).path( "./deploy/gar/Readme.md" ).end() + // .file().data( include_str!( "../../template/deploy/deploy/gar/main.tf" ) ).path( "./deploy/gar/main.tf" ).end() + // .file().data( include_str!( "../../template/deploy/deploy/gar/outputs.tf" ) ).path( "./deploy/gar/outputs.tf" ).end() + // .file().data( include_str!( "../../template/deploy/deploy/gar/variables.tf" ) ).path( "./deploy/gar/variables.tf" ).end() + // // /deploy/gce + // .file().data( include_str!( "../../template/deploy/deploy/gce/Readme.md" ) ).path( "./deploy/gce/Readme.md" ).end() + // .file().data( include_str!( "../../template/deploy/deploy/gce/main.tf" ) ).path( "./deploy/gce/main.tf" ).end() + // .file().data( include_str!( "../../template/deploy/deploy/gce/outputs.tf" ) ).path( "./deploy/gce/outputs.tf" ).end() + // .file().data( include_str!( "../../template/deploy/deploy/gce/variables.tf" ) ).path( "./deploy/gce/variables.tf" ).end() + // // /deploy/gce/templates + // .file().data( include_str!( "../../template/deploy/deploy/gce/templates/cloud-init.tpl" ) ).path( "./deploy/gce/templates/cloud-init.tpl" ).end() + // // /deploy/gcs + // .file().data( include_str!( "../../template/deploy/deploy/gcs/main.tf" ) ).path( "./deploy/gcs/main.tf" ).end() + // // /deploy/hetzner + // .file().data( include_str!( "../../template/deploy/deploy/hetzner/main.tf" ) ).path( "./deploy/hetzner/main.tf" ).end() + // .file().data( include_str!( "../../template/deploy/deploy/hetzner/outputs.tf" ) ).path( "./deploy/hetzner/outputs.tf" ).end() + // .file().data( include_str!( "../../template/deploy/deploy/hetzner/variables.tf" ) ).path( "./deploy/hetzner/variables.tf" ).end() + // // /deploy/hetzner/templates + // .file().data( include_str!( "../../template/deploy/deploy/hetzner/templates/cloud-init.tpl" ) ).path( "./deploy/hetzner/templates/cloud-init.tpl" ).end() + // // /deploy/aws + // .file().data( include_str!( "../../template/deploy/deploy/aws/main.tf" ) ).path( "./deploy/aws/main.tf" ).end() + // .file().data( include_str!( "../../template/deploy/deploy/aws/outputs.tf" ) ).path( "./deploy/aws/outputs.tf" ).end() + // .file().data( include_str!( "../../template/deploy/deploy/aws/variables.tf" ) ).path( "./deploy/aws/variables.tf" ).end() + // // /deploy/aws/templates + // .file().data( include_str!( "../../template/deploy/deploy/aws/templates/cloud-init.tpl" ) ).path( "./deploy/aws/templates/cloud-init.tpl" ).end() + // .form(); + + // Self( formed.files ) + // } + // } + + // // qqq : for Viktor : should not be required + // impl TemplateFiles for DeployTemplateFiles {} + // // qqq : for Viktor : should not be required + // impl IntoIterator for DeployTemplateFiles + // { + // type Item = TemplateFileDescriptor; + + // type IntoIter = std::vec::IntoIter< Self::Item >; + + // fn into_iter( self ) -> Self::IntoIter + // { + // self.0.into_iter() + // } + // } + + // aaa : for Petro : redundant function + // aaa : this function not my, but ok I'll remove it. fn dir_name_to_formatted( dir_name : &str, separator : &str ) -> String { @@ -162,17 +158,34 @@ mod private pub fn deploy_renew ( path : &Path, - mut template : DeployTemplate - ) -> Result< () > + mut template : TemplateHolder + ) + -> error::untyped::Result< () > + // qqq : typed error { if let None = template.load_existing_params( path ) { - let current_dir = get_dir_name()?; + let current_dir = std::env::current_dir()?; + // qqq : for Petro : use file_name + // qqq : for Kos : bad description + let current_dir = current_dir + .components() + .last() + .context( "Invalid current directory" )?; + + let current_dir = current_dir.as_os_str().to_string_lossy(); let artifact_repo_name = dir_name_to_formatted( ¤t_dir, "-" ); let docker_image_name = dir_name_to_formatted( ¤t_dir, "_" ); - template.values.insert_if_empty( "gcp_artifact_repo_name", wca::Value::String( artifact_repo_name ) ); - template.values.insert_if_empty( "docker_image_name", wca::Value::String( docker_image_name ) ); - template.values.insert_if_empty( "gcp_region", wca::Value::String( "europe-central2".into() ) ); + template + .values + .insert_if_empty( "gcp_artifact_repo_name", wca::Value::String( artifact_repo_name ) ); + + template + .values + .insert_if_empty( "docker_image_name", wca::Value::String( docker_image_name ) ); + template + .values + .insert_if_empty( "gcp_region", wca::Value::String( "europe-central2".into() ) ); } template.create_all( path )?; Ok( () ) @@ -183,5 +196,5 @@ mod private crate::mod_interface! { orphan use deploy_renew; - orphan use DeployTemplate; + //orphan use DeployTemplate; } diff --git a/module/move/willbe/src/action/features.rs b/module/move/willbe/src/action/features.rs index 47b9e98f44..26b8701cc2 100644 --- a/module/move/willbe/src/action/features.rs +++ b/module/move/willbe/src/action/features.rs @@ -4,20 +4,21 @@ mod private use std:: { - collections::{ BTreeMap, HashMap }, fmt }; + use collection::{ BTreeMap, HashMap }; - use _path::AbsolutePath; + // // use path::AbsolutePath; use former::Former; - use error_tools::{ for_app::Context, Result }; - use workspace::Workspace; + use error::{ untyped::Context }; + // use workspace::Workspace; /// Options available for the .features command #[ derive( Debug, Former ) ] pub struct FeaturesOptions { - manifest_dir : AbsolutePath, + // crate_dir : AbsolutePath, + crate_dir : CrateDir, with_features_deps : bool, } @@ -62,23 +63,39 @@ mod private ) } ) - } + } } /// List features - pub fn features( FeaturesOptions { manifest_dir, with_features_deps } : FeaturesOptions ) -> Result< FeaturesReport > + pub fn features( FeaturesOptions { crate_dir, with_features_deps } : FeaturesOptions ) + -> error::untyped::Result< FeaturesReport > + // qqq : typed error { - let workspace = Workspace::with_crate_dir( CrateDir::try_from( manifest_dir.clone() )? ).context( "Failed to find workspace" )?; - let packages = workspace.packages()?.into_iter().filter - ( | package | - package.manifest_path().as_str().starts_with( manifest_dir.as_ref().as_os_str().to_str().unwrap() ) - ).collect::< Vec< _ > >(); + let workspace = Workspace::try_from( crate_dir.clone() ).context( "Failed to find workspace" )?; + let packages = workspace.packages().filter + ( + | package | + { + if let Ok( manifest_file ) = package.manifest_file() + { + manifest_file.inner().starts_with(crate_dir.clone().absolute_path()) + } + else + { + false + } + } // aaa : remove unwrap + // aaa : done + ); + // ).collect::< Vec< _ > >(); qqq : rid of. put type at var let mut report = FeaturesReport { with_features_deps, ..Default::default() }; - packages.iter().for_each + packages + // .iter() + .for_each ( | package | { let features = package.features(); diff --git a/module/move/willbe/src/action/list.rs b/module/move/willbe/src/action/list.rs index 6e4bd01dc0..6f2708217b 100644 --- a/module/move/willbe/src/action/list.rs +++ b/module/move/willbe/src/action/list.rs @@ -2,35 +2,21 @@ mod private { use crate::*; - use std:: - { - fmt::{ Formatter, Write }, - path::PathBuf, - collections::HashSet, - }; - use std::collections::HashMap; + + use std::{ fmt, str }; use petgraph:: { - prelude::*, + prelude::{ Dfs, EdgeRef }, algo::toposort, visit::Topo, + Graph, }; - use std::str::FromStr; - use packages::FilterMapOptions; - use wtools::error:: + use error:: { - for_app::{ Error, Context }, - err + ErrWith, err, + untyped::{ Context, format_err }, }; - // aaa : for Petro : don't use cargo_metadata and Package directly, use facade - // aaa : ✅ - - use petgraph::prelude::{ Dfs, EdgeRef }; - use former::Former; - - use workspace::Workspace; - use _path::AbsolutePath; - use workspace::WorkspacePackage; + use tool::{ TreePrinter, ListNodeReport }; /// Args for `list` action. #[ derive( Debug, Default, Copy, Clone ) ] @@ -43,9 +29,9 @@ mod private Topological, } - impl FromStr for ListFormat + impl str::FromStr for ListFormat { - type Err = Error; + type Err = error::untyped::Error; fn from_str( s : &str ) -> Result< Self, Self::Err > { @@ -109,9 +95,9 @@ mod private Local, } - impl FromStr for ListFilter + impl str::FromStr for ListFilter { - type Err = Error; + type Err = error::untyped::Error; fn from_str( s : &str ) -> Result< Self, Self::Err > { @@ -144,144 +130,143 @@ mod private /// - `path_to_manifest`: A `CrateDir` representing the path to the manifest of the crates. /// - `format`: A `ListFormat` enum representing the desired format of the output. /// - `dependency_sources`: A `HashSet` of `DependencySource` representing the sources of the dependencies. - #[ derive( Debug, Former ) ] + #[ derive( Debug, former::Former ) ] pub struct ListOptions { path_to_manifest : CrateDir, format : ListFormat, - info : HashSet< PackageAdditionalInfo >, - dependency_sources : HashSet< DependencySource >, - dependency_categories : HashSet< DependencyCategory >, - } - - struct Symbols - { - down : &'static str, - tee : &'static str, - ell : &'static str, - right : &'static str, - } - - // qqq : fro Bohdan : abstract and move out tree printing. or reuse ready solution for tree printing - // stick to single responsibility - const UTF8_SYMBOLS : Symbols = Symbols - { - down : "│", - tee : "├", - ell : "└", - right : "─", - }; - - /// Represents a node in a dependency graph. - /// It holds essential information about the project dependencies. It is also capable - /// of holding any nested dependencies in a recursive manner, allowing the modeling - /// of complex dependency structures. - #[ derive( Debug, Clone, Eq, PartialEq ) ] - pub struct ListNodeReport - { - /// This could be the name of the library or crate. - pub name : String, - /// Ihe version of the crate. - pub version : Option< String >, - /// The path to the node's source files in the local filesystem. This is - /// optional as not all nodes may have a local presence (e.g., nodes representing remote crates). - pub path : Option< PathBuf >, - /// This field is a flag indicating whether the Node is a duplicate or not. - pub duplicate : bool, - /// A list that stores normal dependencies. - /// Each element in the list is also of the same 'ListNodeReport' type to allow - /// storage of nested dependencies. - pub normal_dependencies : Vec< ListNodeReport >, - /// A list that stores dev dependencies(dependencies required for tests or examples). - /// Each element in the list is also of the same 'ListNodeReport' type to allow - /// storage of nested dependencies. - pub dev_dependencies : Vec< ListNodeReport >, - /// A list that stores build dependencies. - /// Each element in the list is also of the same 'ListNodeReport' type to allow - /// storage of nested dependencies. - pub build_dependencies : Vec< ListNodeReport >, + info : collection::HashSet< PackageAdditionalInfo >, + dependency_sources : collection::HashSet< DependencySource >, + dependency_categories : collection::HashSet< DependencyCategory >, } - impl ListNodeReport - { - /// Displays the name, version, path, and dependencies of a package with appropriate indentation and spacing. - /// - /// # Arguments - /// - /// * `spacer` - A string used for indentation. - /// - /// # Returns - /// - /// * A `Result` containing the formatted string or a `std::fmt::Error` if formatting fails. - pub fn display_with_spacer( &self, spacer : &str ) -> Result< String, std::fmt::Error > - { - let mut f = String::new(); - - write!( f, "{}", self.name )?; - if let Some( version ) = &self.version { write!( f, " {version}" )? } - if let Some( path ) = &self.path { write!( f, " {}", path.display() )? } - if self.duplicate { write!( f, "(*)" )? } - write!( f, "\n" )?; - - let mut new_spacer = format!( "{spacer}{} ", if self.normal_dependencies.len() < 2 { " " } else { UTF8_SYMBOLS.down } ); - - let mut normal_dependencies_iter = self.normal_dependencies.iter(); - let last = normal_dependencies_iter.next_back(); - - for dep in normal_dependencies_iter - { - write!( f, "{spacer}{}{} {}", UTF8_SYMBOLS.tee, UTF8_SYMBOLS.right, dep.display_with_spacer( &new_spacer )? )?; - } - if let Some( last ) = last - { - new_spacer = format!( "{spacer} " ); - write!( f, "{spacer}{}{} {}", UTF8_SYMBOLS.ell, UTF8_SYMBOLS.right, last.display_with_spacer( &new_spacer )? )?; - } - if !self.dev_dependencies.is_empty() - { - let mut dev_dependencies_iter = self.dev_dependencies.iter(); - let last = dev_dependencies_iter.next_back(); - write!( f, "{spacer}[dev-dependencies]\n" )?; - for dep in dev_dependencies_iter - { - write!( f, "{spacer}{}{} {}", UTF8_SYMBOLS.tee, UTF8_SYMBOLS.right, dep.display_with_spacer( &new_spacer )? )?; - } - // unwrap - safe because `is_empty` check - write!( f, "{spacer}{}{} {}", UTF8_SYMBOLS.ell, UTF8_SYMBOLS.right, last.unwrap().display_with_spacer( &new_spacer )? )?; - } - if !self.build_dependencies.is_empty() - { - let mut build_dependencies_iter = self.build_dependencies.iter(); - let last = build_dependencies_iter.next_back(); - write!( f, "{spacer}[build-dependencies]\n" )?; - for dep in build_dependencies_iter - { - write!( f, "{spacer}{}{} {}", UTF8_SYMBOLS.tee, UTF8_SYMBOLS.right, dep.display_with_spacer( &new_spacer )? )?; - } - // unwrap - safe because `is_empty` check - write!( f, "{spacer}{}{} {}", UTF8_SYMBOLS.ell, UTF8_SYMBOLS.right, last.unwrap().display_with_spacer( &new_spacer )? )?; - } - - Ok( f ) - } - } - - impl std::fmt::Display for ListNodeReport - { - fn fmt( &self, f : &mut Formatter< '_ > ) -> std::fmt::Result - { - write!( f, "{}", self.display_with_spacer( "" )? )?; - - Ok( () ) - } - } + // struct Symbols + // { + // down : &'static str, + // tee : &'static str, + // ell : &'static str, + // right : &'static str, + // } + + // // qqq : for Mykyta : make facade, abstract and move out tree printing. or reuse ready solution for tree printing + // // stick to single responsibility + // const UTF8_SYMBOLS : Symbols = Symbols + // { + // down : "│", + // tee : "├", + // ell : "└", + // right : "─", + // }; + + // /// Represents a node in a dependency graph. + // /// It holds essential information about the project dependencies. It is also capable + // /// of holding any nested dependencies in a recursive manner, allowing the modeling + // /// of complex dependency structures. + // #[ derive( Debug, Clone, Eq, PartialEq ) ] + // pub struct ListNodeReport + // { + // /// This could be the name of the library or crate. + // pub name : String, + // /// Ihe version of the crate. + // pub version : Option< String >, + // /// The path to the node's source files in the local filesystem. This is + // /// optional as not all nodes may have a local presence (e.g., nodes representing remote crates). + // pub crate_dir : Option< CrateDir >, + // /// This field is a flag indicating whether the Node is a duplicate or not. + // pub duplicate : bool, + // /// A list that stores normal dependencies. + // /// Each element in the list is also of the same 'ListNodeReport' type to allow + // /// storage of nested dependencies. + // pub normal_dependencies : Vec< ListNodeReport >, + // /// A list that stores dev dependencies(dependencies required for tests or examples). + // /// Each element in the list is also of the same 'ListNodeReport' type to allow + // /// storage of nested dependencies. + // pub dev_dependencies : Vec< ListNodeReport >, + // /// A list that stores build dependencies. + // /// Each element in the list is also of the same 'ListNodeReport' type to allow + // /// storage of nested dependencies. + // pub build_dependencies : Vec< ListNodeReport >, + // } + + // impl ListNodeReport + // { + // /// Displays the name, version, path, and dependencies of a package with appropriate indentation and spacing. + // /// + // /// # Arguments + // /// + // /// * `spacer` - A string used for indentation. + // /// + // /// # Returns + // /// + // /// * A `Result` containing the formatted string or a `std::fmt::Error` if formatting fails. + // pub fn display_with_spacer( &self, spacer : &str ) -> Result< String, std::fmt::Error > + // { + // let mut f = String::new(); + + // write!( f, "{}", self.name )?; + // if let Some( version ) = &self.version { write!( f, " {version}" )? } + // if let Some( crate_dir ) = &self.crate_dir { write!( f, " {}", crate_dir )? } + // if self.duplicate { write!( f, "(*)" )? } + // write!( f, "\n" )?; + + // let mut new_spacer = format!( "{spacer}{} ", if self.normal_dependencies.len() < 2 { " " } else { UTF8_SYMBOLS.down } ); + // let mut normal_dependencies_iter = self.normal_dependencies.iter(); + // let last = normal_dependencies_iter.next_back(); + + // for dep in normal_dependencies_iter + // { + // write!( f, "{spacer}{}{} {}", UTF8_SYMBOLS.tee, UTF8_SYMBOLS.right, dep.display_with_spacer( &new_spacer )? )?; + // } + // if let Some( last ) = last + // { + // new_spacer = format!( "{spacer} " ); + // write!( f, "{spacer}{}{} {}", UTF8_SYMBOLS.ell, UTF8_SYMBOLS.right, last.display_with_spacer( &new_spacer )? )?; + // } + // if !self.dev_dependencies.is_empty() + // { + // let mut dev_dependencies_iter = self.dev_dependencies.iter(); + // let last = dev_dependencies_iter.next_back(); + // write!( f, "{spacer}[dev-dependencies]\n" )?; + // for dep in dev_dependencies_iter + // { + // write!( f, "{spacer}{}{} {}", UTF8_SYMBOLS.tee, UTF8_SYMBOLS.right, dep.display_with_spacer( &new_spacer )? )?; + // } + // // unwrap - safe because `is_empty` check + // write!( f, "{spacer}{}{} {}", UTF8_SYMBOLS.ell, UTF8_SYMBOLS.right, last.unwrap().display_with_spacer( &new_spacer )? )?; + // } + // if !self.build_dependencies.is_empty() + // { + // let mut build_dependencies_iter = self.build_dependencies.iter(); + // let last = build_dependencies_iter.next_back(); + // write!( f, "{spacer}[build-dependencies]\n" )?; + // for dep in build_dependencies_iter + // { + // write!( f, "{spacer}{}{} {}", UTF8_SYMBOLS.tee, UTF8_SYMBOLS.right, dep.display_with_spacer( &new_spacer )? )?; + // } + // // unwrap - safe because `is_empty` check + // write!( f, "{spacer}{}{} {}", UTF8_SYMBOLS.ell, UTF8_SYMBOLS.right, last.unwrap().display_with_spacer( &new_spacer )? )?; + // } + + // Ok( f ) + // } + // } + + // impl std::fmt::Display for ListNodeReport + // { + // fn fmt( &self, f : &mut Formatter< '_ > ) -> std::fmt::Result + // { + // write!( f, "{}", self.display_with_spacer( "" )? )?; + + // Ok( () ) + // } + // } /// Represents the different report formats for the `list` action. #[ derive( Debug, Default, Clone ) ] pub enum ListReport { /// Represents a tree-like report format. - Tree( Vec< ListNodeReport > ), + Tree( Vec< tool::TreePrinter > ), /// Represents a standard list report format in topological order. List( Vec< String > ), /// Represents an empty report format. @@ -289,42 +274,100 @@ mod private Empty, } - impl std::fmt::Display for ListReport + impl fmt::Display for ListReport { - fn fmt( &self, f : &mut Formatter< '_ > ) -> std::fmt::Result + fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> fmt::Result { match self { - Self::Tree( v ) => write!( f, "{}", v.iter().map( | l | l.to_string() ).collect::< Vec< _ > >().join( "\n" ) ), - Self::List( v ) => write!( f, "{}", v.iter().enumerate().map( |( i, v )| format!( "[{i}] {v}" ) ).collect::< Vec< _ > >().join( "\n" ) ), + Self::Tree( v ) => + write! + ( + f, + "{}", + v.iter().map( | l | l.to_string() ).collect::< Vec< _ > >().join( "\n" ) + ), + + Self::List( v ) => + write! + ( + f, + "{}", + v.iter().enumerate().map( |( i, v )| format!( "[{i}] {v}" ) ).collect::< Vec< _ > >().join( "\n" ) + ), + Self::Empty => write!( f, "Nothing" ), } } } - fn process_package_dependency + // aaa : for Bohdan : descirption // aaa : done + /// The `DependencyId` struct encapsulates the essential attributes of a dependency, + #[ derive( Debug, Clone, PartialEq, Eq, Hash ) ] + pub struct DependencyId + { + /// The name of the dependency. + /// + /// This is typically the name of the library or package that the package relies on. + pub name : String, + /// The version requirements for the dependency. + /// + /// Note: This will be compared to other dependencies and packages to build the tree + pub version : semver::VersionReq, + /// An optional path to the manifest file of the dependency. + /// + /// This field may contain a path to the manifest file when the dependency is a local package + /// or when specific path information is needed to locate the dependency's manifest. + pub path : Option< ManifestFile >, + } + + fn process_package_dependency< 'a > ( workspace : &Workspace, - package : &WorkspacePackage, + package : &WorkspacePackageRef< 'a >, args : &ListOptions, - dep_rep : &mut ListNodeReport, - visited : &mut HashSet< String > + dep_rep : &mut tool::ListNodeReport, + visited : &mut collection::HashSet< DependencyId > ) { - for dependency in &package.dependencies() + for dependency in package.dependencies() { - if dependency.path().is_some() && !args.dependency_sources.contains( &DependencySource::Local ) { continue; } - if dependency.path().is_none() && !args.dependency_sources.contains( &DependencySource::Remote ) { continue; } - let dep_id = format!( "{}+{}+{}", dependency.name(), dependency.req(), dependency.path().as_ref().map( | p | p.join( "Cargo.toml" ) ).unwrap_or_default() ); - let mut temp_vis = visited.clone(); - let dependency_rep = process_dependency( workspace, dependency, args, &mut temp_vis ); + // aaa : for Bohdan : bad : suboptimal + // aaa : Is that what you had in mind? + let dep_crate_dir = dependency.crate_dir(); + if dep_crate_dir.is_some() && !args.dependency_sources.contains( &DependencySource::Local ) { continue; } + if dep_crate_dir.is_none() && !args.dependency_sources.contains( &DependencySource::Remote ) { continue; } + + // aaa : extend test coverage. NewType. Description + // aaa : NewType ✅ Description ✅ test coverage ❌ how to test structure without logic? + // qqq : extend test coverage. NewType. Description + let dep_id = DependencyId + { + name : dependency.name(), + // unwrap should be safe because of `semver::VersionReq` + version : dependency.req(), + path : dependency.crate_dir().map( | p | p.manifest_file() ), + }; + // format!( "{}+{}+{}", dependency.name(), dependency.req(), dependency.crate_dir().unwrap().manifest_file() ); + // let dep_id = format!( "{}+{}+{}", dependency.name(), dependency.req(), dependency.path().as_ref().map( | p | p.join( "Cargo.toml" ) ).unwrap_or_default() ); + let mut temp_vis = visited.clone(); + let dependency_rep = process_dependency + ( + workspace, + dependency, + args, + &mut temp_vis + ); match dependency.kind() { - workspace::DependencyKind::Normal if args.dependency_categories.contains( &DependencyCategory::Primary ) => dep_rep.normal_dependencies.push( dependency_rep ), - workspace::DependencyKind::Development if args.dependency_categories.contains( &DependencyCategory::Dev ) => dep_rep.dev_dependencies.push( dependency_rep ), - workspace::DependencyKind::Build if args.dependency_categories.contains( &DependencyCategory::Build ) => dep_rep.build_dependencies.push( dependency_rep ), + DependencyKind::Normal if args.dependency_categories.contains( &DependencyCategory::Primary ) => + dep_rep.normal_dependencies.push( dependency_rep ), + DependencyKind::Development if args.dependency_categories.contains( &DependencyCategory::Dev ) => + dep_rep.dev_dependencies.push( dependency_rep ), + DependencyKind::Build if args.dependency_categories.contains( &DependencyCategory::Build ) => + dep_rep.build_dependencies.push( dependency_rep ), _ => { visited.remove( &dep_id ); std::mem::swap( &mut temp_vis, visited ); } } @@ -332,20 +375,35 @@ mod private } } - fn process_dependency( workspace : &Workspace, dep : &workspace::Dependency, args : &ListOptions, visited : &mut HashSet< String > ) -> ListNodeReport + fn process_dependency + ( + workspace : &Workspace, + dep : DependencyRef< '_ >, + args : &ListOptions, + visited : &mut collection::HashSet< DependencyId > + ) + -> tool::ListNodeReport { - let mut dep_rep = ListNodeReport + let mut dep_rep = tool::ListNodeReport { name : dep.name().clone(), version : if args.info.contains( &PackageAdditionalInfo::Version ) { Some( dep.req().to_string() ) } else { None }, - path : if args.info.contains( &PackageAdditionalInfo::Path ) { dep.path().as_ref().map( | p | p.clone().into_std_path_buf() ) } else { None }, + // manifest_file : if args.info.contains( &PackageAdditionalInfo::Path ) { dep.manifest_file().as_ref().map( | p | p.clone().into_std_path_buf() ) } else { None }, + crate_dir : if args.info.contains( &PackageAdditionalInfo::Path ) { dep.crate_dir() } else { None }, duplicate : false, normal_dependencies : vec![], dev_dependencies : vec![], build_dependencies : vec![], }; - let dep_id = format!( "{}+{}+{}", dep.name(), dep.req(), dep.path().as_ref().map( | p | p.join( "Cargo.toml" ) ).unwrap_or_default() ); + // let dep_id = format!( "{}+{}+{}", dep.name(), dep.req(), dep.crate_dir().as_ref().map( | p | p.join( "Cargo.toml" ) ).unwrap_or_default() ); + let dep_id = DependencyId + { + name : dep.name(), + // unwrap should be safe because of `semver::VersionReq` + version : dep.req(), + path : dep.crate_dir().map( | p | p.manifest_file() ), + }; // if this is a cycle (we have visited this node before) if visited.contains( &dep_id ) { @@ -356,9 +414,9 @@ mod private // if we have not visited this node before, mark it as visited visited.insert( dep_id ); - if let Some( path ) = &dep.path() + if let Some( crate_dir ) = &dep.crate_dir() { - if let Some( package ) = workspace.package_find_by_manifest( path.as_std_path().join( "Cargo.toml" ) ) + if let Some( package ) = workspace.package_find_by_manifest( crate_dir.clone().manifest_file() ) { process_package_dependency( workspace, &package, args, &mut dep_rep, visited ); } @@ -367,19 +425,6 @@ mod private dep_rep } - trait ErrWith< T, T1, E > - { - fn err_with( self, v : T ) -> std::result::Result< T1, ( T, E ) >; - } - - impl< T, T1, E > ErrWith< T, T1, E > for Result< T1, E > - { - fn err_with( self, v : T ) -> Result< T1, ( T, E ) > - { - self.map_err( | e | ( v, e ) ) - } - } - /// Retrieve a list of packages based on the given arguments. /// /// # Arguments @@ -391,106 +436,178 @@ mod private /// - `Result` - A result containing the list report if successful, /// or a tuple containing the list report and error if not successful. #[ cfg_attr( feature = "tracing", tracing::instrument ) ] - pub fn list( args : ListOptions ) -> Result< ListReport, ( ListReport, Error ) > + pub fn list( args : ListOptions ) + -> + ResultWithReport< ListReport, error::untyped::Error > // qqq : should be specific error + // qqq : use typed error { let mut report = ListReport::default(); - let manifest = manifest::open( args.path_to_manifest.absolute_path() ).context( "List of packages by specified manifest path" ).err_with( report.clone() )?; - let metadata = Workspace::with_crate_dir( manifest.crate_dir() ).err_with( report.clone() )?; + let manifest = Manifest::try_from( args.path_to_manifest.clone() ) + .context( "List of packages by specified manifest path" ) + .err_with_report( &report )?; + + let workspace = Workspace::try_from( manifest.crate_dir() ) + .context( "Reading workspace" ) + .err_with_report( &report )?; - let is_package = manifest.package_is().context( "try to identify manifest type" ).err_with( report.clone() )?; + let is_package = manifest.package_is(); + // let is_package = manifest.package_is().context( "try to identify manifest type" ).err_with( report.clone() )?; - let tree_package_report = | path : AbsolutePath, report : &mut ListReport, visited : &mut HashSet< String > | + let tree_package_report = + | manifest_file : ManifestFile, report : &mut ListReport, visited : &mut HashSet< DependencyId > | { - let package = metadata.package_find_by_manifest( path ).unwrap(); - let mut package_report = ListNodeReport + + let package = workspace + .package_find_by_manifest( manifest_file ) + .ok_or_else( || format_err!( "Package not found in the workspace" ) ) + .err_with_report( report )?; + let mut package_report = tool::ListNodeReport { name : package.name().to_string(), + // qqq : for Bohdan : too long lines version : if args.info.contains( &PackageAdditionalInfo::Version ) { Some( package.version().to_string() ) } else { None }, - path : if args.info.contains( &PackageAdditionalInfo::Path ) { Some( package.manifest_path().as_std_path().to_path_buf() ) } else { None }, + // qqq : for Bohdan : don't put multiline if into struct constructor + crate_dir : if args.info.contains( &PackageAdditionalInfo::Path ) + { Some( package.crate_dir() ).transpose() } + else + { Ok( None ) } + .err_with_report( report )?, duplicate : false, normal_dependencies : vec![], dev_dependencies : vec![], build_dependencies : vec![], }; - process_package_dependency( &metadata, &package, &args, &mut package_report, visited ); + process_package_dependency( &workspace, &package, &args, &mut package_report, visited ); + let printer = TreePrinter::new( &package_report ); *report = match report { - ListReport::Tree( ref mut v ) => ListReport::Tree( { v.extend([ package_report ]); v.clone() } ), - ListReport::Empty => ListReport::Tree( vec![ package_report ] ), + ListReport::Tree( ref mut v ) => ListReport::Tree + ( { v.extend([ printer ]); v.clone() } ), + ListReport::Empty => ListReport::Tree( vec![ printer ] ), ListReport::List( _ ) => unreachable!(), }; + Ok( () ) }; + match args.format { ListFormat::Tree if is_package => { - let mut visited = HashSet::new(); - tree_package_report( manifest.manifest_path, &mut report, &mut visited ); + let mut visited = collection::HashSet::new(); + tree_package_report( manifest.manifest_file, &mut report, &mut visited )?; let ListReport::Tree( tree ) = report else { unreachable!() }; - let tree = rearrange_duplicates( merge_dev_dependencies( merge_build_dependencies( tree ) ) ); + let printer = merge_build_dependencies( tree ); + let rep : Vec< ListNodeReport > = printer + .iter() + .map( | printer | printer.info.clone() ) + .collect(); + let tree = rearrange_duplicates( rep ); report = ListReport::Tree( tree ); } ListFormat::Tree => { - let packages = metadata.packages().context( "workspace packages" ).err_with( report.clone() )?; - let mut visited = packages.iter().map( | p | format!( "{}+{}+{}", p.name(), p.version().to_string(), p.manifest_path() ) ).collect(); + let packages = workspace.packages(); + let mut visited = packages + .clone() + .map + ( + // aaa : is it safe to use unwrap here + // unwrap is safe because Version has less information than VersionReq + | p | + DependencyId + { + name : p.name().into(), + version : semver::VersionReq::parse( &p.version().to_string() ).unwrap(), + path : p.manifest_file().ok() + } + ) + .collect(); for package in packages { - tree_package_report( package.manifest_path().as_std_path().try_into().unwrap(), &mut report, &mut visited ) + tree_package_report( package.manifest_file().unwrap(), &mut report, &mut visited )? } let ListReport::Tree( tree ) = report else { unreachable!() }; - let tree = merge_dev_dependencies( merge_build_dependencies( tree ) ); + let printer = merge_build_dependencies( tree ); + let rep : Vec< ListNodeReport > = printer + .iter() + .map( | printer | printer.info.clone() ) + .collect(); + let tree = merge_dev_dependencies( rep ); report = ListReport::Tree( tree ); } ListFormat::Topological => { - let root_crate = manifest - .manifest_data - .as_ref() - .and_then( | m | m.get( "package" ) ) + + let root_crate = manifest.data.get( "package" ) .map( | m | m[ "name" ].to_string().trim().replace( '\"', "" ) ) .unwrap_or_default(); - let dep_filter = move | _p : &WorkspacePackage, d : &workspace::Dependency | + // let root_crate = manifest + // .data + // // .as_ref() + // .and_then( | m | m.get( "package" ) ) + // .map( | m | m[ "name" ].to_string().trim().replace( '\"', "" ) ) + // .unwrap_or_default(); + + let dep_filter = move | _p : WorkspacePackageRef< '_ >, d : DependencyRef< '_ > | { ( - args.dependency_categories.contains( &DependencyCategory::Primary ) && d.kind() == workspace::DependencyKind::Normal - || args.dependency_categories.contains( &DependencyCategory::Dev ) && d.kind() == workspace::DependencyKind::Development - || args.dependency_categories.contains( &DependencyCategory::Build ) && d.kind() == workspace::DependencyKind::Build + args.dependency_categories.contains( &DependencyCategory::Primary ) && d.kind() == DependencyKind::Normal + || args.dependency_categories.contains( &DependencyCategory::Dev ) && d.kind() == DependencyKind::Development + || args.dependency_categories.contains( &DependencyCategory::Build ) && d.kind() == DependencyKind::Build ) && ( - args.dependency_sources.contains( &DependencySource::Remote ) && d.path().is_none() - || args.dependency_sources.contains( &DependencySource::Local ) && d.path().is_some() + args.dependency_sources.contains( &DependencySource::Remote ) && d.crate_dir().is_none() + || args.dependency_sources.contains( &DependencySource::Local ) && d.crate_dir().is_some() ) }; - let packages = metadata.packages().context( "workspace packages" ).err_with( report.clone() )?; - let packages_map = packages::filter + let packages = workspace.packages(); + let packages_map : collection::HashMap< package::PackageName, collection::HashSet< package::PackageName > > = packages::filter ( - packages.as_slice(), - FilterMapOptions { dependency_filter : Some( Box::new( dep_filter ) ), ..Default::default() } + packages.clone(), + packages::FilterMapOptions + { + dependency_filter : Some( Box::new( dep_filter ) ), + ..Default::default() + } ); let graph = graph::construct( &packages_map ); - let sorted = toposort( &graph, None ).map_err( | e | { use std::ops::Index; ( report.clone(), err!( "Failed to process toposort for package : {:?}", graph.index( e.node_id() ) ) ) } )?; - let packages_info = packages.iter().map( | p | ( p.name().clone(), p ) ).collect::< HashMap< _, _ > >(); + let sorted = toposort( &graph, None ) + .map_err + ( + | e | + { + use std::ops::Index; + format_err! + ( + "Failed to process toposort for package : {:?}", + graph.index( e.node_id() ) + ) + } + ) + .err_with_report( &report )?; + let packages_info : collection::HashMap< String, WorkspacePackageRef< '_ > > = + packages.map( | p | ( p.name().to_string(), p ) ).collect(); if root_crate.is_empty() { - let names = sorted - .iter() + let names : Vec< String > = sorted + .into_iter() .rev() - .map( | dep_idx | graph.node_weight( *dep_idx ).unwrap().to_string() ) + .map( | dep_idx | graph.node_weight( dep_idx ).unwrap() ) .map ( - | mut name | + | name : &&package::PackageName | { - if let Some( p ) = packages_info.get( &name ) + let mut name : String = name.to_string(); + if let Some( p ) = packages_info.get( &name[ .. ] ) { if args.info.contains( &PackageAdditionalInfo::Version ) { @@ -500,22 +617,27 @@ mod private if args.info.contains( &PackageAdditionalInfo::Path ) { name.push_str( " " ); - name.push_str( &p.manifest_path().to_string() ); + name.push_str( &p.manifest_file()?.to_string() ); + // aaa : is it safe to use unwrap here? // aaa : should be safe, but now returns an error } } - name + Ok::< String, PathError >( name ) } ) - .collect::< Vec< String > >(); + .collect::< Result< _, _ >>() + .err_with_report( &report )?; report = ListReport::List( names ); } else { - let node = graph.node_indices().find( | n | graph.node_weight( *n ).unwrap() == &&root_crate ).unwrap(); + let node = graph + .node_indices() + .find( | n | graph.node_weight( *n ).unwrap().as_str() == root_crate ) + .unwrap(); let mut dfs = Dfs::new( &graph, node ); let mut subgraph = Graph::new(); - let mut node_map = HashMap::new(); + let mut node_map = collection::HashMap::new(); while let Some( n )= dfs.next( &graph ) { node_map.insert( n, subgraph.add_node( graph[ n ] ) ); @@ -523,7 +645,11 @@ mod private for e in graph.edge_references() { - if let ( Some( &s ), Some( &t ) ) = ( node_map.get( &e.source() ), node_map.get( &e.target() ) ) + if let ( Some( &s ), Some( &t ) ) = + ( + node_map.get( &e.source() ), + node_map.get( &e.target() ) + ) { subgraph.add_edge( s, t, () ); } @@ -533,8 +659,8 @@ mod private let mut names = Vec::new(); while let Some( n ) = topo.next( &subgraph ) { - let mut name = subgraph[ n ].clone(); - if let Some( p ) = packages_info.get( &name ) + let mut name : String = subgraph[ n ].to_string(); + if let Some( p ) = packages_info.get( &name[ .. ] ) { if args.info.contains( &PackageAdditionalInfo::Version ) { @@ -544,7 +670,7 @@ mod private if args.info.contains( &PackageAdditionalInfo::Path ) { name.push_str( " " ); - name.push_str( &p.manifest_path().to_string() ); + name.push_str( &p.manifest_file().unwrap().to_string() ); } } names.push( name ); @@ -559,26 +685,35 @@ mod private Ok( report ) } - fn merge_build_dependencies( mut report: Vec< ListNodeReport > ) -> Vec< ListNodeReport > + fn merge_build_dependencies( mut report: Vec< tool::TreePrinter > ) -> Vec< tool::TreePrinter > { let mut build_dependencies = vec![]; for node_report in &mut report { - build_dependencies = merge_build_dependencies_impl( node_report, build_dependencies ); + build_dependencies = merge_build_dependencies_impl + ( + &mut node_report.info, + build_dependencies + ); } if let Some( last_report ) = report.last_mut() { - last_report.build_dependencies = build_dependencies; + last_report.info.build_dependencies = build_dependencies; } report } - - fn merge_build_dependencies_impl( report : &mut ListNodeReport, mut build_deps_acc : Vec< ListNodeReport > ) -> Vec< ListNodeReport > + + fn merge_build_dependencies_impl + ( + report : &mut tool::ListNodeReport, + mut build_deps_acc : Vec< tool::ListNodeReport > + ) + -> Vec< tool::ListNodeReport > { for dep in report.normal_dependencies.iter_mut() - .chain( report.dev_dependencies.iter_mut() ) - .chain( report.build_dependencies.iter_mut() ) + .chain( report.dev_dependencies.iter_mut() ) + .chain( report.build_dependencies.iter_mut() ) { build_deps_acc = merge_build_dependencies_impl(dep, build_deps_acc ); } @@ -593,8 +728,8 @@ mod private build_deps_acc } - - fn merge_dev_dependencies( mut report: Vec< ListNodeReport > ) -> Vec< ListNodeReport > + + fn merge_dev_dependencies( mut report : Vec< tool::ListNodeReport > ) -> Vec< tool::TreePrinter > { let mut dev_dependencies = vec![]; for node_report in &mut report @@ -605,11 +740,18 @@ mod private { last_report.dev_dependencies = dev_dependencies; } - - report + let printer : Vec< TreePrinter > = report + .iter() + .map( | rep | TreePrinter::new( rep ) ) + .collect(); + printer } - fn merge_dev_dependencies_impl( report : &mut ListNodeReport, mut dev_deps_acc : Vec< ListNodeReport > ) -> Vec< ListNodeReport > + fn merge_dev_dependencies_impl + ( + report : &mut ListNodeReport, + mut dev_deps_acc : Vec< ListNodeReport > + ) -> Vec< ListNodeReport > { for dep in report.normal_dependencies.iter_mut() .chain( report.dev_dependencies.iter_mut() ) @@ -628,27 +770,41 @@ mod private dev_deps_acc } - - fn rearrange_duplicates( mut report : Vec< ListNodeReport > ) -> Vec< ListNodeReport > + + fn rearrange_duplicates( mut report : Vec< tool::ListNodeReport > ) -> Vec< tool::TreePrinter > { - let mut required_normal : HashMap< usize, Vec< ListNodeReport > > = HashMap::new(); + let mut required_normal : collection::HashMap< usize, Vec< tool::ListNodeReport > > = collection::HashMap::new(); for i in 0 .. report.len() { - let ( required, exist ) : ( Vec< _ >, Vec< _ > ) = std::mem::take( &mut report[ i ].normal_dependencies ).into_iter().partition( | d | d.duplicate ); + let ( required, exist ) : ( Vec< _ >, Vec< _ > ) = std::mem::take + ( + &mut report[ i ].normal_dependencies + ) + .into_iter() + .partition( | d | d.duplicate ); report[ i ].normal_dependencies = exist; required_normal.insert( i, required ); } - + rearrange_duplicates_resolver( &mut report, &mut required_normal ); for ( i, deps ) in required_normal { report[ i ].normal_dependencies.extend( deps ); } - - report + + let printer : Vec< TreePrinter > = report + .iter() + .map( | rep | TreePrinter::new( rep ) ) + .collect(); + + printer } - - fn rearrange_duplicates_resolver( report : &mut [ ListNodeReport ], required : &mut HashMap< usize, Vec< ListNodeReport > > ) + + fn rearrange_duplicates_resolver + ( + report : &mut [ ListNodeReport ], + required : &mut HashMap< usize, Vec< ListNodeReport > > + ) { for node in report { @@ -659,7 +815,11 @@ mod private if !node.duplicate { if let Some( r ) = required.iter_mut().flat_map( |( _, v )| v ) - .find( | r | r.name == node.name && r.version == node.version && r.path == node.path ) + .find + ( + | r | + r.name == node.name && r.version == node.version && r.crate_dir == node.crate_dir + ) { std::mem::swap( r, node ); } @@ -673,21 +833,21 @@ mod private crate::mod_interface! { /// Arguments for `list` action. - protected use ListOptions; + own use ListOptions; /// Additional information to include in a package report. - protected use PackageAdditionalInfo; + own use PackageAdditionalInfo; /// Represents where a dependency located. - protected use DependencySource; + own use DependencySource; /// Represents the category of a dependency. - protected use DependencyCategory; + own use DependencyCategory; /// Argument for `list` action. Sets the output format. - protected use ListFormat; + own use ListFormat; /// Argument for `list` action. Sets filter(local or all) packages should be in the output. - protected use ListFilter; + own use ListFilter; /// Contains output of the action. - protected use ListReport; + own use ListReport; /// Contains output of a single node of the action. - protected use ListNodeReport; + // own use ListNodeReport; /// List packages in workspace. orphan use list; } diff --git a/module/move/willbe/src/action/main_header.rs b/module/move/willbe/src/action/main_header.rs index e1b5a7a16e..7c1b5af526 100644 --- a/module/move/willbe/src/action/main_header.rs +++ b/module/move/willbe/src/action/main_header.rs @@ -15,37 +15,26 @@ mod private }; use std::path::PathBuf; use regex::Regex; - use wca::wtools::anyhow::Error; - use action::readme_health_table_renew:: + use entity::{ PathError, WorkspaceInitError }; + use error:: { - readme_path, - workspace_root - }; - use _path::AbsolutePath; - use { CrateDir, query, url, Workspace, wtools }; - use entity::{ CrateDirError, WorkspaceError }; - use wtools::error:: - { - anyhow::format_err, err, - for_app:: - { - Result, - Error as wError, - Context, - }, + untyped::Error, }; - use error_tools:: - { - dependency::*, - for_lib::Error, - }; - + use workspace_md_extension::WorkspaceMdExtension; + static TAGS_TEMPLATE : std::sync::OnceLock< Regex > = std::sync::OnceLock::new(); fn regexes_initialize() { - TAGS_TEMPLATE.set( Regex::new( r"(.|\n|\r\n)+" ).unwrap() ).ok(); + TAGS_TEMPLATE.set + ( + Regex::new + ( + r"(.|\n|\r\n)+" + ) + .unwrap() + ).ok(); } /// Report. @@ -67,14 +56,17 @@ mod private { writeln!( f, "File successful changed : {file_path}." )?; } - else + else { writeln!( f, "File successful changed but contains non-UTF-8 characters." )?; } } - else + else { - if let Some( Some( file_path ) ) = self.found_file.as_ref().map( | p | p.to_str() ) + if let Some( Some( file_path ) ) = self + .found_file + .as_ref() + .map( | p | p.to_str() ) { writeln!( f, "File found but not changed : {file_path}." )?; } @@ -87,17 +79,23 @@ mod private } } - #[ derive( Debug, Error ) ] + /// The `MainHeaderRenewError` enum represents the various errors that can occur during + /// the renewal of the main header. + #[ derive( Debug, error::Error ) ] pub enum MainHeaderRenewError { + /// Represents a common error. #[ error( "Common error: {0}" ) ] - Common(#[ from ] wError ), + Common(#[ from ] Error ), + /// Represents an I/O error. #[ error( "I/O error: {0}" ) ] IO( #[ from ] std::io::Error ), + /// Represents an error related to workspace initialization. #[ error( "Workspace error: {0}" ) ] - Workspace( #[ from ] WorkspaceError), + Workspace( #[ from ] WorkspaceInitError ), + /// Represents an error related to directory paths. #[ error( "Directory error: {0}" ) ] - Directory( #[ from ] CrateDirError ), + Directory( #[ from ] PathError ), } /// The `HeaderParameters` structure represents a set of parameters, used for creating url for header. @@ -112,12 +110,22 @@ mod private impl HeaderParameters { /// Create `HeaderParameters` instance from the folder where Cargo.toml is stored. - fn from_cargo_toml( workspace : Workspace ) -> Result< Self, MainHeaderRenewError > + fn from_cargo_toml( workspace : &Workspace ) -> Result< Self, MainHeaderRenewError > { - let repository_url = workspace.repository_url()?.ok_or_else::< Error, _ >( || err!( "repo_url not found in workspace Cargo.toml" ) )?; - let master_branch = workspace.master_branch()?.unwrap_or( "master".into() ); - let workspace_name = workspace.workspace_name()?.ok_or_else::< Error, _ >( || err!( "workspace_name not found in workspace Cargo.toml" ) )?; - let discord_url = workspace.discord_url()?; + // aaa : for Petro : too long lines, review all files + // aaa : done + let repository_url = workspace + .repository_url() + .ok_or_else::< Error, _ > + ( || err!( "repo_url not found in workspace Cargo.toml" ) )?; + + let master_branch = workspace.master_branch().unwrap_or( "master".into() ); + let workspace_name = workspace + .workspace_name() + .ok_or_else::< Error, _ > + ( || err!( "workspace_name not found in workspace Cargo.toml" ) )?; + + let discord_url = workspace.discord_url(); Ok ( @@ -134,8 +142,15 @@ mod private /// Convert `Self`to header. fn to_header( self ) -> Result< String, MainHeaderRenewError > { - let discord = self.discord_url.map( | discord | - format!( "\n[![discord](https://img.shields.io/discord/872391416519737405?color=eee&logo=discord&logoColor=eee&label=ask)]({discord})" ) + let discord = self.discord_url + .map + ( + | discord | + format! + ( + "\n[![discord](https://img.shields.io/discord/872391416519737405?color=eee&logo=discord&logoColor=eee&label=ask)]({})", + discord + ) ) .unwrap_or_default(); @@ -178,40 +193,41 @@ mod private /// [![docs.rs](https://raster.shields.io/static/v1?label=docs&message=online&color=eee&logo=docsdotrs&logoColor=eee)](https://docs.rs/wtools) /// /// ``` - pub fn readme_header_renew( path : AbsolutePath ) -> Result< MainHeaderRenewReport, ( MainHeaderRenewReport, MainHeaderRenewError ) > + pub fn readme_header_renew( crate_dir : CrateDir ) + // -> Result< MainHeaderRenewReport, ( MainHeaderRenewReport, MainHeaderRenewError ) > + -> ResultWithReport< MainHeaderRenewReport, MainHeaderRenewError > { let mut report = MainHeaderRenewReport::default(); regexes_initialize(); - let mut cargo_metadata = Workspace::with_crate_dir - ( - CrateDir::try_from( path ) - .map_err( | e | ( report.clone(), e.into() ) )? - ).map_err( | e | ( report.clone(), e.into() ) )?; - - let workspace_root = workspace_root( &mut cargo_metadata ) - .map_err( | e | ( report.clone(), e.into() ) )?; - - let header_param = HeaderParameters::from_cargo_toml( cargo_metadata ) - .map_err( | e | ( report.clone(), e.into() ) )?; - + let workspace = Workspace::try_from + ( + crate_dir + ) + .err_with_report( &report )?; + + let workspace_root = workspace + .workspace_root(); + + let header_param = HeaderParameters::from_cargo_toml( &workspace ) + .err_with_report( &report )?; + let read_me_path = workspace_root.join - ( - readme_path( &workspace_root ) - .ok_or_else( || format_err!( "Fail to find README.md" ) ) - .map_err( | e | ( report.clone(), e.into() ) )? + ( + repository::readme_path( &workspace_root ) + .err_with_report( &report )? ); - - report.found_file = Some( read_me_path.clone() ); - + + report.found_file = Some( read_me_path.clone().to_path_buf() ); + let mut file = OpenOptions::new() .read( true ) .write( true ) .open( &read_me_path ) - .map_err( | e | ( report.clone(), e.into() ) )?; + .err_with_report( &report )?; let mut content = String::new(); - file.read_to_string( &mut content ).map_err( | e | ( report.clone(), e.into() ) )?; + file.read_to_string( &mut content ).err_with_report( &report )?; let raw_params = TAGS_TEMPLATE .get() @@ -221,19 +237,26 @@ mod private .map( | m | m.as_str() ) .unwrap_or_default(); - _ = query::parse( raw_params ).context( "Fail to parse arguments" ); + // _ = query::parse( raw_params ).context( "Fail to parse arguments" ); + // qqq : for Petro : why ignored? + // aaa : commented - let header = header_param.to_header().map_err( | e | ( report.clone(), e.into() ) )?; + let header = header_param.to_header().err_with_report( &report )?; let content : String = TAGS_TEMPLATE.get().unwrap().replace - ( - &content, - &format!( "\n{header}\n" ) + ( + &content, + &format! + ( + "\n{}\n", + raw_params, + header, + ) ).into(); - - file.set_len( 0 ).map_err( | e | ( report.clone(), e.into() ) )?; - file.seek( SeekFrom::Start( 0 ) ).map_err( | e | ( report.clone(), e.into() ) )?; - file.write_all( content.as_bytes() ).map_err( | e | ( report.clone(), e.into() ) )?; - report.touched_file = read_me_path; + + file.set_len( 0 ).err_with_report( &report )?; + file.seek( SeekFrom::Start( 0 ) ).err_with_report( &report )?; + file.write_all( content.as_bytes() ).err_with_report( &report )?; + report.touched_file = read_me_path.to_path_buf(); report.success = true; Ok( report ) } @@ -245,4 +268,6 @@ crate::mod_interface! orphan use readme_header_renew; /// Report. orphan use MainHeaderRenewReport; + /// Error. + orphan use MainHeaderRenewError; } \ No newline at end of file diff --git a/module/move/willbe/src/action/mod.rs b/module/move/willbe/src/action/mod.rs index 0c66bb41ce..728271c2a5 100644 --- a/module/move/willbe/src/action/mod.rs +++ b/module/move/willbe/src/action/mod.rs @@ -11,8 +11,6 @@ crate::mod_interface! /// Return the differences between a local and remote package versions. layer publish_diff; /// Generates health table in main Readme.md file of workspace. - // aaa : for Petro : give high quality explanations - // aaa : add more details to description layer readme_health_table_renew; /// Module headers. layer readme_modules_headers_renew; diff --git a/module/move/willbe/src/action/publish.rs b/module/move/willbe/src/action/publish.rs index 6788a11f1c..58412a2d7a 100644 --- a/module/move/willbe/src/action/publish.rs +++ b/module/move/willbe/src/action/publish.rs @@ -3,14 +3,12 @@ mod private { use crate::*; - use std::collections::{ HashSet, HashMap }; - use core::fmt::Formatter; - use std::{ env, fs }; - - use wtools::error::for_app::{ Error, anyhow }; - use _path::AbsolutePath; - use workspace::Workspace; - use package::Package; + use std::{ env, fmt, fs }; + use + { + // error::untyped, + error::ErrWith, + }; /// Represents a report of publishing packages #[ derive( Debug, Default, Clone ) ] @@ -18,14 +16,14 @@ mod private { /// Represents the absolute path to the root directory of the workspace. pub workspace_root_dir : Option< AbsolutePath >, - pub plan : Option< package::PublishPlan >, + pub plan : Option< publish::PublishPlan >, /// Represents a collection of packages and their associated publishing reports. - pub packages : Vec<( AbsolutePath, package::PublishReport )> + pub packages : Vec<( AbsolutePath, publish::PublishReport )> } - impl std::fmt::Display for PublishReport + impl fmt::Display for PublishReport { - fn fmt( &self, f : &mut Formatter< '_ > ) -> std::fmt::Result + fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> fmt::Result { if self.packages.is_empty() { @@ -51,12 +49,20 @@ mod private { if !plan.dry { - let expected_to_publish = plan + let expected_to_publish : Vec< _ > = plan .plans .iter() - .map( | p | ( p.version_bump.crate_dir.absolute_path(), p.package_name.clone(), p.version_bump.clone() ) ) - .collect::< Vec< _ > >(); - let mut actually_published = self.packages.iter() + .map + ( + | p | + ( + p.bump.crate_dir.clone().absolute_path(), + p.package_name.clone(), + p.bump.clone() + ) + ) + .collect(); + let mut actually_published : Vec< _ > = self.packages.iter() .filter_map ( |( path, repo )| @@ -69,12 +75,14 @@ mod private None } ) - .collect::< Vec< _ > >(); + .collect(); writeln!( f, "Status :" )?; - for ( path, name, version ) in expected_to_publish + for ( path, name, version ) in expected_to_publish { - if let Some( pos ) = actually_published.iter().position( | p | p == &path ) + if let Some( pos ) = actually_published + .iter() + .position( | p | p == &path ) { writeln!( f, "✅ {name} {}", version.new_version )?; // want to check that only expected packages actually published @@ -107,45 +115,76 @@ mod private /// # Returns /// A Result containing a `PublishPlan` if successful, or an `Error` otherwise. #[ cfg_attr( feature = "tracing", tracing::instrument ) ] - pub fn publish_plan( patterns : Vec< String >, dry : bool, temp : bool ) -> Result< package::PublishPlan, Error > + pub fn publish_plan + ( + patterns : Vec< String >, + channel : channel::Channel, + dry : bool, + temp : bool + ) + -> Result< publish::PublishPlan, error::untyped::Error > + // qqq : use typed error { - let mut paths = HashSet::new(); + let mut paths = collection::HashSet::new(); // find all packages by specified folders for pattern in &patterns { - let current_path = AbsolutePath::try_from( std::path::PathBuf::from( pattern ) )?; + let current_path = AbsolutePath::try_from + ( + fs::canonicalize( pattern.as_str() )? + )?; + // let current_path = AbsolutePath::try_from( std::path::PathBuf::from( pattern ) )?; // let current_paths = files::find( current_path, &[ "Cargo.toml" ] ); paths.extend( Some( current_path ) ); } - let mut metadata = if paths.is_empty() + let workspace = if paths.is_empty() { - Workspace::from_current_path()? + Workspace::try_from( CurrentPath )? } else { - // FIX : patterns can point to different workspaces. Current solution take first random path from list + // qqq : patterns can point to different workspaces. Current solution take first random path from list. + // A problem may arise if a user provides paths to packages from different workspaces + // and we do not check whether all packages are within the same workspace + // In the current solution, we'll choose the workspace related to the first package let current_path = paths.iter().next().unwrap().clone(); let dir = CrateDir::try_from( current_path )?; - - Workspace::with_crate_dir( dir )? + Workspace::try_from( dir )? }; - let workspace_root_dir : AbsolutePath = metadata - .workspace_root()? + + let workspace_root_dir : AbsolutePath = workspace + .workspace_root() .try_into()?; - let packages = metadata.load()?.packages()?; - let packages_to_publish : Vec< _ > = packages - .iter() - .filter( | &package | paths.contains( &AbsolutePath::try_from( package.manifest_path().as_std_path().parent().unwrap() ).unwrap() ) ) - .map( | p | p.name().clone() ) + + let packages = workspace.packages(); + let packages_to_publish : Vec< String > = packages + .clone() + .filter( | &package | paths.contains( &package.crate_dir().unwrap().into() ) ) + .map( | p | p.name().to_string() ) + .collect(); + let package_map : collection::HashMap< String, package::Package< '_ > > = packages + .map( | p | ( p.name().to_string(), package::Package::from( p ) ) ) .collect(); - let package_map = packages.into_iter().map( | p | ( p.name().clone(), Package::from( p.clone() ) ) ).collect::< HashMap< _, _ > >(); - let graph = metadata.graph(); - let subgraph_wanted = graph::subgraph( &graph, &packages_to_publish ); - let tmp = subgraph_wanted.map( | _, n | graph[ *n ].clone(), | _, e | graph[ *e ].clone() ); + let graph = workspace_graph::graph( &workspace ); + let subgraph_wanted = graph::subgraph + ( + &graph, + &packages_to_publish[ .. ] + ); + let tmp = subgraph_wanted + .map + ( + | _, n | + graph[ *n ].clone(), | _, e | graph[ *e ].clone() + ); - let mut unique_name = format!( "temp_dir_for_publish_command_{}", path_tools::path::unique_folder_name()? ); + let mut unique_name = format! + ( + "temp_dir_for_publish_command_{}", + path::unique_folder_name()? + ); let dir = if temp { @@ -153,7 +192,11 @@ mod private while temp_dir.exists() { - unique_name = format!( "temp_dir_for_publish_command_{}", path_tools::path::unique_folder_name()? ); + unique_name = format! + ( + "temp_dir_for_publish_command_{}", + path::unique_folder_name()? + ); temp_dir = env::temp_dir().join( unique_name ); } @@ -165,14 +208,29 @@ mod private None }; - let subgraph = graph::remove_not_required_to_publish( &package_map, &tmp, &packages_to_publish, dir.clone() )?; - let subgraph = subgraph.map( | _, n | n, | _, e | e ); + let subgraph = graph::remove_not_required_to_publish + ( + &package_map, + &tmp, + &packages_to_publish, + dir.clone() + )?; + let subgraph = subgraph + .map( | _, n | n, | _, e | e ); - let queue = graph::toposort( subgraph ).unwrap().into_iter().map( | n | package_map.get( &n ).unwrap() ).cloned().collect::< Vec< _ > >(); + let queue : Vec< _ > = graph::toposort( subgraph ) + .unwrap() + .into_iter() + .map( | n | package_map.get( &n ).unwrap() ) + .cloned() + .collect(); - let roots = packages_to_publish.iter().map( | p | package_map.get( p ).unwrap().crate_dir() ).collect::< Vec< _ > >(); + let roots : Vec< _ > = packages_to_publish + .iter() + .map( | p | package_map.get( p ).unwrap().crate_dir() ).collect(); - let plan = package::PublishPlan::former() + let plan = publish::PublishPlan::former() + .channel( channel ) .workspace_dir( CrateDir::try_from( workspace_root_dir ).unwrap() ) .option_base_temp_dir( dir.clone() ) .dry( dry ) @@ -188,13 +246,16 @@ mod private /// #[ cfg_attr( feature = "tracing", tracing::instrument ) ] - pub fn publish( plan : package::PublishPlan ) -> Result< PublishReport, ( PublishReport, Error ) > + pub fn publish( plan : publish::PublishPlan ) + -> + ResultWithReport< PublishReport, error::untyped::Error > + // qqq : use typed error { let mut report = PublishReport::default(); let temp = plan.base_temp_dir.clone(); report.plan = Some( plan.clone() ); - for package_report in package::perform_packages_publish( plan ).err_with( || report.clone() )? + for package_report in publish::perform_packages_publish( plan ).err_with_report( &report )? { let path : &std::path::Path = package_report.get_info.as_ref().unwrap().current_path.as_ref(); report.packages.push(( AbsolutePath::try_from( path ).unwrap(), package_report )); @@ -202,31 +263,11 @@ mod private if let Some( dir ) = temp { - fs::remove_dir_all( dir ).err_with( || report.clone() )?; + fs::remove_dir_all( dir ).err_with_report( &report )?; } Ok( report ) } - - - trait ErrWith< T, T1, E > - { - fn err_with< F >( self, f : F ) -> std::result::Result< T1, ( T, E ) > - where - F : FnOnce() -> T; - } - - impl< T, T1, E > ErrWith< T, T1, Error > for Result< T1, E > - where - E : std::fmt::Debug + std::fmt::Display + Send + Sync + 'static, - { - fn err_with< F >( self, f : F ) -> Result< T1, ( T, Error ) > - where - F : FnOnce() -> T, - { - self.map_err( | e | ( f(), anyhow!( e ) ) ) - } - } } // diff --git a/module/move/willbe/src/action/publish_diff.rs b/module/move/willbe/src/action/publish_diff.rs index 9d21fec7ec..d27920c7bc 100644 --- a/module/move/willbe/src/action/publish_diff.rs +++ b/module/move/willbe/src/action/publish_diff.rs @@ -3,17 +3,19 @@ mod private { use crate::*; - use std::path::PathBuf; - use std::collections::HashMap; - use std::fmt::Formatter; + use path::PathBuf; + use collection::HashMap; + use std::fmt; use colored::Colorize; use crates_tools::CrateArchive; - use action::list::{ ListReport, ListNodeReport }; - use _path::AbsolutePath; - use wtools::error::for_app::Result; + use action::list::ListReport; + use error::untyped::Result; + // qqq : group dependencies use diff::{ DiffReport, crate_diff }; - use error_tools::for_app::format_err; + use error::untyped::format_err; + use tool::ListNodeReport; + use tool::TreePrinter; /// Options for `publish_diff` command #[ derive( Debug, former::Former ) ] @@ -22,7 +24,7 @@ mod private path : PathBuf, keep_archive : Option< PathBuf >, } - + #[ derive( Debug ) ] pub struct PublishDiffReport { @@ -30,29 +32,46 @@ mod private pub root_path : AbsolutePath, pub tree : ListNodeReport, } - + impl std::fmt::Display for PublishDiffReport { - fn fmt( &self, f : &mut Formatter< '_ > ) -> std::fmt::Result + fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> std::fmt::Result { let mut tree = self.tree.clone(); - let root_path = tree.path.as_ref().unwrap().clone(); + let root_path = tree.crate_dir.as_ref().unwrap().clone(); let root_name = tree.name.clone(); let root_version = tree.version.as_ref().unwrap().clone(); - + fn modify( diffs : &HashMap< AbsolutePath, DiffReport >, tree : &mut ListNodeReport ) { - let path = tree.path.take().unwrap(); - let path = path.as_path().to_string_lossy(); - let path = path.strip_suffix( "Cargo.toml" ).unwrap_or( &path ); - let root = AbsolutePath::try_from( path ).unwrap(); + let path = tree.crate_dir.take().unwrap(); + let root = AbsolutePath::from( path ); let diff = diffs.get( &root ).unwrap(); let has_changes = diff.has_changes(); - tree.name = if has_changes { format!( "{}", tree.name.yellow() ) } else { tree.name.clone() }; - tree.version.as_mut().map( | v | *v = format!( "{} {}", if has_changes { v.yellow() } else { v.as_str().into() }, if has_changes { "MODIFIED" } else { "" } ) ); - + tree.name = if has_changes + { + format!( "{}", tree.name.yellow() ) + } + else + { + tree.name.clone() + }; + tree + .version + .as_mut() + .map + ( + | v | + *v = format! + ( + "{} {}", + if has_changes { v.yellow() } else { v.as_str().into() }, + if has_changes { "MODIFIED" } else { "" } + ) + ); + for dep in &mut tree.normal_dependencies { modify( diffs, dep ) @@ -60,13 +79,20 @@ mod private } modify( &self.diffs, &mut tree ); - let path = root_path.as_path().to_string_lossy(); - let path = path.strip_suffix( "Cargo.toml" ).unwrap_or( &path ); - let root = AbsolutePath::try_from( path ).unwrap(); + let root = AbsolutePath::from( root_path ); let diff = self.diffs.get( &root ).unwrap(); - - write!( f, "Tree:\n{}\nChanges in `{root_name} {root_version}`:\n{}", tree, diff )?; - + let printer = TreePrinter::new( &tree ); + writeln!( f, "Tree:\n{}", printer )?; + if diff.has_changes() + { + writeln!( f, "Changes detected in `{root_name} {root_version}`:" )?; + } + else + { + writeln!( f, "No changes found in `{root_name} {root_version}`. Files:" )?; + } + write!( f, "{}", diff )?; + Ok( () ) } } @@ -74,10 +100,11 @@ mod private /// Return the differences between a local and remote package versions. #[ cfg_attr( feature = "tracing", tracing::instrument ) ] pub fn publish_diff( o : PublishDiffOptions ) -> Result< PublishDiffReport > + // qqq : don't use 1-prameter Result { let path = AbsolutePath::try_from( o.path )?; let dir = CrateDir::try_from( path.clone() )?; - + let list = action::list ( action::list::ListOptions::former() @@ -89,22 +116,39 @@ mod private .form() ) .unwrap(); - let ListReport::Tree( mut tree ) = list else { return Err( format_err!( "Logical error. Unexpected list format" ) ) }; + let ListReport::Tree( tree ) = list + else + { + return Err( format_err!( "Logical error. Unexpected list format" ) ) + }; let mut tasks = vec![ tree[ 0 ].clone() ]; let mut diffs = HashMap::new(); let mut current_idx = 0; while current_idx < tasks.len() { - let path = tasks[ current_idx ].path.as_ref().unwrap().to_string_lossy(); - let path = path.strip_suffix( "Cargo.toml" ).unwrap_or( &path ); - let path = AbsolutePath::try_from( path )?; + // let path = tasks[ current_idx ].crate_dir.as_ref().unwrap().to_string_lossy(); + let path = tasks[ current_idx ] + .info + .crate_dir + .as_ref() + .unwrap() + .clone() + .absolute_path(); + // aaa : looks bad. use ready newtypes // aaa : removed let dir = CrateDir::try_from( path.clone() )?; let package = package::Package::try_from( dir.clone() )?; let name = &package.name()?; let version = &package.version()?; - _ = cargo::pack( cargo::PackOptions::former().path( dir.as_ref() ).allow_dirty( true ).no_verify( true ).dry( false ).form() )?; + _ = cargo::pack + ( + cargo::PackOptions::former() + .path( dir.as_ref() ) + .allow_dirty( true ) + .checking_consistency( false ) + .dry( false ).form() + )?; let l = CrateArchive::read( packed_crate::local_path( name, version, dir )? )?; let r = CrateArchive::download_crates_io( name, version ).unwrap(); @@ -124,15 +168,25 @@ mod private } } diffs.insert( path, crate_diff( &l, &r ).exclude( diff::PUBLISH_IGNORE_LIST ) ); - tasks.extend( tasks[ current_idx ].normal_dependencies.clone() ); - + let report = tasks[ current_idx ].info.normal_dependencies.clone(); + let printer : Vec< TreePrinter > = report + .iter() + .map( | rep | TreePrinter::new( rep ) ) + .collect(); + tasks.extend( printer ); + current_idx += 1; } + let printer = tree; + let mut rep : Vec< ListNodeReport > = printer + .iter() + .map( | printer | printer.info.clone() ) + .collect(); let report = PublishDiffReport { root_path : path.clone(), diffs, - tree : tree.remove( 0 ), + tree : rep.remove( 0 ), }; Ok( report ) diff --git a/module/move/willbe/src/action/readme_health_table_renew.rs b/module/move/willbe/src/action/readme_health_table_renew.rs index e9a9bb72e6..438c44dcd8 100644 --- a/module/move/willbe/src/action/readme_health_table_renew.rs +++ b/module/move/willbe/src/action/readme_health_table_renew.rs @@ -4,50 +4,72 @@ mod private use std:: { - str::FromStr, - fs::{ OpenOptions, File, read_dir }, - path::{ Path, PathBuf }, + fs::{ OpenOptions, File }, io::{ Write, Read, Seek, SeekFrom }, - collections::HashMap, }; - - // aaa : for Petro : don't use cargo_metadata and Package directly, use facade - // aaa : ✅ - - - use convert_case::{ Case, Casing }; + use path::{ Path, PathBuf }; + use convert_case::Casing; use toml_edit::Document; use regex::bytes::Regex; + use collection::HashMap; - use wtools::error:: + use error:: { - err, - for_app:: + Error, + untyped:: { - Error, - Result, + // Error as wError, // xxx + // Result, Context, format_err, - bail, } }; - use manifest::private::repo_url; - use _path::AbsolutePath; + use manifest::repo_url; + // use path::AbsolutePath; static TAG_TEMPLATE: std::sync::OnceLock< Regex > = std::sync::OnceLock::new(); static CLOSE_TAG: std::sync::OnceLock< Regex > = std::sync::OnceLock::new(); - /// Initializes two global regular expressions that are used to match tags. fn regexes_initialize() { - TAG_TEMPLATE.set( regex::bytes::Regex::new( r#""# ).unwrap() ).ok(); - CLOSE_TAG.set( regex::bytes::Regex::new( r#""# ).unwrap() ).ok(); + TAG_TEMPLATE.set + ( + regex::bytes::Regex::new + ( + r#""# + ).unwrap() + ).ok(); + CLOSE_TAG.set + ( + regex::bytes::Regex::new + ( + r#""# + ).unwrap() + ).ok(); } + #[ derive( Debug, Error )] + pub enum HealthTableRenewError + { + // qqq : rid of the branch + #[ error( "Common error: {0}" ) ] + Common( #[ from ] error::untyped::Error ), + #[ error( "I/O error: {0}" ) ] + IO( #[ from ] std::io::Error ), + #[ error( "Path error: {0}" ) ] + Path( #[ from ] PathError ), + #[ error( "Workspace error: {0}" ) ] + Workspace( #[ from ] WorkspaceInitError ), + #[ error( "Utf8Error error: {0}" ) ] + Utf8Error( #[ from ] std::str::Utf8Error ), + #[ error( "Toml edit error: {0}" ) ] + Toml( #[ from ] toml_edit::TomlError ) + } /// `Stability` is an enumeration that represents the stability level of a feature. - #[ derive( Debug ) ] + #[ derive( Debug, derive_tools::FromStr ) ] + #[ display( style = "snake_case" ) ] pub enum Stability { /// The feature is still being tested and may change. @@ -62,26 +84,11 @@ mod private Deprecated, } - impl FromStr for Stability - { - type Err = Error; - - fn from_str( s : &str ) -> Result< Self, Self::Err > - { - match s - { - "experimental" => Ok( Stability::Experimental ), - "unstable" => Ok( Stability::Unstable ), - "stable" => Ok( Stability::Stable ), - "frozen" => Ok( Stability::Frozen ), - "deprecated" => Ok( Stability::Deprecated ), - _ => Err( err!( "Fail to parse stability" ) ), - } - } - } + // aaa : qqq : derive? + // aaa : add /// Retrieves the stability level of a package from its `Cargo.toml` file. - fn stability_get( package_path: &Path ) -> Result< Stability > + fn stability_get( package_path : &Path ) -> Result< Stability, HealthTableRenewError > { let path = package_path.join( "Cargo.toml" ); if path.exists() @@ -101,48 +108,67 @@ mod private } else { - Err( err!( "No Cargo.toml found" ) ) + // qqq : for Petro : use typed error + Err( HealthTableRenewError::Common( error::untyped::Error::msg( "Cannot find Cargo.toml" ))) } } /// Represents parameters that are common for all tables #[ derive( Debug ) ] - struct GlobalTableParameters + struct GlobalTableOptions { /// Path to the root repository. - core_url: String, + core_url : String, /// User and repository name, written through '/'. - user_and_repo: String, + user_and_repo : String, /// List of branches in the repository. - branches: Option< Vec< String > >, + branches : Option< Vec< String > >, /// workspace root - workspace_root : String, + workspace_root : PathBuf, + // aaa : for Petro : is not that path? + // aaa : done } /// Structure that holds the parameters for generating a table. #[ derive( Debug ) ] - struct TableParameters + struct TableOptions { // Relative path from workspace root to directory with modules - base_path: String, + base_path : String, // include branches column flag - include_branches: bool, + include_branches : bool, // include stability column flag - include_stability: bool, + include_stability : bool, // include docs column flag - include_docs: bool, + include_docs : bool, // include sample column flag - include: bool, + include : bool, } - impl From< HashMap< String, query::Value > > for TableParameters + impl From< HashMap< String, query::Value > > for TableOptions { - fn from( value : HashMap< String, query::Value >) -> Self + fn from( value : HashMap< String, query::Value > ) -> Self { - let include_branches = value.get( "with_branches" ).map( | v | bool::from( v ) ).unwrap_or( true ); - let include_stability = value.get( "with_stability" ).map( | v | bool::from( v ) ).unwrap_or( true ); - let include_docs = value.get( "with_docs" ).map( | v | bool::from( v ) ).unwrap_or( true ); - let include = value.get( "with_gitpod" ).map( | v | bool::from( v ) ).unwrap_or( true ); + let include_branches = value + .get( "with_branches" ) + .map( | v | bool::from( v ) ) + .unwrap_or( true ); + + let include_stability = value + .get( "with_stability" ) + .map( | v | bool::from( v ) ) + .unwrap_or( true ); + + let include_docs = value + .get( "with_docs" ) + .map( | v | bool::from( v ) ) + .unwrap_or( true ); + + let include = value + .get( "with_gitpod" ) + .map( | v | bool::from( v ) ) + .unwrap_or( true ); + let b_p = value.get( "1" ); let base_path = if let Some( query::Value::String( path ) ) = value.get( "path" ).or( b_p ) { @@ -152,19 +178,27 @@ mod private { "./" }; - Self { base_path: base_path.to_string(), include_branches, include_stability, include_docs, include } + Self + { + base_path: base_path.to_string(), + include_branches, + include_stability, + include_docs, + include + } } } - impl GlobalTableParameters + impl GlobalTableOptions { /// Initializes the struct's fields from a `Cargo.toml` file located at a specified path. - fn initialize_from_path( path: &Path ) -> Result< Self > + fn initialize_from_path( path : &Path ) -> Result< Self, HealthTableRenewError > { + let cargo_toml_path = path.join( "Cargo.toml" ); if !cargo_toml_path.exists() { - bail!( "Cannot find Cargo.toml" ) + return Err( HealthTableRenewError::Common( error::untyped::Error::msg( "Cannot find Cargo.toml" ))) } else { @@ -200,7 +234,16 @@ mod private { user_and_repo = url::git_info_extract( core_url )?; } - Ok( Self { core_url: core_url.unwrap_or_default(), user_and_repo, branches, workspace_root: path.to_string_lossy().to_string() } ) + Ok + ( + Self + { + core_url : core_url.unwrap_or_default(), + user_and_repo, + branches, + workspace_root : path.to_path_buf() + } + ) } } @@ -216,15 +259,20 @@ mod private /// will mean that at this place the table with modules located in the directory module/core will be generated. /// The tags do not disappear after generation. /// Anything between the opening and closing tag will be destroyed. - pub fn readme_health_table_renew( path : &Path ) -> Result< () > + // aaa : for Petro : typed errors + // aaa : done + pub fn readme_health_table_renew( path : &Path ) -> Result< (), HealthTableRenewError > { regexes_initialize(); - let absolute_path = AbsolutePath::try_from( path )?; - let mut cargo_metadata = Workspace::with_crate_dir( CrateDir::try_from( absolute_path )? )?; - let workspace_root = workspace_root( &mut cargo_metadata )?; - let mut parameters = GlobalTableParameters::initialize_from_path( &workspace_root )?; + let workspace = Workspace::try_from( CrateDir::try_from( path )? )?; + let workspace_root = workspace.workspace_root(); + let mut parameters = GlobalTableOptions::initialize_from_path + ( + &workspace_root + )?; - let read_me_path = workspace_root.join( readme_path(&workspace_root ).ok_or_else( || format_err!( "Fail to find README.md" ) )?); + let read_me_path = workspace_root + .join( repository::readme_path( &workspace_root )? ); let mut file = OpenOptions::new() .read( true ) .write( true ) @@ -253,8 +301,18 @@ mod private .ok_or( format_err!( "Fail to parse group" ) )? .as_bytes() )?; - let params: TableParameters = query::parse( raw_table_params ).unwrap().into_map( vec![] ).into(); - let table = package_readme_health_table_generate( &mut cargo_metadata, ¶ms, &mut parameters )?; + let params: TableOptions = query::parse + ( + raw_table_params + ).unwrap() + .into_map( vec![] ) + .into(); + let table = package_readme_health_table_generate + ( + &workspace, + ¶ms, + &mut parameters + )?; tables.push( table ); tags_closures.push( ( open.end(), close.start() ) ); } @@ -266,11 +324,22 @@ mod private } /// Writes tables into a file at specified positions. - fn tables_write_into_file( tags_closures : Vec< ( usize, usize ) >, tables: Vec< String >, contents: Vec< u8 >, mut file: File ) -> Result< () > + fn tables_write_into_file + ( + tags_closures : Vec< ( usize, usize ) >, + tables: Vec< String >, + contents: Vec< u8 >, + mut file: File + ) -> Result< (), HealthTableRenewError > { let mut buffer: Vec< u8 > = vec![]; let mut start: usize = 0; - for ( ( end_of_start_tag, start_of_end_tag ), con ) in tags_closures.iter().zip( tables.iter() ) + for + ( + ( end_of_start_tag, start_of_end_tag ), + con + ) + in tags_closures.iter().zip( tables.iter() ) { range_to_target_copy( &*contents, &mut buffer, start, *end_of_start_tag )?; range_to_target_copy( con.as_bytes(), &mut buffer, 0,con.len() - 1 )?; @@ -285,24 +354,35 @@ mod private /// Generate table from `table_parameters`. /// Generate header, iterate over all modules in package (from table_parameters) and append row. - fn package_readme_health_table_generate( cache : &mut Workspace, table_parameters: &TableParameters, parameters: & mut GlobalTableParameters ) -> Result< String, Error > + fn package_readme_health_table_generate + ( + workspace : &Workspace, + table_parameters: &TableOptions, + parameters: &mut GlobalTableOptions, + ) -> Result< String, HealthTableRenewError > { let directory_names = directory_names ( - cache - .workspace_root()? - .join( &table_parameters.base_path ), - &cache - .load()? + workspace + .workspace_root() + .join( &table_parameters.base_path ).to_path_buf(), + workspace .packages() - .map_err( | err | format_err!( err ) )? )?; let mut table = table_header_generate( parameters, &table_parameters ); for package_name in directory_names { let stability = if table_parameters.include_stability { - Some( stability_get( &cache.workspace_root()?.join( &table_parameters.base_path ).join( &package_name ) )? ) + Some + ( + // qqq : use new-type. for example `CrateDir` + stability_get + ( + // qqq : the folder name may not match the package name + &workspace.workspace_root().join( &table_parameters.base_path ).join( &package_name ) + )? + ) } else { @@ -310,63 +390,125 @@ mod private }; if parameters.core_url == "" { - let module_path = &cache.workspace_root()?.join( &table_parameters.base_path ).join( &package_name ); - parameters.core_url = repo_url( &module_path ) + let module_path = workspace + .workspace_root() + .join( &table_parameters.base_path ) + .join( &package_name ); + // parameters.core_url = repo_url( &module_path ) + parameters.core_url = repo_url( &module_path.clone().try_into()? ) .context ( - format_err!( "Can not find Cargo.toml in {} or Fail to extract repository url from git remote.\n specify the correct path to the main repository in Cargo.toml of workspace (in the [workspace.metadata] section named repo_url) in {} OR in Cargo.toml of each module (in the [package] section named repository, specify the full path to the module) for example {} OR ensure that at least one remotest is present in git. ", module_path.display(), cache.workspace_root()?.join( "Cargo.toml" ).display(), module_path.join( "Cargo.toml" ).display() ) + // aaa : for Petro : unreadable : check other lines of code which are long + // aaa : done + format_err! + ( + "Can not find Cargo.toml in {} or Fail to extract repository url from git remote.\n\ +specify the correct path to the main repository in Cargo.toml of workspace (in the [workspace.metadata] section named repo_url) in {} \ +OR in Cargo.toml of each module (in the [package] section named repository, specify the full path to the module) for example {} OR\ +ensure that at least one remotest is present in git. ", + module_path.display(), + workspace.workspace_root().join( "Cargo.toml" ).display(), + module_path.join( "Cargo.toml" ).display() + ) )?; parameters.user_and_repo = url::git_info_extract( ¶meters.core_url )?; } - table.push_str( &row_generate(&package_name, stability.as_ref(), parameters, &table_parameters) ); + table.push_str + ( + &row_generate + ( + &package_name, + stability.as_ref(), + parameters, + &table_parameters + ) + ); } Ok( table ) } /// Return topologically sorted modules name, from packages list, in specified directory. - fn directory_names( path : PathBuf, packages : &[ workspace::WorkspacePackage ] ) -> Result< Vec< String > > + // fn directory_names( path : PathBuf, packages : &[ WorkspacePackageRef< '_ > ] ) -> Result< Vec< String > > + fn directory_names< 'a > + ( + path : PathBuf, + packages : impl Iterator< Item = WorkspacePackageRef< 'a > >, + ) -> Result< Vec< String >, HealthTableRenewError > { let path_clone = path.clone(); - let module_package_filter: Option< Box< dyn Fn( &workspace::WorkspacePackage ) -> bool > > = Some + let module_package_filter : Option< Box< dyn Fn( WorkspacePackageRef< '_ > ) -> bool > > = Some ( Box::new ( move | p | - p.publish().is_none() && p.manifest_path().starts_with( &path ) + { + let manifest_file = p.manifest_file(); + if let Ok( pa ) = manifest_file + { + p.publish().is_none() && pa.starts_with( &path ) + } + else + { + false + } + } // aaa : rid of unwraps + // aaa : done ) ); - let module_dependency_filter: Option< Box< dyn Fn( &workspace::WorkspacePackage, &workspace::Dependency ) -> bool > > = Some + let module_dependency_filter : Option< Box< dyn Fn( WorkspacePackageRef< '_ >, DependencyRef< '_ > ) -> bool > > = Some ( Box::new ( move | _, d | - d.path().is_some() && d.kind() != workspace::DependencyKind::Development && d.path().as_ref().unwrap().starts_with( &path_clone ) + d.crate_dir().is_some() && + d.kind() != + DependencyKind::Development && + d.crate_dir().as_ref().unwrap().starts_with( &path_clone ) ) ); let module_packages_map = packages::filter ( packages, - packages::FilterMapOptions { package_filter: module_package_filter, dependency_filter: module_dependency_filter }, + packages::FilterMapOptions + { + package_filter : module_package_filter, + dependency_filter : module_dependency_filter + }, ); let module_graph = graph::construct( &module_packages_map ); - let names = graph::topological_sort_with_grouping( module_graph ) + let names : Vec< String > = graph::topological_sort_with_grouping( module_graph ) .into_iter() .map - ( - | mut group | + ( + | mut group | { group.sort(); - group - } - ).flatten().collect::< Vec< _ > >(); - - Ok(names) + group + } + ) + .flatten() + .map( | n | n.to_string() ) + .collect(); + + Ok( names ) } /// Generate row that represents a module, with a link to it in the repository and optionals for stability, branches, documentation and links to the gitpod. - fn row_generate( module_name : &str, stability : Option< &Stability >, parameters : &GlobalTableParameters, table_parameters : &TableParameters ) -> String + fn row_generate + ( + module_name : &str, + stability : Option< &Stability >, + parameters : &GlobalTableOptions, + table_parameters : &TableOptions + ) -> String { - let mut rou = format!( "| [{}]({}/{}) |", &module_name, &table_parameters.base_path, &module_name ); + let mut rou = format! + ( + "| [{}]({}/{}) |", + &module_name, + &table_parameters.base_path, + &module_name + ); if table_parameters.include_stability { let mut stability = stability_generate( &stability.as_ref().unwrap() ); @@ -379,7 +521,14 @@ mod private } if table_parameters.include_docs { - rou.push_str( &format!( " [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/{}) |", &module_name ) ); + rou.push_str + ( + &format! + ( + " [![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/{}) |", + &module_name + ) + ); } if table_parameters.include { @@ -389,12 +538,19 @@ mod private let example = if let Some( name ) = find_example_file( p.as_path(), &module_name ) { let path = path.to_string_lossy().replace( '\\', "/" ).replace( "/", "%2F" ); - let tmp = name.replace( '\\', "/" ); + let tmp = name.to_string_lossy().replace( '\\', "/" ); let file_name = tmp.split( '/' ).last().unwrap(); let name = file_name.strip_suffix( ".rs" ).unwrap(); - format!( "[![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE={path}%2Fexamples%2F{file_name},RUN_POSTFIX=--example%20{name}/{})", parameters.core_url ) + format! + ( + "[![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE={}%2Fexamples%2F{},RUN_POSTFIX=--example%20{}/{})", + path, + file_name, + name, + parameters.core_url, + ) } - else + else { "".into() }; @@ -402,26 +558,26 @@ mod private } format!( "{rou}\n" ) } - + /// todo - pub fn find_example_file(base_path : &Path, module_name : &str ) -> Option< String > + pub fn find_example_file( base_path : &Path, module_name : &str ) -> Option< PathBuf > { let examples_dir = base_path.join("examples" ); if examples_dir.exists() && examples_dir.is_dir() { - if let Ok( entries ) = std::fs::read_dir( &examples_dir ) + if let Ok( entries ) = std::fs::read_dir( &examples_dir ) { - for entry in entries + for entry in entries { - if let Ok( entry ) = entry + if let Ok( entry ) = entry { let file_name = entry.file_name(); - if let Some( file_name_str ) = file_name.to_str() + if let Some( file_name_str ) = file_name.to_str() { - if file_name_str == format!( "{module_name}_trivial.rs" ) + if file_name_str == format!( "{module_name}_trivial.rs" ) { - return Some( entry.path().to_string_lossy().into() ) + return Some( entry.path() ) } } } @@ -430,18 +586,18 @@ mod private } // If module_trivial.rs doesn't exist, return any other file in the examples directory - if let Ok( entries ) = std::fs::read_dir( &examples_dir ) + if let Ok( entries ) = std::fs::read_dir( &examples_dir ) { - for entry in entries + for entry in entries { - if let Ok( entry ) = entry + if let Ok( entry ) = entry { let file_name = entry.file_name(); - if let Some( file_name_str ) = file_name.to_str() + if let Some( file_name_str ) = file_name.to_str() { - if file_name_str.ends_with( ".rs" ) + if file_name_str.ends_with( ".rs" ) { - return Some( entry.path().to_string_lossy().into() ) + return Some( entry.path() ) } } } @@ -465,7 +621,11 @@ mod private } /// Generate table header - fn table_header_generate( parameters : &GlobalTableParameters, table_parameters : &TableParameters ) -> String + fn table_header_generate + ( + parameters : &GlobalTableOptions, + table_parameters : &TableOptions + ) -> String { let mut header = String::from( "| Module |" ); let mut separator = String::from( "|--------|" ); @@ -504,7 +664,7 @@ mod private } /// Generate cells for each branch - fn branch_cells_generate( table_parameters: &GlobalTableParameters, module_name: &str ) -> String + fn branch_cells_generate( table_parameters : &GlobalTableOptions, module_name : &str ) -> String { let cells = table_parameters .branches @@ -514,20 +674,29 @@ mod private .map ( | b | - format!( "[![rust-status](https://img.shields.io/github/actions/workflow/status/{}/module_{}_push.yml?label=&branch={b})]({}/actions/workflows/module_{}_push.yml?query=branch%3A{})", table_parameters.user_and_repo, &module_name.to_case( Case::Snake ), table_parameters.core_url, &module_name.to_case( Case::Snake ), b ) + format! + ( + "[![rust-status](https://img.shields.io/github/actions/workflow/status/{}/module_{}_push.yml?label=&branch={})]({}/actions/workflows/module_{}_push.yml?query=branch%3A{})", + table_parameters.user_and_repo, + &module_name.to_case( convert_case::Case::Snake ), + b, + table_parameters.core_url, + &module_name.to_case( convert_case::Case::Snake ), + b, + ) ) .collect::< Vec< String > >() .join( " | " ); format!( " {cells} |" ) } - /// Return workspace root - pub fn workspace_root( metadata : &mut Workspace ) -> Result< PathBuf > - { - Ok( metadata.load()?.workspace_root()?.to_path_buf() ) - } - - fn range_to_target_copy< T : Clone >( source : &[ T ], target : &mut Vec< T >, from : usize, to : usize ) -> Result< () > + fn range_to_target_copy< T : Clone > + ( + source : &[ T ], + target : &mut Vec< T >, + from : usize, + to : usize + ) -> Result< (), HealthTableRenewError > { if from < source.len() && to < source.len() && from <= to { @@ -536,71 +705,20 @@ mod private } else { - bail!( "Incorrect indexes" ) - } - } - - /// Searches for a README file in specific subdirectories of the given directory path. - /// - /// This function attempts to find a README file in the following subdirectories: ".github", - /// the root directory, and "./docs". It returns the path to the first found README file, or - /// `None` if no README file is found in any of these locations. - pub fn readme_path( dir_path : &Path ) -> Option< PathBuf > - { - if let Some( path ) = readme_in_dir_find( &dir_path.join( ".github" ) ) - { - Some( path ) - } - else if let Some( path ) = readme_in_dir_find( dir_path ) - { - Some( path ) - } - else if let Some( path ) = readme_in_dir_find( &dir_path.join( "docs" ) ) - { - Some( path ) - } - else - { - None + Err( HealthTableRenewError::Common( error::untyped::Error::msg( "Incorrect indexes" ))) } } - - /// Searches for a file named "readme.md" in the specified directory path. - /// - /// Given a directory path, this function searches for a file named "readme.md" in the specified - /// directory. - fn readme_in_dir_find( path : &Path ) -> Option< PathBuf > - { - read_dir( path ) - .ok()? - .filter_map( Result::ok ) - .filter( | p | p.path().is_file() ) - .filter_map( | f | - { - let l_f = f.file_name().to_ascii_lowercase(); - if l_f == "readme.md" - { - return Some( f.file_name() ) - } - None - }) - .max() - .map( PathBuf::from ) - } - } crate::mod_interface! { - /// Return workspace root - protected use workspace_root; - /// Find readme.md file in directory - protected use readme_path; + // /// Return workspace root + // own use workspace_root; /// Stability - protected use Stability; + own use Stability; /// Generate Stability badge - protected use stability_generate; - protected use find_example_file; + own use stability_generate; + own use find_example_file; /// Create Table. orphan use readme_health_table_renew; } diff --git a/module/move/willbe/src/action/readme_modules_headers_renew.rs b/module/move/willbe/src/action/readme_modules_headers_renew.rs index 5809369b10..5370a9d0fa 100644 --- a/module/move/willbe/src/action/readme_modules_headers_renew.rs +++ b/module/move/willbe/src/action/readme_modules_headers_renew.rs @@ -1,62 +1,84 @@ mod private { use crate::*; - use _path::AbsolutePath; - use action::readme_health_table_renew::{ readme_path, Stability, stability_generate, find_example_file }; + use std:: + { + borrow::Cow, + fs::OpenOptions, + fmt, + io:: + { + Read, + Seek, + Write, + SeekFrom, + } + }; + use collection::BTreeSet; + // use path::AbsolutePath; + use action::readme_health_table_renew::{ Stability, stability_generate, find_example_file }; use package::Package; - use wtools::error:: + use error:: { err, - for_app:: - { - Result, + untyped:: + { + // Result, Error as wError, Context, }, }; - use std::borrow::Cow; - use std::collections::BTreeSet; - use std::fmt::{Display, Formatter}; - use std::fs::{ OpenOptions }; - use std::io::{ Read, Seek, SeekFrom, Write }; + // aaa : for Petro : group properly, don't repeat std:: + // aaa : done use std::path::PathBuf; use convert_case::{ Case, Casing }; + // use rayon::scope_fifo; use regex::Regex; - use entity::WorkspaceError; - use manifest::private::CrateDirError; + use entity::{ WorkspaceInitError, PathError }; use package::PackageError; - use error_tools::for_lib::Error; - use error_tools::dependency::*; - // aaa : for Petro : rid off crate::x. ask - // aaa : add `use crate::*` first + use error::typed::Error; + use workspace_md_extension::WorkspaceMdExtension; + // use error::ErrWith; static TAGS_TEMPLATE : std::sync::OnceLock< Regex > = std::sync::OnceLock::new(); fn regexes_initialize() { - TAGS_TEMPLATE.set( Regex::new( r"(.|\n|\r\n)+" ).unwrap() ).ok(); + TAGS_TEMPLATE.set + ( + Regex::new + ( + r"(.|\n|\r\n)+" + ).unwrap() + ).ok(); } /// Report. #[ derive( Debug, Default, Clone ) ] pub struct ModulesHeadersRenewReport - { - found_files : BTreeSet< PathBuf >, + { + found_files : BTreeSet< PathBuf >, touched_files : BTreeSet< PathBuf >, } - impl Display for ModulesHeadersRenewReport + impl fmt::Display for ModulesHeadersRenewReport { - fn fmt( &self, f : &mut Formatter< '_ > ) -> std::fmt::Result + fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> fmt::Result { - if self.touched_files.len() < self.found_files.len() + if self.touched_files.len() < self.found_files.len() { - writeln!( f, "Something went wrong.\n{}/{} was touched.", self.found_files.len(), self.touched_files.len() )?; + writeln! + ( + f, + "Something went wrong.\n{}/{} was touched.", + self.found_files.len(), + self.touched_files.len() + )?; return Ok(()) } writeln!( f, "Touched files :" )?; let mut count = self.found_files.len(); - for path in &self.touched_files + for path in &self.touched_files { if let Some( file_path ) = path.to_str() { @@ -72,19 +94,26 @@ mod private } } + /// The `ModulesHeadersRenewError` enum represents the various errors that can occur during + /// the renewal of module headers. #[ derive( Debug, Error ) ] pub enum ModulesHeadersRenewError { + /// Represents a common error. #[ error( "Common error: {0}" ) ] Common(#[ from ] wError ), + /// Represents an I/O error. #[ error( "I/O error: {0}" ) ] IO( #[ from ] std::io::Error ), + /// Represents an error related to workspace initialization. #[ error( "Workspace error: {0}" ) ] - Workspace( #[ from ] WorkspaceError), + Workspace( #[ from ] WorkspaceInitError ), + /// Represents an error related to a package. #[ error( "Package error: {0}" ) ] - Package( #[ from ] PackageError), + Package( #[ from ] PackageError ), + /// Represents an error related to directory paths. #[ error( "Directory error: {0}" ) ] - Directory( #[ from ] CrateDirError ), + Directory( #[ from ] PathError ), } /// The `ModuleHeader` structure represents a set of parameters, used for creating url for header. @@ -101,22 +130,28 @@ mod private { /// Create `ModuleHeader` instance from the folder where Cargo.toml is stored. - fn from_cargo_toml( package : Package, default_discord_url : &Option< String > ) -> Result< Self, ModulesHeadersRenewError > + fn from_cargo_toml< 'a > + ( + package : Package< 'a >, + default_discord_url : &Option< String >, + ) + -> Result< Self, ModulesHeadersRenewError > { let stability = package.stability()?; - let module_name = package.name()?; + let repository_url = package.repository()? + .ok_or_else::< wError, _ >( || err!( "Fail to find repository_url in module`s Cargo.toml" ) )?; - let repository_url = package.repository()?.ok_or_else::< wError, _ >( || err!( "Fail to find repository_url in module`s Cargo.toml" ) )?; - - let discord_url = package.discord_url()?.or_else( || default_discord_url.clone() ); + let discord_url = package + .discord_url()? + .or_else( || default_discord_url.clone() ); Ok ( Self { - module_path: package.manifest_path().parent().unwrap().as_ref().to_path_buf(), + module_path: package.manifest_file().parent().unwrap().as_ref().to_path_buf(), stability, - module_name, + module_name : module_name.to_string(), repository_url, discord_url, } @@ -127,18 +162,42 @@ mod private fn to_header( self, workspace_path : &str ) -> Result< String, ModulesHeadersRenewError > { let discord = self.discord_url.map( | discord_url | - format!( " [![discord](https://img.shields.io/discord/872391416519737405?color=eee&logo=discord&logoColor=eee&label=ask)]({discord_url})" ) + format! + ( + " [![discord](https://img.shields.io/discord/872391416519737405?color=eee&logo=discord&logoColor=eee&label=ask)]({})", + discord_url + ) ) .unwrap_or_default(); - let repo_url = url::extract_repo_url( &self.repository_url ).and_then( | r | url::git_info_extract( &r ).ok() ).ok_or_else::< wError, _ >( || err!( "Fail to parse repository url" ) )?; - let example = if let Some( name ) = find_example_file( self.module_path.as_path(), &self.module_name ) + let repo_url = url::repo_url_extract( &self.repository_url ) + .and_then( | r | url::git_info_extract( &r ).ok() ) + .ok_or_else::< wError, _ >( || err!( "Fail to parse repository url" ) )?; + let example= if let Some( name ) = find_example_file + ( + self.module_path.as_path(), + &self.module_name + ) { - // qqq : for Petro : Hardcoded Strings, would be better to use `PathBuf` to avoid separator mismatch on Windows and Unix - let p = name.strip_prefix( workspace_path ).unwrap().get( 1.. ).unwrap().replace( "\\","%2F" ); - let name = name.replace( "/", "\\" ); - let name = name.split( "\\" ).last().unwrap().split( "." ).next().unwrap(); - format!( " [![Open in Gitpod](https://raster.shields.io/static/v1?label=try&message=online&color=eee&logo=gitpod&logoColor=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE={p},RUN_POSTFIX=--example%20{}/https://github.com/{})", name, repo_url ) + let relative_path = proper_path_tools::path::path_relative + ( + workspace_path.try_into().unwrap(), + name + ) + .to_string_lossy() + .to_string(); + #[ cfg( target_os = "windows" ) ] + let relative_path = relative_path.replace( "\\", "/" ); + // aaa : for Petro : use path_toools + // aaa : used + let p = relative_path.replace( "/","%2F" ); + format! + ( + " [![Open in Gitpod](https://raster.shields.io/static/v1?label=try&message=online&color=eee&logo=gitpod&logoColor=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE={},RUN_POSTFIX=--example%20{}/https://github.com/{})", + p, + p, + repo_url + ) } else { @@ -180,32 +239,63 @@ mod private /// [![experimental](https://raster.shields.io/static/v1?label=&message=experimental&color=orange)](https://github.com/emersion/stability-badges#experimental) | [![rust-status](https://github.com/Username/test/actions/workflows/ModuleChainOfPackagesAPush.yml/badge.svg)](https://github.com/Username/test/actions/workflows/ModuleChainOfPackagesAPush.yml)[![docs.rs](https://img.shields.io/docsrs/_chain_of_packages_a?color=e3e8f0&logo=docs.rs)](https://docs.rs/_chain_of_packages_a)[![Open in Gitpod](https://raster.shields.io/static/v1?label=try&message=online&color=eee&logo=gitpod&logoColor=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=sample%2Frust%2F_chain_of_packages_a_trivial%2Fsrc%2Fmain.rs,RUN_POSTFIX=--example%20_chain_of_packages_a_trivial/https://github.com/Username/test) /// /// ``` - pub fn readme_modules_headers_renew( path : AbsolutePath ) -> Result< ModulesHeadersRenewReport, ( ModulesHeadersRenewReport, ModulesHeadersRenewError ) > + pub fn readme_modules_headers_renew( crate_dir : CrateDir ) + -> ResultWithReport< ModulesHeadersRenewReport, ModulesHeadersRenewError > + // -> Result< ModulesHeadersRenewReport, ( ModulesHeadersRenewReport, ModulesHeadersRenewError ) > { let mut report = ModulesHeadersRenewReport::default(); regexes_initialize(); - let cargo_metadata = Workspace::with_crate_dir( CrateDir::try_from( path ).map_err( | e | ( report.clone(), e.into() ) )? ).map_err( | e | ( report.clone(), e.into() ) )?; - let discord_url = cargo_metadata.discord_url().map_err( | e | ( report.clone(), e.into() ) )?; - let paths = cargo_metadata.packages().map_err( | e | ( report.clone(), e.into() ) )?.into_iter().filter_map( | p | AbsolutePath::try_from( p.manifest_path() ).ok()).collect::< Vec< _ > >(); - report.found_files = paths.iter().map( | ap | ap.as_ref().to_path_buf() ).collect(); + let workspace = Workspace::try_from( crate_dir ) + .err_with_report( &report )?; + let discord_url = workspace.discord_url(); + + // qqq : inspect each collect in willbe and rid of most of them + + let paths : Vec< AbsolutePath > = workspace + .packages() + .filter_map( | p | p.manifest_file().ok().and_then( | a | Some( a.inner() ) ) ) + .collect(); + + report.found_files = paths + .iter() + .map( | ap | ap.as_ref().to_path_buf() ) + .collect(); + for path in paths { let read_me_path = path .parent() .unwrap() - .join( readme_path( path.parent().unwrap().as_ref() ).ok_or_else::< wError, _ >( || err!( "Fail to find README.md" ) ).map_err( | e | ( report.clone(), e.into() ) )? ); + .join + ( + repository::readme_path( path.parent().unwrap().as_ref() ) + // .ok_or_else::< wError, _ >( || err!( "Fail to find README.md at {}", &path ) ) + .err_with_report( &report )? + ); - let pakage = Package::try_from( path.clone() ).map_err( | e | ( report.clone(), e.into() ) )?; - let header = ModuleHeader::from_cargo_toml( pakage.into(), &discord_url ).map_err( | e | ( report.clone(), e.into() ) )?; + let pakage = Package::try_from + ( + CrateDir::try_from + ( + &path + .parent() + .unwrap() + ) + .err_with_report( &report )? + ) + .err_with_report( &report )?; + + let header = ModuleHeader::from_cargo_toml( pakage.into(), &discord_url ) + .err_with_report( &report )?; let mut file = OpenOptions::new() .read( true ) .write( true ) .open( &read_me_path ) - .map_err( | e | ( report.clone(), e.into() ) )?; + .err_with_report( &report )?; let mut content = String::new(); - file.read_to_string( &mut content ).map_err( | e | ( report.clone(), e.into() ) )?; + file.read_to_string( &mut content ).err_with_report( &report )?; let raw_params = TAGS_TEMPLATE .get() @@ -216,21 +306,48 @@ mod private .unwrap_or_default(); _ = query::parse( raw_params ).context( "Fail to parse raw params." ); + // qqq : for Petro : why ignored? - let content = header_content_generate( &content, header, raw_params, cargo_metadata.workspace_root().map_err( | e | ( report.clone(), e.into() ) )?.to_str().unwrap() ).map_err( | e | ( report.clone(), e.into() ) )?; + let content = header_content_generate + ( + &content, + header, + raw_params, + workspace.workspace_root().to_str().unwrap() + ).err_with_report( &report )?; - file.set_len( 0 ).map_err( | e | ( report.clone(), e.into() ) )?; - file.seek( SeekFrom::Start( 0 ) ).map_err( | e | ( report.clone(), e.into() ) )?; - file.write_all( content.as_bytes() ).map_err( | e | ( report.clone(), e.into() ) )?; + file.set_len( 0 ).err_with_report( &report )?; + file.seek( SeekFrom::Start( 0 ) ).err_with_report( &report )?; + file.write_all( content.as_bytes() ).err_with_report( &report )?; report.touched_files.insert( path.as_ref().to_path_buf() ); } Ok( report ) } - fn header_content_generate< 'a >( content : &'a str, header : ModuleHeader, raw_params : &str, workspace_root : &str ) -> Result< Cow< 'a, str > > + fn header_content_generate< 'a > + ( + content : &'a str, + header : ModuleHeader, + raw_params : &str, + workspace_root : &str + ) + // qqq : use typed error + -> error::untyped::Result< Cow< 'a, str > > { let header = header.to_header( workspace_root )?; - let result = TAGS_TEMPLATE.get().unwrap().replace( &content, &format!( "\n{header}\n" ) ); + let result = TAGS_TEMPLATE + .get() + .unwrap() + .replace + ( + &content, + &format! + ( + "\n{}\n", + raw_params, + header + ) + ); Ok( result ) } } @@ -241,4 +358,6 @@ crate::mod_interface! orphan use readme_modules_headers_renew; /// report orphan use ModulesHeadersRenewReport; + /// Error. + orphan use ModulesHeadersRenewError; } \ No newline at end of file diff --git a/module/move/willbe/src/action/test.rs b/module/move/willbe/src/action/test.rs index 7ad9a532a4..be0b90405c 100644 --- a/module/move/willbe/src/action/test.rs +++ b/module/move/willbe/src/action/test.rs @@ -2,31 +2,26 @@ mod private { use crate::*; - use test::*; - use _path::AbsolutePath; + use entity::test::{ TestPlan, TestOptions, TestsReport, tests_run }; - use std::collections::HashSet; + // use test::*; + // qqq : for Petro : no asterisks imports + // qqq : for Petro : bad : not clear what is imported, there are multiple filles with name test + use collection::HashSet; use std::{ env, fs }; - #[ cfg( feature = "progress_bar" ) ] - use indicatif::{ MultiProgress, ProgressStyle }; - use former::Former; - use wtools:: + use error:: { - error:: + untyped:: { - for_app:: - { - Error, - format_err - }, - Result + Error, + format_err }, - iter::Itertools, + // Result }; - use workspace::WorkspacePackage; + use iter::Itertools; /// Used to store arguments for running tests. /// @@ -68,27 +63,39 @@ mod private /// It is possible to enable and disable various features of the crate. /// The function also has the ability to run tests in parallel using `Rayon` crate. /// The result of the tests is written to the structure `TestsReport` and returned as a result of the function execution. - pub fn test( args : TestsCommandOptions, dry : bool ) -> Result< TestsReport, ( TestsReport, Error ) > + // zzz : it probably should not be here + // xxx : use newtype + pub fn test( o : TestsCommandOptions, dry : bool ) + -> ResultWithReport< TestsReport, Error > + // qqq : for Petro : typed error + // -> Result< TestsReport, ( TestsReport, Error ) > { - #[ cfg( feature = "progress_bar" ) ] - let multiprocess = MultiProgress::new(); - #[ cfg( feature = "progress_bar" ) ] - let style = ProgressStyle::with_template - ( - "[{elapsed_precise}] {bar:40.cyan/blue} {pos:>7}/{len:7} {msg}", - ) - .unwrap() - .progress_chars( "##-" ); - let mut reports = TestsReport::default(); + // qqq : incapsulate progress bar logic into some function of struct. don't keep it here + // aaa : done + + let mut report = TestsReport::default(); // fail fast if some additional installations required - let channels = channel::available_channels( args.dir.as_ref() ).map_err( | e | ( reports.clone(), e ) )?; - let channels_diff = args.channels.difference( &channels ).collect::< Vec< _ > >(); + let channels = channel::available_channels( o.dir.as_ref() ) + .err_with_report( &report )?; + let channels_diff : Vec< _ > = o.channels.difference( &channels ).collect(); if !channels_diff.is_empty() { - return Err(( reports, format_err!( "Missing toolchain(-s) that was required : [{}]. Try to install it with `rustup install {{toolchain name}}` command(-s)", channels_diff.into_iter().join( ", " ) ) )) + // aaa : for Petro : non readable + // aaa : readable and with actual command + return Err + (( + report, + format_err! + ( + "Missing toolchain(-s) that was required : [{}]. \ +Try to install it with `rustup install {}` command(-s)", + channels_diff.iter().join( ", " ), + channels_diff.iter().join( " " ) + ) + )) } - reports.dry = dry; + report.dry = dry; let TestsCommandOptions { dir : _ , @@ -104,13 +111,47 @@ mod private optimizations, variants_cap, with_progress, - } = args; + } = o; - let packages = needed_packages( args.dir.clone() ).map_err( | e | ( reports.clone(), e ) )?; + // zzz : watch and review after been ready + // aaa : for Petro : use relevant entity. use either, implement TryFrom< Either< CrateDir, ManifestFile > > + // aaa : done + // qqq : for Petro : nonsense + let path = match EitherDirOrFile::try_from( o.dir.as_ref() ).map_err( | e | ( report.clone(), e.into() ) )?.inner() + { + data_type::Either::Left( crate_dir ) => crate_dir, + data_type::Either::Right( manifest ) => CrateDir::from( manifest ) + }; + + let workspace = Workspace + ::try_from( CrateDir::try_from( path.clone() ).err_with_report( &report )? ) + .err_with_report( &report )? + // xxx : clone? + // aaa : for Petro : use trait !everywhere! + // aaa : !When I wrote this solution, pr with this changes was not yet ready.! + ; + + // let packages = needed_packages( &workspace ); + let packages = workspace + .packages() + .filter + ( + move | p | + p + .manifest_file() + .is_ok() && + p. + manifest_file() + .unwrap() + .starts_with( path.as_ref() ) + ) + // aaa : for Petro : too long line + // aaa : done + ; let plan = TestPlan::try_from ( - &packages, + packages, &channels, power, include_features, @@ -120,16 +161,18 @@ mod private with_all_features, with_none_features, variants_cap, - ).map_err( | e | ( reports.clone(), e ) )?; + ).err_with_report( &report )?; println!( "{plan}" ); + // aaa : split on two functions for create plan and for execute + // aaa : it's already separated, look line: 203 : let result = tests_run( &options ); let temp_path = if temp { let mut unique_name = format! ( "temp_dir_for_test_command_{}", - path_tools::path::unique_folder_name().map_err( | e | ( reports.clone(), e.into() ) )? + path::unique_folder_name().err_with_report( &report )? ); let mut temp_dir = env::temp_dir().join( unique_name ); @@ -139,12 +182,12 @@ mod private unique_name = format! ( "temp_dir_for_test_command_{}", - path_tools::path::unique_folder_name().map_err( | e | ( reports.clone(), e.into() ) )? + path::unique_folder_name().err_with_report( &report )? ); temp_dir = env::temp_dir().join( unique_name ); } - fs::create_dir( &temp_dir ).map_err( | e | ( reports.clone(), e.into() ) )?; + fs::create_dir( &temp_dir ).err_with_report( &report )?; Some( temp_dir ) } else @@ -156,54 +199,25 @@ mod private .concurrent( concurrent ) .plan( plan ) .option_temp( temp_path ) - .dry( dry ); - - #[ cfg( feature = "progress_bar" ) ] - let test_options_former = if with_progress - { - let test_options_former = test_options_former.feature( TestOptionsProgressBarFeature{ multiprocess, style } ); - test_options_former - } - else - { - test_options_former - }; + .dry( dry ) + .with_progress( with_progress ); let options = test_options_former.form(); let result = tests_run( &options ); if temp { - fs::remove_dir_all( options.temp_path.unwrap() ).map_err( | e | ( reports.clone(), e.into() ) )?; + fs::remove_dir_all( options.temp_path.unwrap() ).err_with_report( &report )?; } - result + result.map_err( | ( report, e) | ( report, e.into() ) ) } - fn needed_packages( path : AbsolutePath ) -> Result< Vec< WorkspacePackage > > - { - let path = if path.as_ref().file_name() == Some( "Cargo.toml".as_ref() ) - { - path.parent().unwrap() - } - else - { - path - }; - let metadata = Workspace::with_crate_dir( CrateDir::try_from( path.clone() )? )?; - - let result = metadata - .packages()? - .into_iter() - .filter( move | x | x.manifest_path().starts_with( path.as_ref() ) ) - .collect(); - Ok( result ) - } } crate::mod_interface! { /// run all tests in all crates orphan use test; - protected use TestsCommandOptions; + own use TestsCommandOptions; } diff --git a/module/move/willbe/src/action/workspace_renew.rs b/module/move/willbe/src/action/workspace_renew.rs index d03fcda04d..58e4ad61ea 100644 --- a/module/move/willbe/src/action/workspace_renew.rs +++ b/module/move/willbe/src/action/workspace_renew.rs @@ -3,10 +3,14 @@ mod private use crate::*; use std::fs; use std::path::Path; - use error_tools::for_app::bail; - use error_tools::Result; - use wtools::iter::Itertools; - use crate::template::{Template, TemplateFileDescriptor, TemplateFiles, TemplateFilesBuilder, TemplateParameters, TemplateValues}; + use error::untyped::bail; + // use error::Result; + // qqq : group dependencies + use iter::Itertools; + use template:: + { + TemplateFileDescriptor, TemplateFiles, TemplateFilesBuilder, TemplateParameters, TemplateValues + }; /// Template for creating workspace files. #[ derive( Debug ) ] @@ -17,44 +21,13 @@ mod private values : TemplateValues, } - impl Template for WorkspaceTemplate + impl WorkspaceTemplate { - fn create_all( self, path : &Path ) -> Result< () > - { - self.files.create_all( path, &self.values ) - } - - fn parameters( &self ) -> &TemplateParameters + /// Returns template parameters + pub fn get_parameters( &self ) -> &TemplateParameters { &self.parameters } - - fn set_values( &mut self, values : TemplateValues ) - { - self.values = values - } - - fn parameter_storage( &self ) -> &Path - { - "./.workspace_template.toml".as_ref() - } - - fn template_name( &self ) -> &'static str - { - "workspace" - } - - fn get_values( &self ) -> &TemplateValues - { - &self.values - } - - fn get_values_mut( &mut self ) -> &mut TemplateValues - { - &mut self.values - } - - } impl Default for WorkspaceTemplate @@ -79,25 +52,65 @@ mod private /// /// Default implementation contains all required files. #[ derive( Debug ) ] - pub struct WorkspaceTemplateFiles(Vec< TemplateFileDescriptor > ); + pub struct WorkspaceTemplateFiles( Vec< TemplateFileDescriptor > ); impl Default for WorkspaceTemplateFiles { fn default() -> Self { let formed = TemplateFilesBuilder::former() - .file().data( include_str!( "../../template/workspace/.gitattributes" ) ).path( "./.gitattributes" ).end() - .file().data( include_str!( "../../template/workspace/.gitignore1" ) ).path( "./.gitignore" ).end() - .file().data( include_str!( "../../template/workspace/.gitpod.yml" ) ).path( "./.gitpod.yml" ).end() - .file().data( include_str!( "../../template/workspace/Cargo.hbs" ) ).path( "./Cargo.toml" ).is_template( true ).end() - .file().data( include_str!( "../../template/workspace/Makefile" ) ).path( "./Makefile" ).end() - .file().data( include_str!( "../../template/workspace/Readme.md" ) ).path( "./Readme.md" ).end() - .file().data( include_str!( "../../template/workspace/.cargo/config.toml" ) ).path( "./.cargo/config.toml" ).end() - .file().data( include_str!( "../../template/workspace/module/module1/Cargo.toml.x" ) ).path( "./module/Cargo.toml" ).end() - .file().data( include_str!( "../../template/workspace/module/module1/Readme.md" ) ).path( "./module/module1/Readme.md" ).end() - .file().data( include_str!( "../../template/workspace/module/module1/examples/module1_example.rs" ) ).path( "./module/module1/examples/module1_example.rs" ).end() - .file().data( include_str!( "../../template/workspace/module/module1/src/lib.rs" ) ).path( "./module/module1/src/lib.rs" ).end() - .file().data( include_str!( "../../template/workspace/module/module1/tests/hello_test.rs" ) ).path( "./module/module1/tests/hello_test.rs" ).end() + .file() + .data( include_str!( "../../template/workspace/.gitattributes" ) ) + .path( "./.gitattributes" ) + .end() + .file() + .data( include_str!( "../../template/workspace/.gitignore1" ) ) + .path( "./.gitignore" ) + .end() + .file() + .data( include_str!( "../../template/workspace/.gitpod.yml" ) ) + .path( "./.gitpod.yml" ) + .end() + .file() + .data( include_str!( "../../template/workspace/Cargo.hbs" ) ) + .path( "./Cargo.toml" ) + .is_template( true ) + .end() + .file() + .data( include_str!( "../../template/workspace/Makefile" ) ) + .path( "./Makefile" ) + .end() + .file() + .data( include_str!( "../../template/workspace/Readme.md" ) ) + .path( "./Readme.md" ) + .end() + .file() + .data( include_str!( "../../template/workspace/.cargo/config.toml" ) ) + .path( "./.cargo/config.toml" ) + .end() + .file() + .data( include_str!( "../../template/workspace/module/module1/Cargo.toml.x" ) ) + .path( "./module/Cargo.toml" ) + .end() + .file() + .data( include_str!( "../../template/workspace/module/module1/Readme.md" ) ) + .path( "./module/module1/Readme.md" ) + .end() + .file() + .data + ( + include_str!( "../../template/workspace/module/module1/examples/module1_example.rs" ) + ) + .path( "./module/module1/examples/module1_example.rs" ) + .end() + .file() + .data( include_str!( "../../template/workspace/module/module1/src/lib.rs" ) ) + .path( "./module/module1/src/lib.rs" ) + .end() + .file() + .data( include_str!( "../../template/workspace/module/module1/tests/hello_test.rs" ) ) + .path( "./module/module1/tests/hello_test.rs" ) + .end() .form(); Self( formed.files ) @@ -117,21 +130,42 @@ mod private } } + // zzz // qqq : for Petro : should return report // qqq : for Petro : should have typed error - // aaa : parametrized templates?? - // aaa : use Viktor lib /// Creates workspace template - pub fn workspace_renew( path : &Path, mut template : WorkspaceTemplate, repository_url : String, branches : Vec< String > ) -> Result< () > + pub fn workspace_renew + ( + path : &Path, + mut template : WorkspaceTemplate, + repository_url : String, + branches : Vec< String > + ) + -> error::untyped::Result< () > // qqq : use typed error { - if fs::read_dir(path)?.count() != 0 + if fs::read_dir( path )?.count() != 0 { bail!( "Directory should be empty" ) } - template.values.insert_if_empty( "project_name", wca::Value::String( path.file_name().unwrap().to_string_lossy().into() ) ); + template + .values + .insert_if_empty + ( + "project_name", + wca::Value::String( path.file_name().unwrap().to_string_lossy().into() ) + ); template.values.insert_if_empty( "url", wca::Value::String( repository_url ) ); - template.values.insert_if_empty( "branches", wca::Value::String( branches.into_iter().map( | b | format!( r#""{}""#, b ) ).join( ", " ) ) ); - template.create_all( path )?; + template + .values + .insert_if_empty + ( + "branches", + wca::Value::String + ( + branches.into_iter().map( | b | format!( r#""{}""#, b ) ).join( ", " ) + ) + ); + template.files.create_all( path, &template.values )?; Ok( () ) } } diff --git a/module/move/willbe/src/bin/cargo-will.rs b/module/move/willbe/src/bin/cargo-will.rs index 3e4e4ffeaf..53aa39e51e 100644 --- a/module/move/willbe/src/bin/cargo-will.rs +++ b/module/move/willbe/src/bin/cargo-will.rs @@ -6,7 +6,7 @@ #[ allow( unused_imports ) ] use::willbe::*; -fn main() -> Result< (), wtools::error::for_app::Error > +fn main() -> Result< (), error::untyped::Error > { let args = std::env::args().skip( 1 ).collect(); Ok( willbe::run( args )? ) diff --git a/module/move/willbe/src/bin/will.rs b/module/move/willbe/src/bin/will.rs index e514a10bc4..cbaad31299 100644 --- a/module/move/willbe/src/bin/will.rs +++ b/module/move/willbe/src/bin/will.rs @@ -9,7 +9,10 @@ #[ allow( unused_imports ) ] use::willbe::*; -fn main() -> Result< (), wtools::error::for_app::Error > +fn main() -> Result< (), error::untyped::Error > { Ok( willbe::run( std::env::args().collect() )? ) } + +// cargo_subcommand_metadata::description!( "xxx" ); +// xxx : use \ No newline at end of file diff --git a/module/move/willbe/src/bin/willbe.rs b/module/move/willbe/src/bin/willbe.rs index 4fe12f8995..5943573a67 100644 --- a/module/move/willbe/src/bin/willbe.rs +++ b/module/move/willbe/src/bin/willbe.rs @@ -6,7 +6,7 @@ #[ allow( unused_imports ) ] use::willbe::*; -fn main() -> Result< (), wtools::error::for_app::Error > +fn main() -> Result< (), error::untyped::Error > { Ok( willbe::run( std::env::args().collect() )? ) } diff --git a/module/move/willbe/src/command/cicd_renew.rs b/module/move/willbe/src/command/cicd_renew.rs index f87569e9a8..50b1a8de91 100644 --- a/module/move/willbe/src/command/cicd_renew.rs +++ b/module/move/willbe/src/command/cicd_renew.rs @@ -2,14 +2,19 @@ mod private { use crate::*; - use wtools::error::{ anyhow::Context, Result }; + use error::{ untyped::Context }; /// /// Generate table. /// - pub fn cicd_renew() -> Result< () > + // qqq : typed error + pub fn cicd_renew() -> error::untyped::Result< () > { - action::cicd_renew( &std::env::current_dir()? ).context( "Fail to generate workflow" ) + action::cicd_renew + ( + &std::env::current_dir()? + ) + .context( "Fail to generate workflow" ) } } diff --git a/module/move/willbe/src/command/deploy_renew.rs b/module/move/willbe/src/command/deploy_renew.rs index 7fe0ebf13e..c66107fe8d 100644 --- a/module/move/willbe/src/command/deploy_renew.rs +++ b/module/move/willbe/src/command/deploy_renew.rs @@ -3,18 +3,21 @@ mod private use crate::*; use wca::VerifiedCommand; - use wtools::error::{ anyhow::Context, Result }; - use tool::template::Template; - use action::deploy_renew::*; + use error::{ untyped::Context }; + use tool::TemplateHolder; + //use tool::template::Template; + // use action::deploy_renew::*; /// /// Create new deploy. /// - pub fn deploy_renew( o : VerifiedCommand ) -> Result< () > + // xxx : qqq : typed error + pub fn deploy_renew( o : VerifiedCommand ) -> error::untyped::Result< () > { let current_dir = std::env::current_dir()?; - let mut template = DeployTemplate::default(); + + let mut template = TemplateHolder::default(); _ = template.load_existing_params( ¤t_dir ); let parameters = template.parameters(); let mut values = parameters.values_from_props( &o.props ); @@ -23,7 +26,8 @@ mod private values.interactive_if_empty( mandatory ); } template.set_values( values ); - action::deploy_renew( ¤t_dir, template ).context( "Fail to create deploy template" ) + action::deploy_renew( ¤t_dir, template ) + .context( "Fail to create deploy template" ) } } diff --git a/module/move/willbe/src/command/features.rs b/module/move/willbe/src/command/features.rs index ad69897935..d57a8a7dc0 100644 --- a/module/move/willbe/src/command/features.rs +++ b/module/move/willbe/src/command/features.rs @@ -3,29 +3,34 @@ mod private use crate::*; use action::features::FeaturesOptions; + use std::fs; use std::path::PathBuf; - use _path::AbsolutePath; + // // use path::AbsolutePath; use wca::VerifiedCommand; - use wtools::error::Result; + // use error::Result; + // qqq : group dependencies /// /// List features of a package. /// - pub fn features( o : VerifiedCommand ) -> Result< () > + pub fn features( o : VerifiedCommand ) -> error::untyped::Result< () > // qqq : use typed error { let path : PathBuf = o.args.get_owned( 0 ).unwrap_or_else( || "./".into() ); - let path = AbsolutePath::try_from( path )?; - let with_features_deps = o.props.get_owned( "with_features_deps" ).unwrap_or( false ); - let options = FeaturesOptions::former() - .manifest_dir( path ) + let crate_dir = CrateDir::try_from( fs::canonicalize( path )? )?; + let with_features_deps = o + .props + .get_owned( "with_features_deps" ) + .unwrap_or( false ); + let o = FeaturesOptions::former() + .crate_dir( crate_dir ) .with_features_deps( with_features_deps ) .form(); - let report = action::features( options ); + let report = action::features( o ); match report { - Ok(success) => println!("{success}"), - Err(failure) => eprintln!("{failure}"), + Ok( success ) => println!( "{success}" ), + Err( failure ) => eprintln!( "{failure}" ), } Ok( () ) } diff --git a/module/move/willbe/src/command/list.rs b/module/move/willbe/src/command/list.rs index 154317904c..c1bb086099 100644 --- a/module/move/willbe/src/command/list.rs +++ b/module/move/willbe/src/command/list.rs @@ -3,20 +3,20 @@ mod private { use crate::*; - use { action, wtools }; - use std:: { str::FromStr, path::PathBuf, - collections::HashSet, }; - use wca::VerifiedCommand; - use wtools::error::{ for_app::Context, Result }; + use error::{ untyped::Context }; + use collection::HashSet; - use _path::AbsolutePath; - use action::{ list as l, list::{ ListFormat, ListOptions } }; + use action:: + { + list as l, + list::{ ListFormat, ListOptions }, + }; use former::Former; #[ derive( Former ) ] @@ -47,10 +47,13 @@ mod private /// List workspace packages. /// - pub fn list( o : VerifiedCommand ) -> Result< () > + // qqq : typed error + pub fn list( o : VerifiedCommand ) -> error::untyped::Result< () > { - let path_to_workspace : PathBuf = o.args.get_owned( 0 ).unwrap_or( std::env::current_dir().context( "Workspace list command without subject" )? ); - let path_to_workspace = AbsolutePath::try_from( path_to_workspace )?; + let path_to_workspace : PathBuf = o.args + .get_owned( 0 ) + .unwrap_or( std::env::current_dir().context( "Workspace list command without subject" )? ); + // let path_to_workspace = AbsolutePath::try_from( fs::canonicalize( path_to_workspace )? )?; let ListProperties { format, with_version, with_path, with_local, with_remote, with_primary, with_dev, with_build } = o.props.try_into()?; @@ -69,7 +72,7 @@ mod private if with_dev { categories.insert( l::DependencyCategory::Dev ); } if with_build { categories.insert( l::DependencyCategory::Build ); } - let args = ListOptions::former() + let o = ListOptions::former() .path_to_manifest( crate_dir ) .format( format ) .info( additional_info ) @@ -77,7 +80,7 @@ mod private .dependency_categories( categories ) .form(); - match action::list( args ) + match action::list( o ) { Ok( report ) => { @@ -96,19 +99,29 @@ mod private impl TryFrom< wca::Props > for ListProperties { - type Error = wtools::error::for_app::Error; + type Error = error::untyped::Error; fn try_from( value : wca::Props ) -> Result< Self, Self::Error > { let mut this = Self::former(); - this = if let Some( v ) = value.get_owned( "format" ).map( ListFormat::from_str ) { this.format( v? ) } else { this }; - this = if let Some( v ) = value.get_owned( "with_version" ) { this.with_version::< bool >( v ) } else { this }; - this = if let Some( v ) = value.get_owned( "with_path" ) { this.with_path::< bool >( v ) } else { this }; - this = if let Some( v ) = value.get_owned( "with_local" ) { this.with_local::< bool >( v ) } else { this }; - this = if let Some( v ) = value.get_owned( "with_remote" ) { this.with_remote::< bool >( v ) } else { this }; - this = if let Some( v ) = value.get_owned( "with_primary" ) { this.with_primary::< bool >( v ) } else { this }; - this = if let Some( v ) = value.get_owned( "with_dev" ) { this.with_dev::< bool >( v ) } else { this }; - this = if let Some( v ) = value.get_owned( "with_build" ) { this.with_build::< bool >( v ) } else { this }; + this = if let Some( v ) = value + .get_owned( "format" ) + .map( ListFormat::from_str ) { this.format( v? ) } else { this }; + + this = if let Some( v ) = value + .get_owned( "with_version" ) { this.with_version::< bool >( v ) } else { this }; + this = if let Some( v ) = value + .get_owned( "with_path" ) { this.with_path::< bool >( v ) } else { this }; + this = if let Some( v ) = value + .get_owned( "with_local" ) { this.with_local::< bool >( v ) } else { this }; + this = if let Some( v ) = value + .get_owned( "with_remote" ) { this.with_remote::< bool >( v ) } else { this }; + this = if let Some( v ) = value + .get_owned( "with_primary" ) { this.with_primary::< bool >( v ) } else { this }; + this = if let Some( v ) = value + .get_owned( "with_dev" ) { this.with_dev::< bool >( v ) } else { this }; + this = if let Some( v ) = value + .get_owned( "with_build" ) { this.with_build::< bool >( v ) } else { this }; Ok( this.form() ) } diff --git a/module/move/willbe/src/command/main_header.rs b/module/move/willbe/src/command/main_header.rs index 558f2a625b..efd23e67c4 100644 --- a/module/move/willbe/src/command/main_header.rs +++ b/module/move/willbe/src/command/main_header.rs @@ -2,17 +2,19 @@ mod private { use crate::*; use action; - use _path::AbsolutePath; - use error_tools::Result; - use wtools::error::anyhow::Error; + use error::untyped::{ Error }; /// Generates header to main Readme.md file. - pub fn readme_header_renew() -> Result< () > + // qqq : typed error + pub fn readme_header_renew() -> error::untyped::Result< () > { - match action::readme_header_renew( AbsolutePath::try_from( std::env::current_dir()? )? ) + match action::readme_header_renew + ( + CrateDir::transitive_try_from::< AbsolutePath >( CurrentPath )? + ) { - Ok( report ) => - { + Ok( report ) => + { println!( "{report}" ); Ok( () ) } diff --git a/module/move/willbe/src/command/mod.rs b/module/move/willbe/src/command/mod.rs index 74f58a48bc..4cad62a6dc 100644 --- a/module/move/willbe/src/command/mod.rs +++ b/module/move/willbe/src/command/mod.rs @@ -20,6 +20,11 @@ pub( crate ) mod private .kind( Type::List( Type::String.into(), ',' ) ) .optional( true ) .end() + .property( "channel" ) + .hint( "Release channels for rust." ) + .kind( Type::String ) + .optional( true ) + .end() .property( "dry" ) .hint( "Enables 'dry run'. Does not publish, only simulates. Default is `true`." ) .kind( Type::Bool ) @@ -103,17 +108,17 @@ pub( crate ) mod private .command( "readme.health.table.renew" ) .hint( "Generate a table for the root `Readme.md`" ) - .long_hint( + .long_hint( r#"Generates a data summary table for the `Readme.md` file located in the root of the workspace. To ensure the proper execution of the command, the following tags need to be specified in the Readme.md file: - + - + After executing the command, the tags will not be modified. - + Tags can contains params: - + path: The relative path to the directory from workspace root, which crates will be taken. Default is './'. with_branches: If set to 1, it will display the status of workflow execution on branches specified in branches under workspace.metadata in the Cargo.toml of your workspace. For example, branches = ["master", "alpha"]. Default is 1. with_stability: If set to 1, a column indicating the stability of the module will be added. Information is taken from package.metadata of each module (package.metadata.stability = "stable"). By default, the module is considered experimental. Default is 1. @@ -261,7 +266,7 @@ with_gitpod: If set to 1, a column with a link to Gitpod will be added. Clicking .long_hint( "Generate header which contains a badge with the general status of workspace, a link to discord, an example in gitpod and documentation in workspace`s Readme.md file.\n For use this command you need to specify:\n\n[workspace.metadata]\nmaster_branch = \"alpha\"\nworkspace_name = \"wtools\"\nrepo_url = \"https://github.com/Wandalen/wTools\"\ndiscord_url = \"https://discord.gg/123123\"\n\nin workspace's Cargo.toml.\n\nGenerates header for each workspace member which contains a badge with the status of crate, a link to discord, an example in gitpod and documentation in crate Readme.md file.\nFor use this command you need to specify:\n\n[package]\nname = \"test_module\"\nrepository = \"https://github.com/Username/ProjectName/tree/master/module/test_module\"\n...\n[package.metadata]\nstability = \"stable\" (Optional)\ndiscord_url = \"https://discord.gg/1234567890\" (Optional)\n\nin module's Cargo.toml.") .routine( command::readme_headers_renew ) .end() - + .command( "features" ) .hint( "Lists features of the package" ) .long_hint( "Lists features of the package located in a folder.\nWill list either separate package features or features for every package of a workspace") @@ -283,7 +288,7 @@ with_gitpod: If set to 1, a column with a link to Gitpod will be added. Clicking crate::mod_interface! { - protected use ca; + own use ca; /// List packages. layer list; diff --git a/module/move/willbe/src/command/publish.rs b/module/move/willbe/src/command/publish.rs index 9b1d09eff0..a70af4265d 100644 --- a/module/move/willbe/src/command/publish.rs +++ b/module/move/willbe/src/command/publish.rs @@ -5,13 +5,16 @@ mod private use colored::Colorize; use wca::VerifiedCommand; - use wtools::error::{ Result, for_app::Context }; + use error::{ untyped::Context }; // xxx use former::Former; use std::fmt::Write; + use channel::Channel; #[ derive( Former ) ] struct PublishProperties { + #[ former( default = Channel::Stable ) ] + channel : Channel, #[ former( default = true ) ] dry : bool, #[ former( default = true ) ] @@ -22,20 +25,43 @@ mod private /// Publish package. /// - pub fn publish( o : VerifiedCommand ) -> Result< () > + pub fn publish( o : VerifiedCommand ) -> error::untyped::Result< () > // qqq : use typed error { - let args_line = format!( "{}", o.args.get_owned( 0 ).unwrap_or( std::path::PathBuf::from( "" ) ).display() ); - let prop_line = format!( "{}", o.props.iter().map( | p | format!( "{}:{}", p.0, p.1.to_string() ) ).collect::< Vec< _ > >().join(" ") ); + let args_line = format! + ( + "{}", + o + .args + .get_owned( 0 ) + .unwrap_or( std::path::PathBuf::from( "" ) ).display() + ); + let prop_line = format! + ( + "{}", + o + .props + .iter() + .map( | p | format!( "{}:{}", p.0, p.1.to_string() ) ) + .collect::< Vec< _ > >().join(" ") ); - let patterns : Vec< _ > = o.args.get_owned( 0 ).unwrap_or_else( || vec![ "./".into() ] ); + let patterns : Vec< _ > = o + .args + .get_owned( 0 ) + .unwrap_or_else( || vec![ "./".into() ] ); - let PublishProperties { dry, temp } = o.props.try_into()?; - let plan = action::publish_plan( patterns, dry, temp ).context( "Failed to plan the publication process" )?; + let PublishProperties + { + channel, + dry, + temp + } = o.props.try_into()?; + let plan = action::publish_plan( patterns, channel, dry, temp ) + .context( "Failed to plan the publication process" )?; let mut formatted_plan = String::new(); writeln!( &mut formatted_plan, "Tree :" )?; plan.write_as_tree( &mut formatted_plan )?; - + if !plan.plans.is_empty() { writeln!( &mut formatted_plan, "The following packages are pending for publication :" )?; @@ -49,13 +75,14 @@ mod private { println!( "{report}" ); - if dry && report.packages.iter().find( |( _, p )| p.publish_required ).is_some() + if dry && !report.packages.is_empty() { let args = if args_line.is_empty() { String::new() } else { format!(" {}", args_line) }; let prop = if prop_line.is_empty() { String::new() } else { format!(" {}", prop_line) }; - let line = format!("will .publish{}{} dry:0", args, prop); - println!("To apply plan, call the command `{}`", line.blue()); - // qqq : for Petro : for Bohdan : bad. should be exact command with exact parameters + let line = format!("will .publish{}{} dry:0", args, prop ); + println!("To apply plan, call the command `{}`", line.blue() ); + // aaa : for Petro : for Bohdan : bad. should be exact command with exact parameters + // aaa : it`s already works } Ok( () ) @@ -70,13 +97,23 @@ mod private impl TryFrom< wca::Props > for PublishProperties { - type Error = wtools::error::for_app::Error; + type Error = error::untyped::Error; fn try_from( value : wca::Props ) -> Result< Self, Self::Error > { let mut this = Self::former(); - this = if let Some( v ) = value.get_owned( "dry" ) { this.dry::< bool >( v ) } else { this }; - this = if let Some( v ) = value.get_owned( "temp" ) { this.temp::< bool >( v ) } else { this }; + this = if let Some( v ) = value + .get_owned( "channel" ) + { + this.channel::< Channel >( { let v : String = v; Channel::try_from( v )? } ) + } + else + { this }; + + this = if let Some( v ) = value + .get_owned( "dry" ) { this.dry::< bool >( v ) } else { this }; + this = if let Some( v ) = value + .get_owned( "temp" ) { this.temp::< bool >( v ) } else { this }; Ok( this.form() ) } diff --git a/module/move/willbe/src/command/publish_diff.rs b/module/move/willbe/src/command/publish_diff.rs index 961ba818c4..4691331866 100644 --- a/module/move/willbe/src/command/publish_diff.rs +++ b/module/move/willbe/src/command/publish_diff.rs @@ -2,11 +2,13 @@ mod private { use crate::*; + use std::fs; use std::path::PathBuf; use wca::VerifiedCommand; - use wtools::error::Result; - use _path::AbsolutePath; + // use error::Result; + // qqq : group dependencies + // use path::AbsolutePath; #[ derive( former::Former ) ] struct PublishDiffProperties @@ -27,7 +29,8 @@ mod private /// # Errors /// /// Returns an error if there is an issue with the command. - pub fn publish_diff( o : VerifiedCommand ) -> Result< () > + + pub fn publish_diff( o : VerifiedCommand ) -> error::untyped::Result< () > // qqq : use typed error { let path : PathBuf = o.args.get_owned( 0 ).unwrap_or( std::env::current_dir()? ); let PublishDiffProperties { keep_archive } = o.props.try_into()?; @@ -40,7 +43,7 @@ mod private println!( "{}", action::publish_diff( o )? ); if let Some( keep ) = keep_archive { - let keep = AbsolutePath::try_from( keep ).unwrap(); + let keep = AbsolutePath::try_from( fs::canonicalize( keep )? ).unwrap(); println!( "Remote version of the package was saved at `{}`", keep.as_ref().display() ); } @@ -49,12 +52,16 @@ mod private impl TryFrom< wca::Props > for PublishDiffProperties { - type Error = wtools::error::for_app::Error; + type Error = error::untyped::Error; fn try_from( value : wca::Props ) -> Result< Self, Self::Error > { let mut this = Self::former(); - this = if let Some( v ) = value.get_owned( "keep_archive" ) { this.keep_archive::< PathBuf >( v ) } else { this }; + this = if let Some( v ) = value + .get_owned( "keep_archive" ) + { this.keep_archive::< PathBuf >( v ) } + else + { this }; Ok( this.form() ) } diff --git a/module/move/willbe/src/command/readme_headers_renew.rs b/module/move/willbe/src/command/readme_headers_renew.rs index d8b4edd5c5..9a79a2b144 100644 --- a/module/move/willbe/src/command/readme_headers_renew.rs +++ b/module/move/willbe/src/command/readme_headers_renew.rs @@ -1,34 +1,33 @@ mod private { use crate::*; - use _path::AbsolutePath; use action; - use wtools::error::anyhow::Error; - use error_tools::{ Result, err }; + use error::{ err }; use std::fmt::{ Display, Formatter }; #[ derive( Debug, Default ) ] struct ReadmeHeadersRenewReport { main_header_renew_report : action::MainHeaderRenewReport, - main_header_renew_error : Option< Error >, + main_header_renew_error : Option< action::MainHeaderRenewError >, // aaa : for Petro : typed error // aaa : done modules_headers_renew_report : action::ModulesHeadersRenewReport, - modules_headers_renew_error : Option< Error >, + modules_headers_renew_error : Option< action::ModulesHeadersRenewError >, // aaa : for Petro : typed error // aaa : done } impl Display for ReadmeHeadersRenewReport { fn fmt( &self, f : &mut Formatter< '_ > ) -> std::fmt::Result { - match ( &self.main_header_renew_error, &self.modules_headers_renew_error ) - { - ( Some( main ), Some( modules ) ) => + match ( &self.main_header_renew_error, &self.modules_headers_renew_error ) + { + ( Some( main ), Some( modules ) ) => { writeln! - ( - f, - "Main header renew report : \n{}\nError : \n{:?}\nModules headers renew report : \n{}\nError : \n{:?}", - self.main_header_renew_report, main, self.modules_headers_renew_report, modules + ( + f, + "Main header renew report : \ +{}\nError : \n{:?}\nModules headers renew report : \n{}\nError : \n{:?}", + self.main_header_renew_report, main, self.modules_headers_renew_report, modules )?; } ( Some( main ), None ) => @@ -36,7 +35,8 @@ mod private writeln! ( f, - "Main header renew report : \n{}\nError : \n{:?}\nModules headers renew report : \n{}", + "Main header renew report : \ +{}\nError : \n{:?}\nModules headers renew report : \n{}", self.main_header_renew_report, main, self.modules_headers_renew_report )?; } @@ -45,7 +45,8 @@ mod private writeln! ( f, - "Main header renew report : \n{}\nModules headers renew report : \n{}\nError : \n{:?}\n", + "Main header renew report : \ +{}\nModules headers renew report : \n{}\nError : \n{:?}\n", self.main_header_renew_report, self.modules_headers_renew_report, modules )?; } @@ -62,29 +63,30 @@ mod private Ok( () ) } } - + /// Aggregates two commands: `generate_modules_headers` & `generate_main_header` - pub fn readme_headers_renew() -> Result< () > + pub fn readme_headers_renew() -> error::untyped::Result< () > // qqq : use typed error { let mut report = ReadmeHeadersRenewReport::default(); - let absolute_path = AbsolutePath::try_from( std::env::current_dir()? )?; + // let absolute_path = AbsolutePath::try_from( std::env::current_dir()? )?; + let crate_dir = CrateDir::transitive_try_from::< AbsolutePath >( CurrentPath )?; let mut fail = false; - - match action::readme_header_renew( absolute_path.clone() ) + + match action::readme_header_renew( crate_dir.clone() ) { - Ok( r ) => + Ok( r ) => { report.main_header_renew_report = r; } - Err( ( r, error ) ) => + Err( ( r, error ) ) => { fail = true; report.main_header_renew_report = r; - report.main_header_renew_error = Some( Error::from( error ) ); + report.main_header_renew_error = Some( error ); } }; - match action::readme_modules_headers_renew( absolute_path ) + match action::readme_modules_headers_renew( crate_dir ) { Ok( r ) => { @@ -94,10 +96,10 @@ mod private { fail = true; report.modules_headers_renew_report = r; - report.modules_headers_renew_error = Some( Error::from( error ) ); + report.modules_headers_renew_error = Some( error ); } } - + if fail { eprintln!( "{report}" ); diff --git a/module/move/willbe/src/command/readme_health_table_renew.rs b/module/move/willbe/src/command/readme_health_table_renew.rs index 945490062f..c91b5b6357 100644 --- a/module/move/willbe/src/command/readme_health_table_renew.rs +++ b/module/move/willbe/src/command/readme_health_table_renew.rs @@ -2,14 +2,19 @@ mod private { use crate::*; - use wtools::error::{ for_app::Context, Result }; + use error::{ untyped::Context }; /// /// Generate table. /// - pub fn readme_health_table_renew() -> Result< () > + // qqq : typed error + pub fn readme_health_table_renew() -> error::untyped::Result< () > { - action::readme_health_table_renew( &std::env::current_dir()? ).context( "Fail to create table" ) + action::readme_health_table_renew + ( + &std::env::current_dir()? + ) + .context( "Fail to create table" ) } } diff --git a/module/move/willbe/src/command/readme_modules_headers_renew.rs b/module/move/willbe/src/command/readme_modules_headers_renew.rs index e959c12365..391205210e 100644 --- a/module/move/willbe/src/command/readme_modules_headers_renew.rs +++ b/module/move/willbe/src/command/readme_modules_headers_renew.rs @@ -1,23 +1,25 @@ mod private { use crate::*; - use _path::AbsolutePath; - use wtools::error::{ for_app::Error, Result }; + // use path::AbsolutePath; + // use error::{ untyped::Error }; /// Generate headers for workspace members - pub fn readme_modules_headers_renew() -> Result< () > + // qqq : typed error + pub fn readme_modules_headers_renew() -> error::untyped::Result< () > { - match action::readme_modules_headers_renew( AbsolutePath::try_from( std::env::current_dir()? )? ) + match action::readme_modules_headers_renew( CrateDir::transitive_try_from::< AbsolutePath >( CurrentPath )? ) { - Ok( report ) => + Ok( report ) => { println!( "{report}" ); Ok( () ) } - Err( ( report, e ) ) => + Err( ( report, e ) ) => { eprintln!( "{report}" ); - Err( Error::from( e ).context( "Fail to generate modules headers." ) ) + Err( error::untyped::Error::from( e ).context( "Fail to generate modules headers." ) ) + // qqq : use typed error } } } diff --git a/module/move/willbe/src/command/test.rs b/module/move/willbe/src/command/test.rs index 25019344fb..9a05c92c89 100644 --- a/module/move/willbe/src/command/test.rs +++ b/module/move/willbe/src/command/test.rs @@ -3,16 +3,17 @@ mod private { use crate::*; - use std::collections::HashSet; - use std::path::PathBuf; + use collection::HashSet; + use std::fs; use colored::Colorize; use wca::VerifiedCommand; - use wtools::error::Result; - use _path::AbsolutePath; + // use error::Result; + // qqq : group dependencies + use path::{ AbsolutePath, PathBuf }; use action::test::TestsCommandOptions; use former::Former; use channel::Channel; - use error_tools::for_app::bail; + use error::untyped::bail; use optimization::Optimization; #[ derive( Former, Debug ) ] @@ -47,13 +48,30 @@ mod private } /// run tests in specified crate - pub fn test( o : VerifiedCommand ) -> Result< () > + // qqq : don't use 1-prameter Result + pub fn test( o : VerifiedCommand ) -> error::untyped::Result< () > // qqq : use typed error { - let args_line = format!( "{}", o.args.get_owned( 0 ).unwrap_or( std::path::PathBuf::from( "" ) ).display() ); - let prop_line = format!( "{}", o.props.iter().map( | p | format!( "{}:{}", p.0, p.1.to_string() ) ).collect::< Vec< _ > >().join(" ") ); + let args_line = format! + ( + "{}", + o + .args + .get_owned( 0 ) + .unwrap_or( std::path::PathBuf::from( "" ) ) + .display() + ); + let prop_line = format! + ( + "{}", + o + .props + .iter() + .map( | p | format!( "{}:{}", p.0, p.1.to_string() ) ) + .collect::< Vec< _ > >().join(" ") + ); let path : PathBuf = o.args.get_owned( 0 ).unwrap_or_else( || "./".into() ); - let path = AbsolutePath::try_from( path )?; + let path = AbsolutePath::try_from( fs::canonicalize( path )? )?; let TestsProperties { dry, @@ -68,7 +86,7 @@ mod private with_all_features, with_none_features, with_debug, - with_release, + with_release, with_progress } = o.props.try_into()?; @@ -82,7 +100,8 @@ mod private if optimizations.is_empty() { - bail!( "Cannot run tests if with_debug and with_release are both false. Set at least one of them to true." ); + bail!( "Cannot run tests if with_debug and with_release are both false. \ +Set at least one of them to true." ); } @@ -103,7 +122,7 @@ mod private match action::test( args, dry ) { - + Ok( report ) => { if dry @@ -113,11 +132,11 @@ mod private let line = format!("will .publish{}{} dry:0", args, prop); println!("To apply plan, call the command `{}`", line.blue()); } - else - { + else + { println!( "{report} "); } - + Ok( () ) } Err( ( report, e ) ) => @@ -130,25 +149,39 @@ mod private impl TryFrom< wca::Props > for TestsProperties { - type Error = wtools::error::for_app::Error; + type Error = error::untyped::Error; fn try_from( value : wca::Props ) -> Result< Self, Self::Error > { let mut this = Self::former(); - this = if let Some( v ) = value.get_owned( "dry" ) { this.dry::< bool >( v ) } else { this }; - this = if let Some( v ) = value.get_owned( "temp" ) { this.temp::< bool >( v ) } else { this }; - this = if let Some( v ) = value.get_owned( "with_stable" ) { this.with_stable::< bool >( v ) } else { this }; - this = if let Some( v ) = value.get_owned( "with_nightly" ) { this.with_nightly::< bool >( v ) } else { this }; - this = if let Some( v ) = value.get_owned( "concurrent" ) { this.concurrent::< u32 >( v ) } else { this }; - this = if let Some( v ) = value.get_owned( "power" ) { this.power::< u32 >( v ) } else { this }; - this = if let Some( v ) = value.get_owned( "include" ) { this.include::< Vec< String > >( v ) } else { this }; - this = if let Some( v ) = value.get_owned( "exclude" ) { this.exclude::< Vec< String > >( v ) } else { this }; - this = if let Some( v ) = value.get_owned( "with_debug" ) { this.with_debug::< bool >( v ) } else { this }; - this = if let Some( v ) = value.get_owned( "with_release" ) { this.with_release::< bool >( v ) } else { this }; - this = if let Some( v ) = value.get_owned( "with_all_features" ) { this.with_all_features::< bool >( v ) } else { this }; - this = if let Some( v ) = value.get_owned( "with_none_features" ) { this.with_none_features::< bool >( v ) } else { this }; - this = if let Some( v ) = value.get_owned( "always" ) { this.enabled_features::< Vec< String > >( v ) } else { this }; - this = if let Some( v ) = value.get_owned( "with_progress" ) { this.with_progress::< bool >( v ) } else { this }; + this = if let Some( v ) = value + .get_owned( "dry" ) { this.dry::< bool >( v ) } else { this }; + this = if let Some( v ) = value + .get_owned( "temp" ) { this.temp::< bool >( v ) } else { this }; + this = if let Some( v ) = value + .get_owned( "with_stable" ) { this.with_stable::< bool >( v ) } else { this }; + this = if let Some( v ) = value + .get_owned( "with_nightly" ) { this.with_nightly::< bool >( v ) } else { this }; + this = if let Some( v ) = value + .get_owned( "concurrent" ) { this.concurrent::< u32 >( v ) } else { this }; + this = if let Some( v ) = value + .get_owned( "power" ) { this.power::< u32 >( v ) } else { this }; + this = if let Some( v ) = value + .get_owned( "include" ) { this.include::< Vec< String > >( v ) } else { this }; + this = if let Some( v ) = value + .get_owned( "exclude" ) { this.exclude::< Vec< String > >( v ) } else { this }; + this = if let Some( v ) = value + .get_owned( "with_debug" ) { this.with_debug::< bool >( v ) } else { this }; + this = if let Some( v ) = value + .get_owned( "with_release" ) { this.with_release::< bool >( v ) } else { this }; + this = if let Some( v ) = value + .get_owned( "with_all_features" ) { this.with_all_features::< bool >( v ) } else { this }; + this = if let Some( v ) = value + .get_owned( "with_none_features" ) { this.with_none_features::< bool >( v ) } else { this }; + this = if let Some( v ) = value + .get_owned( "always" ) { this.enabled_features::< Vec< String > >( v ) } else { this }; + this = if let Some( v ) = value + .get_owned( "with_progress" ) { this.with_progress::< bool >( v ) } else { this }; Ok( this.form() ) } diff --git a/module/move/willbe/src/command/workspace_renew.rs b/module/move/willbe/src/command/workspace_renew.rs index 26cc520bf4..7baa1515f6 100644 --- a/module/move/willbe/src/command/workspace_renew.rs +++ b/module/move/willbe/src/command/workspace_renew.rs @@ -4,7 +4,7 @@ mod private use former::Former; use wca::VerifiedCommand; - use wtools::error::{ anyhow::Context, Result }; + use error::{ untyped::Context }; use action::WorkspaceTemplate; #[ derive( Former ) ] @@ -18,23 +18,33 @@ mod private /// Create new workspace. /// - pub fn workspace_renew( o : VerifiedCommand ) -> Result< () > + // qqq : typed error + pub fn workspace_renew( o : VerifiedCommand ) -> error::untyped::Result< () > // qqq : use typed error { let WorkspaceNewProperties { repository_url, branches } = o.props.try_into()?; let template = WorkspaceTemplate::default(); - action::workspace_renew( &std::env::current_dir()?, template, repository_url, branches ).context( "Fail to create workspace" ) + action::workspace_renew + ( + &std::env::current_dir()?, + template, + repository_url, + branches + ) + .context( "Fail to create workspace" ) } impl TryFrom< wca::Props > for WorkspaceNewProperties { - type Error = wtools::error::for_app::Error; + type Error = error::untyped::Error; fn try_from( value : wca::Props ) -> std::result::Result< Self, Self::Error > { let mut this = Self::former(); - this = if let Some( v ) = value.get_owned( "repository_url" ) { this.repository_url::< String >( v ) } else { this }; - this = if let Some( v ) = value.get_owned( "branches" ) { this.branches::< Vec< String > >( v ) } else { this }; + this = if let Some( v ) = value + .get_owned( "repository_url" ) { this.repository_url::< String >( v ) } else { this }; + this = if let Some( v ) = value + .get_owned( "branches" ) { this.branches::< Vec< String > >( v ) } else { this }; Ok( this.form() ) } diff --git a/module/move/willbe/src/entity/channel.rs b/module/move/willbe/src/entity/channel.rs index e9611212d1..cb45418c06 100644 --- a/module/move/willbe/src/entity/channel.rs +++ b/module/move/willbe/src/entity/channel.rs @@ -4,12 +4,11 @@ mod private use std:: { fmt::Formatter, - path::Path, - collections::HashSet, + ffi::OsString, }; - use std::ffi::OsString; - use error_tools::for_app::Error; - use wtools::error::Result; + use path::Path; + use collection::HashSet; + use error::untyped::{ Error }; use process_tools::process::*; /// The `Channel` enum represents different release channels for rust. @@ -35,10 +34,25 @@ mod private } } + impl TryFrom< String > for Channel + { + type Error = error::untyped::Error; + fn try_from( value : String ) -> Result< Self, Self::Error > + { + Ok( match value.as_ref() + { + "stable" => Self::Stable, + "nightly" => Self::Nightly, + other => error::untyped::bail!( "Unexpected channel value. Expected [stable, channel]. Got: `{other}`" ), + }) + } + } + /// Retrieves a list of available channels. /// /// This function takes a path and returns a `Result` with a vector of strings representing the available channels. - pub fn available_channels< P >( path : P ) -> Result< HashSet< Channel > > + // qqq : typed error + pub fn available_channels< P >( path : P ) -> error::untyped::Result< HashSet< Channel > > where P : AsRef< Path >, { @@ -52,8 +66,9 @@ mod private let list = report .out .lines() - .map( | l | l.split_once( '-' ).unwrap().0 ) - .filter_map( | c | match c + // toolchain with a name without `-` may exist, but we are looking at specific ones + .filter_map( | l | l.split_once( '-' ) ) + .filter_map( |( c, _ ) | match c { "stable" => Some( Channel::Stable ), "nightly" => Some( Channel::Nightly ), @@ -69,6 +84,6 @@ mod private crate::mod_interface! { - protected use Channel; - protected use available_channels; + own use Channel; + own use available_channels; } diff --git a/module/move/willbe/src/entity/code.rs b/module/move/willbe/src/entity/code.rs new file mode 100644 index 0000000000..5c8418bad8 --- /dev/null +++ b/module/move/willbe/src/entity/code.rs @@ -0,0 +1,43 @@ +mod private +{ + use crate::*; + + use std:: + { + borrow::Cow, + }; + + /// A trait for converting an object to its code representation. + /// + /// The `AsCode` trait defines a method for converting an object into a code representation, + /// typically as a string. This can be useful for generating code from various data structures + /// or objects. + /// + /// ``` + pub trait AsCode + { + /// Converts the object to its code representation. + fn as_code< 'a >( &'a self ) -> std::io::Result< Cow< 'a, str > >; + } + + /// A trait for retrieving an iterator over items of a source file. + /// + /// The `CodeItems` trait is used to represent objects that can provide an iterator over their + /// contained source files. This is useful in scenarios where you need to access or process + /// all source files associated with an object, such as a workspace or a package. + pub trait CodeItems + { + /// Returns an iterator over the source files. + fn items( &self ) -> impl IterTrait< '_, syn::Item >; + } +} + +// + +crate::mod_interface! +{ + + exposed use AsCode; + exposed use CodeItems; + +} diff --git a/module/move/willbe/src/entity/dependency.rs b/module/move/willbe/src/entity/dependency.rs new file mode 100644 index 0000000000..337ecb01a2 --- /dev/null +++ b/module/move/willbe/src/entity/dependency.rs @@ -0,0 +1,287 @@ +mod private +{ + + use crate::*; + + // use crates_tools::CrateArchive; + // use workspace::Workspace; + use error:: + { + // untyped::Result, + // typed::Error, + untyped::format_err, + }; + + /// A dependency of the main crate + #[ derive( Debug, Clone, Copy ) ] + #[ repr( transparent ) ] + pub struct DependencyRef< 'a > + { + inner : &'a cargo_metadata::Dependency, + } + + impl< 'a > DependencyRef< 'a > + { + + /// The file system path for a local path dependency. + /// Only produced on cargo 1.51+ + pub fn crate_dir( &self ) -> Option< CrateDir > + { + match &self.inner.path + { + Some( path ) => path.as_path().try_into().ok(), + None => None, + } + } + + /// Name as given in the Cargo.toml. + pub fn name( &self ) -> String + { + self.inner.name.clone() + } + + /// The kind of dependency this is. + pub fn kind( &self ) -> DependencyKind + { + match self.inner.kind + { + cargo_metadata::DependencyKind::Normal => DependencyKind::Normal, + cargo_metadata::DependencyKind::Development => DependencyKind::Development, + cargo_metadata::DependencyKind::Build => DependencyKind::Build, + cargo_metadata::DependencyKind::Unknown => DependencyKind::Unknown, + } + } + + /// Required version + pub fn req( &self ) -> semver::VersionReq + { + self.inner.req.clone() + } + } + + impl< 'a > From< &'a cargo_metadata::Dependency > for DependencyRef< 'a > + { + #[ inline( always ) ] + fn from( inner : &'a cargo_metadata::Dependency ) -> Self + { + Self { inner } + } + } + + /// Dependencies can come in three kinds + #[ derive( Eq, PartialEq, Debug, Clone, Copy ) ] + pub enum DependencyKind + { + /// The 'normal' kind + Normal, + /// Those used in tests only + Development, + /// Those used in build scripts only + Build, + /// The 'unknown' kind + Unknown, + } + + // + + /// Identifier of any crate (local and remote). + #[ derive( Debug, Clone, Hash, Eq, PartialEq ) ] + pub struct CrateId + { + /// The name of the crate. + pub name : String, // qqq : that should be Arc< str > + /// The absolute path to the crate, if available. + pub crate_dir : Option< CrateDir >, // qqq : that should be Option< Arc< CrateDir > > + // pub path : Option< AbsolutePath >, + } + + impl< 'a > From< &WorkspacePackageRef< 'a > > for CrateId + { + fn from( value : &WorkspacePackageRef< 'a > ) -> Self + { + Self + { + name : value.name().into(), + crate_dir : Some( value.crate_dir().unwrap() ) + // path : Some( AbsolutePath::try_from( value.manifest_file().parent().unwrap() ).unwrap() ), + } + } + } + + impl From< &DependencyRef< '_ > > for CrateId + { + fn from( value : &DependencyRef< '_ > ) -> Self + { + Self + { + name : value.name().into(), + crate_dir : value.crate_dir(), + // path : value.path().clone().map( | path | AbsolutePath::try_from( path ).unwrap() ), + } + } + } + + /// Sorting variants for dependencies. + #[ derive( Debug, Copy, Clone ) ] + pub enum DependenciesSort + { + /// List will be topologically sorted. + Topological, + /// List will be unsorted. + Unordered, + } + + #[ derive( Debug, Clone ) ] + /// Args for `local_dependencies` function. + pub struct DependenciesOptions + { + /// With dependencies of dependencies. + pub recursive : bool, + /// With sorting. + pub sort : DependenciesSort, + /// Include dev dependencies. + pub with_dev : bool, + /// Include remote dependencies. + pub with_remote : bool, + } + + impl Default for DependenciesOptions + { + fn default() -> Self + { + Self + { + recursive : true, + sort : DependenciesSort::Unordered, + with_dev : false, + with_remote : false, + } + } + } + + // qqq : for Bohdan : poor description + /// Recursive implementation of the `list` function + pub fn _list< 'a > + ( + workspace : &Workspace, // aaa : for Bohdan : no mut // aaa : no mut + package : &Package< 'a >, + graph : &mut collection::HashMap< CrateId, collection::HashSet< CrateId > >, + opts : DependenciesOptions + ) + // qqq : use typed error + -> error::untyped::Result< CrateId > + { + let DependenciesOptions + { + recursive, + sort : _, + with_dev, + with_remote, + } = opts; + if recursive && with_remote { unimplemented!( "`recursive` + `with_remote` options") } + + let manifest_file = &package.manifest_file(); + + let package = workspace + .package_find_by_manifest( &manifest_file ) + .ok_or( format_err!( "Package not found in the workspace with path : `{}`", manifest_file.as_ref().display() ) )?; + + let deps : collection::HashSet< _ > = package + .dependencies() + // .iter() + .filter( | dep | ( with_remote || dep.crate_dir().is_some() ) && ( with_dev || dep.kind() != DependencyKind::Development ) ) + .map( | dep | CrateId::from( &dep ) ) + .collect(); + + let package = CrateId::from( &package ); + graph.insert( package.clone(), deps.clone() ); + + if recursive + { + for dep in deps + { + if graph.get( &dep ).is_none() + { + // unwrap because `recursive` + `with_remote` not yet implemented + _list + ( + workspace, + &dep.crate_dir.unwrap().try_into()?, + // &dep.path.as_ref().unwrap().join( "Cargo.toml" ).try_into().unwrap(), + graph, + opts.clone(), + )?; + } + } + } + + Ok( package ) + } + + /// Returns local dependencies of a specified package by its package path from a workspace. + /// + /// # Arguments + /// + /// - `workspace` - holds cached information about the workspace, such as the packages it contains and their dependencies. By passing it as a mutable reference, function can update the cache as needed. + /// - `package` - The package package file contains package about the package such as its name, version, and dependencies. + /// - `opts` - used to specify options or configurations for fetching local dependencies. + /// + /// # Returns + /// + /// If the operation is successful, returns a vector of `PathBuf` objects, where each `PathBuf` represents the path to a local dependency of the specified package. + // qqq : typed error? + pub fn list< 'a > + ( + workspace : &mut Workspace, + package : &Package< 'a >, + opts : DependenciesOptions + ) + // qqq : use typed error + -> error::untyped::Result< Vec< CrateId > > + { + let mut graph = collection::HashMap::new(); + let root = _list( workspace, package, &mut graph, opts.clone() )?; + + let output = match opts.sort + { + DependenciesSort::Unordered => + { + graph + .into_iter() + .flat_map( | ( id, dependency ) | + { + dependency + .into_iter() + .chain( Some( id ) ) + }) + .unique() + .filter( | x | x != &root ) + .collect() + } + DependenciesSort::Topological => + { + // qqq : too long line + graph::toposort( graph::construct( &graph ) ).map_err( | err | format_err!( "{}", err ) )?.into_iter().filter( | x | x != &root ).collect() + }, + }; + + Ok( output ) + } + +} + +// + +crate::mod_interface! +{ + + exposed use DependencyRef; + exposed use DependencyKind; + + own use CrateId; + own use DependenciesSort; + own use DependenciesOptions; + own use _list; + own use list; + +} diff --git a/module/move/willbe/src/entity/diff.rs b/module/move/willbe/src/entity/diff.rs index 49ef63b29a..08b0638b77 100644 --- a/module/move/willbe/src/entity/diff.rs +++ b/module/move/willbe/src/entity/diff.rs @@ -4,17 +4,17 @@ mod private use std:: { - collections::HashSet, fmt::Formatter, - path::PathBuf, }; - use std::collections::HashMap; + use path::PathBuf; + use collection::HashMap; use colored::Colorize; use crates_tools::CrateArchive; - use similar::*; + use collection::HashSet; + use similar::{ TextDiff, ChangeTag }; + + // use similar::*; // qqq : for Bohdan : bad - use wtools::iter::Itertools; - /// These files are ignored because they can be safely changed without affecting functionality /// /// - `.cargo_vcs_info.json` - contains the git sha1 hash that varies between different commits @@ -78,7 +78,7 @@ mod private Is : Into< HashSet< I > >, I : AsRef< std::path::Path >, { - let current = self.0.keys().cloned().collect::< HashSet< _ > >(); + let current : HashSet< _ > = self.0.keys().cloned().collect(); let Some( key ) = current.iter().next() else { return self }; let crate_part = std::path::Path::new( key.components().next().unwrap().as_os_str() ); @@ -218,9 +218,9 @@ mod private crate::mod_interface! { - protected use Diff; - protected use DiffItem; - protected use DiffReport; - protected use crate_diff; - protected use PUBLISH_IGNORE_LIST; + own use Diff; + own use DiffItem; + own use DiffReport; + own use crate_diff; + own use PUBLISH_IGNORE_LIST; } \ No newline at end of file diff --git a/module/move/willbe/src/entity/features.rs b/module/move/willbe/src/entity/features.rs index 54f38b2d22..300fa7ca2f 100644 --- a/module/move/willbe/src/entity/features.rs +++ b/module/move/willbe/src/entity/features.rs @@ -1,12 +1,9 @@ mod private { use crate::*; - use std::collections::{ BTreeSet, HashSet }; - // aaa : for Petro : don't use cargo_metadata and Package directly, use facade - // aaa : ✅ - use error_tools::for_app::{ bail, Result }; - use wtools::iter::Itertools; - use workspace::WorkspacePackage; + use collection::{ BTreeSet, HashSet }; + use error::untyped::{ bail }; // xxx + use iter::Itertools; /// Generates a powerset of the features available in the given `package`, /// filtered according to specified inclusion and exclusion criteria, @@ -42,12 +39,9 @@ mod private /// // Use `feature_combinations` as needed. /// ``` - // aaa : for Petro : bad, don't use ignore with need - // aaa : I have to ignore this test because the function accepts &Package as input, and to mock it requires a lot of lines - pub fn features_powerset ( - package : &WorkspacePackage, + package : WorkspacePackageRef< '_ >, power : usize, exclude_features : &[ String ], include_features : &[ String ], @@ -56,7 +50,8 @@ mod private with_none_features : bool, variants_cap : u32, ) - -> Result< HashSet< BTreeSet< String > > > + // qqq : for Petro : typed error + -> error::untyped::Result< HashSet< BTreeSet< String > > > { let mut features_powerset = HashSet::new(); @@ -109,14 +104,14 @@ mod private with_none_features : bool, enabled_features : &[ String ], total_features : usize - ) - -> usize + ) + -> usize { let mut estimate = 0; let mut binom = 1; let power = power.min( n ); - for k in 0..=power + for k in 0..=power { estimate += binom; binom = binom * ( n - k ) / ( k + 1 ); @@ -125,13 +120,13 @@ mod private if with_all_features { estimate += 1; } if with_none_features { estimate += 1; } - if !enabled_features.is_empty() + if !enabled_features.is_empty() { let len = enabled_features.len(); - let combinations = ( 0..=len.min( total_features ) ).map( | k | + let combinations = ( 0..=len.min( total_features ) ).map( | k | { let mut binom = 1; - for i in 0..k + for i in 0..k { binom = binom * ( len - i ) / ( i + 1 ); } @@ -148,6 +143,6 @@ mod private crate::mod_interface! { /// Features - protected use features_powerset; - protected use estimate_with; + own use features_powerset; + own use estimate_with; } diff --git a/module/move/willbe/src/entity/files.rs b/module/move/willbe/src/entity/files.rs new file mode 100644 index 0000000000..96efecf308 --- /dev/null +++ b/module/move/willbe/src/entity/files.rs @@ -0,0 +1,54 @@ +/// Internal namespace. +pub( crate ) mod private +{ + use crate::*; + + use std:: + { + io, + }; + use error:: + { + typed::Error, + }; + + /// `PathError` enum represents errors when creating a `CrateDir` object. + #[ derive( Debug, Error ) ] + pub enum PathError + { + /// Indicates a validation error with a descriptive message. + #[ error( "Failed to create a `CrateDir` object due to `{0}`" ) ] + Validation( String ), + /// Try to read or write + #[ error( "IO operation failed. Details : {0}" ) ] + Io( #[ from ] io::Error ), + } + +} + +// + +mod crate_dir; +mod manifest_file; +mod source_file; +mod either; + +// + +crate::mod_interface! +{ + exposed use super:: + { + crate_dir::CrateDir, + manifest_file::ManifestFile, + source_file:: + { + SourceFile, + Entries, + Sources, + // Items, + }, + either::EitherDirOrFile + }; + exposed use PathError; +} diff --git a/module/move/willbe/src/entity/files/crate_dir.rs b/module/move/willbe/src/entity/files/crate_dir.rs new file mode 100644 index 0000000000..7ea3424e56 --- /dev/null +++ b/module/move/willbe/src/entity/files/crate_dir.rs @@ -0,0 +1,259 @@ +use crate::*; + +use entity:: +{ + PathError, + ManifestFile, +}; +use core:: +{ + fmt, + ops:: + { + Deref, + DerefMut, + }, +}; +use std:: +{ + path::{ Path, PathBuf }, + io, +}; +// use error:: +// { +// Result, +// }; +use path::{ AbsolutePath, Utf8Path, Utf8PathBuf }; + +/// Path to crate directory +#[ derive( Clone, Ord, PartialOrd, Eq, PartialEq, Hash ) ] +pub struct CrateDir( AbsolutePath ); + +impl CrateDir +{ + + /// Returns inner type which is an absolute path. + #[ inline( always ) ] + pub fn absolute_path( self ) -> AbsolutePath + { + self.0 + } + + /// Returns path to manifest aka cargo file. + #[ inline( always ) ] + pub fn manifest_file( self ) -> ManifestFile + { + self.into() + } + +} + +impl fmt::Display for CrateDir +{ + fn fmt( &self, f : &mut fmt::Formatter<'_> ) -> fmt::Result + { + write!( f, "{}", self.0.display() ) + } +} + +impl fmt::Debug for CrateDir +{ + fn fmt( &self, f : &mut fmt::Formatter<'_> ) -> fmt::Result + { + write!( f, "crate dir :: {}", self.0.display() ) + } +} + +impl From< ManifestFile > for CrateDir +{ + fn from( src : ManifestFile ) -> Self + { + Self ( src.inner().parent().unwrap() ) + } +} + +impl From< CrateDir > for AbsolutePath +{ + fn from( src : CrateDir ) -> Self + { + src.absolute_path() + } +} + +impl From< CrateDir > for PathBuf +{ + fn from( src : CrateDir ) -> Self + { + src.absolute_path().inner() + } +} + +impl< 'a > TryFrom< &'a CrateDir > for &'a str +{ + type Error = std::io::Error; + fn try_from( src : &'a CrateDir ) -> Result< &'a str, Self::Error > + { + ( &src.0 ).try_into() + } +} + +impl TryFrom< &CrateDir > for String +{ + type Error = std::io::Error; + fn try_from( src : &CrateDir ) -> Result< String, Self::Error > + { + let src2 : &str = src.try_into()?; + Ok( src2.into() ) + } +} + +// impl< IntoPath : TryInto< PathBuf > > TryFrom< ( IntoPath, ) > +// for CrateDir +// where +// PathError : From< < IntoPath as TryInto< PathBuf > >::Error >, +// { +// type Error = PathError; +// +// #[ inline( always ) ] +// fn try_from( ( crate_dir_path, ) : ( IntoPath, ) ) -> Result< Self, Self::Error > +// { +// Self::try_from( AbsolutePath::try_from( crate_dir_path.try_into()? )? ) +// } +// } + +impl TryFrom< &AbsolutePath > for CrateDir +{ + type Error = PathError; + + #[ inline( always ) ] + fn try_from( crate_dir_path : &AbsolutePath ) -> Result< Self, Self::Error > + { + crate_dir_path.clone().try_into() + } +} + +impl TryFrom< AbsolutePath > for CrateDir +{ + type Error = PathError; + + #[ inline( always ) ] + fn try_from( crate_dir_path : AbsolutePath ) -> Result< Self, Self::Error > + { + if !crate_dir_path.as_ref().join( "Cargo.toml" ).is_file() + { + let err = io::Error::new( io::ErrorKind::InvalidData, format!( "Cannot find crate dir at {crate_dir_path:?}" ) ); + return Err( PathError::Io( err ) ); + } + Ok( Self( crate_dir_path ) ) + } +} + +impl TryFrom< &PathBuf > for CrateDir +{ + type Error = PathError; + + #[ inline( always ) ] + fn try_from( crate_dir_path : &PathBuf ) -> Result< Self, Self::Error > + { + Self::try_from( AbsolutePath::try_from( crate_dir_path )? ) + } +} + +impl TryFrom< PathBuf > for CrateDir +{ + type Error = PathError; + + #[ inline( always ) ] + fn try_from( crate_dir_path : PathBuf ) -> Result< Self, Self::Error > + { + Self::try_from( AbsolutePath::try_from( crate_dir_path )? ) + } +} + +impl TryFrom< &Path > for CrateDir +{ + type Error = PathError; + + #[ inline( always ) ] + fn try_from( crate_dir_path : &Path ) -> Result< Self, Self::Error > + { + Self::try_from( AbsolutePath::try_from( crate_dir_path )? ) + } +} + +impl TryFrom< &str > for CrateDir +{ + type Error = PathError; + + #[ inline( always ) ] + fn try_from( crate_dir_path : &str ) -> Result< Self, Self::Error > + { + Self::try_from( AbsolutePath::try_from( crate_dir_path )? ) + } +} + +impl TryFrom< Utf8PathBuf > for CrateDir +{ + type Error = PathError; + + #[ inline( always ) ] + fn try_from( crate_dir_path : Utf8PathBuf ) -> Result< Self, Self::Error > + { + Self::try_from( AbsolutePath::try_from( crate_dir_path )? ) + } +} + +impl TryFrom< &Utf8PathBuf > for CrateDir +{ + type Error = PathError; + + #[ inline( always ) ] + fn try_from( crate_dir_path : &Utf8PathBuf ) -> Result< Self, Self::Error > + { + Self::try_from( AbsolutePath::try_from( crate_dir_path )? ) + } +} + +impl TryFrom< &Utf8Path > for CrateDir +{ + type Error = PathError; + + #[ inline( always ) ] + fn try_from( crate_dir_path : &Utf8Path ) -> Result< Self, Self::Error > + { + Self::try_from( AbsolutePath::try_from( crate_dir_path )? ) + } +} + +impl AsRef< Path > for CrateDir +{ + fn as_ref( &self ) -> &Path + { + self.0.as_ref() + } +} + +impl AsMut< Path > for CrateDir +{ + fn as_mut( &mut self ) -> &mut Path + { + self.0.as_mut() + } +} + +impl Deref for CrateDir +{ + type Target = AbsolutePath; + fn deref( &self ) -> &Self::Target + { + &self.0 + } +} + +impl DerefMut for CrateDir +{ + fn deref_mut( &mut self ) -> &mut Self::Target + { + &mut self.0 + } +} diff --git a/module/move/willbe/src/entity/files/either.rs b/module/move/willbe/src/entity/files/either.rs new file mode 100644 index 0000000000..aa7fdb5863 --- /dev/null +++ b/module/move/willbe/src/entity/files/either.rs @@ -0,0 +1,90 @@ +use crate::*; +use core:: +{ + ops:: + { + Deref, + DerefMut, + }, +}; +use std:: +{ + path::Path, +}; +// use error:: +// { +// Result, +// }; + +/// Wrapper over `data_type::Either< CrateDir, ManifestFile >` with utils methods. +#[ derive( Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug ) ] +pub struct EitherDirOrFile( data_type::Either< CrateDir, ManifestFile > ); + +impl EitherDirOrFile +{ + /// Returns inner type which is an data_type::Either< CrateDir, ManifestFile >. + pub fn inner( self ) -> data_type::Either< CrateDir, ManifestFile > + { + self.0 + } + +} + +impl TryFrom< &Path > for EitherDirOrFile +{ + type Error = PathError; + + fn try_from( value : &Path ) -> Result< Self, Self::Error > + { + if value.file_name() == Some( "Cargo.toml".as_ref() ) + { + Ok( Self( data_type::Either::Right( ManifestFile::try_from( value )? ) ) ) + } + else + { + Ok( Self( data_type::Either::Left( CrateDir::try_from( value )? ) ) ) + } + } +} + +impl AsRef< Path > for EitherDirOrFile +{ + fn as_ref( &self ) -> &Path + { + match &self.0 + { + data_type::Either::Left( crate_dir ) => crate_dir.as_ref(), + data_type::Either::Right( manifest_path ) => manifest_path.as_ref(), + } + } +} + +impl AsMut< Path > for EitherDirOrFile +{ + fn as_mut( &mut self ) -> &mut Path + { + match &mut self.0 + { + data_type::Either::Left( crate_dir ) => crate_dir.as_mut(), + data_type::Either::Right( manifest_path ) => manifest_path.as_mut(), + } + } +} + +impl Deref for EitherDirOrFile +{ + type Target = Path; + + fn deref( &self ) -> &Self::Target + { + self.0.deref() + } +} + +impl DerefMut for EitherDirOrFile +{ + fn deref_mut( &mut self ) -> &mut Self::Target + { + self.0.deref_mut() + } +} \ No newline at end of file diff --git a/module/move/willbe/src/entity/files/manifest_file.rs b/module/move/willbe/src/entity/files/manifest_file.rs new file mode 100644 index 0000000000..78af49e41b --- /dev/null +++ b/module/move/willbe/src/entity/files/manifest_file.rs @@ -0,0 +1,276 @@ +use crate::*; + +use entity:: +{ + PathError, + CrateDir, +}; +use core:: +{ + fmt, + ops:: + { + Deref, + DerefMut, + }, +}; +use std:: +{ + path::{ Path, PathBuf }, + io, +}; + +use path::{ AbsolutePath, Utf8Path, Utf8PathBuf }; + +// use error:: +// { +// Result, +// }; + +/// Path to crate directory +#[ derive( Clone, Ord, PartialOrd, Eq, PartialEq, Hash ) ] +pub struct ManifestFile( AbsolutePath ); + +impl ManifestFile +{ + // aaa : bad : for Petro : why clone? + // /// Returns an absolute path. + // pub fn absolute_path( &self ) -> AbsolutePath + // { + // self.0.clone() + // } + + /// Returns inner type whicj is an absolute path. + #[ inline( always ) ] + pub fn inner( self ) -> AbsolutePath + { + self.0 + } + + /// Returns path to crate dir. + #[ inline( always ) ] + pub fn crate_dir( self ) -> CrateDir + { + self.into() + } + +} + +impl fmt::Display for ManifestFile +{ + fn fmt( &self, f : &mut fmt::Formatter<'_> ) -> fmt::Result + { + write!( f, "{}", self.0.display() ) + } +} + +impl fmt::Debug for ManifestFile +{ + fn fmt( &self, f : &mut fmt::Formatter<'_> ) -> fmt::Result + { + write!( f, "manifest file :: {}", self.0.display() ) + } +} + +// impl AsRef< AbsolutePath > for ManifestFile +// { +// fn as_ref( &self ) -> &AbsolutePath +// { +// &self.0 +// } +// } + +impl From< CrateDir > for ManifestFile +{ + fn from( src : CrateDir ) -> Self + { + Self( src.absolute_path().join( "Cargo.toml" ) ) + } +} + +impl From< ManifestFile > for AbsolutePath +{ + fn from( src : ManifestFile ) -> Self + { + src.inner() + } +} + +impl From< ManifestFile > for PathBuf +{ + fn from( src : ManifestFile ) -> Self + { + src.inner().inner() + } +} + +// impl From< &ManifestFile > for &str +// { +// fn from( src : &ManifestFile ) -> Self +// { +// src.to_str() +// } +// } + +impl< 'a > TryFrom< &'a ManifestFile > for &'a str +{ + type Error = std::io::Error; + fn try_from( src : &'a ManifestFile ) -> Result< &'a str, Self::Error > + { + ( &src.0 ).try_into() + } +} + +impl TryFrom< &ManifestFile > for String +{ + type Error = std::io::Error; + fn try_from( src : &ManifestFile ) -> Result< String, Self::Error > + { + let src2 : &str = src.try_into()?; + Ok( src2.into() ) + } +} + +impl TryFrom< &AbsolutePath > for ManifestFile +{ + type Error = PathError; + + #[ inline( always ) ] + fn try_from( manifest_file : &AbsolutePath ) -> Result< Self, Self::Error > + { + manifest_file.clone().try_into() + } +} + +impl TryFrom< AbsolutePath > for ManifestFile +{ + type Error = PathError; + + #[ inline( always ) ] + fn try_from( manifest_file : AbsolutePath ) -> Result< Self, Self::Error > + { + + if !manifest_file.as_ref().ends_with( "Cargo.toml" ) + { + let err = io::Error::new( io::ErrorKind::Other, format!( "File path does not end with Cargo.toml as it should {manifest_file:?}" ) ); + return Err( PathError::Io( err ) ); + } + + if !manifest_file.as_ref().is_file() + { + let err = io::Error::new( io::ErrorKind::InvalidData, format!( "Cannot find crate dir at {manifest_file:?}" ) ); + return Err( PathError::Io( err ) ); + } + Ok( Self( manifest_file ) ) + } +} + +impl TryFrom< PathBuf > for ManifestFile +{ + type Error = PathError; + + #[ inline( always ) ] + fn try_from( manifest_file : PathBuf ) -> Result< Self, Self::Error > + { + Self::try_from( AbsolutePath::try_from( manifest_file )? ) + } +} + +impl TryFrom< &PathBuf > for ManifestFile +{ + type Error = PathError; + + #[ inline( always ) ] + fn try_from( manifest_file : &PathBuf ) -> Result< Self, Self::Error > + { + Self::try_from( AbsolutePath::try_from( manifest_file )? ) + } +} + +impl TryFrom< &Path > for ManifestFile +{ + type Error = PathError; + + #[ inline( always ) ] + fn try_from( manifest_file : &Path ) -> Result< Self, Self::Error > + { + Self::try_from( AbsolutePath::try_from( manifest_file )? ) + } +} + +impl TryFrom< &str > for ManifestFile +{ + type Error = PathError; + + #[ inline( always ) ] + fn try_from( crate_dir_path : &str ) -> Result< Self, Self::Error > + { + Self::try_from( AbsolutePath::try_from( crate_dir_path )? ) + } +} + +impl TryFrom< Utf8PathBuf > for ManifestFile +{ + type Error = PathError; + + #[ inline( always ) ] + fn try_from( manifest_file : Utf8PathBuf ) -> Result< Self, Self::Error > + { + Self::try_from( AbsolutePath::try_from( manifest_file )? ) + } +} + +impl TryFrom< &Utf8PathBuf > for ManifestFile +{ + type Error = PathError; + + #[ inline( always ) ] + fn try_from( manifest_file : &Utf8PathBuf ) -> Result< Self, Self::Error > + { + Self::try_from( AbsolutePath::try_from( manifest_file )? ) + } +} + +impl TryFrom< &Utf8Path > for ManifestFile +{ + type Error = PathError; + + #[ inline( always ) ] + fn try_from( manifest_file : &Utf8Path ) -> Result< Self, Self::Error > + { + Self::try_from( AbsolutePath::try_from( manifest_file )? ) + } +} + +impl AsRef< Path > for ManifestFile +{ + fn as_ref( &self ) -> &Path + { + self.0.as_ref() + } +} + +impl AsMut< Path > for ManifestFile +{ + fn as_mut( &mut self ) -> &mut Path + { + self.0.as_mut() + } +} + +impl Deref for ManifestFile +{ + type Target = AbsolutePath; + fn deref( &self ) -> &Self::Target + { + &self.0 + } +} + +impl DerefMut for ManifestFile +{ + fn deref_mut( &mut self ) -> &mut Self::Target + { + &mut self.0 + } +} diff --git a/module/move/willbe/src/entity/files/source_file.rs b/module/move/willbe/src/entity/files/source_file.rs new file mode 100644 index 0000000000..b895d3eec2 --- /dev/null +++ b/module/move/willbe/src/entity/files/source_file.rs @@ -0,0 +1,270 @@ +use crate::*; + +use entity:: +{ + PathError, + ManifestFile, +}; +use core:: +{ + fmt, + ops:: + { + Deref, + DerefMut, + }, +}; +use std:: +{ + fs, + path::{ Path, PathBuf }, + borrow::Cow, +}; +// use error:: +// { +// Result, +// }; +use path::{ AbsolutePath, Utf8Path, Utf8PathBuf }; + +/// Path to a source file +#[ derive( Clone, Ord, PartialOrd, Eq, PartialEq, Hash ) ] +pub struct SourceFile( AbsolutePath ); + +impl SourceFile +{ + + /// Returns inner type which is an absolute path. + #[ inline( always ) ] + pub fn inner( self ) -> AbsolutePath + { + self.0 + } + +} + +impl fmt::Display for SourceFile +{ + fn fmt( &self, f : &mut fmt::Formatter<'_> ) -> fmt::Result + { + write!( f, "{}", self.0.display() ) + } +} + +impl fmt::Debug for SourceFile +{ + fn fmt( &self, f : &mut fmt::Formatter<'_> ) -> fmt::Result + { + write!( f, "source file :: {}", self.0.display() ) + } +} + +impl From< ManifestFile > for SourceFile +{ + fn from( src : ManifestFile ) -> Self + { + Self ( src.inner().parent().unwrap() ) + } +} + +impl From< SourceFile > for AbsolutePath +{ + fn from( src : SourceFile ) -> Self + { + src.inner() + } +} + +impl From< SourceFile > for PathBuf +{ + fn from( src : SourceFile ) -> Self + { + src.inner().inner() + } +} + +impl< 'a > TryFrom< &'a SourceFile > for &'a str +{ + type Error = std::io::Error; + fn try_from( src : &'a SourceFile ) -> Result< &'a str, Self::Error > + { + ( &src.0 ).try_into() + } +} + +impl TryFrom< &SourceFile > for String +{ + type Error = std::io::Error; + fn try_from( src : &SourceFile ) -> Result< String, Self::Error > + { + let src2 : &str = src.try_into()?; + Ok( src2.into() ) + } +} + +impl TryFrom< &AbsolutePath > for SourceFile +{ + type Error = PathError; + + #[ inline( always ) ] + fn try_from( src : &AbsolutePath ) -> Result< Self, Self::Error > + { + src.clone().try_into() + } +} + +impl TryFrom< AbsolutePath > for SourceFile +{ + type Error = PathError; + + #[ inline( always ) ] + fn try_from( src : AbsolutePath ) -> Result< Self, Self::Error > + { + Ok( Self( src ) ) + } +} + +impl TryFrom< PathBuf > for SourceFile +{ + type Error = PathError; + + #[ inline( always ) ] + fn try_from( src : PathBuf ) -> Result< Self, Self::Error > + { + Self::try_from( AbsolutePath::try_from( src )? ) + } +} + +impl TryFrom< &Path > for SourceFile +{ + type Error = PathError; + + #[ inline( always ) ] + fn try_from( src : &Path ) -> Result< Self, Self::Error > + { + Self::try_from( AbsolutePath::try_from( src )? ) + } +} + +impl TryFrom< &str > for SourceFile +{ + type Error = PathError; + + #[ inline( always ) ] + fn try_from( src : &str ) -> Result< Self, Self::Error > + { + Self::try_from( AbsolutePath::try_from( src )? ) + } +} + +impl TryFrom< Utf8PathBuf > for SourceFile +{ + type Error = PathError; + + #[ inline( always ) ] + fn try_from( src : Utf8PathBuf ) -> Result< Self, Self::Error > + { + Self::try_from( AbsolutePath::try_from( src )? ) + } +} + +impl TryFrom< &Utf8PathBuf > for SourceFile +{ + type Error = PathError; + + #[ inline( always ) ] + fn try_from( src : &Utf8PathBuf ) -> Result< Self, Self::Error > + { + Self::try_from( AbsolutePath::try_from( src )? ) + } +} + +impl TryFrom< &Utf8Path > for SourceFile +{ + type Error = PathError; + + #[ inline( always ) ] + fn try_from( src : &Utf8Path ) -> Result< Self, Self::Error > + { + Self::try_from( AbsolutePath::try_from( src )? ) + } +} + +impl AsRef< Path > for SourceFile +{ + fn as_ref( &self ) -> &Path + { + self.0.as_ref() + } +} + +impl AsMut< Path > for SourceFile +{ + fn as_mut( &mut self ) -> &mut Path + { + self.0.as_mut() + } +} + +impl Deref for SourceFile +{ + type Target = AbsolutePath; + fn deref( &self ) -> &Self::Target + { + &self.0 + } +} + +impl DerefMut for SourceFile +{ + fn deref_mut( &mut self ) -> &mut Self::Target + { + &mut self.0 + } +} + +// = + +impl CodeItems for SourceFile +{ + fn items( &self ) -> impl IterTrait< '_, syn::Item > + { + // xxx : use closures instead of expect + let content = fs::read_to_string( self.as_ref() ).expect( &format!( "Failed to parse file {self}" ) ); + let parsed : syn::File = syn::parse_file( &content ).expect( &format!( "Failed to parse file {self}" ) ); + parsed.items.into_iter() + } +} + +impl AsCode for SourceFile +{ + fn as_code< 'a >( &'a self ) -> std::io::Result< Cow< 'a, str > > + { + Ok( Cow::Owned( std::fs::read_to_string( self.as_ref() )? ) ) + } +} + +// = + +/// A trait that defines a method for retrieving an iterator over entries. +/// +/// The `Entries` trait is used to represent objects that can provide an iterator over their +/// contained entries, which are represented as source files. This can be useful in scenarios +/// where you need to access or process all entries associated with an object. +pub trait Entries +{ + /// Returns an iterator over the entries. + fn entries( &self ) -> impl IterTrait< '_, SourceFile >; +} + +/// A trait that defines a method for retrieving an iterator over source files. +/// +/// The `Sources` trait is used to represent objects that can provide an iterator over their +/// contained source files. This can be useful in scenarios where you need to access or process +/// all source files associated with an object. +pub trait Sources +{ + /// Returns an iterator over the source files. + fn sources( &self ) -> impl IterTrait< '_, SourceFile >; +} + +// = diff --git a/module/move/willbe/src/entity/git.rs b/module/move/willbe/src/entity/git.rs new file mode 100644 index 0000000000..eeeddfd5a4 --- /dev/null +++ b/module/move/willbe/src/entity/git.rs @@ -0,0 +1,88 @@ +mod private +{ + use crate::*; + + use std::fmt; + use process_tools::process; + use error:: + { + untyped::{ format_err, Context }, + }; + + #[ derive( Debug, Default, Clone ) ] + /// Represents an extended Git report with optional process reports. + pub struct ExtendedGitReport + { + /// Optional report for the `git add` process. + pub add : Option< process::Report >, + /// Optional report for the `git commit` process. + pub commit : Option< process::Report >, + /// Optional report for the `git push` process. + pub push : Option< process::Report >, + } + + impl fmt::Display for ExtendedGitReport + { + fn fmt( &self, f : &mut fmt::Formatter<'_> ) -> fmt::Result + { + let Self { add, commit, push } = &self; + + if let Some( add ) = add { writeln!( f, "{add}" )? } + if let Some( commit ) = commit { writeln!( f, "{commit}" )? } + if let Some( push ) = push { writeln!( f, "{push}" )? } + + Ok( () ) + } + } + + // aaa : for Bohdan : should not be here // aaa : done + // aaa : for Bohdan : documentation // aaa : done + /// The `GitOptions` struct represents a set of options used to perform a Git commit operation. + #[ derive( Debug, Clone ) ] + pub struct GitOptions + { + /// An absolute path to the root directory of the Git repository. + pub git_root : AbsolutePath, + /// A vector of absolute paths to the files or directories that should be committed. + pub items : Vec< AbsolutePath >, + /// A string containing the commit message. + pub message : String, + /// A boolean flag indicating whether the commit should be performed in dry run mode + /// (i.e., no changes are actually made to the repository) + pub dry : bool, + } + + /// Performs a Git commit operation using the provided options + pub fn perform_git_commit( o : GitOptions ) -> error::untyped::Result< ExtendedGitReport > + // qqq : use typed error + { + use tool::git; + let mut report = ExtendedGitReport::default(); + if o.items.is_empty() { return Ok( report ); } + let items : error::untyped::Result< Vec< _ > > = o + .items + .iter() + .map + ( + | item | item.as_ref().strip_prefix( o.git_root.as_ref() ).map( std::path::Path::to_string_lossy ) + .with_context( || format!("git_root: {}, item: {}", o.git_root.as_ref().display(), item.as_ref().display() ) ) + ) + .collect(); + + let res = git::add( &o.git_root, &items?, o.dry ).map_err( | e | format_err!( "{report}\n{e}" ) )?; + report.add = Some( res ); + let res = git::commit( &o.git_root, &o.message, o.dry ).map_err( | e | format_err!( "{report}\n{e}" ) )?; + report.commit = Some( res ); + + Ok( report ) + } +} + +// + +crate::mod_interface! +{ + own use ExtendedGitReport; + own use GitOptions; + own use perform_git_commit; +} diff --git a/module/move/willbe/src/entity/manifest.rs b/module/move/willbe/src/entity/manifest.rs index d167175177..97f02977b9 100644 --- a/module/move/willbe/src/entity/manifest.rs +++ b/module/move/willbe/src/entity/manifest.rs @@ -7,82 +7,14 @@ pub( crate ) mod private { io::{ self, Read }, fs, - path::{ Path, PathBuf }, }; - use wtools::error:: + use error:: { - Result, - thiserror, - for_lib::Error, - for_app::format_err, + typed::Error, + untyped::{ format_err }, }; - use _path::AbsolutePath; - /// `CrateDirError` enum represents errors when creating a `CrateDir` object. - #[ derive( Debug, Error ) ] - pub enum CrateDirError - { - /// Indicates a validation error with a descriptive message. - #[ error( "Failed to create a `CrateDir` object due to `{0}`" ) ] - Validation( String ), - } - - /// Path to crate directory - #[ derive( Debug, Clone ) ] - pub struct CrateDir( AbsolutePath ); - - impl AsRef< Path > for CrateDir - { - fn as_ref( &self ) -> &Path - { - self.0.as_ref() - } - } - - impl TryFrom< AbsolutePath > for CrateDir - { - // aaa : make better errors - // aaa : use `CrateDirError` for it - type Error = CrateDirError; - - fn try_from( crate_dir_path : AbsolutePath ) -> Result< Self, Self::Error > - { - if !crate_dir_path.as_ref().join( "Cargo.toml" ).exists() - { - return Err( CrateDirError::Validation( "The path is not a crate directory path".into() ) ); - } - - Ok( Self( crate_dir_path ) ) - } - } - - impl TryFrom< PathBuf > for CrateDir - { - type Error = CrateDirError; - - fn try_from( crate_dir_path : PathBuf ) -> Result< Self, Self::Error > - { - if !crate_dir_path.join( "Cargo.toml" ).exists() - { - return Err( CrateDirError::Validation( "The path is not a crate directory path".into() ) ); - } - - Ok( Self( AbsolutePath::try_from( crate_dir_path ).unwrap() ) ) - } - } - - impl CrateDir - { - /// Returns an absolute path. - pub fn absolute_path( &self ) -> AbsolutePath - { - self.0.clone() - } - } - - - -/// Represents errors related to manifest data processing. + /// Represents errors related to manifest data processing. #[ derive( Debug, Error ) ] pub enum ManifestError { @@ -110,45 +42,43 @@ pub( crate ) mod private pub struct Manifest { /// Path to `Cargo.toml` - pub manifest_path : AbsolutePath, + // pub manifest_file : AbsolutePath, + pub manifest_file : ManifestFile, + // aaa : for Bohdan : for Petro : why not ManifestFile? /// Strict type of `Cargo.toml` manifest. - pub manifest_data : Option< toml_edit::Document >, + pub data : toml_edit::Document, + // pub data : Option< toml_edit::Document >, } - impl TryFrom< AbsolutePath > for Manifest + impl TryFrom< ManifestFile > for Manifest { - // aaa : make better errors - // aaa : return `ManifestError` type Error = ManifestError; - fn try_from( manifest_path : AbsolutePath ) -> Result< Self, Self::Error > + fn try_from( manifest_file : ManifestFile ) -> Result< Self, Self::Error > { - if !manifest_path.as_ref().ends_with( "Cargo.toml" ) - { - let err = io::Error::new( io::ErrorKind::NotFound, "Cannot find manifest" ); - return Err( ManifestError::Io( err ) ); - } + + let read = fs::read_to_string( &manifest_file )?; + let data = read.parse::< toml_edit::Document >() + .map_err( | e | io::Error::new( io::ErrorKind::InvalidData, e ) )?; Ok ( Manifest { - manifest_path, - manifest_data : None, + manifest_file, + data, } ) } } - impl From< CrateDir > for Manifest + impl TryFrom< CrateDir > for Manifest { - fn from( value : CrateDir ) -> Self + type Error = ManifestError; + + fn try_from( src : CrateDir ) -> Result< Self, Self::Error > { - Self - { - manifest_path : value.0.join( "Cargo.toml" ), - manifest_data : None, - } + Self::try_from( src.manifest_file() ) } } @@ -164,99 +94,66 @@ pub( crate ) mod private /// A mutable reference to the TOML document. pub fn data( &mut self ) -> &mut toml_edit::Document { - if self.manifest_data.is_none() { self.load().unwrap() } - - self.manifest_data.as_mut().unwrap() + // if self.data.is_none() { self.load().unwrap() } + // self.data.as_mut().unwrap() + &mut self.data } - + /// Returns path to `Cargo.toml`. - pub fn manifest_path( &self ) -> &AbsolutePath + pub fn manifest_file( &self ) -> &AbsolutePath { - &self.manifest_path + &self.manifest_file } /// Path to directory where `Cargo.toml` located. pub fn crate_dir( &self ) -> CrateDir { - CrateDir( self.manifest_path.parent().unwrap() ) - } - - /// Load manifest from path. - pub fn load( &mut self ) -> Result< (), ManifestError > - { - let read = fs::read_to_string( &self.manifest_path )?; - let result = read.parse::< toml_edit::Document >().map_err( | e | io::Error::new( io::ErrorKind::InvalidData, e ) )?; - self.manifest_data = Some( result ); - - Ok( () ) + self.manifest_file.parent().unwrap().try_into().unwrap() + // CrateDir( self.manifest_file.parent().unwrap() ) } - // aaa : for Bohdan : don't abuse anyhow - // aaa : return `io` error /// Store manifest. pub fn store( &self ) -> io::Result< () > { - // If the `manifest_data` doesn't contain any data, then there's no point in attempting to write - if let Some( data ) = &self.manifest_data - { - fs::write( &self.manifest_path, data.to_string() )?; - } + fs::write( &self.manifest_file, self.data.to_string() )?; Ok( () ) } /// Check that the current manifest is the manifest of the package (can also be a virtual workspace). - pub fn package_is( &self ) -> Result< bool, ManifestError> + pub fn package_is( &self ) -> bool { - let data = self.manifest_data.as_ref().ok_or_else( || ManifestError::EmptyManifestData )?; - if data.get( "package" ).is_some() && data[ "package" ].get( "name" ).is_some() - { - return Ok( true ); - } - Ok( false ) + // let data = self.data.as_ref().ok_or_else( || ManifestError::EmptyManifestData )?; + let data = &self.data; + data.get( "package" ).is_some() && data[ "package" ].get( "name" ).is_some() } /// Check that module is local. /// The package is defined as local if the `publish` field is set to `false' or the registers are specified. - pub fn local_is( &self ) -> Result + pub fn local_is( &self ) -> bool { - let data = self.manifest_data.as_ref().ok_or_else( || ManifestError::EmptyManifestData )?; + // let data = self.data.as_ref().ok_or_else( || ManifestError::EmptyManifestData )?; + let data = &self.data; if data.get( "package" ).is_some() && data[ "package" ].get( "name" ).is_some() { let remote = data[ "package" ].get( "publish" ).is_none() - || data[ "package" ][ "publish" ].as_bool().ok_or_else( || ManifestError::CannotFindValue( "[package], [publish]".into() ) )?; - return Ok(!remote); - } - Ok(true) - } - } + || data[ "package" ][ "publish" ].as_bool().or( Some( true ) ).unwrap(); - /// Create and load manifest by specified path - // aaa : for Bohdan : use newtype, add proper errors handing - // aaa : return `ManifestError` - pub fn open( path : AbsolutePath ) -> Result< Manifest, ManifestError > - { - let mut manifest = if let Ok( dir ) = CrateDir::try_from( path.clone() ) - { - Manifest::from( dir ) + return !remote; + } + true } - else - { - Manifest::try_from( path )? - }; - - manifest.load()?; - - Ok( manifest ) } /// Retrieves the repository URL of a package from its `Cargo.toml` file. - pub fn repo_url( package_path : &Path ) -> Result< String > + // qqq : use typed error + pub fn repo_url( crate_dir : &CrateDir ) -> error::untyped::Result< String > { - let path = package_path.join( "Cargo.toml" ); + let path = crate_dir.clone().manifest_file().inner().inner(); if path.exists() { let mut contents = String::new(); + // qqq : zzz : for Petro : redundant read and parse fs::File::open( path )?.read_to_string( &mut contents )?; let doc = contents.parse::< toml_edit::Document >()?; @@ -266,12 +163,12 @@ pub( crate ) mod private .and_then( | i | i.as_str() ); if let Some( repo_url ) = repo_url { - url::extract_repo_url( repo_url ).ok_or_else( || format_err!( "Fail to extract repository url ") ) + url::repo_url_extract( repo_url ).ok_or_else( || format_err!( "Fail to extract repository url ") ) } else { - let report = git::ls_remote_url( package_path )?; - url::extract_repo_url( &report.out.trim() ).ok_or_else( || format_err!( "Fail to extract repository url from git remote.") ) + let report = tool::git::ls_remote_url( crate_dir.clone().absolute_path() )?; + url::repo_url_extract( &report.out.trim() ).ok_or_else( || format_err!( "Fail to extract repository url from git remote.") ) } } else @@ -287,9 +184,6 @@ pub( crate ) mod private crate::mod_interface! { exposed use Manifest; - exposed use CrateDir; orphan use ManifestError; - orphan use CrateDirError; - protected use open; - protected use repo_url; + own use repo_url; } diff --git a/module/move/willbe/src/entity/mod.rs b/module/move/willbe/src/entity/mod.rs index 24342f1c3b..6f26700128 100644 --- a/module/move/willbe/src/entity/mod.rs +++ b/module/move/willbe/src/entity/mod.rs @@ -1,5 +1,16 @@ crate::mod_interface! { + /// Rust toolchain channel: stable/nightly. + layer channel; + orphan use super::channel; + + /// Source code. + layer code; + orphan use super::code; + + /// Dependency of a package. + layer dependency; + orphan use super::dependency; /// Compare two crate archives and create a difference report. layer diff; @@ -9,43 +20,71 @@ crate::mod_interface! layer features; orphan use super::features; + /// Paths and files. + layer files; + orphan use super::files; + + /// Git. + layer git; + orphan use super::git; + + /// To manipulate manifest data. + layer manifest; + orphan use super::manifest; + + /// Rust build optimization: debug/release + layer optimization; + orphan use super::optimization; + + /// Offers capabilities for package management, facilitating the handling and organization of packages. + layer package; + orphan use super::package; + + /// Md's extension for workspace. + layer package_md_extension; + orphan use super::package_md_extension; + + /// Provides a set of functionalities for handling and manipulating packages. + layer packages; + orphan use super::packages; + /// Handles operations related to packed Rust crates layer packed_crate; orphan use super::packed_crate; - + + /// Progress bar staff. + layer progress_bar; + orphan use super::progress_bar; + + /// Publish. + layer publish; + orphan use super::publish; + /// Facade for `preatytable` crate. layer table; orphan use super::table; - /// Provides a set of functionalities for handling and manipulating packages. - layer packages; - orphan use super::packages; + /// Operations with tests + layer test; + orphan use super::test; - /// Offers capabilities for package management, facilitating the handling and organization of packages. - layer package; - orphan use super::package; + /// Provides an opportunity to work with versions. + layer version; + orphan use super::version; /// It features the ability to interact with workspaces, manage their participants, and other functionalities. layer workspace; orphan use super::workspace; - /// To manipulate manifest data. - layer manifest; - orphan use super::manifest; + /// Workspace' graph. + layer workspace_graph; + orphan use super::workspace_graph; - /// Provides an opportunity to work with versions. - layer version; - orphan use super::version; + /// Md's extension for workspace. + layer workspace_md_extension; + orphan use super::workspace_md_extension; - /// Operations with tests - layer test; - orphan use super::test; - - /// Rust toolchain channel: stable/nightly. - layer channel; - orphan use super::channel; - - /// Rust build optimization: debug/release - layer optimization; - orphan use super::optimization; + /// Packages of workspace. + layer workspace_package; + orphan use super::workspace_package; } diff --git a/module/move/willbe/src/entity/optimization.rs b/module/move/willbe/src/entity/optimization.rs index a2c1a58241..875dd76100 100644 --- a/module/move/willbe/src/entity/optimization.rs +++ b/module/move/willbe/src/entity/optimization.rs @@ -1,9 +1,8 @@ mod private { - use std::fmt::Formatter; - /// Rust optimization - #[ derive( Debug, Default, Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd ) ] + #[ derive( Debug, Default, Copy, Clone, Hash, Eq, PartialEq, Ord, PartialOrd, derive_tools::Display ) ] + #[ display( style = "snake_case" ) ] pub enum Optimization { /// Debug @@ -12,23 +11,9 @@ mod private /// Release Release, } - - // qqq : use derive - impl std::fmt::Display for Optimization - { - fn fmt( &self, f : &mut Formatter< '_ > ) -> std::fmt::Result - { - match self - { - Optimization::Debug => write!( f, "debug" ), - Optimization::Release => write!( f, "release" ), - } - } - } } -// qqq : for Petro : why is it here? crate::mod_interface! { - protected use Optimization; + own use Optimization; } diff --git a/module/move/willbe/src/entity/package.rs b/module/move/willbe/src/entity/package.rs index 9e1f281ebc..5e53b6ea19 100644 --- a/module/move/willbe/src/entity/package.rs +++ b/module/move/willbe/src/entity/package.rs @@ -4,46 +4,38 @@ mod private use std:: { - path::Path, - collections::{ HashMap, HashSet }, + hash::Hash, }; - use std::fmt::Formatter; - use std::hash::Hash; - use std::path::PathBuf; - use process_tools::process; - use manifest::{ Manifest, ManifestError }; use crates_tools::CrateArchive; - - use workspace::Workspace; - use _path::AbsolutePath; - - use wtools:: + use error:: { - iter::Itertools, - error:: - { - thiserror, - Result, - for_lib::Error, - for_app::{ format_err, Context }, - } + // Result, + typed::Error, }; - use action::readme_health_table_renew::Stability; - use former::Former; - use workspace::WorkspacePackage; - use diff::crate_diff; - use version::version_revert; - use error_tools::for_app::Error; + /// A wrapper type for representing the name of a package. /// + /// This struct encapsulates a `String` that holds the name of a package. + #[ derive + ( + Debug, Default, Clone, Hash, Ord, PartialOrd, Eq, PartialEq, + derive_tools::Display, derive_tools::Deref, derive_tools::From, derive_tools::AsRef, + ) ] + pub struct PackageName( String ); + + // + /// Represents different types of packages in a Cargo workspace. + /// + /// It is designed to accommodate the two primary types of package + /// representations within a Cargo workspace. #[ derive( Debug, Clone ) ] - pub enum Package + pub enum Package< 'a > { /// `Cargo.toml` file. Manifest( Manifest ), - /// Cargo metadata package. - Metadata( WorkspacePackage ), + /// Cargo package package. + WorkspacePackageRef( WorkspacePackageRef< 'a > ), } /// Represents errors related to package handling. @@ -52,10 +44,10 @@ mod private { /// Manifest error. #[ error( "Manifest error. Reason : {0}." ) ] - Manifest( #[ from ] ManifestError ), - /// Fail to load metadata. - #[ error( "Fail to load metadata." ) ] - Metadata, + Manifest( #[ from ] manifest::ManifestError ), + /// Fail to load package. + #[ error( "Fail to load package." ) ] + WorkspacePackageRef, /// Fail to load remote package. #[ error( "Fail to load remote package." ) ] LoadRemotePackage, @@ -70,49 +62,45 @@ mod private NotAPackage, } - impl TryFrom< AbsolutePath > for Package + impl< 'a > TryFrom< ManifestFile > for Package< 'a > { - // aaa : make better errors - // aaa : return `PackageError` instead of `anohow` message type Error = PackageError; - fn try_from( value : AbsolutePath ) -> Result< Self, Self::Error > + fn try_from( value : ManifestFile ) -> Result< Self, Self::Error > { - let manifest = manifest::open( value.clone() )?; - if !manifest.package_is()? + let package = Manifest::try_from( value )?; + if !package.package_is() { return Err( PackageError::NotAPackage ); } - Ok( Self::Manifest( manifest ) ) + Ok( Self::Manifest( package ) ) } } - impl TryFrom< CrateDir > for Package + impl< 'a > TryFrom< CrateDir > for Package< 'a > { type Error = PackageError; fn try_from( value : CrateDir ) -> Result< Self, Self::Error > { - let manifest = manifest::open( value.absolute_path().join( "Cargo.toml" ) )?; - if !manifest.package_is()? + let package = Manifest::try_from( value )?; + if !package.package_is() { return Err( PackageError::NotAPackage ); } - Ok( Self::Manifest( manifest ) ) + Ok( Self::Manifest( package ) ) } } - impl TryFrom< Manifest > for Package + impl< 'a > TryFrom< Manifest > for Package< 'a > { - // aaa : make better errors - // aaa : return `PackageError` instead of `anohow` message type Error = PackageError; fn try_from( value : Manifest ) -> Result< Self, Self::Error > { - if !value.package_is()? + if !value.package_is() { return Err( PackageError::NotAPackage ); } @@ -121,23 +109,24 @@ mod private } } - impl From< WorkspacePackage > for Package + impl< 'a > From< WorkspacePackageRef< 'a > > for Package< 'a > { - fn from( value : WorkspacePackage ) -> Self + fn from( value : WorkspacePackageRef< 'a > ) -> Self { - Self::Metadata( value ) + Self::WorkspacePackageRef( value ) } } - impl Package + impl< 'a > Package< 'a > { + /// Path to `Cargo.toml` - pub fn manifest_path( &self ) -> AbsolutePath + pub fn manifest_file( &self ) -> ManifestFile { match self { - Self::Manifest( manifest ) => manifest.manifest_path.clone(), - Self::Metadata( metadata ) => AbsolutePath::try_from( metadata.manifest_path().as_std_path().to_path_buf() ).unwrap(), + Self::Manifest( package ) => package.manifest_file.clone(), + Self::WorkspacePackageRef( package ) => package.manifest_file().unwrap(), } } @@ -146,33 +135,8 @@ mod private { match self { - Self::Manifest( manifest ) => manifest.crate_dir(), - Self::Metadata( metadata ) => - { - let path = metadata.manifest_path().parent().unwrap().as_std_path().to_path_buf(); - let absolute = AbsolutePath::try_from( path ).unwrap(); - - CrateDir::try_from( absolute ).unwrap() - }, - } - } - - /// Package name - pub fn name( &self ) -> Result< String, PackageError > - { - match self - { - Self::Manifest( manifest ) => - { - let data = manifest.manifest_data.as_ref().ok_or_else( || PackageError::Manifest( ManifestError::EmptyManifestData ) )?; - - // Unwrap safely because of the `Package` type guarantee - Ok( data[ "package" ][ "name" ].as_str().unwrap().to_string() ) - } - Self::Metadata( metadata ) => - { - Ok( metadata.name().clone() ) - } + Self::Manifest( package ) => package.crate_dir(), + Self::WorkspacePackageRef( package ) => package.crate_dir().unwrap(), } } @@ -181,89 +145,35 @@ mod private { match self { - Self::Manifest( manifest ) => + Self::Manifest( package ) => { - let data = manifest.manifest_data.as_ref().ok_or_else( || PackageError::Manifest( ManifestError::EmptyManifestData ) )?; + // let data = package.data.as_ref().ok_or_else( || PackageError::Manifest( ManifestError::EmptyManifestData ) )?; + let data = &package.data; // Unwrap safely because of the `Package` type guarantee Ok( data[ "package" ][ "version" ].as_str().unwrap().to_string() ) } - Self::Metadata( metadata ) => - { - Ok( metadata.version().to_string() ) - } - } - } - - /// Stability - pub fn stability( &self ) -> Result< Stability, PackageError > - { - match self - { - Self::Manifest( manifest ) => - { - let data = manifest.manifest_data.as_ref().ok_or_else( || PackageError::Manifest( ManifestError::EmptyManifestData ) )?; - - // Unwrap safely because of the `Package` type guarantee - Ok( data[ "package" ].get( "metadata" ).and_then( | m | m.get( "stability" ) ).and_then( | s | s.as_str() ).and_then( | s | s.parse::< Stability >().ok() ).unwrap_or( Stability::Experimental) ) - } - Self::Metadata( metadata ) => + Self::WorkspacePackageRef( package ) => { - Ok( metadata.metadata()[ "stability" ].as_str().and_then( | s | s.parse::< Stability >().ok() ).unwrap_or( Stability::Experimental) ) - } - } - } - - /// Repository - pub fn repository( &self ) -> Result< Option< String >, PackageError > - { - match self - { - Self::Manifest( manifest ) => - { - let data = manifest.manifest_data.as_ref().ok_or_else( || PackageError::Manifest( ManifestError::EmptyManifestData ) )?; - - // Unwrap safely because of the `Package` type guarantee - Ok( data[ "package" ].get( "repository" ).and_then( | r | r.as_str() ).map( | r | r.to_string()) ) - } - Self::Metadata( metadata ) => - { - Ok( metadata.repository().cloned() ) - } - } - } - - /// Discord url - pub fn discord_url( &self ) -> Result< Option< String >, PackageError > - { - match self - { - Self::Manifest( manifest ) => - { - let data = manifest.manifest_data.as_ref().ok_or_else( || PackageError::Manifest( ManifestError::EmptyManifestData ) )?; - - Ok( data[ "package" ].get( "metadata" ).and_then( | m | m.get( "discord_url" ) ).and_then( | url | url.as_str() ).map( | r | r.to_string() ) ) - } - Self::Metadata( metadata ) => - { - Ok( metadata.metadata()[ "discord_url" ].as_str().map( | url | url.to_string() ) ) + Ok( package.version().to_string() ) } } } /// Check that module is local. - pub fn local_is( &self ) -> Result< bool, ManifestError > + pub fn local_is( &self ) -> bool { match self { - Self::Manifest( manifest ) => + Self::Manifest( package ) => { - // verify that manifest not empty - manifest.local_is() + // verify that package not empty + package.local_is() } - Self::Metadata( metadata ) => + Self::WorkspacePackageRef( package ) => { - Ok( !( metadata.publish().is_none() || metadata.publish().as_ref().is_some_and( | p | p.is_empty() ) ) ) + !( package.publish().is_none() || package.publish().as_ref().is_some_and( | p | p.is_empty() ) ) + // Ok( !( package.publish().is_none() || package.publish().as_ref().is_some_and( | p | p.is_empty() ) ) ) } } } @@ -273,647 +183,15 @@ mod private { match self { - Package::Manifest( manifest ) => Ok( manifest.clone() ), - Package::Metadata( metadata ) => manifest::open + Package::Manifest( package ) => Ok( package.clone() ), + Package::WorkspacePackageRef( package ) => Manifest::try_from ( - AbsolutePath::try_from( metadata.manifest_path() ).map_err( | _ | PackageError::LocalPath )? + package.manifest_file().map_err( | _ | PackageError::LocalPath )? // qqq : use trait ) - .map_err( | _ | PackageError::Metadata ), - } - } - - /// Returns the `Metadata` - pub fn metadata( &self ) -> Result< WorkspacePackage, PackageError > - { - match self - { - Package::Manifest( manifest ) => - Workspace::with_crate_dir( manifest.crate_dir() ).map_err( | _ | PackageError::Metadata )? - .package_find_by_manifest( &manifest.manifest_path ) - .ok_or_else( || PackageError::Metadata ), - Package::Metadata( metadata ) => Ok( metadata.clone() ), - } - } - } - - #[ derive( Debug, Default, Clone ) ] - pub struct ExtendedGitReport - { - pub add : Option< process::Report >, - pub commit : Option< process::Report >, - pub push : Option< process::Report >, - } - - impl std::fmt::Display for ExtendedGitReport - { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - let Self { add, commit, push } = &self; - if let Some( add ) = add { writeln!( f, "{add}" )? } - if let Some( commit ) = commit { writeln!( f, "{commit}" )? } - if let Some( push ) = push { writeln!( f, "{push}" )? } - - Ok( () ) - } - } - - #[ derive( Debug, Clone ) ] - pub struct GitOptions - { - pub git_root : AbsolutePath, - pub items : Vec< AbsolutePath >, - pub message : String, - pub dry : bool, - } - - fn perform_git_commit( o : GitOptions ) -> Result< ExtendedGitReport > - { - let mut report = ExtendedGitReport::default(); - if o.items.is_empty() { return Ok( report ); } - let items = o - .items - .iter() - .map - ( - | item | item.as_ref().strip_prefix( o.git_root.as_ref() ).map( Path::to_string_lossy ) - .with_context( || format!("git_root: {}, item: {}", o.git_root.as_ref().display(), item.as_ref().display() ) ) - ) - .collect::< Result< Vec< _ > > >()?; - let res = git::add( &o.git_root, &items, o.dry ).map_err( | e | format_err!( "{report}\n{e}" ) )?; - report.add = Some( res ); - let res = git::commit( &o.git_root, &o.message, o.dry ).map_err( | e | format_err!( "{report}\n{e}" ) )?; - report.commit = Some( res ); - - Ok( report ) - } - - #[ derive( Debug, Clone ) ] - pub struct PackagePublishInstruction - { - pub package_name : String, - pub pack : cargo::PackOptions, - pub version_bump : version::BumpOptions, - pub git_options : GitOptions, - pub publish : cargo::PublishOptions, - pub dry : bool, - } - - /// Represents a planner for publishing a single package. - #[ derive( Debug, Former ) ] - #[ perform( fn build() -> PackagePublishInstruction ) ] - pub struct PublishSinglePackagePlanner - { - workspace_dir : CrateDir, - package : Package, - base_temp_dir : Option< PathBuf >, - #[ former( default = true ) ] - dry : bool, - } - - impl PublishSinglePackagePlanner - { - fn build( self ) -> PackagePublishInstruction - { - let crate_dir = self.package.crate_dir(); - let workspace_root : AbsolutePath = self.workspace_dir.absolute_path(); - let pack = cargo::PackOptions - { - path : crate_dir.as_ref().into(), - allow_dirty : self.dry, - no_verify : self.dry, - temp_path : self.base_temp_dir.clone(), - dry : self.dry, - }; - let old_version : version::Version = self.package.version().as_ref().unwrap().try_into().unwrap(); - let new_version = old_version.clone().bump(); - // bump the package version in dependents (so far, only workspace) - let dependencies = vec![ CrateDir::try_from( workspace_root.clone() ).unwrap() ]; - let version_bump = version::BumpOptions - { - crate_dir : crate_dir.clone(), - old_version : old_version.clone(), - new_version : new_version.clone(), - dependencies : dependencies.clone(), - dry : self.dry, - }; - let git_options = GitOptions - { - git_root : workspace_root, - items : dependencies.iter().chain([ &crate_dir ]).map( | d | d.absolute_path().join( "Cargo.toml" ) ).collect(), - message : format!( "{}-v{}", self.package.name().unwrap(), new_version ), - dry : self.dry, - }; - let publish = cargo::PublishOptions - { - path : crate_dir.as_ref().into(), - temp_path : self.base_temp_dir.clone(), - retry_count : 2, - dry : self.dry, - }; - - PackagePublishInstruction - { - package_name : self.package.name().unwrap(), - pack, - version_bump, - git_options, - publish, - dry : self.dry, - } - } - } - - /// Performs package publishing based on the given arguments. - /// - /// # Arguments - /// - /// * `args` - The package publishing instructions. - /// - /// # Returns - /// - /// * `Result` - The result of the publishing operation, including information about the publish, version bump, and git operations. - pub fn perform_package_publish( instruction : PackagePublishInstruction ) -> Result< PublishReport, ( PublishReport, Error ) > - { - let mut report = PublishReport::default(); - let PackagePublishInstruction - { - package_name: _, - mut pack, - mut version_bump, - mut git_options, - mut publish, - dry, - } = instruction; - pack.dry = dry; - version_bump.dry = dry; - git_options.dry = dry; - publish.dry = dry; - - report.get_info = Some( cargo::pack( pack ).map_err( | e | ( report.clone(), e ) )? ); - // qqq : redundant field? - report.publish_required = true; - let bump_report = version::version_bump( version_bump ).map_err( | e | ( report.clone(), e ) )?; - report.bump = Some( bump_report.clone() ); - let git_root = git_options.git_root.clone(); - let git = match perform_git_commit( git_options ) - { - Ok( git ) => git, - Err( e ) => - { - version_revert( &bump_report ) - .map_err( | le | - ( - report.clone(), - format_err!( "Base error:\n{}\nRevert error:\n{}", e.to_string().replace( '\n', "\n\t" ), le.to_string().replace( '\n', "\n\t" ) ) - ))?; - return Err(( report, e )); - } - }; - report.add = git.add; - report.commit = git.commit; - report.publish = match cargo::publish( publish ) - { - Ok( publish ) => Some( publish ), - Err( e ) => - { - git::reset( git_root.as_ref(), true, 1, false ) - .map_err( | le | - ( - report.clone(), - format_err!( "Base error:\n{}\nRevert error:\n{}", e.to_string().replace( '\n', "\n\t" ), le.to_string().replace( '\n', "\n\t" ) ) - ))?; - return Err(( report, e )); - } - }; - - let res = git::push( &git_root, dry ).map_err( | e | ( report.clone(), e ) )?; - report.push = Some( res ); - - Ok( report ) - } - - /// `PublishPlan` manages the overall publication process for multiple packages. - /// It organizes the necessary details required for publishing each individual package. - /// This includes the workspace root directory, any temporary directories used during the process, - /// and the set of specific instructions for publishing each package. - #[ derive( Debug, Former, Clone ) ] - pub struct PublishPlan - { - /// `workspace_dir` - This is the root directory of your workspace, containing all the Rust crates - /// that make up your package. It is used to locate the packages within your workspace that are meant - /// to be published. The value here is represented by `CrateDir` which indicates the directory of the crate. - pub workspace_dir : CrateDir, - - /// `base_temp_dir` - This is used for any temporary operations during the publication process, like - /// building the package or any other processes that might require the storage of transient data. It's - /// optional as not all operations will require temporary storage. The type used is `PathBuf` which allows - /// manipulation of the filesystem paths. - pub base_temp_dir : Option< PathBuf >, - - /// `dry` - A boolean value indicating whether to do a dry run. If set to `true`, the application performs - /// a simulated run without making any actual changes. If set to `false`, the operations are actually executed. - /// This property is optional and defaults to `true`. - #[ former( default = true ) ] - pub dry : bool, - - /// Required for tree view only - pub roots : Vec< CrateDir >, - - /// `plans` - This is a vector containing the instructions for publishing each package. Each item - /// in the `plans` vector indicates a `PackagePublishInstruction` set for a single package. It outlines - /// how to build and where to publish the package amongst other instructions. The `#[setter( false )]` - /// attribute indicates that there is no setter method for the `plans` variable and it can only be modified - /// within the struct. - #[ scalar( setter = false ) ] - pub plans : Vec< PackagePublishInstruction >, - } - - impl PublishPlan - { - /// Displays a tree-like structure of crates and their dependencies. - /// - /// # Arguments - /// - /// * `f` - A mutable reference to a `Formatter` used for writing the output. - /// - /// # Errors - /// - /// Returns a `std::fmt::Error` if there is an error writing to the formatter. - pub fn write_as_tree< W >( &self, f : &mut W ) -> std::fmt::Result - where - W : std::fmt::Write - { - let name_bump_report = self - .plans - .iter() - .map( | x | ( &x.package_name, ( x.version_bump.old_version.to_string(), x.version_bump.new_version.to_string() ) ) ) - .collect::< HashMap< _, _ > >(); - for wanted in &self.roots - { - let list = action::list - ( - action::list::ListOptions::former() - .path_to_manifest( wanted.clone() ) - .format( action::list::ListFormat::Tree ) - .dependency_sources([ action::list::DependencySource::Local ]) - .dependency_categories([ action::list::DependencyCategory::Primary ]) - .form() - ) - .map_err( |( _, _e )| std::fmt::Error )?; - let action::list::ListReport::Tree( list ) = list else { unreachable!() }; - - fn callback( name_bump_report : &HashMap< &String, ( String, String ) >, mut r : action::list::ListNodeReport ) -> action::list::ListNodeReport - { - if let Some(( old, new )) = name_bump_report.get( &r.name ) - { - r.version = Some( format!( "({old} -> {new})" ) ); - } - r.normal_dependencies = r.normal_dependencies.into_iter().map( | r | callback( name_bump_report, r ) ).collect(); - r.dev_dependencies = r.dev_dependencies.into_iter().map( | r | callback( name_bump_report, r ) ).collect(); - r.build_dependencies = r.build_dependencies.into_iter().map( | r | callback( name_bump_report, r ) ).collect(); - - r - } - let list = list.into_iter().map( | r | callback( &name_bump_report, r ) ).collect(); - - let list = action::list::ListReport::Tree( list ); - writeln!( f, "{}", list )?; - } - - Ok( () ) - } - - /// Format and display the list of packages and their version bumps in a formatted way. - /// - /// # Arguments - /// - /// - `f`: A mutable reference to a `Formatter` where the output will be written to. - /// - /// # Errors - /// - /// Returns a `std::fmt::Error` if there is an error writing to the formatter. - pub fn write_as_list< W >( &self, f : &mut W ) -> std::fmt::Result - where - W : std::fmt::Write - { - for ( idx, package ) in self.plans.iter().enumerate() - { - let bump = &package.version_bump; - writeln!( f, "[{idx}] {} ({} -> {})", package.package_name, bump.old_version, bump.new_version )?; + .map_err( | _ | PackageError::WorkspacePackageRef ), } - - Ok( () ) - } - } - - impl PublishPlanFormer - { - pub fn option_base_temp_dir( mut self, path : Option< PathBuf > ) -> Self - { - self.storage.base_temp_dir = path; - self - } - - pub fn package< IntoPackage >( mut self, package : IntoPackage ) -> Self - where - IntoPackage : Into< Package >, - { - let mut plan = PublishSinglePackagePlanner::former(); - if let Some( workspace ) = &self.storage.workspace_dir - { - plan = plan.workspace_dir( workspace.clone() ); - } - if let Some( base_temp_dir ) = &self.storage.base_temp_dir - { - plan = plan.base_temp_dir( base_temp_dir.clone() ); - } - if let Some( dry ) = self.storage.dry - { - plan = plan.dry( dry ); - } - let plan = plan - .package( package ) - .perform(); - let mut plans = self.storage.plans.unwrap_or_default(); - plans.push( plan ); - - self.storage.plans = Some( plans ); - - self - } - - pub fn packages< IntoPackageIter, IntoPackage >( mut self, packages : IntoPackageIter ) -> Self - where - IntoPackageIter : IntoIterator< Item = IntoPackage >, - IntoPackage : Into< Package >, - { - for package in packages - { - self = self.package( package ); - } - - self - } - } - - - /// Perform publishing of multiple packages based on the provided publish plan. - /// - /// # Arguments - /// - /// * `plan` - The publish plan with details of packages to be published. - /// - /// # Returns - /// - /// Returns a `Result` containing a vector of `PublishReport` if successful, else an error. - pub fn perform_packages_publish( plan : PublishPlan ) -> Result< Vec< PublishReport > > - { - let mut report = vec![]; - for package in plan.plans - { - let res = perform_package_publish( package ).map_err( |( current_rep, e )| format_err!( "{}\n{current_rep}\n{e}", report.iter().map( | r | format!( "{r}" ) ).join( "\n" ) ) )?; - report.push( res ); } - Ok( report ) - } - - /// Holds information about the publishing process. - #[ derive( Debug, Default, Clone ) ] - pub struct PublishReport - { - /// Retrieves information about the package. - pub get_info : Option< process::Report >, - /// Indicates whether publishing is required for the package. - pub publish_required : bool, - /// Bumps the version of the package. - pub bump : Option< version::ExtendedBumpReport >, - /// Report of adding changes to the Git repository. - pub add : Option< process::Report >, - /// Report of committing changes to the Git repository. - pub commit : Option< process::Report >, - /// Report of pushing changes to the Git repository. - pub push : Option< process::Report >, - /// Report of publishes the package using the `cargo publish` command. - pub publish : Option< process::Report >, - } - - impl std::fmt::Display for PublishReport - { - fn fmt( &self, f : &mut Formatter< '_ > ) -> std::fmt::Result - { - let PublishReport - { - get_info, - publish_required, - bump, - add, - commit, - push, - publish, - } = self; - - if get_info.is_none() - { - f.write_str( "Empty report" )?; - return Ok( () ) - } - let info = get_info.as_ref().unwrap(); - write!( f, "{}", info )?; - - if !publish_required - { - f.write_str( "The package has no changes, so no publishing is required" )?; - return Ok( () ) - } - - if let Some( bump ) = bump - { - writeln!( f, "{}", bump )?; - } - if let Some( add ) = add - { - write!( f, "{add}" )?; - } - if let Some( commit ) = commit - { - write!( f, "{commit}" )?; - } - if let Some( push ) = push - { - write!( f, "{push}" )?; - } - if let Some( publish ) = publish - { - write!( f, "{publish}" )?; - } - - Ok( () ) - } - } - - /// Sorting variants for dependencies. - #[ derive( Debug, Copy, Clone ) ] - pub enum DependenciesSort - { - /// List will be topologically sorted. - Topological, - /// List will be unsorted. - Unordered, - } - - #[ derive( Debug, Clone ) ] - /// Args for `local_dependencies` function. - pub struct DependenciesOptions - { - /// With dependencies of dependencies. - pub recursive : bool, - /// With sorting. - pub sort : DependenciesSort, - /// Include dev dependencies. - pub with_dev : bool, - /// Include remote dependencies. - pub with_remote : bool, - } - - impl Default for DependenciesOptions - { - fn default() -> Self - { - Self - { - recursive : true, - sort : DependenciesSort::Unordered, - with_dev : false, - with_remote : false, - } - } - } - - // - - /// Identifier of any crate(local and remote) - #[ derive( Debug, Clone, Hash, Eq, PartialEq ) ] - pub struct CrateId - { - /// TODO : make it private - pub name : String, - /// TODO : make it private - pub path : Option< AbsolutePath >, - } - - impl From< &WorkspacePackage > for CrateId - { - fn from( value : &WorkspacePackage ) -> Self - { - Self - { - name : value.name().clone(), - path : Some( AbsolutePath::try_from( value.manifest_path().parent().unwrap() ).unwrap() ), - } - } - } - - impl From< &workspace::Dependency > for CrateId - { - fn from( value : &workspace::Dependency ) -> Self - { - Self - { - name : value.name().clone(), - path : value.path().clone().map( | path | AbsolutePath::try_from( path ).unwrap() ), - } - } - } - - /// Recursive implementation of the `dependencies` function - pub fn _dependencies - ( - workspace : &mut Workspace, - manifest : &Package, - graph : &mut HashMap< CrateId, HashSet< CrateId > >, - opts : DependenciesOptions - ) -> Result< CrateId > - { - let DependenciesOptions - { - recursive, - sort : _, - with_dev, - with_remote, - } = opts; - if recursive && with_remote { unimplemented!( "`recursive` + `with_remote` options") } - - let manifest_path = &manifest.manifest_path(); - - let package = workspace - .load()? - .package_find_by_manifest( &manifest_path ) - .ok_or( format_err!( "Package not found in the workspace with path : `{}`", manifest_path.as_ref().display() ) )?; - - let deps = package - .dependencies() - .iter() - .filter( | dep | ( with_remote || dep.path().is_some() ) && ( with_dev || dep.kind() != workspace::DependencyKind::Development ) ) - .map( CrateId::from ) - .collect::< HashSet< _ > >(); - - let package = CrateId::from( &package ); - graph.insert( package.clone(), deps.clone() ); - - if recursive - { - for dep in deps - { - if graph.get( &dep ).is_none() - { - // unwrap because `recursive` + `with_remote` not yet implemented - _dependencies( workspace, &dep.path.as_ref().unwrap().join( "Cargo.toml" ).try_into().unwrap(), graph, opts.clone() )?; - } - } - } - - Ok( package ) - } - - /// Returns local dependencies of a specified package by its manifest path from a workspace. - /// - /// # Arguments - /// - /// - `workspace` - holds cached information about the workspace, such as the packages it contains and their dependencies. By passing it as a mutable reference, function can update the cache as needed. - /// - `manifest` - The package manifest file contains metadata about the package such as its name, version, and dependencies. - /// - `opts` - used to specify options or configurations for fetching local dependencies. - /// - /// # Returns - /// - /// If the operation is successful, returns a vector of `PathBuf` objects, where each `PathBuf` represents the path to a local dependency of the specified package. - pub fn dependencies( workspace : &mut Workspace, manifest : &Package, opts : DependenciesOptions ) -> Result< Vec< CrateId > > - { - let mut graph = HashMap::new(); - let root = _dependencies( workspace, manifest, &mut graph, opts.clone() )?; - - let output = match opts.sort - { - DependenciesSort::Unordered => - { - graph - .into_iter() - .flat_map( | ( id, dependency ) | - { - dependency - .into_iter() - .chain( Some( id ) ) - }) - .unique() - .filter( | x | x != &root ) - .collect() - } - DependenciesSort::Topological => - { - graph::toposort( graph::construct( &graph ) ).map_err( | err | format_err!( "{}", err ) )?.into_iter().filter( | x | x != &root ).collect() - }, - }; - - Ok( output ) } // @@ -926,9 +204,9 @@ mod private /// - `true` if the package needs to be published. /// - `false` if there is no need to publish the package. /// - /// Panics if the manifest is not loaded or local package is not packed. + /// Panics if the package is not loaded or local package is not packed. - pub fn publish_need( package : &Package, path : Option< PathBuf > ) -> Result< bool, PackageError > + pub fn publish_need< 'a >( package : &Package< 'a >, path : Option< path::PathBuf > ) -> Result< bool, PackageError > { let name = package.name()?; let version = package.version()?; @@ -936,8 +214,6 @@ mod private .map( | p | p.join( format!( "package/{0}-{1}.crate", name, version ) ) ) .unwrap_or( packed_crate::local_path( &name, &version, package.crate_dir() ).map_err( | _ | PackageError::LocalPath )? ); - // aaa : for Bohdan : bad, properly handle errors - // aaa : return result instead of panic let local_package = CrateArchive::read( local_package_path ).map_err( | _ | PackageError::ReadArchive )?; let remote_package = match CrateArchive::download_crates_io( name, version ) { @@ -947,8 +223,9 @@ mod private _ => return Err( PackageError::LoadRemotePackage ), }; - Ok( crate_diff( &local_package, &remote_package ).exclude( diff::PUBLISH_IGNORE_LIST ).has_changes() ) + Ok( diff::crate_diff( &local_package, &remote_package ).exclude( diff::PUBLISH_IGNORE_LIST ).has_changes() ) } + } // @@ -956,20 +233,10 @@ mod private crate::mod_interface! { - protected use PublishSinglePackagePlanner; - protected use PublishPlan; - protected use perform_package_publish; - protected use perform_packages_publish; - - protected use PublishReport; - protected use Package; - protected use PackageError; - - protected use publish_need; + exposed use Package; + own use PackageName; + own use PackageError; - protected use CrateId; - protected use DependenciesSort; - protected use DependenciesOptions; - protected use dependencies; + own use publish_need; } diff --git a/module/move/willbe/src/entity/package_md_extension.rs b/module/move/willbe/src/entity/package_md_extension.rs new file mode 100644 index 0000000000..0401b30644 --- /dev/null +++ b/module/move/willbe/src/entity/package_md_extension.rs @@ -0,0 +1,152 @@ +/// Internal namespace. +pub( crate ) mod private +{ + use crate::*; + + /// Md's extension for workspace + pub trait PackageMdExtension + { + /// Package name + fn name( &self ) -> Result< &str, package::PackageError >; + + /// Stability + fn stability( &self ) -> Result< action::readme_health_table_renew::Stability, package::PackageError >; + + /// Repository + fn repository( &self ) -> Result< Option< String >, package::PackageError >; + + /// Discord url + fn discord_url( &self ) -> Result< Option< String >, package::PackageError >; + } + + impl < 'a > package::Package< 'a > + { + /// Package name + pub fn name( &self ) -> Result< &str, package::PackageError > + { + match self + { + Self::Manifest( manifest ) => + { + // let data = manifest.data.as_ref().ok_or_else( || PackageError::Manifest( ManifestError::EmptyManifestData ) )?; + let data = &manifest.data; + + // Unwrap safely because of the `Package` type guarantee + // Ok( data[ "package" ][ "name" ].as_str().unwrap().to_string() ) + Ok( data[ "package" ][ "name" ].as_str().unwrap() ) + } + Self::WorkspacePackageRef( package ) => + { + Ok( package.name() ) + } + } + } + + /// Stability + pub fn stability( &self ) -> Result< action::readme_health_table_renew::Stability, package::PackageError > + { + // aaa : for Petro : bad : first of all it should be in trait. also there is duplicated code + // aaa : done + // aaa : for Petro : review other similar places + // aaa : done + match self + { + Self::Manifest( _ ) => + { + // Unwrap safely because of the `Package` type guarantee + Ok + ( + self.package_metadata() + .and_then( | m | m.get( "stability" ) ) + .and_then( | s | s.as_str() ) + .and_then( | s | s.parse::< action::readme_health_table_renew::Stability >().ok() ) + .unwrap_or( action::readme_health_table_renew::Stability::Experimental ) + ) + } + Self::WorkspacePackageRef( package ) => + { + Ok + ( + package + .metadata()[ "stability" ] + .as_str() + .and_then( | s | s.parse::< action::readme_health_table_renew::Stability >().ok() ) + .unwrap_or( action::readme_health_table_renew::Stability::Experimental) + ) + } + } + } + + /// Repository + pub fn repository( &self ) -> Result< Option< String >, package::PackageError > + { + match self + { + Self::Manifest( manifest ) => + { + // let data = manifest.data.as_ref().ok_or_else( || PackageError::Manifest( ManifestError::EmptyManifestData ) )?; + let data = &manifest.data; + + // Unwrap safely because of the `Package` type guarantee + Ok + ( + data[ "package" ] + .get( "repository" ) + .and_then( | r | r.as_str() ) + .map( | r | r.to_string()) + ) + } + Self::WorkspacePackageRef( package ) => + { + Ok( package.repository().cloned() ) + } + } + } + + /// Discord url + pub fn discord_url( &self ) -> Result< Option< String >, package::PackageError > + { + match self + { + Self::Manifest( _ ) => + { + // let data = manifest.data.as_ref().ok_or_else( || PackageError::Manifest( ManifestError::EmptyManifestData ) )?; + Ok + ( + self.package_metadata() + .and_then( | m | m.get( "discord_url" ) ) + .and_then( | url | url.as_str() ) + .map( | r | r.to_string() ) + ) + } + Self::WorkspacePackageRef( package ) => + { + Ok( package.metadata()[ "discord_url" ].as_str().map( | url | url.to_string() ) ) + } + } + } + + fn package_metadata( &self ) -> Option< &toml_edit::Item > + { + match self { + package::Package::Manifest( manifest ) => + { + let data = &manifest.data; + + data[ "package" ] + .get( "metadata" ) + } + package::Package::WorkspacePackageRef(_) => + { + None + } + } + } + } +} + + +crate::mod_interface! +{ + own use PackageMdExtension; +} diff --git a/module/move/willbe/src/entity/packages.rs b/module/move/willbe/src/entity/packages.rs index 5f48b09b3f..6dd4006db3 100644 --- a/module/move/willbe/src/entity/packages.rs +++ b/module/move/willbe/src/entity/packages.rs @@ -4,13 +4,14 @@ mod private use std:: { fmt::Formatter, - collections::{ HashMap, HashSet }, }; - use workspace::WorkspacePackage; - use crate::workspace::Dependency; + use package::PackageName; + use collection::{ HashMap, HashSet }; - /// Type aliasing for String - pub type PackageName = String; + // use workspace::WorkspacePackageRef< '_ >; + // use Dependency; + + // aaa : poor description // aaa : removed /// A configuration struct for specifying optional filters when using the /// `filter` function. It allows users to provide custom filtering @@ -22,13 +23,13 @@ mod private /// applied to each package, and only packages that satisfy the condition /// are included in the final result. If not provided, a default filter that /// accepts all packages is used. - pub package_filter : Option< Box< dyn Fn( &WorkspacePackage ) -> bool > >, + pub package_filter : Option< Box< dyn Fn( WorkspacePackageRef< '_ > ) -> bool > >, /// An optional dependency filtering function. If provided, this function /// is applied to each dependency of each package, and only dependencies /// that satisfy the condition are included in the final result. If not /// provided, a default filter that accepts all dependencies is used. - pub dependency_filter : Option< Box< dyn Fn( &WorkspacePackage, &Dependency ) -> bool > >, + pub dependency_filter : Option< Box< dyn Fn( WorkspacePackageRef< '_ >, DependencyRef< '_ > ) -> bool > >, } impl std::fmt::Debug for FilterMapOptions @@ -71,25 +72,31 @@ mod private /// which dependencies should be included in the return for that package. If not provided, all /// dependencies for a package are included. - // qqq : for Bohdan : for Petro : bad. don't use PackageMetadata directly, use its abstraction only! + // aaa : for Bohdan : for Petro : bad. don't use PackageMetadata directly, use its abstraction only! - pub fn filter( packages : &[ WorkspacePackage ], options : FilterMapOptions ) -> HashMap< PackageName, HashSet< PackageName > > + pub fn filter< 'a > + ( + // packages : &[ WorkspacePackageRef< '_ > ], + packages : impl Iterator< Item = WorkspacePackageRef< 'a > >, + options : FilterMapOptions, + ) + -> HashMap< PackageName, HashSet< PackageName > > { let FilterMapOptions { package_filter, dependency_filter } = options; let package_filter = package_filter.unwrap_or_else( || Box::new( | _ | true ) ); let dependency_filter = dependency_filter.unwrap_or_else( || Box::new( | _, _ | true ) ); packages - .iter() + // .iter() .filter( | &p | package_filter( p ) ) .map ( | package | ( - package.name().clone(), + package.name().to_string().into(), package.dependencies() - .iter() - .filter( | &d | dependency_filter( package, d ) ) - .map( | d | d.name().clone() ) + // .iter() + .filter( | d | dependency_filter( package, *d ) ) + .map( | d | d.name().into() ) .collect::< HashSet< _ > >() ) ) @@ -102,8 +109,7 @@ mod private crate::mod_interface! { - protected use PackageName; - protected use FilterMapOptions; - protected use filter; + own use FilterMapOptions; + own use filter; } diff --git a/module/move/willbe/src/entity/packed_crate.rs b/module/move/willbe/src/entity/packed_crate.rs index 9bf462d782..77da22b98e 100644 --- a/module/move/willbe/src/entity/packed_crate.rs +++ b/module/move/willbe/src/entity/packed_crate.rs @@ -9,7 +9,7 @@ mod private time::Duration, path::PathBuf, }; - use wtools::error::{ for_app::Context, Result }; + use error::{ untyped::Context }; use ureq::Agent; /// Returns the local path of a packed `.crate` file based on its name, version, and manifest path. @@ -17,18 +17,18 @@ mod private /// # Args : /// - `name` - the name of the package. /// - `version` - the version of the package. - /// - `manifest_path` - path to the package `Cargo.toml` file. + /// - `manifest_file` - path to the package `Cargo.toml` file. /// /// # Returns : /// The local packed `.crate` file of the package - pub fn local_path< 'a >( name : &'a str, version : &'a str, crate_dir : CrateDir ) -> Result< PathBuf > + // qqq : typed error + pub fn local_path< 'a >( name : &'a str, version : &'a str, crate_dir : CrateDir ) -> error::untyped::Result< PathBuf > { let buf = format!( "package/{0}-{1}.crate", name, version ); - - let workspace = Workspace::with_crate_dir( crate_dir )?; + let workspace = Workspace::try_from( crate_dir )?; let mut local_package_path = PathBuf::new(); - local_package_path.push( workspace.target_directory()? ); + local_package_path.push( workspace.target_directory() ); local_package_path.push( buf ); Ok( local_package_path ) @@ -37,7 +37,8 @@ mod private /// /// Get data of remote package from crates.io. /// - pub fn download< 'a >( name : &'a str, version : &'a str ) -> Result< Vec< u8 > > + // qqq : typed error + pub fn download< 'a >( name : &'a str, version : &'a str ) -> error::untyped::Result< Vec< u8 > > { let agent : Agent = ureq::AgentBuilder::new() .timeout_read( Duration::from_secs( 5 ) ) @@ -67,7 +68,7 @@ mod private crate::mod_interface! { - protected use local_path; - protected use download; + own use local_path; + own use download; } diff --git a/module/move/willbe/src/entity/progress_bar.rs b/module/move/willbe/src/entity/progress_bar.rs new file mode 100644 index 0000000000..c9fef4cf07 --- /dev/null +++ b/module/move/willbe/src/entity/progress_bar.rs @@ -0,0 +1,108 @@ +mod private +{ + /// The `ProgressBar` structure is used to display progress indicators in the terminal. + /// It wraps the functionality of the `indicatif` library. + /// + /// This structure is only available when the `progress_bar` feature is enabled. + #[ cfg( feature = "progress_bar" ) ] + pub struct ProgressBar< 'a > + { + /// A reference to the `MultiProgress` object from the `indicatif` library, which + /// allows managing multiple progress bars simultaneously. This object is necessary + /// for coordinating the display of multiple progress bars. + pub( crate ) multi_progress: &'a indicatif::MultiProgress, + /// The `ProgressBar` object from the `indicatif` library, which represents + /// an individual progress indicator. It is used to update the progress state + /// and display it in the terminal. + pub( crate ) progress_bar: indicatif::ProgressBar, + } + + #[ cfg( feature = "progress_bar" ) ] + impl < 'a > std::fmt::Debug for ProgressBar< 'a > + { + fn fmt( &self, f : &mut std::fmt::Formatter< '_ > ) -> std::fmt::Result + { + f.debug_struct( "ProgressBar" ) + .finish() + } + } + + /// The `MultiProgress` structure is used to manage and display multiple progress + /// indicators simultaneously in the terminal. It utilizes the `indicatif` library. + /// + /// This structure is only available when the `progress_bar` feature is enabled. + #[ cfg( feature = "progress_bar" ) ] + pub struct MultiProgress + { + multi_progress: indicatif::MultiProgress, + progress_style: indicatif::ProgressStyle, + } + + #[ cfg( feature = "progress_bar" ) ] + impl MultiProgress + { + /// Creates a new `ProgressBar` instance tied to the `MultiProgress` manager. + /// This function initializes a new progress bar with a specified length and applies + /// the defined style to it. + /// + /// # Parameters + /// + /// - `variants_len`: The total length or count that the progress bar will track. + /// + /// # Returns + /// + /// A `ProgressBar` instance that can be used to update and display progress. + pub fn progress_bar< 'a >( &'a self, variants_len : u64 ) -> ProgressBar< 'a > + { + let progress_bar = + { + let pb = self.multi_progress.add( indicatif::ProgressBar::new( variants_len ) ); + pb.set_style( self.progress_style.clone() ); + pb.inc( 0 ); + pb + }; + ProgressBar + { + multi_progress : &self.multi_progress, + progress_bar, + } + } + } + + #[ cfg( feature = "progress_bar" ) ] + impl std::fmt::Debug for MultiProgress + { + fn fmt( &self, f : &mut std::fmt::Formatter< '_ > ) -> std::fmt::Result + { + f.debug_struct( "MultiprogressProgress" ) + .finish() + } + } + + + #[ cfg( feature = "progress_bar" ) ] + impl Default for MultiProgress + { + fn default() -> Self + { + Self + { + multi_progress: indicatif::MultiProgress::new(), + progress_style: indicatif::ProgressStyle::with_template + ( + "[{elapsed_precise}] {bar:40.cyan/blue} {pos:>7}/{len:7} {msg}", + ) + .unwrap() + .progress_chars( "##-" ), + } + } + } +} + +crate::mod_interface! +{ + #[ cfg( feature = "progress_bar" ) ] + own use ProgressBar; + #[ cfg( feature = "progress_bar" ) ] + own use MultiProgress; +} \ No newline at end of file diff --git a/module/move/willbe/src/entity/publish.rs b/module/move/willbe/src/entity/publish.rs new file mode 100644 index 0000000000..ed1e336129 --- /dev/null +++ b/module/move/willbe/src/entity/publish.rs @@ -0,0 +1,442 @@ +mod private +{ + use crate::*; + + use std::fmt; + use process_tools::process; + use + { + iter::Itertools, + error:: + { + // Result, + untyped::{ format_err, Error }, + } + }; + use error::ErrWith; + + /// Represents instructions for publishing a package. + #[ derive( Debug, Clone ) ] + pub struct PackagePublishInstruction + { + /// The name of the package. + pub package_name : package::PackageName, + /// Options for packing the package using Cargo. + pub pack : cargo::PackOptions, + /// Options for bumping the package version. + pub bump : version::BumpOptions, + /// Git options related to the package. + pub git_options : entity::git::GitOptions, + /// Options for publishing the package using Cargo. + pub publish : cargo::PublishOptions, + /// Indicates whether the process should be dry-run (no actual publishing). + pub dry : bool, + } + + /// Represents a planner for publishing a single package. + #[ derive( Debug, former::Former ) ] + #[ perform( fn build() -> PackagePublishInstruction ) ] + pub struct PublishSinglePackagePlanner< 'a > + { + workspace_dir : CrateDir, + package : package::Package< 'a >, + channel : channel::Channel, + base_temp_dir : Option< path::PathBuf >, + #[ former( default = true ) ] + dry : bool, + } + + impl< 'a > PublishSinglePackagePlanner< 'a > + { + fn build( self ) -> PackagePublishInstruction + { + let crate_dir = self.package.crate_dir(); + let workspace_root : AbsolutePath = self.workspace_dir.clone().absolute_path(); + let pack = cargo::PackOptions + { + path : crate_dir.clone().absolute_path().inner(), + channel : self.channel, + allow_dirty : self.dry, + checking_consistency : !self.dry, + temp_path : self.base_temp_dir.clone(), + dry : self.dry, + }; + let old_version : Version = self.package.version().as_ref().unwrap().try_into().unwrap(); + let new_version = old_version.clone().bump(); + // bump the package version in dependents (so far, only workspace) + let dependencies = vec![ CrateDir::try_from( workspace_root.clone() ).unwrap() ]; + let bump = version::BumpOptions + { + crate_dir : crate_dir.clone(), + old_version : old_version.clone(), + new_version : new_version.clone(), + dependencies : dependencies.clone(), + dry : self.dry, + }; + let git_options = entity::git::GitOptions + { + git_root : workspace_root, + items : dependencies.iter().chain([ &crate_dir ]).map( | d | d.clone().absolute_path().join( "Cargo.toml" ) ).collect(), + message : format!( "{}-v{}", self.package.name().unwrap(), new_version ), + dry : self.dry, + }; + let publish = cargo::PublishOptions + { + path : crate_dir.clone().absolute_path().inner(), + temp_path : self.base_temp_dir.clone(), + retry_count : 2, + dry : self.dry, + }; + + PackagePublishInstruction + { + package_name : self.package.name().unwrap().to_string().into(), + pack, + bump, + git_options, + publish, + dry : self.dry, + } + } + } + + /// `PublishPlan` manages the overall publication process for multiple packages. + /// It organizes the necessary details required for publishing each individual package. + /// This includes the workspace root directory, any temporary directories used during the process, + /// and the set of specific instructions for publishing each package. + #[ derive( Debug, former::Former, Clone ) ] + pub struct PublishPlan + { + /// `workspace_dir` - This is the root directory of your workspace, containing all the Rust crates + /// that make up your package. It is used to locate the packages within your workspace that are meant + /// to be published. The value here is represented by `CrateDir` which indicates the directory of the crate. + pub workspace_dir : CrateDir, + + /// `base_temp_dir` - This is used for any temporary operations during the publication process, like + /// building the package or any other processes that might require the storage of transient data. It's + /// optional as not all operations will require temporary storage. The type used is `PathBuf` which allows + /// manipulation of the filesystem paths. + pub base_temp_dir : Option< path::PathBuf >, + + /// Release channels for rust. + pub channel : channel::Channel, + + /// `dry` - A boolean value indicating whether to do a dry run. If set to `true`, the application performs + /// a simulated run without making any actual changes. If set to `false`, the operations are actually executed. + /// This property is optional and defaults to `true`. + #[ former( default = true ) ] + pub dry : bool, + + /// Required for tree view only + pub roots : Vec< CrateDir >, + + /// `plans` - This is a vector containing the instructions for publishing each package. Each item + /// in the `plans` vector indicates a `PackagePublishInstruction` set for a single package. It outlines + /// how to build and where to publish the package amongst other instructions. The `#[setter( false )]` + /// attribute indicates that there is no setter method for the `plans` variable and it can only be modified + /// within the struct. + #[ scalar( setter = false ) ] + pub plans : Vec< PackagePublishInstruction >, + } + + impl PublishPlan + { + /// Displays a tree-like structure of crates and their dependencies. + /// + /// # Arguments + /// + /// * `f` - A mutable reference to a `Formatter` used for writing the output. + /// + /// # Errors + /// + /// Returns a `std::fmt::Error` if there is an error writing to the formatter. + pub fn write_as_tree< W >( &self, f : &mut W ) -> fmt::Result + where + W : fmt::Write + { + let name_bump_report : collection::HashMap< _, _ > = self + .plans + .iter() + .map( | x | ( x.package_name.as_ref(), ( x.bump.old_version.to_string(), x.bump.new_version.to_string() ) ) ) + .collect(); + for wanted in &self.roots + { + let list = action::list + ( + action::list::ListOptions::former() + .path_to_manifest( wanted.clone() ) + .format( action::list::ListFormat::Tree ) + .dependency_sources([ action::list::DependencySource::Local ]) + .dependency_categories([ action::list::DependencyCategory::Primary ]) + .form() + ) + .map_err( |( _, _e )| fmt::Error )?; + let action::list::ListReport::Tree( list ) = list else { unreachable!() }; + + fn callback( name_bump_report : &collection::HashMap< &String, ( String, String ) >, mut r : tool::ListNodeReport ) -> tool::ListNodeReport + { + if let Some(( old, new )) = name_bump_report.get( &r.name ) + { + r.version = Some( format!( "({old} -> {new})" ) ); + } + r.normal_dependencies = r.normal_dependencies.into_iter().map( | r | callback( name_bump_report, r ) ).collect(); + r.dev_dependencies = r.dev_dependencies.into_iter().map( | r | callback( name_bump_report, r ) ).collect(); + r.build_dependencies = r.build_dependencies.into_iter().map( | r | callback( name_bump_report, r ) ).collect(); + + r + } + let printer = list; + let rep : Vec< tool::ListNodeReport > = printer.iter().map( | printer | printer.info.clone() ).collect(); + let list: Vec< tool::ListNodeReport > = rep.into_iter().map( | r | callback( &name_bump_report, r ) ).collect(); + let printer : Vec< tool::TreePrinter > = list.iter().map( | rep | tool::TreePrinter::new( rep ) ).collect(); + + let list = action::list::ListReport::Tree( printer ); + writeln!( f, "{}", list )?; + } + + Ok( () ) + } + + /// Format and display the list of packages and their version bumps in a formatted way. + /// + /// # Arguments + /// + /// - `f`: A mutable reference to a `Formatter` where the output will be written to. + /// + /// # Errors + /// + /// Returns a `std::fmt::Error` if there is an error writing to the formatter. + pub fn write_as_list< W >( &self, f : &mut W ) -> fmt::Result + where + W : fmt::Write + { + for ( idx, package ) in self.plans.iter().enumerate() + { + let bump = &package.bump; + writeln!( f, "[{idx}] {} ({} -> {})", package.package_name, bump.old_version, bump.new_version )?; + } + + Ok( () ) + } + } + + impl< 'a > PublishPlanFormer + { + pub fn option_base_temp_dir( mut self, path : Option< path::PathBuf > ) -> Self + { + self.storage.base_temp_dir = path; + self + } + + pub fn package< IntoPackage >( mut self, package : IntoPackage ) -> Self + where + IntoPackage : Into< package::Package< 'a > >, + { + let channel = self.storage.channel.unwrap_or_default(); + let mut plan = PublishSinglePackagePlanner::former(); + if let Some( workspace ) = &self.storage.workspace_dir + { + plan = plan.workspace_dir( workspace.clone() ); + } + if let Some( base_temp_dir ) = &self.storage.base_temp_dir + { + plan = plan.base_temp_dir( base_temp_dir.clone() ); + } + if let Some( dry ) = self.storage.dry + { + plan = plan.dry( dry ); + } + let plan = plan + .channel( channel ) + .package( package ) + .perform(); + let mut plans = self.storage.plans.unwrap_or_default(); + plans.push( plan ); + + self.storage.plans = Some( plans ); + + self + } + + pub fn packages< IntoPackageIter, IntoPackage >( mut self, packages : IntoPackageIter ) -> Self + where + IntoPackageIter : IntoIterator< Item = IntoPackage >, + IntoPackage : Into< package::Package< 'a > >, + { + for package in packages + { + self = self.package( package ); + } + + self + } + + } + + /// Holds information about the publishing process. + #[ derive( Debug, Default, Clone ) ] + pub struct PublishReport + { + /// Retrieves information about the package. + pub get_info : Option< process::Report >, + /// Bumps the version of the package. + pub bump : Option< version::ExtendedBumpReport >, + /// Report of adding changes to the Git repository. + pub add : Option< process::Report >, + /// Report of committing changes to the Git repository. + pub commit : Option< process::Report >, + /// Report of pushing changes to the Git repository. + pub push : Option< process::Report >, + /// Report of publishes the package using the `cargo publish` command. + pub publish : Option< process::Report >, + } + + impl fmt::Display for PublishReport + { + fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> fmt::Result + { + let PublishReport + { + get_info, + bump, + add, + commit, + push, + publish, + } = self; + + if get_info.is_none() + { + f.write_str( "Empty report" )?; + return Ok( () ) + } + let info = get_info.as_ref().unwrap(); + write!( f, "{}", info )?; + + if let Some( bump ) = bump + { + writeln!( f, "{}", bump )?; + } + if let Some( add ) = add + { + write!( f, "{add}" )?; + } + if let Some( commit ) = commit + { + write!( f, "{commit}" )?; + } + if let Some( push ) = push + { + write!( f, "{push}" )?; + } + if let Some( publish ) = publish + { + write!( f, "{publish}" )?; + } + + Ok( () ) + } + } + + /// Performs package publishing based on the given arguments. + /// + /// # Arguments + /// + /// * `args` - The package publishing instructions. + /// + /// # Returns + /// + /// * `Result` - The result of the publishing operation, including information about the publish, version bump, and git operations. + + pub fn perform_package_publish( instruction : PackagePublishInstruction ) -> ResultWithReport< PublishReport, Error > + { + let mut report = PublishReport::default(); + let PackagePublishInstruction + { + package_name: _, + mut pack, + mut bump, + mut git_options, + mut publish, + dry, + } = instruction; + pack.dry = dry; + bump.dry = dry; + git_options.dry = dry; + publish.dry = dry; + + report.get_info = Some( cargo::pack( pack ).err_with_report( &report )? ); + // aaa : redundant field? // aaa : removed + let bump_report = version::bump( bump ).err_with_report( &report )?; + report.bump = Some( bump_report.clone() ); + let git_root = git_options.git_root.clone(); + let git = match entity::git::perform_git_commit( git_options ) + { + Ok( git ) => git, + Err( e ) => + { + version::revert( &bump_report ) + .map_err( | le | format_err!( "Base error:\n{}\nRevert error:\n{}", e.to_string().replace( '\n', "\n\t" ), le.to_string().replace( '\n', "\n\t" ) ) ) + .err_with_report( &report )?; + return Err(( report, e )); + } + }; + report.add = git.add; + report.commit = git.commit; + report.publish = match cargo::publish( publish ) + { + Ok( publish ) => Some( publish ), + Err( e ) => + { + tool::git::reset( git_root.as_ref(), true, 1, false ) + .map_err + ( + | le | + format_err!( "Base error:\n{}\nRevert error:\n{}", e.to_string().replace( '\n', "\n\t" ), le.to_string().replace( '\n', "\n\t" ) ) + ) + .err_with_report( &report )?; + return Err(( report, e )); + } + }; + + let res = tool::git::push( &git_root, dry ).err_with_report( &report )?; + report.push = Some( res ); + + Ok( report ) + } + + /// Perform publishing of multiple packages based on the provided publish plan. + /// + /// # Arguments + /// + /// * `plan` - The publish plan with details of packages to be published. + /// + /// # Returns + /// + /// Returns a `Result` containing a vector of `PublishReport` if successful, else an error. + pub fn perform_packages_publish( plan : PublishPlan ) -> error::untyped::Result< Vec< PublishReport > > + // qqq : use typed error + { + let mut report = vec![]; + for package in plan.plans + { + let res = perform_package_publish( package ).map_err( |( current_rep, e )| format_err!( "{}\n{current_rep}\n{e}", report.iter().map( | r | format!( "{r}" ) ).join( "\n" ) ) )?; + report.push( res ); + } + + Ok( report ) + } + +} + +// + +crate::mod_interface! +{ + own use PublishPlan; + own use PackagePublishInstruction; + own use PublishSinglePackagePlanner; + own use PublishReport; + own use perform_package_publish; + own use perform_packages_publish; +} diff --git a/module/move/willbe/src/entity/table.rs b/module/move/willbe/src/entity/table.rs index 564c1f6d43..38e789686c 100644 --- a/module/move/willbe/src/entity/table.rs +++ b/module/move/willbe/src/entity/table.rs @@ -9,14 +9,14 @@ mod private inner : prettytable::Table, } - impl Display for Table + impl Display for Table { - fn fmt( &self, f : &mut Formatter< '_ > ) -> std::fmt::Result + fn fmt( &self, f : &mut Formatter< '_ > ) -> std::fmt::Result { writeln!( f, "{}", self.inner.to_string() ) } } - + impl Table { /// Create an empty table. @@ -28,7 +28,7 @@ mod private } } } - + impl Table { /// Set the optional header. @@ -36,17 +36,17 @@ mod private { self.inner.set_titles( row.inner ); } - + /// Append a row in the table. pub fn add_row(&mut self, row : Row ) { self.inner.add_row( row.inner ); } } - + impl Default for Table { - fn default() -> Self + fn default() -> Self { let mut table = Self::new(); let format = default_format(); @@ -69,17 +69,17 @@ mod private .build(); format } - + /// Represent a table row made of cells. #[ derive( Debug ) ] pub struct Row { inner : prettytable::Row, } - + impl Row { - + /// Append a cell at the end of the row. pub fn add_cell( &mut self, title : &str ) { @@ -88,7 +88,7 @@ mod private self.inner.add_cell( prettytable::Cell::new( title ) ); } } - + impl Row { /// Create an row of length size, with empty strings stored. @@ -104,6 +104,6 @@ mod private crate::mod_interface! { - protected use Table; - protected use Row; + own use Table; + own use Row; } \ No newline at end of file diff --git a/module/move/willbe/src/entity/test.rs b/module/move/willbe/src/entity/test.rs index b8298d7f4e..938c5ca415 100644 --- a/module/move/willbe/src/entity/test.rs +++ b/module/move/willbe/src/entity/test.rs @@ -1,63 +1,47 @@ mod private { - // qqq : for Petro : use https://github.com/console-rs/indicatif - use crate::*; use table::*; + // qqq : for Bohdan no asterisk imports, but in special cases use std:: { - collections::{ BTreeMap, BTreeSet, HashSet }, - fmt::Formatter, - sync::{ Arc, Mutex }, - path::Path, + fmt, + sync, }; - use std::collections::HashMap; - use std::ffi::OsString; - use std::fmt::{ Debug, Display }; /* qqq : import only fmt here and everywhere */ - use std::marker::PhantomData; - use std::path::PathBuf; - // aaa : for Petro : don't use cargo_metadata directly, use facade - // aaa : ✅ - use colored::Colorize; - // qqq : for Petro : don't do micro imports - // qqq : for Petro : don't do micro imports - #[ cfg( feature = "progress_bar" ) ] - use indicatif:: + use colored::Colorize as _; + use process_tools::process::*; + use error:: { - MultiProgress, - ProgressBar, - ProgressStyle + Error, + untyped::format_err, }; - use rayon::ThreadPoolBuilder; - use process_tools::process::*; - use wtools::error::anyhow::{ Error, format_err }; - use wtools::iter::Itertools; - use wtools::error::Result; - use former::Former; - use channel::Channel; - use optimization::Optimization; - use workspace::WorkspacePackage; - - /// Newtype for package name - #[ derive( Debug, Default, Clone ) ] - pub struct PackageName( String ); + use package::PackageName; + + #[ derive( Debug, Error ) ] + pub enum TestError + { + #[ error( "Common error: {0}" ) ] + Common( #[ from ] error::untyped::Error ), + #[ error( "Path error: {0}" ) ] + Path( #[ from ] PathError ), + } /// Represents a variant for testing purposes. - #[ derive( Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Former ) ] + #[ derive( Debug, Clone, Eq, PartialEq, Ord, PartialOrd, former::Former ) ] pub struct TestVariant { /// Represents the channel for the test variant. - channel : Channel, + channel : channel::Channel, /// Represents the optimization setting for the test variant. - optimization : Optimization, + optimization : optimization::Optimization, /// Contains additional features or characteristics of the test variant. - features : BTreeSet< String >, + features : collection::BTreeSet, } - impl Display for TestVariant + impl fmt::Display for TestVariant { - fn fmt( &self, f : &mut Formatter< '_ >) -> std::fmt::Result + fn fmt( &self, f : &mut fmt::Formatter< '_ >) -> fmt::Result { let features = if self.features.is_empty() { " ".to_string() } else { self.features.iter().join( " " ) }; writeln!( f, "{} {} {}", self.optimization, self.channel, features )?; @@ -72,9 +56,9 @@ mod private packages_plan : Vec< TestPackagePlan >, } - impl Display for TestPlan + impl fmt::Display for TestPlan { - fn fmt( &self, f : &mut Formatter< '_ >) -> std::fmt::Result + fn fmt( &self, f : &mut fmt::Formatter< '_ >) -> std::fmt::Result { writeln!( f, "Plan: " )?; for plan in &self.packages_plan @@ -98,19 +82,20 @@ mod private /// `with_all_features` - If it's true - add to powerset one subset which contains all features. /// `with_none_features` - If it's true - add to powerset one empty subset. /// `variants_cap` - Maximum of subset in powerset - pub fn try_from + pub fn try_from< 'a > ( - packages : &[ WorkspacePackage ], - channels : &HashSet< Channel >, + packages : impl core::iter::Iterator< Item = WorkspacePackageRef< 'a > >, + channels : &collection::HashSet< channel::Channel >, power : u32, include_features : Vec< String >, exclude_features : Vec< String >, - optimizations : &HashSet< Optimization >, + optimizations : &collection::HashSet< optimization::Optimization >, enabled_features : Vec< String >, with_all_features : bool, with_none_features : bool, variants_cap : u32, - ) -> Result< Self > + ) + -> Result< Self, TestError > { let mut packages_plan = vec![]; for package in packages @@ -142,17 +127,18 @@ mod private #[ derive( Debug ) ] pub struct TestPackagePlan { - enabled_features : BTreeSet< String >, - package : PathBuf, - test_variants : BTreeSet< TestVariant >, + enabled_features : collection::BTreeSet< String >, + // package : PathBuf, + crate_dir : CrateDir, + test_variants : collection::BTreeSet< TestVariant >, } - impl Display for TestPackagePlan + impl fmt::Display for TestPackagePlan { - fn fmt( &self, f : &mut Formatter< '_ >) -> std::fmt::Result + fn fmt( &self, f : &mut fmt::Formatter< '_ >) -> std::fmt::Result { - writeln!( f, "Package : {}\nThe tests will be executed using the following configurations :", self.package.file_name().unwrap().to_string_lossy() )?; - let mut all_features = BTreeSet::new(); + writeln!( f, "Package : {}\nThe tests will be executed using the following configurations :", self.crate_dir.clone().absolute_path() )?; + let mut all_features = collection::BTreeSet::new(); for variant in &self.test_variants { let features = variant.features.iter().cloned(); @@ -216,22 +202,24 @@ mod private /// `with_all_features` - If it's true - add to powerset one subset which contains all features. /// `with_none_features` - If it's true - add to powerset one empty subset. /// `variants_cap` - Maximum of subset in powerset - fn try_from + fn try_from< 'a > ( - package : &WorkspacePackage, - channels : &HashSet< Channel >, + package : WorkspacePackageRef< 'a >, + channels : &collection::HashSet< channel::Channel >, power : u32, include_features : &[ String ], exclude_features : &[ String ], - optimizations : &HashSet< Optimization >, + optimizations : &collection::HashSet< optimization::Optimization >, enabled_features : &[ String ], with_all_features : bool, with_none_features : bool, variants_cap : u32, - ) -> Result< Self > + ) + -> Result< Self, TestError > { - let dir = package.manifest_path().parent().unwrap().as_std_path().to_path_buf(); - let mut test_variants = BTreeSet::new(); + // let crate_dir = package.manifest_file().parent().unwrap().as_std_path().to_path_buf(); + let crate_dir = package.crate_dir()?; + let mut test_variants = collection::BTreeSet::new(); let features_powerset = features::features_powerset ( package, @@ -266,14 +254,22 @@ mod private Self { enabled_features: enabled_features.iter().cloned().collect(), - package : dir, + crate_dir, test_variants, } ) } } - fn generate_features_cells( ff : &mut Vec< String >, variant : &TestVariant, row : &mut Row, mut counter : usize, mut flag : bool, enabled_features : &BTreeSet< String > ) + fn generate_features_cells + ( + ff : &mut Vec< String >, + variant : &TestVariant, + row : &mut Row, + mut counter : usize, + mut flag : bool, + enabled_features : &collection::BTreeSet< String > + ) { for feature in ff { @@ -296,29 +292,20 @@ mod private } } - #[ derive( Debug, Former ) ] + #[ derive( Debug, former::Former ) ] pub struct PackageTestOptions< 'a > { - temp_path : Option< PathBuf >, + temp_path : Option< path::PathBuf >, plan : &'a TestPackagePlan, dry : bool, - progress_bar_feature : Option< PackageTestOptionsProgressBarFeature< 'a > >, - } - - #[ derive( Debug ) ] - struct PackageTestOptionsProgressBarFeature< 'a > - { - phantom : PhantomData< &'a () >, - #[ cfg( feature = "progress_bar" ) ] - multi_progress : &'a Option< &'a MultiProgress >, + with_progress : bool, #[ cfg( feature = "progress_bar" ) ] - progress_bar : &'a Option< ProgressBar > + progress_bar : progress_bar::ProgressBar< 'a > } - impl PackageTestOptionsFormer< '_ > { - pub fn option_temp( mut self, value : impl Into< Option< PathBuf > > ) -> Self + pub fn option_temp( mut self, value : impl Into< Option< path::PathBuf > > ) -> Self { self.storage.temp_path = value.into(); self @@ -326,14 +313,14 @@ mod private } /// Represents the options for the test. - #[ derive( Debug, Former, Clone ) ] + #[ derive( Debug, former::Former, Clone ) ] pub struct SingleTestOptions { /// Specifies the release channels for rust. /// More details : https://rust-lang.github.io/rustup/concepts/channels.html#:~:text=Rust%20is%20released%20to%20three,releases%20are%20made%20every%20night. - channel : Channel, + channel : channel::Channel, /// Specifies the optimization for rust. - optimization : Optimization, + optimization : optimization::Optimization, /// Determines whether to use default features in the test. /// Enabled by default. #[ former( default = true ) ] @@ -343,9 +330,9 @@ mod private #[ former( default = false ) ] with_all_features : bool, /// Specifies a list of features to be enabled in the test. - enable_features : BTreeSet< String >, + enable_features : collection::BTreeSet< String >, /// Temp directory path - temp_directory_path : Option< PathBuf >, + temp_directory_path : Option< path::PathBuf >, /// A boolean indicating whether to perform a dry run or not. dry : bool, /// RUST_BACKTRACE @@ -357,15 +344,17 @@ mod private { fn as_rustup_args( &self ) -> Vec< String > { - debug_assert!( !self.with_default_features ); // qqq : remove later - debug_assert!( !self.with_all_features ); // qqq : remove later + debug_assert!( !self.with_default_features ); // aaa : remove later + debug_assert!( !self.with_all_features ); // aaa : remove later [ "run".into(), self.channel.to_string(), "cargo".into(), "test".into() ] .into_iter() - .chain( if self.optimization == Optimization::Release { Some( "--release".into() ) } else { None } ) + .chain( if self.optimization == optimization::Optimization::Release { Some( "--release".into() ) } else { None } ) .chain( if self.with_default_features { None } else { Some( "--no-default-features".into() ) } ) - // qqq : for Petro : bad, --no-default-features is always enabled! + // aaa : for Petro : bad, --no-default-features is always enabled! + // aaa : add `debug_assert!( !self.with_default_features )` .chain( if self.with_all_features { Some( "--all-features".into() ) } else { None } ) - // qqq : for Petro : bad, --all-features is always disabled! + // aaa : for Petro : bad, --all-features is always disabled! + // aaa : add `debug_assert!( !self.with_all_features )` .chain( if self.enable_features.is_empty() { None } else { Some([ "--features".into(), self.enable_features.iter().join( "," ) ]) }.into_iter().flatten() ) .chain( self.temp_directory_path.clone().map( | p | vec![ "--target-dir".to_string(), p.to_string_lossy().into() ] ).into_iter().flatten() ) .collect() @@ -385,13 +374,11 @@ mod private /// Returns a `Result` containing a `Report` if the command is executed successfully, /// or an error if the command fails to execute. pub fn _run< P >( path : P, options : SingleTestOptions ) -> Result< Report, Report > + // xxx where - P : AsRef< Path > + P : AsRef< path::Path > { let ( program, args ) = ( "rustup", options.as_rustup_args() ); - // qqq : for Petro : rustup ??? - // aaa : for Petro : RUST_BACKTRACE=1 ?? // add to SingleTestOptions, by default true - // aaa : add if options.dry { @@ -409,10 +396,10 @@ mod private } else { - let envs = if options.backtrace { [( "RUST_BACKTRACE".to_string(), "full".to_string() )].into_iter().collect() } else { HashMap::new() }; + let envs = if options.backtrace { [( "RUST_BACKTRACE".to_string(), "full".to_string() )].into_iter().collect() } else { collection::HashMap::new() }; Run::former() .bin_path( program ) - .args( args.into_iter().map( OsString::from ).collect::< Vec< _ > >() ) + .args( args.into_iter().map( std::ffi::OsString::from ).collect::< Vec< _ > >() ) .current_path( path.as_ref().to_path_buf() ) .joining_streams( true ) .env_variable( envs ) @@ -421,7 +408,7 @@ mod private } /// `TestOptions` is a structure used to store the arguments for tests. - #[ derive( Former ) ] + #[ derive( former::Former ) ] pub struct TestOptions { /// Plan for testing @@ -431,40 +418,22 @@ mod private pub concurrent : u32, /// `temp_path` - path to temp directory. - pub temp_path : Option< PathBuf >, + pub temp_path : Option< path::PathBuf >, /// A boolean indicating whether to perform a dry run or not. pub dry : bool, - /// This field contains fields for progress_bar feature - pub feature : Option< TestOptionsProgressBarFeature >, + /// Progress bar flag. + pub with_progress : bool, } - // qqq : for Petro : remove after Former fix - /// Structure for progress bar feature field - pub struct TestOptionsProgressBarFeature - { - #[ cfg( feature = "progress_bar" ) ] - /// Base progress bar - pub multiprocess : MultiProgress, - - #[ cfg( feature = "progress_bar" ) ] - /// Style for progress bar - pub style : ProgressStyle, - } + // aaa : for Petro : remove after Former fix + // aaa : done - impl Debug for TestOptionsProgressBarFeature + impl fmt::Debug for TestOptions { - fn fmt( &self, f : &mut Formatter< '_ >) -> std::fmt::Result + fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> std::fmt::Result { - f.debug_struct( "TestOptionsProgressBarFeature" ) - .finish() - } - } - - impl Debug for TestOptions - { - fn fmt( &self, f : &mut Formatter< '_ >) -> std::fmt::Result { f.debug_struct( "TestOptions" ) .field( "plan", &self.plan) .field( "concurrent", &self.concurrent) @@ -476,7 +445,7 @@ mod private impl TestOptionsFormer { - pub fn option_temp( mut self, value : impl Into< Option< PathBuf > > ) -> Self + pub fn option_temp( mut self, value : impl Into< Option< path::PathBuf > > ) -> Self { self.storage.temp_path = value.into(); self @@ -505,15 +474,14 @@ mod private /// for which the tests were run, and the values are nested `BTreeMap` where the keys are /// feature names and the values are `Report` structs representing the test results for /// the specific feature and channel. - pub tests : BTreeMap< TestVariant, Result< Report, Report > > , + pub tests : collection::BTreeMap< TestVariant, Result< Report, Report > >, /// Enabled features - pub enabled_features : BTreeSet< String >, - // qqq : for Petro : rid off map of map of map, keep flat map + pub enabled_features : collection::BTreeSet, } - impl Display for TestReport + impl fmt::Display for TestReport { - fn fmt( &self, f : &mut Formatter< '_ > ) -> std::fmt::Result + fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> std::fmt::Result { if self.dry { @@ -521,7 +489,7 @@ mod private } let mut failed = 0; let mut success = 0; - let mut all_features = BTreeSet::new(); + let mut all_features = collection::BTreeSet::new(); for variant in self.tests.keys() { let features = variant.features.iter().cloned(); @@ -550,7 +518,7 @@ mod private } table.set_header( header_row ); - writeln!( f, "{} {}\n", "\n=== Module".bold(), self.package_name.0.bold() )?; + writeln!( f, "{} {}\n", "\n=== Module".bold(), self.package_name.bold() )?; if self.tests.is_empty() { writeln!( f, "unlucky" )?; @@ -628,16 +596,17 @@ mod private pub failure_reports : Vec< TestReport >, } - impl Display for TestsReport + impl fmt::Display for TestsReport { - fn fmt( &self, f : &mut Formatter< '_ > ) -> std::fmt::Result + fn fmt( &self, f : &mut fmt::Formatter< '_ > ) -> std::fmt::Result { - if self.dry - { - writeln!( f, "\nYou can execute the plan with 'will .test dry : 0'." )?; - // qqq : for Petro : bad. should be exact command with exact parameters / при виклику зовнішніх команд повинен бути вивід у консоль про цей виклик і його аргументи за виключенням коли ційлий блок виводу прихований (у моєму випадку при фейлі) - return Ok( () ) - } + // if self.dry + // { + // writeln!( f, "\nYou can execute the plan with 'will .test dry : 0'." )?; + // // aaa : for Petro : bad. should be exact command with exact parameters / при виклику зовнішніх команд повинен бути вивід у консоль про цей виклик і його аргументи за виключенням коли ційлий блок виводу прихований (у моєму випадку при фейлі) + // // aaa : coment in because its redundant, this behavior already implemented + // return Ok( () ) + // } if self.success_reports.is_empty() && self.failure_reports.is_empty() { writeln!( f, "The tests have not been run." )?; @@ -668,13 +637,15 @@ mod private /// `tests_run` is a function that runs tests on a given package with specified arguments. /// It returns a `TestReport` on success, or a `TestReport` and an `Error` on failure. - pub fn run( options : &PackageTestOptions< '_ > ) -> Result< TestReport, ( TestReport, Error ) > + pub fn run( options : &PackageTestOptions< '_ > ) + -> ResultWithReport< TestReport, TestError > + // -> Result< TestReport, ( TestReport, TestError ) > { let mut report = TestReport::default(); report.dry = options.dry; report.enabled_features = options.plan.enabled_features.clone(); - let report = Arc::new( Mutex::new( report ) ); - let dir = options.plan.package.clone(); + let report = sync::Arc::new( sync::Mutex::new( report ) ); + let crate_dir = options.plan.crate_dir.clone(); rayon::scope ( @@ -684,7 +655,7 @@ mod private { let TestVariant{ channel, optimization, features } = variant; let r = report.clone(); - let dir = dir.clone(); + let crate_dir = crate_dir.clone(); s.spawn ( move | _ | @@ -698,33 +669,29 @@ mod private if let Some( p ) = options.temp_path.clone() { - let path = p.join( path_tools::path::unique_folder_name().unwrap() ); - // qqq : for Petro : rid off unwrap + let path = p.join( path::unique_folder_name().unwrap() ); std::fs::create_dir_all( &path ).unwrap(); args_t = args_t.temp_directory_path( path ); } #[ cfg( feature = "progress_bar" ) ] - let _s = + if options.with_progress { - let s = if let Some( multi_progress ) = options.progress_bar_feature.as_ref().and_then( | f | f.multi_progress.as_ref() ) + let _s = { - let s = multi_progress.add( ProgressBar::new_spinner().with_message( format!( "{}", variant ) ) ); + let s = options.progress_bar.multi_progress.add( indicatif::ProgressBar::new_spinner().with_message( format!( "{}", variant ) ) ); s.enable_steady_tick( std::time::Duration::from_millis( 100 ) ); - Some( s ) - } - else - { - None + s }; - // spinner.enable_steady_tick( std::time::Duration::from_millis( 100 ) ); - s - }; + } let args = args_t.form(); let temp_dir = args.temp_directory_path.clone(); - let cmd_rep = _run( dir, args ); + let cmd_rep = _run( crate_dir, args ); r.lock().unwrap().tests.insert( variant.clone(), cmd_rep ); #[ cfg( feature = "progress_bar" ) ] - options.progress_bar_feature.as_ref().unwrap().progress_bar.as_ref().map( | b | b.inc( 1 ) ); + if options.with_progress + { + options.progress_bar.progress_bar.inc( 1 ); + } if let Some( path ) = temp_dir { std::fs::remove_dir_all( path ).unwrap(); @@ -736,21 +703,27 @@ mod private ); // unpack. all tasks must be completed until now - let report = Mutex::into_inner( Arc::into_inner( report ).unwrap() ).unwrap(); + let report = sync::Mutex::into_inner( sync::Arc::into_inner( report ).unwrap() ).unwrap(); let at_least_one_failed = report .tests .iter() .any( | ( _, result ) | result.is_err() ); - if at_least_one_failed { Err( ( report, format_err!( "Some tests was failed" ) ) ) } else { Ok( report ) } + if at_least_one_failed { Err( ( report, format_err!( "Some tests was failed" ).into() ) ) } else { Ok( report ) } } /// Run tests for given packages. - pub fn tests_run( args : &TestOptions ) -> Result< TestsReport, ( TestsReport, Error ) > + pub fn tests_run( args : &TestOptions ) + -> ResultWithReport< TestsReport, TestError > + // -> Result< TestsReport, ( TestsReport, TestError ) > { + #[ cfg( feature = "progress_bar" ) ] + let multi_progress = progress_bar::MultiProgress::default(); + #[ cfg( feature = "progress_bar" ) ] + let mm = &multi_progress; let mut report = TestsReport::default(); report.dry = args.dry; - let report = Arc::new( Mutex::new( report ) ); - let pool = ThreadPoolBuilder::new().use_current_thread().num_threads( args.concurrent as usize ).build().unwrap(); + let report = sync::Arc::new( sync::Mutex::new( report ) ); + let pool = rayon::ThreadPoolBuilder::new().use_current_thread().num_threads( args.concurrent as usize ).build().unwrap(); pool.scope ( | s | @@ -762,35 +735,17 @@ mod private ( move | _ | { + let test_package_options = PackageTestOptions::former() + .option_temp( args.temp_path.clone() ) + .plan( plan ) + .dry( args.dry ) + .with_progress( args.with_progress ); + #[ cfg( feature = "progress_bar" ) ] - let pb = + let test_package_options = { - let pb = if let Some( feature ) = args.feature.as_ref() - { - let pb = feature.multiprocess.add(ProgressBar::new(plan.test_variants.len() as u64)); - pb.set_style( args.feature.as_ref().unwrap().style.clone() ); - pb.inc( 0 ); - Some( pb ) - } - else - { - None - }; - pb + test_package_options.progress_bar( mm.progress_bar( plan.test_variants.len() as u64 ) ) }; - #[ cfg( feature = "progress_bar" ) ] - let multi_progress = args.feature.as_ref().map( | f | &f.multiprocess ); - let test_package_options = PackageTestOptions::former().option_temp( args.temp_path.clone() ).plan( plan ).dry( args.dry ); - #[ cfg( feature = "progress_bar" ) ] - let test_package_options = test_package_options.progress_bar_feature - ( - PackageTestOptionsProgressBarFeature - { - phantom : PhantomData, - multi_progress : &multi_progress, - progress_bar : &pb, - } - ); let options = test_package_options.form(); match run( &options ) { @@ -808,14 +763,14 @@ mod private } } ); - let report = Arc::into_inner( report ).unwrap().into_inner().unwrap(); + let report = sync::Arc::into_inner( report ).unwrap().into_inner().unwrap(); if report.failure_reports.is_empty() { Ok( report ) } else { - Err(( report, format_err!( "Some tests was failed" ) )) + Err(( report, format_err!( "Some tests was failed" ).into() )) } } } @@ -823,17 +778,14 @@ mod private crate::mod_interface! { - protected use SingleTestOptions; - protected use TestVariant; - protected use _run; - - protected use TestPlan; + own use SingleTestOptions; + own use TestVariant; + own use _run; - protected use TestOptions; - protected use TestReport; - protected use TestsReport; - protected use run; - protected use tests_run; - - protected use TestOptionsProgressBarFeature; -} \ No newline at end of file + own use TestPlan; + own use TestOptions; + own use TestReport; + own use TestsReport; + own use run; + own use tests_run; +} diff --git a/module/move/willbe/src/entity/version.rs b/module/move/willbe/src/entity/version.rs index e3900e1d57..0722b8a59c 100644 --- a/module/move/willbe/src/entity/version.rs +++ b/module/move/willbe/src/entity/version.rs @@ -12,11 +12,10 @@ mod private use toml_edit::value; use semver::Version as SemVersion; - use wtools::error::for_app::Result; + use error::untyped::Result; use manifest::Manifest; - use _path::AbsolutePath; use package::Package; - use wtools::{ error::anyhow::format_err, iter::Itertools }; + use { error::untyped::format_err, iter::Itertools }; /// Wrapper for a SemVer structure #[ derive( Debug, Clone, Eq, PartialEq, Ord, PartialOrd ) ] @@ -109,61 +108,6 @@ mod private } } - /// Bump version by manifest. - /// It takes data from the manifest and increments the version number according to the semantic versioning scheme. - /// It then writes the updated manifest file back to the same path, unless the flag is set to true, in which case it only returns the new version number as a string. - /// - /// # Args : - /// - `manifest` - a manifest mutable reference - /// - `dry` - a flag that indicates whether to apply the changes or not - /// - `true` - does not modify the manifest file, but only returns the new version; - /// - `false` - overwrites the manifest file with the new version. - /// - /// # Returns : - /// - `Ok` - the new version number as a string; - /// - `Err` - if the manifest file cannot be read, written, parsed. - pub fn bump( manifest : &mut Manifest, dry : bool ) -> Result< BumpReport, manifest::ManifestError > - { - let mut report = BumpReport::default(); - - let version= - { - if manifest.manifest_data.is_none() - { - manifest.load()?; - } - let data = manifest.manifest_data.as_ref().unwrap(); - if !manifest.package_is()? - { - return Err( manifest::ManifestError::NotAPackage ); - } - let package = data.get( "package" ).unwrap(); - - let version = package.get( "version" ); - if version.is_none() - { - return Err( manifest::ManifestError::CannotFindValue( "version".into() ) ); - } - let version = version.unwrap().as_str().unwrap(); - report.name = Some( package[ "name" ].as_str().unwrap().to_string() ); - report.old_version = Some( version.to_string() ); - - Version::from_str( version ).map_err( | e | manifest::ManifestError::InvalidValue( e.to_string() ) )? - }; - - let new_version = version.bump().to_string(); - report.new_version = Some( new_version.clone() ); - - if !dry - { - let data = manifest.manifest_data.as_mut().unwrap(); - data[ "package" ][ "version" ] = value( &new_version ); - manifest.store()?; - } - - Ok( report ) - } - // qqq : we have to replace the implementation above with the implementation below, don't we? // qqq : for Bohdan : duplication? @@ -206,7 +150,7 @@ mod private /// Package new version. pub new_version : Option< String >, /// Files that should(already) changed for bump. - pub changed_files : Vec< AbsolutePath > + pub changed_files : Vec< ManifestFile > } impl std::fmt::Display for ExtendedBumpReport @@ -237,19 +181,22 @@ mod private /// /// # Arguments /// - /// * `args` - The options for version bumping. + /// * `o` - The options for version bumping. /// /// # Returns /// /// Returns a result containing the extended bump report if successful. /// - pub fn version_bump( o : BumpOptions ) -> Result< ExtendedBumpReport > + // qqq : should be typed error, apply err_with + // qqq : don't use 1-prameter Result + pub fn bump( o : BumpOptions ) -> Result< ExtendedBumpReport > { let mut report = ExtendedBumpReport::default(); - let package_path = o.crate_dir.absolute_path().join( "Cargo.toml" ); - let package = Package::try_from( package_path.clone() ).map_err( | e | format_err!( "{report:?}\n{e:#?}" ) )?; + // let manifest_file = o.crate_dir.inner().join( "Cargo.toml" ); + let manifest_file = o.crate_dir.manifest_file(); + let package = Package::try_from( manifest_file.clone() ).map_err( | e | format_err!( "{report:?}\n{e:#?}" ) )?; let name = package.name().map_err( | e | format_err!( "{report:?}\n{e:#?}" ) )?; - report.name = Some( name.clone() ); + report.name = Some( name.into() ); let package_version = package.version().map_err( | e | format_err!( "{report:?}\n{e:#?}" ) )?; let current_version = version::Version::try_from( package_version.as_str() ).map_err( | e | format_err!( "{report:?}\n{e:#?}" ) )?; if current_version > o.new_version @@ -262,17 +209,20 @@ mod private let mut package_manifest = package.manifest().map_err( | e | format_err!( "{report:?}\n{e:#?}" ) )?; if !o.dry { - let data = package_manifest.manifest_data.as_mut().unwrap(); + // let data = package_manifest.data.as_mut().unwrap(); + let data = &mut package_manifest.data; data[ "package" ][ "version" ] = value( &o.new_version.to_string() ); package_manifest.store()?; } - report.changed_files = vec![ package_path ]; + report.changed_files = vec![ manifest_file ]; let new_version = &o.new_version.to_string(); for dep in &o.dependencies { - let manifest_path = dep.absolute_path().join( "Cargo.toml" ); - let mut manifest = manifest::open( manifest_path.clone() ).map_err( | e | format_err!( "{report:?}\n{e:#?}" ) )?; - let data = manifest.manifest_data.as_mut().unwrap(); + // let manifest_file = dep.absolute_path().join( "Cargo.toml" ); + let manifest_file = dep.clone().manifest_file(); + let mut manifest = Manifest::try_from( manifest_file.clone() ).map_err( | e | format_err!( "{report:?}\n{e:#?}" ) )?; + // let data = manifest.data.as_mut().unwrap(); + let data = &mut manifest.data; let item = if let Some( item ) = data.get_mut( "package" ) { item } else if let Some( item ) = data.get_mut( "workspace" ) { item } else { return Err( format_err!( "{report:?}\nThe manifest nor the package and nor the workspace" ) ); }; @@ -291,7 +241,7 @@ mod private } } if !o.dry { manifest.store().map_err( | e | format_err!( "{report:?}\n{e:#?}" ) )?; } - report.changed_files.push( manifest_path ); + report.changed_files.push( manifest_file ); } Ok( report ) @@ -306,7 +256,8 @@ mod private /// # Returns /// /// Returns `Ok(())` if the version is reverted successfully. Returns `Err` with an error message if there is any issue with reverting the version. - pub fn version_revert( report : &ExtendedBumpReport ) -> Result< () > + // qqq : don't use 1-prameter Result + pub fn revert( report : &ExtendedBumpReport ) -> error::untyped::Result< () > // qqq : use typed error { let Some( name ) = report.name.as_ref() else { return Ok( () ) }; let Some( old_version ) = report.old_version.as_ref() else { return Ok( () ) }; @@ -337,7 +288,7 @@ mod private for path in &report.changed_files { - let mut manifest = manifest::open( path.clone() )?; + let mut manifest = Manifest::try_from( path.clone() )?; let data = manifest.data(); if let Some( workspace ) = data.get_mut( "workspace" ) { @@ -361,6 +312,58 @@ mod private Ok( () ) } + + // qqq : for Bohdan : not used? why is it needed? + /// Bump version by manifest. + /// It takes data from the manifest and increments the version number according to the semantic versioning scheme. + /// It then writes the updated manifest file back to the same path, unless the flag is set to true, in which case it only returns the new version number as a string. + /// + /// # Args : + /// - `manifest` - a manifest mutable reference + /// - `dry` - a flag that indicates whether to apply the changes or not + /// - `true` - does not modify the manifest file, but only returns the new version; + /// - `false` - overwrites the manifest file with the new version. + /// + /// # Returns : + /// - `Ok` - the new version number as a string; + /// - `Err` - if the manifest file cannot be read, written, parsed. + pub fn manifest_bump( manifest : &mut Manifest, dry : bool ) -> Result< BumpReport, manifest::ManifestError > + { + let mut report = BumpReport::default(); + + let version= + { + let data = &manifest.data; + if !manifest.package_is() + { + return Err( manifest::ManifestError::NotAPackage ); + } + let package = data.get( "package" ).unwrap(); + + let version = package.get( "version" ); + if version.is_none() + { + return Err( manifest::ManifestError::CannotFindValue( "version".into() ) ); + } + let version = version.unwrap().as_str().unwrap(); + report.name = Some( package[ "name" ].as_str().unwrap().to_string() ); + report.old_version = Some( version.to_string() ); + + Version::from_str( version ).map_err( | e | manifest::ManifestError::InvalidValue( e.to_string() ) )? + }; + + let new_version = version.bump().to_string(); + report.new_version = Some( new_version.clone() ); + + if !dry + { + let data = &mut manifest.data; + data[ "package" ][ "version" ] = value( &new_version ); + manifest.store()?; + } + + Ok( report ) + } } // @@ -368,20 +371,21 @@ mod private crate::mod_interface! { /// Version entity. - protected use Version; + exposed use Version; /// Report for bump operation. - protected use BumpReport; - - /// Bump version. - protected use bump; + own use BumpReport; /// Options for version bumping. - protected use BumpOptions; + own use BumpOptions; /// Report about a changing version with list of files that was changed. - protected use ExtendedBumpReport; + own use ExtendedBumpReport; + /// Bumps the version of a package and its dependencies. - protected use version_bump; + own use manifest_bump; + /// Bump version. + own use bump; + /// Reverts the version of a package. - protected use version_revert; + own use revert; } diff --git a/module/move/willbe/src/entity/workspace.rs b/module/move/willbe/src/entity/workspace.rs index b477aa3c97..3fc37828fd 100644 --- a/module/move/willbe/src/entity/workspace.rs +++ b/module/move/willbe/src/entity/workspace.rs @@ -1,367 +1,296 @@ mod private { - use std::collections::BTreeMap; use crate::*; - use std::path::Path; - use cargo_metadata::camino::{ Utf8Path, Utf8PathBuf }; - use petgraph::Graph; - use serde::Deserialize; - use serde_json::Value; - use wtools::error:: + // qqq : for Bohdan : bad + // use std::*; + + use std::slice; + use former::{ Former }; + + /// Stores information about the current workspace. + #[ derive( Debug, Clone ) ] + pub struct Workspace { - for_app::Context, - for_lib::Error, - Result - }; - use _path::AbsolutePath; - - /// Facade for cargo_metadata::Package - #[ derive( Debug, Clone, Deserialize ) ] - pub struct WorkspacePackage + /// Metadata of the workspace, containing detailed information about the packages, dependencies, and other workspace-related data. + pub metadata : cargo_metadata::Metadata, + /// The directory containing the manifest file (`Cargo.toml`) of the workspace. + pub crate_dir : CrateDir, + } + + /// Represents errors related to workspace operations. + #[ derive( Debug, error::typed::Error ) ] + pub enum WorkspaceInitError { - #[ serde( flatten ) ] - inner : cargo_metadata::Package + /// Something went wrong with path to a workspace. + #[ error( "Path error. Details: {0}" ) ] + Path( #[ from ] PathError ), + /// Something went wrong with the workspace' data + #[ error( "Can not load workspace data. Details: {0}" ) ] + Metadata( #[ from ] cargo_metadata::Error ), + /// Files error + #[ error( "I/O error: {0}" ) ] + IO( #[ from ] std::io::Error ), } - - impl From< cargo_metadata::Package > for WorkspacePackage + + impl TryFrom< CrateDir > for Workspace { - fn from( inner : cargo_metadata::Package) -> Self + type Error = WorkspaceInitError; + + /// Load data from current directory + fn try_from( mut crate_dir : CrateDir ) -> Result< Self, Self::Error > { - Self + let metadata = cargo_metadata::MetadataCommand::new() + .current_dir( crate_dir.as_ref() ) + .no_deps() + .exec()?; + // inout crate dir may refer on crate's manifest dir, not workspace's manifest dir + crate_dir = ( &metadata.workspace_root ).try_into()?; + Ok( Self { - inner - } + metadata, + crate_dir, + }) } + } - - impl WorkspacePackage + + impl TryFrom< CurrentPath > for Workspace { - /// The name field as given in the Cargo.toml - pub fn name( &self ) -> &String - { - &self.inner.name - } - - /// List of dependencies of this particular package - pub fn dependencies( &self ) -> Vec< Dependency > - { - self.inner.dependencies.iter().cloned().map( Dependency::from ).collect() - } - - /// Path containing the Cargo.toml - pub fn manifest_path( &self ) -> &Utf8Path - { - self.inner.manifest_path.as_path() - } - - /// The version field as specified in the Cargo.toml - pub fn version( &self ) -> semver::Version - { - self.inner.version.clone() - } - - /// List of registries to which this package may be published (derived from the publish field). - /// Publishing is unrestricted if None, and forbidden if the Vec is empty. - /// This is always None if running with a version of Cargo older than 1.39. - pub fn publish( &self ) -> Option< &Vec< String > > - { - self.inner.publish.as_ref() - } - - ///Contents of the free form package.metadata section. - /// This contents can be serialized to a struct using serde: - /// ``` rust - /// use serde::Deserialize; - /// use serde_json::json; - /// - /// #[ derive( Debug, Deserialize ) ] - /// struct SomePackageMetadata - /// { - /// some_value : i32, - /// } - /// - /// fn main() - /// { - /// let value = json! - /// ({ - /// "some_value" : 42, - /// }); - /// - /// let package_metadata : SomePackageMetadata = serde_json::from_value( value ).unwrap(); - /// assert_eq!( package_metadata.some_value, 42 ); - /// } - /// ``` - pub fn metadata( &self ) -> &Value - { - &self.inner.metadata - } - - /// The repository URL as specified in the Cargo.toml - pub fn repository( &self ) -> Option< &String > - { - self.inner.repository.as_ref() - } - - /// Features provided by the crate, mapped to the features required by that feature. - pub fn features( &self ) -> &BTreeMap< String, Vec< String > > + type Error = WorkspaceInitError; + + /// Load data from current directory + fn try_from( cd : CurrentPath ) -> Result< Self, Self::Error > { - &self.inner.features + Self::try_from( CrateDir::transitive_try_from::< AbsolutePath >( cd )? ) } + } - - /// A dependency of the main crate - #[ derive( Debug ) ] - pub struct Dependency + + impl From< cargo_metadata::Metadata > for Workspace { - inner : cargo_metadata::Dependency, + fn from( metadata : cargo_metadata::Metadata ) -> Self + { + // SAFE: `workspace_root` is a path to a`Cargo.toml` file, therefor the parent is the directory + let path = metadata.workspace_root.as_std_path().parent().unwrap().to_path_buf(); + let crate_dir = CrateDir::try_from( path ).unwrap(); + Self + { + metadata, + crate_dir, + } + } } - - impl Dependency + + impl Workspace { - /// The file system path for a local path dependency. - /// Only produced on cargo 1.51+ - pub fn path( &self ) -> Option< Utf8PathBuf > + + /// Returns list of all packages + pub fn packages< 'a >( &'a self ) + -> core::iter::Map + < + slice::Iter< 'a, cargo_metadata::Package >, + impl Fn( &'a cargo_metadata::Package ) -> WorkspacePackageRef< 'a > + Clone, + > { - self.inner.path.clone() + self.metadata.packages.iter().map( WorkspacePackageRef::from ) } - - /// Name as given in the Cargo.toml. - pub fn name( &self ) -> String + + /// Returns the path to workspace root + pub fn workspace_root( &self ) -> CrateDir { - self.inner.name.clone() + // Safe because workspace_root.as_std_path() is always a path to a directory + CrateDir::try_from( self.metadata.workspace_root.as_std_path() ).unwrap() } - - /// The kind of dependency this is. - pub fn kind( &self ) -> DependencyKind + + /// Returns the path to target directory + pub fn target_directory( &self ) -> &std::path::Path { - match self.inner.kind - { - cargo_metadata::DependencyKind::Normal => DependencyKind::Normal, - cargo_metadata::DependencyKind::Development => DependencyKind::Development, - cargo_metadata::DependencyKind::Build => DependencyKind::Build, - cargo_metadata::DependencyKind::Unknown => DependencyKind::Unknown, - } + self.metadata.target_directory.as_std_path() } - - /// he required version - pub fn req( &self ) -> semver::VersionReq + + /// Find a package by its manifest file path + pub fn package_find_by_manifest< 'a, P >( &'a self, manifest_file : P ) -> Option< WorkspacePackageRef< 'a > > + where + P : AsRef< std::path::Path >, { - self.inner.req.clone() + self + .packages() + .find( | &p | p.manifest_file().unwrap().as_ref() == manifest_file.as_ref() ) } - } - - impl From< cargo_metadata::Dependency > for Dependency - { - fn from( inner : cargo_metadata::Dependency ) -> Self + + /// Filter of packages. + pub fn packages_which< 'a >( &'a self ) -> PackagesFilterFormer< 'a > { - Self - { - inner - } + // PackagesFilter::new( self ) + PackagesFilter::former().workspace( self ) } - } - /// Dependencies can come in three kinds - #[ derive( Eq, PartialEq, Debug ) ] - pub enum DependencyKind - { - /// The 'normal' kind - Normal, - /// Those used in tests only - Development, - /// Those used in build scripts only - Build, - /// The 'unknown' kind - Unknown, } - - /// Stores information about current workspace. - #[ derive( Debug, Clone ) ] - pub struct Workspace + + + #[ derive( Former ) ] + // #[ debug ] + #[ allow( missing_debug_implementations ) ] + pub struct PackagesFilter< 'a > { - metadata : Option< cargo_metadata::Metadata >, - manifest_dir : CrateDir, + workspace : &'a Workspace, + crate_dir : Box< dyn PackageFilter >, + manifest_file : Box< dyn PackageFilter >, } - /// Represents errors related to workspace operations. - #[ derive( Debug, Error ) ] - pub enum WorkspaceError + pub trait PackageFilter { - /// Metadata is non. - #[ error( "Metadata is non " ) ] - MetadataError, + fn include( &self, package : WorkspacePackageRef< '_ > ) -> bool; } - impl Workspace + impl Default for Box< dyn PackageFilter > { - /// Load data from current directory - pub fn from_current_path() -> Result< Self > + fn default() -> Self { - let current_path = AbsolutePath::try_from( std::env::current_dir().unwrap_or_default() )?; - let metadata = cargo_metadata::MetadataCommand::new().no_deps().exec().context("fail to load CargoMetadata")?; - Ok( Self - { - metadata : Some( metadata ), - manifest_dir : CrateDir::try_from( current_path )?, - }) + Box::new( PackageFilterAll ) } + } - /// Load data from current directory - pub fn with_crate_dir( crate_dir : CrateDir ) -> Result< Self > + pub struct PackageFilterAll; + impl PackageFilter for PackageFilterAll + { + #[ inline( always ) ] + fn include( &self, _package : WorkspacePackageRef< '_ > ) -> bool { - Ok - ( - Self - { - metadata : Some( cargo_metadata::MetadataCommand::new().current_dir( crate_dir.as_ref() ).no_deps().exec().context( "fail to load CargoMetadata" )? ), - manifest_dir : crate_dir, - } - ) + true } } - impl From< cargo_metadata::Metadata > for Workspace + pub struct PackageFilterCrateDir( CrateDir ); + impl PackageFilter for PackageFilterCrateDir { - fn from( value : cargo_metadata::Metadata ) -> Self + #[ inline( always ) ] + fn include( &self, package : WorkspacePackageRef< '_ > ) -> bool { - let path = value.workspace_root.as_std_path().parent().unwrap().to_path_buf(); - let path = AbsolutePath::try_from( path ).unwrap(); - Self - { - metadata : Some( value ), - manifest_dir : CrateDir::try_from( path ).unwrap(), - } + self.0 == package.crate_dir().unwrap() } } - impl Workspace + impl From< CrateDir > for Box< dyn PackageFilter > { - /// Load data from the current location or from cache - // FIX : Maybe unsafe. Take metadata of workspace in current dir. - pub fn load( &mut self ) -> Result< &mut Self > + #[ inline( always ) ] + fn from( src : CrateDir ) -> Self { - if self.metadata.is_none() - { - let metadata = Self::with_crate_dir( self.manifest_dir.clone() )?.metadata.unwrap(); - _ = self.metadata.insert( metadata ); - } - - Ok( self ) + Box::new( PackageFilterCrateDir( src ) ) } + } - /// Force loads data from the current location - // FIX : Maybe unsafe. Take metadata of workspace in current dir. - pub fn force_reload( &mut self ) -> Result< &mut Self > + pub struct PackageFilterManifestFile( ManifestFile ); + impl PackageFilter for PackageFilterManifestFile + { + #[ inline( always ) ] + fn include( &self, package : WorkspacePackageRef< '_ > ) -> bool { - let metadata = Self::with_crate_dir( self.manifest_dir.clone() )?.metadata.unwrap(); - _ = self.metadata.insert( metadata ); - - Ok( self ) + self.0 == package.manifest_file().unwrap() } } - impl Workspace + impl From< ManifestFile > for Box< dyn PackageFilter > { - /// Returns list of all packages - pub fn packages( &self ) -> Result< Vec< WorkspacePackage >, WorkspaceError > + #[ inline( always ) ] + fn from( src : ManifestFile ) -> Self { - self - .metadata - .as_ref() - .ok_or_else( || WorkspaceError::MetadataError ) - .map( | metadata | metadata.packages.clone() ) - .map( | p | p.into_iter().map( WorkspacePackage::from ).collect() ) + Box::new( PackageFilterManifestFile( src ) ) } + } + impl< 'a > PackagesFilter< 'a > + { - /// Returns the path to workspace root - pub fn workspace_root( &self ) -> Result< &Path, WorkspaceError > + pub fn new( workspace : &'a Workspace ) -> Self { - Ok( self.metadata.as_ref().ok_or_else( || WorkspaceError::MetadataError )?.workspace_root.as_std_path() ) + Self + { + workspace, + crate_dir : Default::default(), + manifest_file : Default::default(), + } } - /// Returns the path to target directory - pub fn target_directory( &self ) -> Result< &Path, WorkspaceError > + #[ inline( always ) ] + pub fn iter( &'a self ) -> impl Iterator< Item = WorkspacePackageRef< 'a > > + Clone { - Ok( self.metadata.as_ref().ok_or_else( || WorkspaceError::MetadataError )?.target_directory.as_std_path() ) - } - /// Return discord url - pub fn discord_url( &self ) -> Result< Option< String >, WorkspaceError > - { - Ok( self.metadata.as_ref().ok_or_else( || WorkspaceError::MetadataError )?.workspace_metadata[ "discord_url" ].as_str().map( | url | url.to_string() ) ) - } + // self + // .workspace + // .packages() + // .find( | &p | p.manifest_file().unwrap().as_ref() == manifest_file.as_ref() ) - /// Return the master branch - pub fn master_branch( &self ) -> Result< Option< String >, WorkspaceError > - { - Ok( self.metadata.as_ref().ok_or_else( || WorkspaceError::MetadataError )?.workspace_metadata.get( "master_branch" ).and_then( | b | b.as_str() ).map( | b | b.to_string() ) ) - } + // let filter_crate_dir = if Some( crate_dir ) = self.crate_dir + // { + // | p | p.manifest_file().unwrap().as_ref() == manifest_file.as_ref() + // } - /// Return the repository url - pub fn repository_url( &self ) -> Result< Option< String >, WorkspaceError > - { - Ok( self.metadata.as_ref().ok_or_else( || WorkspaceError::MetadataError )?.workspace_metadata.get( "repo_url" ).and_then( | b | b.as_str() ).map( | b | b.to_string() ) ) + std::iter::empty() } - /// Return the workspace_name - pub fn workspace_name( &self ) -> Result< Option< String >, WorkspaceError > + } + + impl< 'a > PackagesFilterFormer< 'a > + { + #[ inline( always ) ] + // pub fn find< 'a >( self ) -> impl Iterator< Item = WorkspacePackageRef< 'a > > + Clone + pub fn find( self ) -> Option< WorkspacePackageRef< 'a > > { - Ok( self.metadata.as_ref().ok_or_else( || WorkspaceError::MetadataError )?.workspace_metadata.get( "workspace_name" ).and_then( | b | b.as_str() ).map( | b | b.to_string() ) ) + let formed = self.form(); + + formed + .workspace + .packages() + .find( | &p | + { + if !formed.crate_dir.include( p ) { return false }; + if !formed.manifest_file.include( p ) { return false }; + return true; + }) + .clone() + // .unwrap() + + // let filter_crate_dir = if Some( crate_dir ) = self.crate_dir + // { + // | p | p.manifest_file().unwrap().as_ref() == manifest_file.as_ref() + // } + + // std::iter::empty() } + } - /// Find a package by its manifest file path - pub fn package_find_by_manifest< P >( &self, manifest_path : P ) -> Option< WorkspacePackage > - where - P : AsRef< Path >, + impl Entries for Workspace + { + fn entries( &self ) -> impl IterTrait< '_, SourceFile > { self .packages() - .ok() - .and_then - ( - | packages | - packages - .iter() - .find( | &p | p.manifest_path().as_std_path() == manifest_path.as_ref() ) - .cloned() - ) + .flat_map( | package | package.entries().collect::< Vec< _ > >() ) + .collect::< Vec< _ > >() + .into_iter() } + } - /// Returns a graph of packages. - pub( crate ) fn graph( &self ) -> Graph< String, String > + impl Sources for Workspace + { + fn sources( &self ) -> impl IterTrait< '_, SourceFile > { - let packages = self.packages().unwrap(); - let module_package_filter : Option< Box< dyn Fn( &WorkspacePackage ) -> bool > > = Some - ( - Box::new( move | p | p.publish().is_none() ) - ); - let module_dependency_filter : Option< Box< dyn Fn( &WorkspacePackage, &Dependency ) -> bool > > = Some - ( - Box::new - ( - move | _, d | d.path().is_some() && d.kind() != DependencyKind::Development - ) - ); - let module_packages_map = packages::filter - ( - packages.as_slice(), - packages::FilterMapOptions { package_filter : module_package_filter, dependency_filter : module_dependency_filter }, - ); - - graph::construct( &module_packages_map ).map( | _, x | x.to_string(), | _, x | x.to_string() ) + self + .packages() + .flat_map( | package | package.sources().collect::< Vec< _ > >() ) + .collect::< Vec< _ > >().into_iter() + // .into_iter() } } + } // crate::mod_interface! { + exposed use WorkspaceInitError; exposed use Workspace; - orphan use WorkspaceError; - protected use WorkspacePackage; - protected use Dependency; - protected use DependencyKind; } diff --git a/module/move/willbe/src/entity/workspace_graph.rs b/module/move/willbe/src/entity/workspace_graph.rs new file mode 100644 index 0000000000..c0cc7c29c7 --- /dev/null +++ b/module/move/willbe/src/entity/workspace_graph.rs @@ -0,0 +1,38 @@ +pub( crate ) mod private +{ + use crate::*; + + /// Returns a graph of packages. + pub fn graph( workspace : &Workspace ) -> petgraph::Graph< String, String > + { + let packages = workspace.packages(); + let module_package_filter : Option< Box< dyn Fn( WorkspacePackageRef< '_ > ) -> bool > > = Some + ( + Box::new( move | p | p.publish().is_none() ) + ); + let module_dependency_filter : Option< Box< dyn Fn( WorkspacePackageRef< '_ >, DependencyRef< '_ > ) -> bool > > = Some + ( + Box::new + ( + move | _, d | d.crate_dir().is_some() && d.kind() != DependencyKind::Development + ) + ); + let module_packages_map = packages::filter + ( + // packages.as_slice(), + packages, + packages::FilterMapOptions { package_filter : module_package_filter, dependency_filter : module_dependency_filter }, + ); + + graph::construct( &module_packages_map ).map( | _, x | x.to_string(), | _, x | x.to_string() ) + } +} + +// + +crate::mod_interface! +{ + own use graph; +} + +// xxx : move \ No newline at end of file diff --git a/module/move/willbe/src/entity/workspace_md_extension.rs b/module/move/willbe/src/entity/workspace_md_extension.rs new file mode 100644 index 0000000000..b971c26d97 --- /dev/null +++ b/module/move/willbe/src/entity/workspace_md_extension.rs @@ -0,0 +1,70 @@ +/// Internal namespace. +pub( crate ) mod private +{ + use crate::*; + + /// Md's extension for workspace + pub trait WorkspaceMdExtension + { + /// Return discord url + fn discord_url( &self ) -> Option< String >; + + /// Return the master branch + fn master_branch( &self ) -> Option< String >; + + /// Return the repository url + fn repository_url( &self ) -> Option< String >; + + /// Return the workspace_name + fn workspace_name( &self ) -> Option< String >; + } + + impl WorkspaceMdExtension for Workspace + { + fn discord_url( &self ) -> Option< String > + { + self + .metadata + .workspace_metadata[ "discord_url" ] + .as_str() + .map( | url | url.to_string() ) + } + + fn master_branch( &self ) -> Option< String > + { + self + .metadata + .workspace_metadata + .get( "master_branch" ) + .and_then( | b | b.as_str() ) + .map( | b | b.to_string() ) + } + + fn repository_url( &self ) -> Option< String > + { + self + .metadata + .workspace_metadata + .get( "repo_url" ) + .and_then( | b | b.as_str() ) + .map( | b | b.to_string() ) + } + + fn workspace_name( &self ) -> Option< String > + { + self + .metadata + .workspace_metadata + .get( "workspace_name" ) + .and_then( | b | b.as_str() ) + .map( | b | b.to_string() ) + } + } + +} + + +crate::mod_interface! +{ + own use WorkspaceMdExtension; +} diff --git a/module/move/willbe/src/entity/workspace_package.rs b/module/move/willbe/src/entity/workspace_package.rs new file mode 100644 index 0000000000..6ecada7108 --- /dev/null +++ b/module/move/willbe/src/entity/workspace_package.rs @@ -0,0 +1,212 @@ +mod private +{ + use crate::*; + use macros::kw; + use collection::BTreeMap; + use serde_json::Value; + + use std:: + { + borrow::Cow, + }; + + // xxx : qqq : Deref, DerefMut, AsRef, AsMut + + /// Facade for cargo_metadata::Package + #[ derive( Debug, Clone, Copy ) ] + #[ repr( transparent ) ] + pub struct WorkspacePackageRef< 'a > + { + // #[ serde( flatten ) ] + inner : &'a cargo_metadata::Package, + } + + impl< 'a > From< &'a cargo_metadata::Package > for WorkspacePackageRef< 'a > + { + fn from( inner : &'a cargo_metadata::Package ) -> Self + { + Self + { + inner + } + } + } + + impl< 'a > WorkspacePackageRef< 'a > + { + /// The name field as given in the Cargo.toml + pub fn name( &'a self ) -> &'a str + { + &self.inner.name + } + + /// List of dependencies of this particular package + pub fn dependencies( &'a self ) + -> core::iter::Map + < + core::slice::Iter< 'a, cargo_metadata::Dependency >, + fn( &'a cargo_metadata::Dependency ) -> DependencyRef< 'a >, + > + { + fn dependency_from( dependency : &cargo_metadata::Dependency ) -> DependencyRef< '_ > + { + dependency.into() + } + self.inner.dependencies.iter().map( dependency_from ) + } + + /// Path to the manifest Cargo.toml + pub fn manifest_file( &self ) -> Result< ManifestFile, PathError > + { + self.inner.manifest_path.as_path().try_into() + } + + /// Path to the directory with manifest Cargo.toml. + pub fn crate_dir( &self ) -> Result< CrateDir, PathError > + { + // SAFE because `manifest_path containing the Cargo.toml` + self.inner.manifest_path.as_path().parent().unwrap().try_into() + } + + /// The version field as specified in the Cargo.toml + pub fn version( &self ) -> semver::Version + { + self.inner.version.clone() + } + + /// List of registries to which this package may be published (derived from the publish field). + /// Publishing is unrestricted if None, and forbidden if the Vec is empty. + /// This is always None if running with a version of Cargo older than 1.39. + pub fn publish( &self ) -> Option< &Vec< String > > + { + self.inner.publish.as_ref() + } + + ///Contents of the free form package.metadata section. + /// This contents can be serialized to a struct using serde: + /// ``` rust + /// use serde::Deserialize; + /// use serde_json::json; + /// + /// #[ derive( Debug, Deserialize ) ] + /// struct SomePackageMetadata + /// { + /// some_value : i32, + /// } + /// + /// fn main() + /// { + /// let value = json! + /// ({ + /// "some_value" : 42, + /// }); + /// + /// let package_metadata : SomePackageMetadata = serde_json::from_value( value ).unwrap(); + /// assert_eq!( package_metadata.some_value, 42 ); + /// } + /// ``` + pub fn metadata( &self ) -> &Value + { + &self.inner.metadata + } + + /// The repository URL as specified in the Cargo.toml + pub fn repository( &self ) -> Option< &String > + { + self.inner.repository.as_ref() + } + + /// Features provided by the crate, mapped to the features required by that feature. + pub fn features( &self ) -> &BTreeMap< String, Vec< String > > + { + &self.inner.features + } + } + + impl< 'a > Entries for WorkspacePackageRef< 'a > + { + fn entries( &self ) -> impl IterTrait< '_, SourceFile > + { + self.inner.targets.iter().map( | target | + { + let src_path = &target.src_path; + let source : SourceFile = src_path.try_into().expect( &format!( "Illformed path to source file {src_path}" ) ); + // println!( " -- {:?} {:?}", source, target.kind ); + source + }) + } + } + + impl< 'a > Sources for WorkspacePackageRef< 'a > + { + fn sources( &self ) -> impl IterTrait< '_, SourceFile > + { + use walkdir::WalkDir; + let crate_dir = self.crate_dir().unwrap(); + WalkDir::new( crate_dir ) + .into_iter() + .filter_map( Result::ok ) + .filter( | e | e.path().extension().map_or( false, | ext | ext == "rs" ) ) + .map( | e | SourceFile::try_from( e.path() ).unwrap() ) + .collect::< Vec< _ > >() + .into_iter() + } + } + + impl< 'a > CodeItems for WorkspacePackageRef< 'a > + { + fn items( &self ) -> impl IterTrait< '_, syn::Item > + { + self + .sources() + .flat_map( | source | source.items().collect::< Vec< _ > >().into_iter() ) + .collect::< Vec< _ > >().into_iter() + } + } + + impl< 'a > AsCode for WorkspacePackageRef< 'a > + { + fn as_code< 'b >( &'b self ) -> std::io::Result< Cow< 'b, str > > + { + let mut results : Vec< String > = Vec::new(); + // zzz : introduce formatter + + for source in self.sources() + { + let code = source.as_code()?.into_owned(); + let mut filename = source + .as_ref() + .with_extension( "" ) + .file_name() + .expect( &format!( "Cant get file name of path {}", source.as_ref().display() ) ) + .to_string_lossy() + .replace( ".", "_" ); + + if kw::is( &filename ) + { + filename.push_str( "_rs" ); + } + + // qqq : xxx : use callbacks instead of expect + + results.push( format!( "// === Begin of File {}", source.as_ref().display() ) ); + results.push( format!( "mod {}\n{{\n", filename ) ); + results.push( code ); + results.push( "\n}".to_string() ); + results.push( format!( "// === End of File {}", source.as_ref().display() ) ); + + } + + let joined = results.join( "\n" ); + Ok( Cow::Owned( joined ) ) + } + } + +} + +// + +crate::mod_interface! +{ + exposed use WorkspacePackageRef; +} diff --git a/module/move/willbe/src/lib.rs b/module/move/willbe/src/lib.rs index 3f0adc2fe1..df3c1c5c4b 100644 --- a/module/move/willbe/src/lib.rs +++ b/module/move/willbe/src/lib.rs @@ -3,10 +3,7 @@ #![ doc( html_root_url = "https://docs.rs/willbe/" ) ] #![ doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/", "Readme.md" ) ) ] -use mod_interface::mod_interface; -/// Micro wtools -pub mod wtools; -use wtools::*; +pub use mod_interface::mod_interface; /// Internal namespace. pub( crate ) mod private @@ -18,14 +15,14 @@ pub( crate ) mod private /// It then terminates the program with an exit code of 1 to indicate an error due to the lack of input. /// /// Do not support interactive mode. - pub fn run( args : Vec< String > ) -> Result< (), wtools::error::for_app::Error > + pub fn run( args : Vec< String > ) -> Result< (), error::untyped::Error > { #[ cfg( feature = "tracing" ) ] { tracing_subscriber::fmt().pretty().init(); } - let args = args.into_iter().skip( 1 ).collect::< Vec< String > >(); + let args : Vec< String > = args.into_iter().skip( 1 ).collect(); let ca = command::ca() .help_variants( [ wca::HelpVariants::General, wca::HelpVariants::SubjectCommand ] ) @@ -44,12 +41,13 @@ pub( crate ) mod private } } + } mod_interface! { - protected use run; + own use run; /// Entities of which spaces consists of. layer entity; diff --git a/module/move/willbe/src/tool/_path.rs b/module/move/willbe/src/tool/_path.rs deleted file mode 100644 index a8209366f7..0000000000 --- a/module/move/willbe/src/tool/_path.rs +++ /dev/null @@ -1,170 +0,0 @@ -/// Internal namespace. -pub( crate ) mod private -{ - use std::path::{ Path, PathBuf }; - use std::time::{ SystemTime, UNIX_EPOCH }; - use cargo_metadata::camino::{ Utf8Path, Utf8PathBuf }; - - /// Absolute path. - #[ derive( Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash ) ] - pub struct AbsolutePath( PathBuf ); - - impl TryFrom< &str > for AbsolutePath - { - type Error = std::io::Error; - - fn try_from( value : &str ) -> Result< Self, Self::Error > - { - let value = PathBuf::from( value ); - Ok( Self( canonicalize( value )? ) ) - } - } - - impl TryFrom< String > for AbsolutePath - { - type Error = std::io::Error; - - fn try_from( value : String ) -> Result< Self, Self::Error > - { - let value = PathBuf::from( value ); - Ok( Self( canonicalize( value )? ) ) - } - } - - impl TryFrom< PathBuf > for AbsolutePath - { - type Error = std::io::Error; - - fn try_from( value : PathBuf ) -> Result< Self, Self::Error > - { - Ok( Self( canonicalize( value )? ) ) - } - } - - impl TryFrom< &Path > for AbsolutePath - { - type Error = std::io::Error; - - fn try_from( value : &Path ) -> Result< Self, Self::Error > - { - Ok( Self( canonicalize( value )? ) ) - } - } - - impl TryFrom< Utf8PathBuf > for AbsolutePath - { - type Error = std::io::Error; - - fn try_from( value : Utf8PathBuf ) -> Result< Self, Self::Error > - { - AbsolutePath::try_from( value.as_std_path() ) - } - } - - impl TryFrom< &Utf8Path > for AbsolutePath - { - type Error = std::io::Error; - - fn try_from( value : &Utf8Path ) -> Result< Self, Self::Error > - { - AbsolutePath::try_from( value.as_std_path() ) - } - } - - impl AsRef< Path > for AbsolutePath - { - fn as_ref( &self ) -> &Path - { - self.0.as_ref() - } - } - - impl AbsolutePath - { - /// Returns the Path without its final component, if there is one. - /// Returns None if the path terminates in a root or prefix, or if it's the empty string. - pub fn parent( &self ) -> Option< AbsolutePath > - { - self.0.parent().map( PathBuf::from ).map( AbsolutePath ) - } - - /// Creates an owned `AbsolutePath` with path adjoined to self. - pub fn join< P >( &self, path : P ) -> AbsolutePath - where - P : AsRef< Path >, - { - Self::try_from( self.0.join( path ) ).unwrap() - } - } - - // qqq : for Petro : for Bohdan : bad. move out - - /// Check if path has a glob. - #[ allow( dead_code ) ] - fn glob_is( path : &str ) -> bool - { - let glob_chars = "*?[{"; - let mut last_char = ' '; - for char in path.chars() - { - if last_char != '\\' && glob_chars.contains( char ) - { - return true; - } - - last_char = char; - } - - false - } - - /// Returns the canonical, absolute form of the path with all intermediate components normalized and symbolic links resolved. - pub fn canonicalize( path : impl AsRef< Path > ) -> std::io::Result< PathBuf > - { - let path = path.as_ref().canonicalize()?; - - // In Windows the regular/legacy paths (C :\foo) are supported by all programs, but have lots of bizarre restrictions for backwards compatibility with MS-DOS. - // And there are Windows NT UNC paths (\\?\C :\foo), which are more robust and with fewer gotchas, but are rarely supported by Windows programs. Even Microsoft’s own! - // - // https://github.com/rust-lang/rust/issues/42869 - #[ cfg( target_os = "windows" ) ] - let path = - { - const VERBATIM_PREFIX : &str = r#"\\?\"#; - let p = path.display().to_string(); - if p.starts_with( VERBATIM_PREFIX ) - { - PathBuf::from( &p[ VERBATIM_PREFIX.len() .. ] ) - } - else - { - path.into() - } - }; - - Ok( path ) - } - - /// Generate name based on system time - pub fn unique_folder_name() -> crate::wtools::error::Result< String > - { - let timestamp = SystemTime::now() - .duration_since( UNIX_EPOCH )? - .as_nanos(); - - Ok( format!( "{}", timestamp ) ) - } - -} - -crate::mod_interface! -{ - // qqq : remove this? - // protected use glob_is; - protected use canonicalize; - protected use unique_folder_name; - - protected use AbsolutePath; -} - -// qqq : for Petro : for Bohdan : rid off this file. use proper_path_tools diff --git a/module/move/willbe/src/tool/cargo.rs b/module/move/willbe/src/tool/cargo.rs index d24ac23565..71590ecd45 100644 --- a/module/move/willbe/src/tool/cargo.rs +++ b/module/move/willbe/src/tool/cargo.rs @@ -1,25 +1,59 @@ +/// Internal namespace. mod private { - use std::ffi::OsString; - use crate::*; + #[ allow( unused_imports ) ] + use crate::tool::*; + use std::ffi::OsString; use std::path::PathBuf; - use error_tools::err; - use error_tools::for_app::format_err; + use error::err; + use error::untyped::format_err; use former::Former; - use process_tools::process::*; - use wtools::error::Result; + use process_tools::process; + // use process_tools::process::*; + // qqq : for Bohdan : bad + // use error::Result; + // qqq : group dependencies + + // qqq : for Bohdan : bad : tools can't depend on entitties! + use crate::channel::Channel; + + // aaa : documentation /// aaa : documented - /// Represents pack options + /// Represents options for packaging a project. + /// + /// The `PackOptions` struct encapsulates various options that can be configured when packaging a project, + /// including the path to the project, the distribution channel, and various flags for controlling the behavior of the packaging process. #[ derive( Debug, Former, Clone ) ] pub struct PackOptions { + /// The path to the project to be packaged. + /// + /// This field specifies the file system path where the project is located. pub( crate ) path : PathBuf, - #[ former( default = false ) ] + /// The distribution channel for the packaging project. + /// + /// This field specifies the channel through which the packaged project will be distributed. + /// + pub( crate ) channel : Channel, + /// Flag indicating whether to allow packaging even if the working directory is dirty. + /// + /// This field is set to `true` by default, meaning that packaging will proceed even if there are uncommitted changes. + #[ former( default = true ) ] pub( crate ) allow_dirty : bool, + // qqq : rename to checking_changes + /// Flag indicating whether to skip verification checks. #[ former( default = false ) ] - pub( crate ) no_verify : bool, + // aaa : don't abuse negative form, rename to checking_consistency + // renamed and changed logic + pub( crate ) checking_consistency : bool, + /// An optional temporary path to be used during packaging. + /// + /// This field may contain a path to a temporary directory that will be used during the packaging process. pub( crate ) temp_path : Option< PathBuf >, + /// Flag indicating whether to perform a dry run. + /// + /// This field specifies whether the packaging process should be a dry run, meaning that no actual changes will be made. pub( crate ) dry : bool, } @@ -36,10 +70,10 @@ mod private { fn to_pack_args( &self ) -> Vec< String > { - [ "package".to_string() ] + [ "run".to_string(), self.channel.to_string(), "cargo".into(), "package".into() ] .into_iter() .chain( if self.allow_dirty { Some( "--allow-dirty".to_string() ) } else { None } ) - .chain( if self.no_verify { Some( "--no-verify".to_string() ) } else { None } ) + .chain( if !self.checking_consistency { Some( "--no-verify".to_string() ) } else { None } ) .chain( self.temp_path.clone().map( | p | vec![ "--target-dir".to_string(), p.to_string_lossy().into() ] ).into_iter().flatten() ) .collect() } @@ -58,15 +92,17 @@ mod private track_caller, tracing::instrument( fields( caller = ?{ let x = std::panic::Location::caller(); ( x.file(), x.line() ) } ) ) )] - pub fn pack( args : PackOptions ) -> Result< Report > + // qqq : should be typed error, apply err_with + // qqq : use typed error + pub fn pack( args : PackOptions ) -> error::untyped::Result< process::Report > { - let ( program, options ) = ( "cargo", args.to_pack_args() ); + let ( program, options ) = ( "rustup", args.to_pack_args() ); if args.dry { Ok ( - Report + process::Report { command : format!( "{program} {}", options.join( " " ) ), out : String::new(), @@ -78,7 +114,7 @@ mod private } else { - Run::former() + process::Run::former() .bin_path( program ) .args( options.into_iter().map( OsString::from ).collect::< Vec< _ > >() ) .current_path( args.path ) @@ -112,7 +148,7 @@ mod private fn as_publish_args( &self ) -> Vec< String > { let target_dir = self.temp_path.clone().map( | p | vec![ "--target-dir".to_string(), p.to_string_lossy().into() ] ); - [ "publish".to_string() ].into_iter().chain( target_dir.into_iter().flatten() ).collect::< Vec< String > >() + [ "publish".to_string() ].into_iter().chain( target_dir.into_iter().flatten() ).collect() } } @@ -123,7 +159,8 @@ mod private track_caller, tracing::instrument( fields( caller = ?{ let x = std::panic::Location::caller(); ( x.file(), x.line() ) } ) ) )] - pub fn publish( args : PublishOptions ) -> Result< Report > + pub fn publish( args : PublishOptions ) -> error::untyped::Result< process::Report > + // qqq : use typed error { let ( program, arguments) = ( "cargo", args.as_publish_args() ); @@ -131,7 +168,7 @@ mod private { Ok ( - Report + process::Report { command : format!( "{program} {}", arguments.join( " " ) ), out : String::new(), @@ -144,10 +181,10 @@ mod private else { let mut results = Vec::with_capacity( args.retry_count + 1 ); - let run_args = arguments.into_iter().map( OsString::from ).collect::< Vec< _ > >(); + let run_args : Vec< _ > = arguments.into_iter().map( OsString::from ).collect(); for _ in 0 .. args.retry_count + 1 { - let result = Run::former() + let result = process::Run::former() .bin_path( program ) .args( run_args.clone() ) .current_path( &args.path ) @@ -164,7 +201,7 @@ mod private } else { - Err( results.remove( 0 ) ).map_err( | report | err!( report.to_string() ) ) + Err( results.remove( 0 ) ).map_err( | report | err!( report.to_string() ) ) } } } @@ -174,10 +211,10 @@ mod private crate::mod_interface! { - protected use pack; - protected use publish; + own use pack; + own use publish; - protected use PublishOptions; - protected use PackOptions; + own use PublishOptions; + own use PackOptions; -} +} \ No newline at end of file diff --git a/module/move/willbe/src/tool/collection.rs b/module/move/willbe/src/tool/collection.rs new file mode 100644 index 0000000000..cf1cf710c0 --- /dev/null +++ b/module/move/willbe/src/tool/collection.rs @@ -0,0 +1,12 @@ +/// Internal namespace. +pub( crate ) mod private +{ +} + +crate::mod_interface! +{ + + use ::collection_tools; + own use ::collection_tools::own::*; + +} diff --git a/module/move/willbe/src/tool/error.rs b/module/move/willbe/src/tool/error.rs new file mode 100644 index 0000000000..2647ee56ff --- /dev/null +++ b/module/move/willbe/src/tool/error.rs @@ -0,0 +1,21 @@ +/// Internal namespace. +#[ allow( unused_imports ) ] +pub( crate ) mod private +{ + use crate::tool::*; + use ::error_tools::own::*; + +} + +crate::mod_interface! +{ + // #![ debug ] + + use ::error_tools; + own use ::error_tools::own::*; + + // exposed use ErrWith; + // exposed use ResultWithReport; + // exposed use ::error_tools::Result; + +} diff --git a/module/move/willbe/src/tool/files.rs b/module/move/willbe/src/tool/files.rs index 8dfbc4f78c..a8dc67350b 100644 --- a/module/move/willbe/src/tool/files.rs +++ b/module/move/willbe/src/tool/files.rs @@ -1,15 +1,17 @@ - /// Internal namespace. pub( crate ) mod private { + #[ allow( unused_imports ) ] + use crate::tool::*; + use std::path::{ Path, PathBuf }; /// /// Find paths. /// - /* rrr : Dmytro : dubious prototype */ + /* xxx : check */ pub fn find< P, S >( base_dir : P, patterns : &[ S ] ) -> Vec< PathBuf > where P : AsRef< Path >, @@ -21,7 +23,7 @@ pub( crate ) mod private .into_iter() .filter_map( Result::ok ) .map( | s | s.path().to_path_buf() ) - .collect::< Vec< PathBuf > >() + .collect() } /// Check if path is valid. @@ -35,6 +37,6 @@ pub( crate ) mod private crate::mod_interface! { - protected use valid_is; + own use valid_is; orphan use find; } diff --git a/module/move/willbe/src/tool/git.rs b/module/move/willbe/src/tool/git.rs index c90dc08109..828e4d3c64 100644 --- a/module/move/willbe/src/tool/git.rs +++ b/module/move/willbe/src/tool/git.rs @@ -1,11 +1,14 @@ +/// Internal namespace. mod private { - use crate::*; + #[ allow( unused_imports ) ] + use crate::tool::*; + use std::ffi::OsString; use std::path::Path; use process_tools::process::*; - use wtools::error::Result; - use wtools::error::err; + use error::err; + // qqq : group dependencies /// Adds changes to the Git staging area. /// @@ -18,8 +21,11 @@ mod private /// /// # Returns : /// Returns a result containing a report indicating the result of the operation. + // qqq : should be typed error, apply err_with #[ cfg_attr( feature = "tracing", tracing::instrument( skip( path, objects ), fields( path = %path.as_ref().display() ) ) ) ] - pub fn add< P, Os, O >( path : P, objects : Os, dry : bool ) -> Result< Report > + pub fn add< P, Os, O >( path : P, objects : Os, dry : bool ) + -> error::untyped::Result< Report > + // qqq : use typed error where P : AsRef< Path >, Os : AsRef< [ O ] >, @@ -27,7 +33,8 @@ mod private { let objects = objects.as_ref().iter().map( | x | x.as_ref() ); - let ( program, args ) = ( "git", Some( "add" ).into_iter().chain( objects ).collect::< Vec< _ > >() ); + // qqq : for Bohdan : don't enlarge length of lines artificially + let ( program, args ) : ( _, Vec< _ > ) = ( "git", Some( "add" ).into_iter().chain( objects ).collect() ); if dry { @@ -65,8 +72,10 @@ mod private /// /// # Returns : /// Returns a result containing a report indicating the result of the operation. + // qqq : should be typed error, apply err_with #[ cfg_attr( feature = "tracing", tracing::instrument( skip( path, message ), fields( path = %path.as_ref().display(), message = %message.as_ref() ) ) ) ] - pub fn commit< P, M >( path : P, message : M, dry : bool ) -> Result< Report > + pub fn commit< P, M >( path : P, message : M, dry : bool ) -> error::untyped::Result< Report > + // qqq : don't use 1-prameter Result where P : AsRef< Path >, M : AsRef< str >, @@ -108,8 +117,12 @@ mod private /// /// # Returns : /// Returns a result containing a report indicating the result of the operation. + + // qqq : should be typed error, apply err_with + #[ cfg_attr( feature = "tracing", tracing::instrument( skip( path ), fields( path = %path.as_ref().display() ) ) ) ] - pub fn push< P >( path : P, dry : bool ) -> Result< Report > + pub fn push< P >( path : P, dry : bool ) -> error::untyped::Result< Report > + // qqq : don't use 1-prameter Result where P : AsRef< Path >, { @@ -138,7 +151,7 @@ mod private .run().map_err( | report | err!( report.to_string() ) ) } } - + /// This function is a wrapper around the `git reset` command. /// /// # Args : @@ -150,13 +163,18 @@ mod private /// /// # Returns : /// This function returns a `Result` containing a `Report` if the command is executed successfully. The `Report` contains the command executed, the output -// git reset command wrapper - pub fn reset< P >( path : P, hard : bool, commits_count : usize, dry : bool ) -> Result< Report > + /// git reset command wrapper + + // qqq : should be typed error, apply err_with + + pub fn reset< P >( path : P, hard : bool, commits_count : usize, dry : bool ) + -> error::untyped::Result< Report > + // qqq : don't use 1-prameter Result where P : AsRef< Path >, { if commits_count < 1 { return Err( err!( "Cannot reset, the count of commits must be greater than 0" ) ) } - let ( program, args ) = + let ( program, args ) : ( _, Vec< _ > ) = ( "git", Some( "reset" ) @@ -164,7 +182,7 @@ mod private .chain( if hard { Some( "--hard" ) } else { None } ) .map( String::from ) .chain( Some( format!( "HEAD~{}", commits_count ) ) ) - .collect::< Vec< _ > >() + .collect() ); if dry @@ -200,7 +218,11 @@ mod private /// # Returns /// /// A `Result` containing a `Report`, which represents the result of the command execution. - pub fn ls_remote_url< P >( path : P ) -> Result< Report > + + // qqq : should be typed error, apply err_with + // qqq : don't use 1-prameter Result + + pub fn ls_remote_url< P >( path : P ) -> error::untyped::Result< Report > where P : AsRef< Path >, { @@ -218,9 +240,9 @@ mod private crate::mod_interface! { - protected use add; - protected use commit; - protected use push; - protected use reset; - protected use ls_remote_url; + own use add; + own use commit; + own use push; + own use reset; + own use ls_remote_url; } diff --git a/module/move/willbe/src/tool/graph.rs b/module/move/willbe/src/tool/graph.rs index db91c15afb..b322b76025 100644 --- a/module/move/willbe/src/tool/graph.rs +++ b/module/move/willbe/src/tool/graph.rs @@ -1,17 +1,20 @@ /// Internal namespace. pub( crate ) mod private { + #[ allow( unused_imports ) ] use crate::*; + // use crate::tool::*; + // qqq : bad : for Bohdan : asterist only crate::* and prelude::* + use std:: { ops::Index, fmt::Debug, hash::Hash, - collections::{ HashMap, HashSet } }; - use std::collections::VecDeque; - use std::path::PathBuf; + use collection::{ HashMap, HashSet, VecDeque }; + use path::PathBuf; use petgraph:: { graph::Graph, @@ -20,9 +23,13 @@ pub( crate ) mod private use petgraph::graph::NodeIndex; use petgraph::prelude::*; - use error_tools::for_lib::Error; - use error::Result; + use error:: + { + typed::Error, + }; + use package::{ Package, publish_need }; + // qqq : for Bohdan : bad : tools can't depend on entitties! #[ derive( Debug, Error ) ] pub enum GraphError< T : Debug > @@ -40,8 +47,11 @@ pub( crate ) mod private /// The graph with all accepted packages pub fn construct< PackageIdentifier > ( - packages : &HashMap< PackageIdentifier, - HashSet< PackageIdentifier > > + packages : &HashMap + < + PackageIdentifier, + HashSet< PackageIdentifier >, + > ) -> Graph< &PackageIdentifier, &PackageIdentifier > where @@ -96,7 +106,7 @@ pub( crate ) mod private .iter() .rev() .map( | dep_idx | ( *graph.node_weight( *dep_idx ).unwrap() ).clone() ) - .collect::< Vec< _ > >() + .collect() ), Err( index ) => Err( GraphError::Cycle( ( *graph.index( index.node_id() ) ).clone() ) ), // aaa : for Bohdan : bad, make proper error handling @@ -116,37 +126,37 @@ pub( crate ) mod private pub fn topological_sort_with_grouping< 'a, PackageIdentifier : Clone + std::fmt::Debug > ( graph : Graph< &'a PackageIdentifier, &'a PackageIdentifier > - ) - -> Vec< Vec< PackageIdentifier > > + ) + -> Vec< Vec< PackageIdentifier > > { let mut in_degree = HashMap::new(); - for node in graph.node_indices() + for node in graph.node_indices() { in_degree.insert( node, graph.neighbors_directed( node, Incoming ).count() ); } let mut roots = VecDeque::new(); - for ( node, °ree ) in in_degree.iter() + for ( node, °ree ) in in_degree.iter() { - if degree == 0 + if degree == 0 { roots.push_back( *node ); } } let mut result = Vec::new(); - while !roots.is_empty() + while !roots.is_empty() { let mut next_roots = Vec::new(); let mut group = Vec::new(); - while let Some( node ) = roots.pop_front() + while let Some( node ) = roots.pop_front() { group.push( node ); - for edge in graph.neighbors( node ) + for edge in graph.neighbors( node ) { let degree = in_degree.get_mut( &edge ).unwrap(); *degree -= 1; - if *degree == 0 + if *degree == 0 { next_roots.push( edge ); } @@ -158,12 +168,12 @@ pub( crate ) mod private result .into_iter() .map - ( - | vec | + ( + | vec | vec .iter() .map( | dep_idx | ( *graph.node_weight( *dep_idx ).unwrap() ).clone() ) - .collect() + .collect() ) .rev() .collect() @@ -236,14 +246,17 @@ pub( crate ) mod private /// # Returns /// /// A new `Graph` with the nodes that are not required to be published removed. - pub fn remove_not_required_to_publish - ( - package_map : &HashMap< String, Package >, - graph : &Graph< String, String >, - roots : &[ String ], + + // qqq : for Bohdan : typed error + pub fn remove_not_required_to_publish< 'a > + ( + package_map : &HashMap< String, Package< 'a > >, + graph : &Graph< String, String >, + roots : &[ String ], temp_path : Option< PathBuf >, - ) - -> Result< Graph< String, String > > + ) + -> error::untyped::Result< Graph< String, String > > + // qqq : use typed error! { let mut nodes = HashSet::new(); let mut cleared_graph = Graph::new(); @@ -264,9 +277,9 @@ pub( crate ) mod private } let package = package_map.get( &graph[ n ] ).unwrap(); _ = cargo::pack - ( + ( cargo::PackOptions::former() - .path( package.crate_dir().absolute_path().as_ref().to_path_buf() ) + .path( package.crate_dir().absolute_path() ) .option_temp_path( temp_path.clone() ) .dry( false ) .allow_dirty( true ) @@ -304,9 +317,9 @@ pub( crate ) mod private crate::mod_interface! { - protected use construct; - protected use toposort; - protected use topological_sort_with_grouping; - protected use subgraph; - protected use remove_not_required_to_publish; + own use construct; + own use toposort; + own use topological_sort_with_grouping; + own use subgraph; + own use remove_not_required_to_publish; } diff --git a/module/move/willbe/src/tool/http.rs b/module/move/willbe/src/tool/http.rs index 4cd557ef59..6819edf305 100644 --- a/module/move/willbe/src/tool/http.rs +++ b/module/move/willbe/src/tool/http.rs @@ -1,7 +1,8 @@ /// Internal namespace. pub( crate ) mod private { - use crate::*; + #[ allow( unused_imports ) ] + use crate::tool::*; use std:: { @@ -9,13 +10,14 @@ pub( crate ) mod private fmt::Write, time::Duration }; - use wtools::error::{ for_app::Context, Result }; + use error::{ untyped::Context }; use ureq::Agent; /// /// Get data of remote package. /// - pub fn download< 'a >( name : &'a str, version : &'a str ) -> Result< Vec< u8 > > + // qqq : typed error + pub fn download< 'a >( name : &'a str, version : &'a str ) -> error::untyped::Result< Vec< u8 > > { let agent : Agent = ureq::AgentBuilder::new() .timeout_read( Duration::from_secs( 5 ) ) diff --git a/module/move/willbe/src/tool/iter.rs b/module/move/willbe/src/tool/iter.rs new file mode 100644 index 0000000000..b9cd5f3279 --- /dev/null +++ b/module/move/willbe/src/tool/iter.rs @@ -0,0 +1,12 @@ +/// Internal namespace. +pub( crate ) mod private +{ +} + +// + +crate::mod_interface! +{ + use ::iter_tools; + own use ::iter_tools::own::*; +} diff --git a/module/move/willbe/src/tool/macros.rs b/module/move/willbe/src/tool/macros.rs new file mode 100644 index 0000000000..155ff49386 --- /dev/null +++ b/module/move/willbe/src/tool/macros.rs @@ -0,0 +1,12 @@ +/// Internal namespace. +pub( crate ) mod private +{ +} + +crate::mod_interface! +{ + + use ::macro_tools; + own use ::macro_tools::own::*; + +} diff --git a/module/move/willbe/src/tool/mod.rs b/module/move/willbe/src/tool/mod.rs index 8f8e77635e..060a323c2f 100644 --- a/module/move/willbe/src/tool/mod.rs +++ b/module/move/willbe/src/tool/mod.rs @@ -1,17 +1,37 @@ crate::mod_interface! { - /// Make sha-1 hash for data. - layer sha; - orphan use super::sha; + /// Interaction module with the `cargo` utilities. + layer cargo; + orphan use super::cargo; + + /// Function and structures to work with collections. + layer collection; + orphan use super::collection; + + /// Errors handling. + layer error; + orphan use super::error; /// Operate over files. layer files; orphan use super::files; - + + /// Http requests. + layer http; + orphan use super::http; + + /// Iterating things. + layer iter; + orphan use super::iter; + /// Work with paths. - layer _path; - orphan use super::_path; + layer macros; + orphan use super::macros; + + /// Work with paths. + layer path; + orphan use super::path; /// Tools for working with dependencies graph. layer graph; @@ -25,10 +45,6 @@ crate::mod_interface! layer git; orphan use super::git; - /// Interaction module with the `cargo` utilities. - layer cargo; - orphan use super::cargo; - /// The parse function parses an input string into a HashMap where the keys are String and the values are of type Value. layer query; orphan use super::query; @@ -36,4 +52,19 @@ crate::mod_interface! /// Tools for parsing and extracting information from url. layer url; orphan use super::url; -} + + /// Tools for printing a tree + layer tree; + orphan use super::tree; + + /// Repository tools. + layer repository; + orphan use super::repository; + + exposed use ::former:: + { + Former, + Assign, + }; + +} \ No newline at end of file diff --git a/module/move/willbe/src/tool/path.rs b/module/move/willbe/src/tool/path.rs new file mode 100644 index 0000000000..b2abea76e1 --- /dev/null +++ b/module/move/willbe/src/tool/path.rs @@ -0,0 +1,12 @@ +/// Internal namespace. +pub( crate ) mod private +{ +} + +crate::mod_interface! +{ + + use ::proper_path_tools; + own use ::proper_path_tools::own::*; + +} diff --git a/module/move/willbe/src/tool/query.rs b/module/move/willbe/src/tool/query.rs index 6686858821..3528d887ae 100644 --- a/module/move/willbe/src/tool/query.rs +++ b/module/move/willbe/src/tool/query.rs @@ -1,14 +1,19 @@ +/// Internal namespace. mod private { - use crate::*; + #[ allow( unused_imports ) ] + use crate::tool::*; use std:: { str::FromStr, - collections::HashMap }; - use error_tools::for_app::bail; - use wtools::error::{ for_app::{ Error }, Result }; + use error:: + { + untyped::{ Error, bail }, + // Result, + }; + use collection::HashMap; #[ derive( Debug, PartialEq, Eq, Clone ) ] /// Parser value enum @@ -143,7 +148,8 @@ mod private /// expected_map.insert( "key".to_string(), Value::String( r#"hello\'test\'test"#.into() ) ); /// assert_eq!( parse( r#"{ key : 'hello\'test\'test' }"# ).unwrap().into_map( vec![] ), expected_map ); /// ``` - pub fn parse( input_string : &str ) -> Result< ParseResult > + // qqq : use typed error + pub fn parse( input_string : &str ) -> error::untyped::Result< ParseResult > { if input_string.len() < 2 { @@ -194,7 +200,8 @@ mod private result } - fn parse_to_map(input : Vec< String > ) -> Result< HashMap< String, Value > > + // qqq : use typed error + fn parse_to_map(input : Vec< String > ) -> error::untyped::Result< HashMap< String, Value > > { let mut map = HashMap::new(); for line in input @@ -245,7 +252,8 @@ mod private Ok( map ) } - fn parse_to_vec( input : Vec< String > ) -> Result< Vec< Value > > + // qqq : use typed error + fn parse_to_vec( input : Vec< String > ) -> error::untyped::Result< Vec< Value > > { Ok( input.into_iter().filter_map( | w | Value::from_str( w.trim() ).ok() ).collect() ) } @@ -253,7 +261,7 @@ mod private crate::mod_interface! { - protected use parse; - protected use Value; - protected use ParseResult; + own use parse; + own use Value; + own use ParseResult; } diff --git a/module/move/willbe/src/tool/repository.rs b/module/move/willbe/src/tool/repository.rs new file mode 100644 index 0000000000..9ddb691f03 --- /dev/null +++ b/module/move/willbe/src/tool/repository.rs @@ -0,0 +1,61 @@ +/// Internal namespace. +pub( crate ) mod private +{ + #[ allow( unused_imports ) ] + use crate::tool::*; + + /// Searches for a README file in specific subdirectories of the given directory path. + /// + /// This function attempts to find a README file in the following subdirectories: ".github", + /// the root directory, and "./docs". It returns the path to the first found README file, or + /// `None` if no README file is found in any of these locations. + pub fn readme_path( dir_path : &std::path::Path ) -> Result< std::path::PathBuf, std::io::Error > + { + if let Some( path ) = readme_in_dir_find( &dir_path.join( ".github" ) ) + { + Ok( path ) + } + else if let Some( path ) = readme_in_dir_find( dir_path ) + { + Ok( path ) + } + else if let Some( path ) = readme_in_dir_find( &dir_path.join( "docs" ) ) + { + Ok( path ) + } + else + { + Err( std::io::Error::new( std::io::ErrorKind::NotFound, format!( "Fail to find README.md at {}", &dir_path.display() ) ) ) + } + } + + /// Searches for a file named "readme.md" in the specified directory path. + /// + /// Given a directory path, this function searches for a file named "readme.md" in the specified + /// directory. + fn readme_in_dir_find( path : &std::path::Path ) -> Option< std::path::PathBuf > + { + std::fs::read_dir( path ) + .ok()? + .filter_map( Result::ok ) + .filter( | p | p.path().is_file() ) + .filter_map( | f | + { + let l_f = f.file_name().to_ascii_lowercase(); + if l_f == "readme.md" + { + return Some( f.file_name() ) + } + None + }) + .max() + .map( std::path::PathBuf::from ) + } + +} + + +crate::mod_interface! +{ + own use readme_path; +} diff --git a/module/move/willbe/src/tool/sha.rs b/module/move/willbe/src/tool/sha.rs deleted file mode 100644 index 5bb60bed23..0000000000 --- a/module/move/willbe/src/tool/sha.rs +++ /dev/null @@ -1,26 +0,0 @@ -/// Internal namespace. -pub( crate ) mod private -{ - use sha1::{ Sha1, Digest }; - - // zzz : not used - - /// - /// Make sha-1 hash for data. - /// - - pub fn hash( data : &[ u8 ] ) -> Vec< u8 > - { - let mut hasher = Sha1::new(); - hasher.update( data ); - let result = hasher.finalize(); - result.to_vec() - } -} - -// - -crate::mod_interface! -{ - orphan use hash; -} diff --git a/module/move/willbe/src/tool/template.rs b/module/move/willbe/src/tool/template.rs index ae07683d4b..affe4072be 100644 --- a/module/move/willbe/src/tool/template.rs +++ b/module/move/willbe/src/tool/template.rs @@ -1,49 +1,135 @@ +/// Internal namespace. mod private { - use std::collections::BTreeMap; - use std::fs; - use error_tools::for_app::Context; - use error_tools::Result; - use former::Former; - use wca::Props; - use std::path::Path; - use std::path::PathBuf; - use wca::Value; - use std::collections::HashMap; - - // qqq : for Viktor : is that trait really necessary? + #[ allow( unused_imports ) ] + use crate::tool::*; + + use std:: + { + fs, + path:: + { + Path, + PathBuf + }, + }; + use error::untyped::Context; + + // qqq : for Nikita : is that trait really necessary? // Template - remove // DeployTemplate - move here // DeployTemplateFiles - remove - /// Trait for creating a template for a file structure. - pub trait Template< F > : Sized - where - F : TemplateFiles + Default + /// Template for creating deploy files. + /// + /// Includes terraform deploy options to GCP, and Hetzner, + /// a Makefile for useful commands, and a key directory. + #[ derive( Debug ) ] + pub struct TemplateHolder { - /// Creates all files in the template. + /// Files of the template. + pub files : Vec< TemplateFileDescriptor >, + /// Parameters definitions. + pub parameters : TemplateParameters, + /// The values associated with the template. + pub values : TemplateValues, + } + + impl TemplateFiles for Vec< TemplateFileDescriptor > {} + + // qqq : for Viktor : why DeployTemplate can't be part of template.rs? + + impl TemplateHolder + { + /// Creates all files in the specified path using the template values. + /// + /// # Parameters /// - /// Path is the base path for the template to be created in. - fn create_all( self, path : &Path ) -> Result< () >; + /// - `path`: A reference to the path where the files will be created. + /// + /// # Returns + /// + /// A `Result` which is `Ok` if the files are created successfully, or an `Err` otherwise. + pub fn create_all( self, path : &path::Path ) -> error::untyped::Result< () > // qqq : use typed error + { + self.files.create_all( path, &self.values ) + } + + /// Returns a reference to the template parameters. + /// + /// # Returns + /// + /// A reference to `TemplateParameters`. + pub fn parameters( &self ) -> &TemplateParameters + { + &self.parameters + } + + /// Sets the template values. + /// + /// # Parameters + /// + /// - `values`: The new `TemplateValues` to be set. + pub fn set_values( &mut self, values : TemplateValues ) + { + self.values = values + } - /// Returns all parameters used by the template. - fn parameters( &self ) -> &TemplateParameters; + /// Returns a reference to the template values. + /// + /// # Returns + /// + /// A reference to `TemplateValues`. + pub fn get_values( &self ) -> &TemplateValues + { + &self.values + } - /// Sets values for provided parameters. - fn set_values( &mut self, values : TemplateValues ); + /// Returns a mutable reference to the template values. + /// + /// # Returns + /// + /// A mutable reference to `TemplateValues`. + pub fn get_values_mut( &mut self ) -> &mut TemplateValues + { + &mut self.values + } - /// Relative path for parameter values storage. - fn parameter_storage( &self ) -> &Path; + /// Returns the path to the parameter storage file. + /// + /// # Returns + /// + /// A reference to a `Path` representing the parameter storage file. + pub fn parameter_storage( &self ) -> &Path + { + "./.deploy_template.toml".as_ref() + // qqq : for Mykyta : hardcode? + } + /// Returns the name of the template. + /// + /// # Returns /// - fn template_name( &self ) -> &'static str; + /// A static string slice representing the template name. + pub fn template_name( &self ) -> &'static str + { + "deploy" + } - /// Loads provided parameters from previous run. - fn load_existing_params( &mut self, path : &Path ) -> Option< () > + /// Loads existing parameters from the specified path and updates the template values. + /// + /// # Parameters + /// + /// - `path`: A reference to the path where the parameter file is located. + /// + /// # Returns + /// + /// An `Option` which is `Some(())` if the parameters are loaded successfully, or `None` otherwise. + pub fn load_existing_params( &mut self, path : &Path ) -> Option< () > { let data = fs::read_to_string( path.join( self.parameter_storage() ) ).ok()?; let document = data.parse::< toml_edit::Document >().ok()?; - let parameters = self.parameters().descriptors.iter().map( | d | &d.parameter ).cloned().collect::< Vec< _ > >(); + let parameters : Vec< _ > = self.parameters().descriptors.iter().map( | d | &d.parameter ).cloned().collect(); let template_table = document.get( self.template_name() )?; for parameter in parameters { @@ -59,20 +145,14 @@ mod private ); if let Some( value ) = value { - self.get_values_mut().insert_if_empty( ¶meter, Value::String( value.into() ) ); + self.get_values_mut().insert_if_empty( ¶meter, wca::Value::String( value.into() ) ); } } Some( () ) } - /// Get all template values. - fn get_values( &self ) -> &TemplateValues; - - /// Get all template values as a mutable reference. - fn get_values_mut( &mut self ) -> &mut TemplateValues; - /// Fetches mandatory parameters that are not set yet. - fn get_missing_mandatory( &self ) -> Vec< &str > + pub fn get_missing_mandatory( &self ) -> Vec< &str > { let values = self.get_values(); self @@ -84,6 +164,26 @@ mod private } } + impl Default for TemplateHolder + { + fn default() -> Self + { + let parameters = TemplateParameters::former() + .parameter( "gcp_project_id" ).is_mandatory( true ).end() + .parameter( "gcp_region" ).end() + .parameter( "gcp_artifact_repo_name" ).end() + .parameter( "docker_image_name" ).end() + .form(); + + Self + { + files : Default::default(), + parameters, + values : Default::default(), + } + } + } + /// Files stored in a template. /// /// Can be iterated over, consuming the owner of the files. @@ -92,7 +192,7 @@ mod private /// Creates all files in provided path with values for required parameters. /// /// Consumes owner of the files. - fn create_all( self, path : &Path, values : &TemplateValues ) -> Result< () > + fn create_all( self, path : &Path, values : &TemplateValues ) -> error::untyped::Result< () > // qqq : use typed error { let fsw = FileSystem; for file in self.into_iter() @@ -104,7 +204,7 @@ mod private } /// Parameters required for the template. - #[ derive( Debug, Default, Former ) ] + #[ derive( Debug, Default, former::Former ) ] pub struct TemplateParameters { #[ subform_entry( setter = false ) ] @@ -114,12 +214,12 @@ mod private impl TemplateParameters { /// Extracts template values from props for parameters required for this template. - pub fn values_from_props( &self, props : &Props ) -> TemplateValues + pub fn values_from_props( &self, props : &wca::Props ) -> TemplateValues { let values = self.descriptors .iter() .map( | d | &d.parameter ) - .map( | param | ( param.clone(), props.get( param ).map( Value::clone ) ) ) + .map( | param | ( param.clone(), props.get( param ).map( wca::Value::clone ) ) ) .collect(); TemplateValues( values ) } @@ -132,7 +232,7 @@ mod private } /// Parameter description. - #[ derive( Debug, Default, Former ) ] + #[ derive( Debug, Default, former::Former ) ] pub struct TemplateParameterDescriptor { parameter : String, @@ -154,14 +254,14 @@ mod private /// Holds a map of parameters and their values. #[ derive( Debug, Default ) ] - pub struct TemplateValues( HashMap< String, Option< Value > > ); + pub struct TemplateValues( collection::HashMap< String, Option< wca::Value > > ); impl TemplateValues { /// Converts values to a serializable object. /// /// Currently only `String`, `Number`, and `Bool` are supported. - pub fn to_serializable( &self ) -> BTreeMap< String, String > + pub fn to_serializable( &self ) -> collection::BTreeMap< String, String > { self.0.iter().map ( @@ -173,11 +273,11 @@ mod private { match value { - Value::String( val ) => val.to_string(), - Value::Number( val ) => val.to_string(), - Value::Path( _ ) => "unsupported".to_string(), - Value::Bool( val ) => val.to_string(), - Value::List( _ ) => "unsupported".to_string(), + wca::Value::String( val ) => val.to_string(), + wca::Value::Number( val ) => val.to_string(), + wca::Value::Path( _ ) => "unsupported".to_string(), + wca::Value::Bool( val ) => val.to_string(), + wca::Value::List( _ ) => "unsupported".to_string(), } } ) @@ -189,7 +289,7 @@ mod private } /// Inserts new value if parameter wasn't initialized before. - pub fn insert_if_empty( &mut self, key : &str, value : Value ) + pub fn insert_if_empty( &mut self, key : &str, value : wca::Value ) { if let None = self.0.get( key ).and_then( | v | v.as_ref() ) { @@ -204,7 +304,7 @@ mod private { println! ("Parameter `{key}` is not set" ); let answer = wca::ask( "Enter value" ); - self.0.insert( key.into(), Some( Value::String( answer ) ) ); + self.0.insert( key.into(), Some( wca::Value::String( answer ) ) ); } } } @@ -213,7 +313,7 @@ mod private /// /// Holds raw template data, relative path for the file, and a flag that /// specifies whether the raw data should be treated as a template. - #[ derive( Debug, Former ) ] + #[ derive( Debug, former::Former ) ] pub struct TemplateFileDescriptor { path : PathBuf, @@ -225,7 +325,7 @@ mod private impl TemplateFileDescriptor { fn contents< FS : FileSystemPort >( &self, fs : &FS, path : &PathBuf, values : &TemplateValues ) - -> Result< String > + -> error::untyped::Result< String > { let contents = if self.is_template { @@ -263,7 +363,8 @@ mod private } } - fn build_template( &self, values : &TemplateValues ) -> Result< String > + // qqq : use typed error + fn build_template( &self, values : &TemplateValues ) -> error::untyped::Result< String > { let mut handlebars = handlebars::Handlebars::new(); handlebars.register_escape_fn( handlebars::no_escape ); @@ -271,7 +372,7 @@ mod private handlebars.render( "templated_file", &values.to_serializable() ).context( "Failed creating a templated file" ) } - fn create_file< FS : FileSystemPort >( &self, fs : &FS, path : &Path, values : &TemplateValues ) -> Result< () > + fn create_file< FS : FileSystemPort >( &self, fs : &FS, path : &Path, values : &TemplateValues ) -> error::untyped::Result< () > // qqq : use typed error { let path = path.join( &self.path ); let data = self.contents( fs, &path, values )?.as_bytes().to_vec(); @@ -298,7 +399,7 @@ mod private } /// Helper builder for full template file list. - #[ derive( Debug, Former ) ] + #[ derive( Debug, former::Former ) ] pub struct TemplateFilesBuilder { /// Stores all file descriptors for current template. @@ -337,17 +438,17 @@ mod private pub trait FileSystemPort { /// Writing to file implementation. - fn write( &self, instruction : &FileWriteInstruction ) -> Result< () >; + fn write( &self, instruction : &FileWriteInstruction ) -> error::untyped::Result< () >; // qqq : use typed error /// Reading from a file implementation. - fn read( &self, instruction : &FileReadInstruction ) -> Result< Vec< u8 > >; + fn read( &self, instruction : &FileReadInstruction ) -> error::untyped::Result< Vec< u8 > >; // qqq : use typed error } - // qqq : xxx : why not public? + // zzz : why not public? struct FileSystem; impl FileSystemPort for FileSystem { - fn write( &self, instruction : &FileWriteInstruction ) -> Result< () > + fn write( &self, instruction : &FileWriteInstruction ) -> error::untyped::Result< () > // qqq : use typed error { let FileWriteInstruction { path, data } = instruction; let dir = path.parent().context( "Invalid file path provided" )?; @@ -358,7 +459,8 @@ mod private fs::write( path, data ).context( "Failed creating and writing to file" ) } - fn read( &self, instruction : &FileReadInstruction ) -> Result< Vec< u8 > > + // qqq : use typed error + fn read( &self, instruction : &FileReadInstruction ) -> error::untyped::Result< Vec< u8 > > { let FileReadInstruction { path } = instruction; fs::read( path ).context( "Failed reading a file" ) @@ -372,7 +474,8 @@ mod private crate::mod_interface! { - orphan use Template; + //orphan use Template; + orphan use TemplateHolder; orphan use TemplateFiles; orphan use TemplateFileDescriptor; orphan use TemplateParameters; diff --git a/module/move/willbe/src/tool/tree.rs b/module/move/willbe/src/tool/tree.rs new file mode 100644 index 0000000000..3c1e0c670b --- /dev/null +++ b/module/move/willbe/src/tool/tree.rs @@ -0,0 +1,167 @@ +mod private +{ + use std::fmt::Write; + use crate::CrateDir; + use std::fmt::Formatter; + + /// Struct for formatting and printing tree-like structures. + /// It contains symbols used for visualizing the tree and information about the tree nodes. + #[ derive( Debug, Clone, Eq, PartialEq ) ] + pub struct TreePrinter + { + /// Symbols used for visualizing the tree. + symbols : Symbols, + /// Information about the tree nodes. + pub info : ListNodeReport, + } + + impl TreePrinter + { + /// Creates a new instance of `TreePrinter` with the provided node information. + /// + /// # Parameters + /// + /// - `info`: A reference to a `ListNodeReport` object containing information about the tree nodes. + /// + /// # Returns + /// + /// A new instance of `TreePrinter`. + pub fn new(info : &ListNodeReport) -> Self + { + TreePrinter + { + symbols : Symbols::default(), + info : info.clone(), + } + } + + /// Displays the name, version, path, and dependencies of a package with appropriate indentation and spacing. + /// + /// # Arguments + /// + /// * `spacer` - A string used for indentation. + /// + /// # Returns + /// + /// * A `Result` containing the formatted string or a `std::fmt::Error` if formatting fails. + pub fn display_with_spacer( &self, spacer : &str ) -> Result< String, std::fmt::Error > + { + let mut f = String::new(); + + write!( f, "{}", self.info.name )?; + if let Some( version ) = &self.info.version { write!( f, " {version}" )? } + if let Some( crate_dir ) = &self.info.crate_dir { write!( f, " {}", crate_dir )? } + if self.info.duplicate { write!( f, "(*)" )? } + write!( f, "\n" )?; + + let mut new_spacer = format!( "{spacer}{} ", if self.info.normal_dependencies.len() < 2 { " " } else { self.symbols.down } ); + + let mut normal_dependencies_iter = self.info.normal_dependencies.iter(); + let last = normal_dependencies_iter.next_back(); + + for dep in normal_dependencies_iter + { + write!( f, "{spacer}{}{} {}", self.symbols.tee, self.symbols.right, Self::display_with_spacer( &TreePrinter::new( dep ), &new_spacer )? )?; + } + if let Some( last ) = last + { + new_spacer = format!( "{spacer} " ); + write!( f, "{spacer}{}{} {}", self.symbols.ell, self.symbols.right, Self::display_with_spacer( &TreePrinter::new( last ), &new_spacer )? )?; + } + if !self.info.dev_dependencies.is_empty() + { + let mut dev_dependencies_iter = self.info.dev_dependencies.iter(); + let last = dev_dependencies_iter.next_back(); + write!( f, "{spacer}[dev-dependencies]\n" )?; + for dep in dev_dependencies_iter + { + write!( f, "{spacer}{}{} {}", self.symbols.tee, self.symbols.right, Self::display_with_spacer( &TreePrinter::new( dep ), &new_spacer )? )?; + } + // unwrap - safe because `is_empty` check + write!( f, "{spacer}{}{} {}", self.symbols.ell, self.symbols.right, Self::display_with_spacer( &TreePrinter::new( last.unwrap() ), &new_spacer )? )?; + } + if !self.info.build_dependencies.is_empty() + { + let mut build_dependencies_iter = self.info.build_dependencies.iter(); + let last = build_dependencies_iter.next_back(); + write!( f, "{spacer}[build-dependencies]\n" )?; + for dep in build_dependencies_iter + { + write!( f, "{spacer}{}{} {}", self.symbols.tee, self.symbols.right, Self::display_with_spacer( &TreePrinter::new( dep ), &new_spacer )? )?; + } + // unwrap - safe because `is_empty` check + write!( f, "{spacer}{}{} {}", self.symbols.ell, self.symbols.right, Self::display_with_spacer( &TreePrinter::new( last.unwrap() ), &new_spacer )? )?; + } + + Ok( f ) + } + } + + impl std::fmt::Display for TreePrinter + { + fn fmt( &self, f : &mut Formatter< '_ > ) -> std::fmt::Result + { + write!( f, "{}", self.display_with_spacer( "" )? )?; + + Ok( () ) + } + } + + #[ derive( Debug, Clone, Eq, PartialEq ) ] + struct Symbols + { + down : &'static str, + tee : &'static str, + ell : &'static str, + right : &'static str, + } + + impl Default for Symbols + { + fn default() -> Self { + Self + { + down : "│", + tee : "├", + ell : "└", + right : "─", + } + } + } + + /// Represents a node in a dependency graph. + /// It holds essential information about the project dependencies. It is also capable + /// of holding any nested dependencies in a recursive manner, allowing the modeling + /// of complex dependency structures. + #[ derive( Debug, Clone, Eq, PartialEq ) ] + pub struct ListNodeReport + { + /// This could be the name of the library or crate. + pub name : String, + /// Ihe version of the crate. + pub version : Option< String >, + /// The path to the node's source files in the local filesystem. This is + /// optional as not all nodes may have a local presence (e.g., nodes representing remote crates). + pub crate_dir : Option< CrateDir >, + /// This field is a flag indicating whether the Node is a duplicate or not. + pub duplicate : bool, + /// A list that stores normal dependencies. + /// Each element in the list is also of the same 'ListNodeReport' type to allow + /// storage of nested dependencies. + pub normal_dependencies : Vec< ListNodeReport >, + /// A list that stores dev dependencies(dependencies required for tests or examples). + /// Each element in the list is also of the same 'ListNodeReport' type to allow + /// storage of nested dependencies. + pub dev_dependencies : Vec< ListNodeReport >, + /// A list that stores build dependencies. + /// Each element in the list is also of the same 'ListNodeReport' type to allow + /// storage of nested dependencies. + pub build_dependencies : Vec< ListNodeReport >, + } +} + +crate::mod_interface! +{ + orphan use TreePrinter; + orphan use ListNodeReport; +} \ No newline at end of file diff --git a/module/move/willbe/src/tool/url.rs b/module/move/willbe/src/tool/url.rs index f841613d79..f1ab5b8f9c 100644 --- a/module/move/willbe/src/tool/url.rs +++ b/module/move/willbe/src/tool/url.rs @@ -1,13 +1,17 @@ +/// Internal namespace. mod private { - use error_tools::for_app:: + #[ allow( unused_imports ) ] + use crate::tool::*; + + use error::untyped:: { format_err, - Result, + // Result, }; /// Extracts the repository URL from a full URL. - pub fn extract_repo_url( full_url : &str ) -> Option< String > + pub fn repo_url_extract( full_url : &str ) -> Option< String > { let parts : Vec< &str > = full_url.split( '/' ).collect(); @@ -25,7 +29,8 @@ mod private } /// Extracts the username and repository name from a given URL. - pub fn git_info_extract( url : &String ) -> Result< String > + // qqq : use typed error + pub fn git_info_extract( url : &String ) -> error::untyped::Result< String > { let parts : Vec< &str > = url.split( '/' ).collect(); if parts.len() >= 2 @@ -34,13 +39,13 @@ mod private } else { - Err( format_err!( "Fail to extract git username and repository name" ) ) + Err( format_err!( "Fail to extract git username and repository name" ) ) } } } crate::mod_interface! { - protected use extract_repo_url; - protected use git_info_extract; + own use repo_url_extract; + own use git_info_extract; } diff --git a/module/move/willbe/src/wtools.rs b/module/move/willbe/src/wtools.rs index 58a2d73144..1735805c0b 100644 --- a/module/move/willbe/src/wtools.rs +++ b/module/move/willbe/src/wtools.rs @@ -1,28 +1,28 @@ -pub use error_tools::err; - -// pub use error_tools::BasicError; - -pub use mod_interface::mod_interface; - -/// error tools -pub mod error -{ - pub use error_tools::*; - pub use error_tools::for_lib::*; - pub use::error_tools::dependency::*; -} - -/// This module provides utilities for working with iterators. -pub mod iter -{ - pub use iter_tools::prelude::*; -} - -/// Collection of function and structures to manipulate paths. -pub mod path_tools -{ - // pub use proper_path_tools::protected::*; - // pub use proper_path_tools::protected::path; - // xxx : make use proper_path_tools::protected::path working - pub use proper_path_tools::path; -} +// pub use error::err; +// +// // pub use error::BasicError; +// +// pub use mod_interface::mod_interface; +// +// /// error tools +// pub mod error +// { +// pub use error::*; +// pub use error::typed::*; +// pub use::error_tools::dependency::*; +// } +// +// /// This module provides utilities for working with iterators. +// pub mod iter +// { +// pub use iter_tools::prelude::*; +// } +// +// /// Collection of function and structures to manipulate paths. +// pub mod path_tools +// { +// // pub use proper_path_tools::own::*; +// // pub use proper_path_tools::own::path; +// // zzz : make use proper_path_tools::own::path working +// pub use proper_path::own as path; +// } diff --git a/module/move/willbe/template/deploy/Makefile.hbs b/module/move/willbe/template/deploy/Makefile.hbs index 05601a05cf..2f3461aea8 100644 --- a/module/move/willbe/template/deploy/Makefile.hbs +++ b/module/move/willbe/template/deploy/Makefile.hbs @@ -43,129 +43,129 @@ export AWS_ACCESS_KEY_ID ?= $(SECRET_AWS_ACCESS_KEY_ID) # AWS Secret Access key for deploying to an EC2 instance export AWS_SECRET_ACCESS_KEY ?= $(SECRET_AWS_ACCESS_KEY) -# Check Hetzner and deployment related keys +# Check Hetzner and deployment related keys check-hetzner-keys: - @[ -f key/SECRET_CSP_HETZNER ] \ + @[ -f key/SECRET_CSP_HETZNER ] \ || [ ! -z "${SECRET_CSP_HETZNER}" ] \ || { echo "ERROR: File key/SECRET_CSP_HETZNER does not exist"; exit 1; } -# Check AWS and deployment related keys +# Check AWS and deployment related keys check-aws-keys: - @[ -f key/SECRET_AWS_ACCESS_KEY_ID ] \ + @[ -f key/SECRET_AWS_ACCESS_KEY_ID ] \ || [ ! -z "${SECRET_AWS_ACCESS_KEY_ID}" ] \ || echo "ERROR: File key/SECRET_AWS_ACCESS_KEY_ID does not exist" - @[ -f key/SECRET_AWS_ACCESS_KEY ] \ + @[ -f key/SECRET_AWS_ACCESS_KEY ] \ || [ ! -z "${SECRET_AWS_ACCESS_KEY}" ] \ || echo "ERROR: File key/SECRET_AWS_ACCESS_KEY does not exist" - @[ -f key/SECRET_AWS_ACCESS_KEY_ID ] \ + @[ -f key/SECRET_AWS_ACCESS_KEY_ID ] \ || [ ! -z "${SECRET_AWS_ACCESS_KEY_ID}" ] \ || exit 1 - @[ -f key/SECRET_AWS_ACCESS_KEY ] \ + @[ -f key/SECRET_AWS_ACCESS_KEY ] \ || [ ! -z "${SECRET_AWS_ACCESS_KEY}" ] \ || exit 1 check-gce-keys: - @echo "All required GCE keys are the same as GCP keys" + @echo "All required GCE keys are the same as GCP keys" # Check if required GCP keys are present check-gcp-keys: - @[ -f key/service_account.json ] \ + @[ -f key/service_account.json ] \ || echo "ERROR: File key/service_account.json does not exist" - @[ -f key/SECRET_STATE_ARCHIVE_KEY ] \ + @[ -f key/SECRET_STATE_ARCHIVE_KEY ] \ || [ ! -z "${SECRET_STATE_ARCHIVE_KEY}" ] \ || echo "ERROR: File key/SECRET_STATE_ARCHIVE_KEY does not exist" - @[ -f key/service_account.json ] \ + @[ -f key/service_account.json ] \ || exit 1 - @[ -f key/SECRET_STATE_ARCHIVE_KEY ] \ + @[ -f key/SECRET_STATE_ARCHIVE_KEY ] \ || [ ! -z "${SECRET_STATE_ARCHIVE_KEY}" ] \ || exit 1 # Start local docker container start: - docker compose up -d + docker compose up -d # Stop local docker container stop: - docker compose down + docker compose down # Remove created docker image clean: stop - docker rmi $(TF_VAR_IMAGE_NAME) - docker buildx prune -af + docker rmi $(TF_VAR_IMAGE_NAME) + docker buildx prune -af # Install gcloud for Debian/Ubuntu install-gcloud: - # GCloud - sudo apt-get update - sudo apt-get install -y apt-transport-https ca-certificates gnupg curl sudo - curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg --dearmor -o /usr/share/keyrings/cloud.google.gpg - echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list - sudo apt-get update && sudo apt-get install -y google-cloud-cli + # GCloud + sudo apt-get update + sudo apt-get install -y apt-transport-https ca-certificates gnupg curl sudo + curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg --dearmor -o /usr/share/keyrings/cloud.google.gpg + echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list + sudo apt-get update && sudo apt-get install -y google-cloud-cli # Install terraform for Debian/Ubuntu install-terraform: - sudo apt-get update && sudo apt-get install -y gnupg software-properties-common - wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor | sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg - gpg --no-default-keyring --keyring /usr/share/keyrings/hashicorp-archive-keyring.gpg --fingerprint - echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list - sudo apt update && sudo apt-get install terraform + sudo apt-get update && sudo apt-get install -y gnupg software-properties-common + wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor | sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg + gpg --no-default-keyring --keyring /usr/share/keyrings/hashicorp-archive-keyring.gpg --fingerprint + echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list + sudo apt update && sudo apt-get install terraform # Install gcloud and terraform install: install-gcloud install-terraform - gcloud --version - terraform -version + gcloud --version + terraform -version # Login to GCP with user account gcp-auth: - gcloud auth application-default login + gcloud auth application-default login # Authorize to GCP with service account gcp-service: - gcloud auth activate-service-account --key-file=$(google_sa_creds) + gcloud auth activate-service-account --key-file=$(google_sa_creds) # Add docker repo auth helper gcp-docker: - gcloud auth configure-docker $(TF_VAR_REGION)-docker.pkg.dev --quiet + gcloud auth configure-docker $(TF_VAR_REGION)-docker.pkg.dev --quiet # Initializes all terraform projects # Downloads required modules and validates .tf files tf-init: - terraform -chdir=$(tf_dir)/gar init - terraform -chdir=$(tf_dir)/gce init - terraform -chdir=$(tf_dir)/hetzner init - terraform -chdir=$(tf_dir)/aws init + terraform -chdir=$(tf_dir)/gar init + terraform -chdir=$(tf_dir)/gce init + terraform -chdir=$(tf_dir)/hetzner init + terraform -chdir=$(tf_dir)/aws init # Creates Artifact Registry repository on GCP in specified location create-artifact-repo: tf-init - terraform -chdir=$(tf_dir)/gar apply -auto-approve + terraform -chdir=$(tf_dir)/gar apply -auto-approve # Builds uarust_conf_site image build-image: - docker build . -t name:$(TF_VAR_IMAGE_NAME) -t $(tag) + docker build . -t name:$(TF_VAR_IMAGE_NAME) -t $(tag) # Builds and pushes local docker image to the private repository push-image: gcp-docker create-artifact-repo - docker push $(tag) + docker push $(tag) # Creates GCE instance with the website configured on boot create-gce: check-gce-keys gcp-service state_storage_pull push-image - terraform -chdir=$(tf_dir)/gce apply -auto-approve + terraform -chdir=$(tf_dir)/gce apply -auto-approve # Creates AWS EC2 instance with the website configured on boot create-aws: check-aws-keys gcp-service state_storage_pull push-image - terraform -chdir=$(tf_dir)/aws apply -auto-approve + terraform -chdir=$(tf_dir)/aws apply -auto-approve # Creates Hetzner instance with the website configured on boot create-hetzner: check-hetzner-keys gcp-service state_storage_pull push-image - terraform -chdir=$(tf_dir)/hetzner apply -auto-approve + terraform -chdir=$(tf_dir)/hetzner apply -auto-approve # Deploys everything and updates terraform states deploy-in-container: create-$(CSP) state_storage_push # Deploys using tools from the container deploy: check-gcp-keys build-image - docker build . -t deploy-$(TF_VAR_IMAGE_NAME) -f ./$(tf_dir)/Dockerfile --build-arg google_sa_creds="$(google_sa_creds)" - @docker run -v //var/run/docker.sock:/var/run/docker.sock -v .:/app \ + docker build . -t deploy-$(TF_VAR_IMAGE_NAME) -f ./$(tf_dir)/Dockerfile --build-arg google_sa_creds="$(google_sa_creds)" + @docker run -v //var/run/docker.sock:/var/run/docker.sock -v .:/app \ -e SECRET_STATE_ARCHIVE_KEY=$(SECRET_STATE_ARCHIVE_KEY) \ -e SECRET_CSP_HETZNER=$(SECRET_CSP_HETZNER) \ -e SECRET_AWS_ACCESS_KEY_ID=$(SECRET_AWS_ACCESS_KEY_ID) \ @@ -175,35 +175,35 @@ deploy: check-gcp-keys build-image # Review changes that terraform will do on apply tf-plan: tf-init - terraform -chdir=$(tf_dir)/gar plan - terraform -chdir=$(tf_dir)/gce plan - terraform -chdir=$(tf_dir)/hetzner plan - terraform -chdir=$(tf_dir)/aws plan + terraform -chdir=$(tf_dir)/gar plan + terraform -chdir=$(tf_dir)/gce plan + terraform -chdir=$(tf_dir)/hetzner plan + terraform -chdir=$(tf_dir)/aws plan # Destroy created infrastracture on GCP tf-destroy: tf-init - terraform -chdir=$(tf_dir)/gar destroy - terraform -chdir=$(tf_dir)/gce destroy - terraform -chdir=$(tf_dir)/hetzner destroy - terraform -chdir=$(tf_dir)/aws destroy + terraform -chdir=$(tf_dir)/gar destroy + terraform -chdir=$(tf_dir)/gce destroy + terraform -chdir=$(tf_dir)/hetzner destroy + terraform -chdir=$(tf_dir)/aws destroy # Pushes encrypted terraform state files to the GCS Bucket state_storage_push: - @echo Pushing encrypted terraform state files to the GCS Bucket - @gcloud storage cp $(tf_dir)/gce/terraform.tfstate gs://$(TF_VAR_BUCKET_NAME)/gce.tfstate --encryption-key="$(SECRET_STATE_ARCHIVE_KEY)" - @gcloud storage cp $(tf_dir)/gar/terraform.tfstate gs://$(TF_VAR_BUCKET_NAME)/gar.tfstate --encryption-key="$(SECRET_STATE_ARCHIVE_KEY)" - @gcloud storage cp $(tf_dir)/hetzner/terraform.tfstate gs://$(TF_VAR_BUCKET_NAME)/hetzner.tfstate --encryption-key="$(SECRET_STATE_ARCHIVE_KEY)" - @gcloud storage cp $(tf_dir)/aws/terraform.tfstate gs://$(TF_VAR_BUCKET_NAME)/aws.tfstate --encryption-key="$(SECRET_STATE_ARCHIVE_KEY)" + @echo Pushing encrypted terraform state files to the GCS Bucket + @gcloud storage cp $(tf_dir)/gce/terraform.tfstate gs://$(TF_VAR_BUCKET_NAME)/gce.tfstate --encryption-key="$(SECRET_STATE_ARCHIVE_KEY)" + @gcloud storage cp $(tf_dir)/gar/terraform.tfstate gs://$(TF_VAR_BUCKET_NAME)/gar.tfstate --encryption-key="$(SECRET_STATE_ARCHIVE_KEY)" + @gcloud storage cp $(tf_dir)/hetzner/terraform.tfstate gs://$(TF_VAR_BUCKET_NAME)/hetzner.tfstate --encryption-key="$(SECRET_STATE_ARCHIVE_KEY)" + @gcloud storage cp $(tf_dir)/aws/terraform.tfstate gs://$(TF_VAR_BUCKET_NAME)/aws.tfstate --encryption-key="$(SECRET_STATE_ARCHIVE_KEY)" # Pulls and decrypts terraform state files to the GCS Bucket state_storage_pull: - @echo Pulling terraform state files to the GCS Bucket - -@gcloud storage cp gs://$(TF_VAR_BUCKET_NAME)/gce.tfstate $(tf_dir)/gce/terraform.tfstate --decryption-keys="$(SECRET_STATE_ARCHIVE_KEY)" - -@gcloud storage cp gs://$(TF_VAR_BUCKET_NAME)/gar.tfstate $(tf_dir)/gar/terraform.tfstate --decryption-keys="$(SECRET_STATE_ARCHIVE_KEY)" - -@gcloud storage cp gs://$(TF_VAR_BUCKET_NAME)/hetzner.tfstate $(tf_dir)/hetzner/terraform.tfstate --decryption-keys="$(SECRET_STATE_ARCHIVE_KEY)" - -@gcloud storage cp gs://$(TF_VAR_BUCKET_NAME)/aws.tfstate $(tf_dir)/aws/terraform.tfstate --decryption-keys="$(SECRET_STATE_ARCHIVE_KEY)" + @echo Pulling terraform state files to the GCS Bucket + -@gcloud storage cp gs://$(TF_VAR_BUCKET_NAME)/gce.tfstate $(tf_dir)/gce/terraform.tfstate --decryption-keys="$(SECRET_STATE_ARCHIVE_KEY)" + -@gcloud storage cp gs://$(TF_VAR_BUCKET_NAME)/gar.tfstate $(tf_dir)/gar/terraform.tfstate --decryption-keys="$(SECRET_STATE_ARCHIVE_KEY)" + -@gcloud storage cp gs://$(TF_VAR_BUCKET_NAME)/hetzner.tfstate $(tf_dir)/hetzner/terraform.tfstate --decryption-keys="$(SECRET_STATE_ARCHIVE_KEY)" + -@gcloud storage cp gs://$(TF_VAR_BUCKET_NAME)/aws.tfstate $(tf_dir)/aws/terraform.tfstate --decryption-keys="$(SECRET_STATE_ARCHIVE_KEY)" # Creates GCS Bucket for terraform states state_storage_init: - terraform -chdir=$(tf_dir)/gcs init - terraform -chdir=$(tf_dir)/gcs apply + terraform -chdir=$(tf_dir)/gcs init + terraform -chdir=$(tf_dir)/gcs apply diff --git a/module/move/willbe/template/workflow/standard_rust_push.yml b/module/move/willbe/template/workflow/standard_rust_push.yml index 1812c69512..958901ba1f 100644 --- a/module/move/willbe/template/workflow/standard_rust_push.yml +++ b/module/move/willbe/template/workflow/standard_rust_push.yml @@ -23,7 +23,7 @@ concurrency : group : standard_rust_push_${{ inputs.module_name }}_${{ github.ref }}_ ${{ contains( inputs.commit_message, '+test' ) || startsWith( inputs.commit_message, 'merge' ) }} - cancel-in-progress : true + cancel-in-progress : ${{ contains( inputs.commit_message, '+test' ) || startsWith( inputs.commit_message, 'merge' ) }} env : @@ -57,8 +57,10 @@ jobs : - name: Set MANIFEST_ROOT_PATH id: rootpath run: echo "::set-output name=path::$(dirname ${{ inputs.manifest_path }})" + - name: Build module + run: cd ${{ steps.rootpath.outputs.path }} && cargo build && cd - - name: Audit the modules - run: cd ${{ steps.rootpath.outputs.path }} && make audit + run: make audit continue-on-error: true - name: Generate documentation for the modules run: make doc open=no manifest_path=${{ inputs.manifest_path }} diff --git a/module/move/willbe/template/workspace/Makefile b/module/move/willbe/template/workspace/Makefile index b1036cde01..994c511991 100644 --- a/module/move/willbe/template/workspace/Makefile +++ b/module/move/willbe/template/workspace/Makefile @@ -22,10 +22,10 @@ VERSION ?= $(strip $(shell grep -m1 'version = "' Cargo.toml | cut -d '"' -f2)) # Sync local repostiry. # # Usage : -# make git.sync [message='description of changes'] +# make git.sync [message='description of changes'] git.sync : - git add --all && git commit -am $(message) && git pull + git add --all && git commit -am $(message) && git pull sync : git.sync @@ -36,10 +36,10 @@ sync : git.sync # Check vulnerabilities with cargo-audit. # # Usage : -# make audit +# make audit audit : - cargo audit + cargo audit # # === General commands @@ -48,88 +48,88 @@ audit : # Generate crates documentation from Rust sources. # # Usage : -# make doc [private=(yes|no)] [open=(yes|no)] [clean=(no|yes)] [manifest_path=(|[path])] +# make doc [private=(yes|no)] [open=(yes|no)] [clean=(no|yes)] [manifest_path=(|[path])] doc : ifeq ($(clean),yes) - @rm -rf target/doc/ + @rm -rf target/doc/ endif - cargo doc --all-features \ - $(if $(call eq,$(private),no),,--document-private-items) \ - $(if $(call eq,$(manifest_path),),--manifest-path ./Cargo.toml,--manifest-path $(manifest_path)) \ - $(if $(call eq,$(open),no),,--open) + cargo doc --all-features \ + $(if $(call eq,$(private),no),,--document-private-items) \ + $(if $(call eq,$(manifest_path),),--manifest-path ./Cargo.toml,--manifest-path $(manifest_path)) \ + $(if $(call eq,$(open),no),,--open) # Lint Rust sources with Clippy. # # Usage : -# make lint [warnings=(no|yes)] [manifest_path=(|[path])] +# make lint [warnings=(no|yes)] [manifest_path=(|[path])] lint : - cargo clippy --all-features \ - $(if $(call eq,$(manifest_path),),--manifest-path ./Cargo.toml,--manifest-path $(manifest_path)) \ - $(if $(call eq,$(warnings),no),-- -D warnings,) + cargo clippy --all-features \ + $(if $(call eq,$(manifest_path),),--manifest-path ./Cargo.toml,--manifest-path $(manifest_path)) \ + $(if $(call eq,$(warnings),no),-- -D warnings,) # Check Rust sources `check`. # # Usage : -# make check [manifest_path=(|[path])] +# make check [manifest_path=(|[path])] check : - cargo check \ - $(if $(call eq,$(manifest_path),),--manifest-path ./Cargo.toml,--manifest-path $(manifest_path)) + cargo check \ + $(if $(call eq,$(manifest_path),),--manifest-path ./Cargo.toml,--manifest-path $(manifest_path)) # Format and lint Rust sources. # # Usage : -# make normalize +# make normalize normalize : fmt lint # Perform common checks on the module. # # Usage : -# make checkmate +# make checkmate checkmate : doc lint check # Format Rust sources with rustfmt. # # Usage : -# make fmt [check=(no|yes)] +# make fmt [check=(no|yes)] fmt : - { find -L module -name *.rs -print0 ; } | xargs -0 rustfmt +nightly $(if $(call eq,$(check),yes),-- --check,) + { find -L module -name *.rs -print0 ; } | xargs -0 rustfmt +nightly $(if $(call eq,$(check),yes),-- --check,) # cargo +nightly fmt --all $(if $(call eq,$(check),yes),-- --check,) # Run project Rust sources with Cargo. # # Usage : -# make up +# make up up : - cargo up + cargo up # Run project Rust sources with Cargo. # # Usage : -# make clean +# make clean clean : - cargo clean && rm -rf Cargo.lock && cargo cache -a && cargo update + cargo clean && rm -rf Cargo.lock && cargo cache -a && cargo update # Run Rust tests of project. # # Usage : -# make test +# make test test : - cargo test --all-features + cargo test --all-features # Run format link test and tests. # # Usage : -# make all +# make all all : fmt lint test @@ -138,14 +138,14 @@ all : fmt lint test # .PHONY : \ - all \ - audit \ - docs \ - lint \ - check \ - fmt \ - normalize \ - checkmate \ - test \ - up \ - doc + all \ + audit \ + docs \ + lint \ + check \ + fmt \ + normalize \ + checkmate \ + test \ + up \ + doc diff --git a/module/move/willbe/template/workspace/module/module1/Cargo.toml.x b/module/move/willbe/template/workspace/module/module1/Cargo.toml.x index 9cf134e518..eba1f8da41 100644 --- a/module/move/willbe/template/workspace/module/module1/Cargo.toml.x +++ b/module/move/willbe/template/workspace/module/module1/Cargo.toml.x @@ -13,4 +13,4 @@ workspace = true features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] + diff --git a/module/move/willbe/template/workspace/module/module1/examples/module1_example.rs b/module/move/willbe/template/workspace/module/module1/examples/module1_example.rs index 1ce8bc56f8..d7a0d23ef4 100644 --- a/module/move/willbe/template/workspace/module/module1/examples/module1_example.rs +++ b/module/move/willbe/template/workspace/module/module1/examples/module1_example.rs @@ -7,6 +7,6 @@ use example_module::hello; ///test fn main() { - let h = hello(); - println!( "{}", h ); + let h = hello(); + println!( "{}", h ); } diff --git a/module/move/willbe/template/workspace/module/module1/src/lib.rs b/module/move/willbe/template/workspace/module/module1/src/lib.rs index d7b38faf6c..19c783b9ef 100644 --- a/module/move/willbe/template/workspace/module/module1/src/lib.rs +++ b/module/move/willbe/template/workspace/module/module1/src/lib.rs @@ -3,5 +3,5 @@ /// Example pub fn hello() -> String { - "hello world!".into() + "hello world!".into() } diff --git a/module/move/willbe/template/workspace/module/module1/tests/hello_test.rs b/module/move/willbe/template/workspace/module/module1/tests/hello_test.rs index 7ea32f1cba..06400d06b3 100644 --- a/module/move/willbe/template/workspace/module/module1/tests/hello_test.rs +++ b/module/move/willbe/template/workspace/module/module1/tests/hello_test.rs @@ -5,5 +5,5 @@ use example_module::*; #[ test ] fn example_test() { - assert_eq!( "hello world!".to_string(), hello() ); + assert_eq!( "hello world!".to_string(), hello() ); } diff --git a/module/move/willbe/tests/asset/full_config/_willbe_variadic_tag_configurations_c/Cargo.toml b/module/move/willbe/tests/asset/full_config/_willbe_variadic_tag_configurations_full_config_c/Cargo.toml similarity index 77% rename from module/move/willbe/tests/asset/full_config/_willbe_variadic_tag_configurations_c/Cargo.toml rename to module/move/willbe/tests/asset/full_config/_willbe_variadic_tag_configurations_full_config_c/Cargo.toml index 4df78cb6f0..289fc79ca1 100644 --- a/module/move/willbe/tests/asset/full_config/_willbe_variadic_tag_configurations_c/Cargo.toml +++ b/module/move/willbe/tests/asset/full_config/_willbe_variadic_tag_configurations_full_config_c/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "_willbe_variadic_tag_configurations_c" +name = "_willbe_variadic_tag_configurations_full_config_c" version = "0.1.0" edition = "2021" diff --git a/module/move/willbe/tests/asset/full_config/_willbe_variadic_tag_configurations_c/examples/_willbe_variadic_tag_configurations_c_trivial.rs b/module/move/willbe/tests/asset/full_config/_willbe_variadic_tag_configurations_full_config_c/examples/_willbe_variadic_tag_configurations_c_trivial.rs similarity index 100% rename from module/move/willbe/tests/asset/full_config/_willbe_variadic_tag_configurations_c/examples/_willbe_variadic_tag_configurations_c_trivial.rs rename to module/move/willbe/tests/asset/full_config/_willbe_variadic_tag_configurations_full_config_c/examples/_willbe_variadic_tag_configurations_c_trivial.rs diff --git a/module/move/willbe/tests/asset/full_config/_willbe_variadic_tag_configurations_c/src/lib.rs b/module/move/willbe/tests/asset/full_config/_willbe_variadic_tag_configurations_full_config_c/src/lib.rs similarity index 100% rename from module/move/willbe/tests/asset/full_config/_willbe_variadic_tag_configurations_c/src/lib.rs rename to module/move/willbe/tests/asset/full_config/_willbe_variadic_tag_configurations_full_config_c/src/lib.rs diff --git a/module/move/willbe/tests/asset/single_module_with_example/module/test_module/Cargo.toml b/module/move/willbe/tests/asset/single_module_with_example/module/test_module/Cargo.toml index 64eeb328e8..76dabe6c73 100644 --- a/module/move/willbe/tests/asset/single_module_with_example/module/test_module/Cargo.toml +++ b/module/move/willbe/tests/asset/single_module_with_example/module/test_module/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "test_module" +name = "single_module_with_example_test_module" version = "0.1.0" edition = "2021" repository = "https://github.com/Wandalen/wTools/tree/master/module/move/test_module" diff --git a/module/move/willbe/tests/asset/single_module_without_master_branch_and_discord/test_module/Cargo.toml b/module/move/willbe/tests/asset/single_module_without_master_branch_and_discord/test_module/Cargo.toml index 6f4364e11f..aec6e6f988 100644 --- a/module/move/willbe/tests/asset/single_module_without_master_branch_and_discord/test_module/Cargo.toml +++ b/module/move/willbe/tests/asset/single_module_without_master_branch_and_discord/test_module/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "test_module" +name = "single_module_without_master_branch_and_discord_test_module" version = "0.1.0" edition = "2021" diff --git a/module/move/willbe/tests/asset/three_packages/b/Cargo.toml b/module/move/willbe/tests/asset/three_packages/b/Cargo.toml index f460a5fc09..b7bc4425f5 100644 --- a/module/move/willbe/tests/asset/three_packages/b/Cargo.toml +++ b/module/move/willbe/tests/asset/three_packages/b/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "_chain_of_packages_b" +name = "_three_packages_b" version = "0.1.0" edition = "2021" repository = "https://github.com/Username/test/b" @@ -9,4 +9,4 @@ stability = "stable" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -_chain_of_packages_c = { path = "../c" } +_three_packages_c = { path = "../c" } diff --git a/module/move/willbe/tests/asset/three_packages/c/Cargo.toml b/module/move/willbe/tests/asset/three_packages/c/Cargo.toml index 4d263a19f3..28539ecdd1 100644 --- a/module/move/willbe/tests/asset/three_packages/c/Cargo.toml +++ b/module/move/willbe/tests/asset/three_packages/c/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "_chain_of_packages_c" +name = "_three_packages_c" version = "0.1.0" edition = "2021" repository = "https://github.com/Username/test/c" diff --git a/module/move/willbe/tests/asset/three_packages/d/Cargo.toml b/module/move/willbe/tests/asset/three_packages/d/Cargo.toml index 3fc29d91b6..24e9f550b1 100644 --- a/module/move/willbe/tests/asset/three_packages/d/Cargo.toml +++ b/module/move/willbe/tests/asset/three_packages/d/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "_chain_of_packages_d" +name = "_three_packages_d" version = "0.1.0" edition = "2021" repository = "https://github.com/Username/test/c" diff --git a/module/move/willbe/tests/asset/three_packages_with_features/b/Cargo.toml b/module/move/willbe/tests/asset/three_packages_with_features/b/Cargo.toml index b9c97a9443..5d105f6c90 100644 --- a/module/move/willbe/tests/asset/three_packages_with_features/b/Cargo.toml +++ b/module/move/willbe/tests/asset/three_packages_with_features/b/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "_chain_of_packages_b" +name = "_three_packages_with_features_b" version = "0.1.0" edition = "2021" repository = "https://github.com/Username/test/b" @@ -9,9 +9,9 @@ stability = "stable" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -_chain_of_packages_c = { path = "../c", optional = true } +_three_packages_with_features_c = { path = "../c", optional = true } [features] enabled = [] default = ["boo"] -boo = ["_chain_of_packages_c"] +boo = ["_three_packages_with_features_c"] diff --git a/module/move/willbe/tests/asset/three_packages_with_features/c/Cargo.toml b/module/move/willbe/tests/asset/three_packages_with_features/c/Cargo.toml index 0bcd46b4e3..e935a23dbc 100644 --- a/module/move/willbe/tests/asset/three_packages_with_features/c/Cargo.toml +++ b/module/move/willbe/tests/asset/three_packages_with_features/c/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "_chain_of_packages_c" +name = "_three_packages_with_features_c" version = "0.1.0" edition = "2021" repository = "https://github.com/Username/test/c" diff --git a/module/move/willbe/tests/asset/three_packages_with_features/d/Cargo.toml b/module/move/willbe/tests/asset/three_packages_with_features/d/Cargo.toml index a6e5f08b8f..45e924ea2b 100644 --- a/module/move/willbe/tests/asset/three_packages_with_features/d/Cargo.toml +++ b/module/move/willbe/tests/asset/three_packages_with_features/d/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "_chain_of_packages_d" +name = "_three_packages_with_features_d" version = "0.1.0" edition = "2021" repository = "https://github.com/Username/test/c" diff --git a/module/move/willbe/tests/inc/action/cicd_renew.rs b/module/move/willbe/tests/inc/action_tests/cicd_renew.rs similarity index 92% rename from module/move/willbe/tests/inc/action/cicd_renew.rs rename to module/move/willbe/tests/inc/action_tests/cicd_renew.rs index 4f9b0bc17b..ffbbe5b570 100644 --- a/module/move/willbe/tests/inc/action/cicd_renew.rs +++ b/module/move/willbe/tests/inc/action_tests/cicd_renew.rs @@ -1,16 +1,17 @@ use super::*; use assert_fs::prelude::*; -use the_module::action; +use the_module:: +{ + action, + collection::HashMap, +}; // -// aaa : for Petro : rid off redundant namespace. ask -// aaa : remove use std:: { fs::File, io::Read, - collections::HashMap }; use std::fs::create_dir_all; use serde::Deserialize; @@ -69,10 +70,10 @@ fn default_case() uses : "Username/test/.github/workflows/standard_rust_push.yml@alpha".into(), with }; - let expected = Workflow + let exp = Workflow { name : "test_module".into(), - on : + on : { let mut map = HashMap::new(); let mut push_map = HashMap::new(); @@ -90,13 +91,14 @@ fn default_case() // Act _ = action::cicd_renew( &temp ).unwrap(); + dbg!( &file_path ); // Assert let mut file = File::open( file_path ).unwrap(); let mut content = String::new(); _ = file.read_to_string( &mut content ).unwrap(); - let actual: Workflow = serde_yaml::from_str( &content ).unwrap(); - assert_eq!( expected, actual ); + let got : Workflow = serde_yaml::from_str( &content ).unwrap(); + assert_eq!( got, exp ); assert!( base_path.join( "appropriate_branch.yml" ).exists() ); assert!( base_path.join( "appropriate_branch_beta.yml" ).exists() ); diff --git a/module/move/willbe/tests/inc/action/features.rs b/module/move/willbe/tests/inc/action_tests/features.rs similarity index 69% rename from module/move/willbe/tests/inc/action/features.rs rename to module/move/willbe/tests/inc/action_tests/features.rs index c27e99c3b4..37a4b63cae 100644 --- a/module/move/willbe/tests/inc/action/features.rs +++ b/module/move/willbe/tests/inc/action_tests/features.rs @@ -18,8 +18,9 @@ fn package_no_features() { // Arrange let temp = arrange( "three_packages/b" ); + // let x : PathBuf = temp.path().to_owned(); let options = willbe::action::features::FeaturesOptions::former() - .manifest_dir( willbe::_path::AbsolutePath::try_from( temp.path().to_owned() ).unwrap() ) + .crate_dir( willbe::CrateDir::try_from( temp.path().to_owned() ).unwrap() ) .form(); // Act @@ -28,7 +29,7 @@ fn package_no_features() // Assert assert!( report.contains( "\ -Package _chain_of_packages_b:\ +Package _three_packages_b:\ " ) ); } @@ -38,7 +39,7 @@ fn package_features() // Arrange let temp = arrange( "three_packages_with_features/b" ); let options = willbe::action::features::FeaturesOptions::former() - .manifest_dir( willbe::_path::AbsolutePath::try_from( temp.path().to_owned() ).unwrap() ) + .crate_dir( willbe::CrateDir::try_from( temp.path().to_owned() ).unwrap() ) .form(); // Act @@ -47,8 +48,8 @@ fn package_features() // Assert assert!( report.contains( "\ -Package _chain_of_packages_b: -\t_chain_of_packages_c +Package _three_packages_with_features_b: +\t_three_packages_with_features_c \tboo \tdefault \tenabled\ @@ -60,7 +61,7 @@ fn package_features_with_features_deps() { let temp = arrange( "three_packages_with_features/b" ); let options = willbe::action::features::FeaturesOptions::former() - .manifest_dir( willbe::_path::AbsolutePath::try_from( temp.path().to_owned() ).unwrap() ) + .crate_dir( willbe::CrateDir::try_from( temp.path().to_owned() ).unwrap() ) .with_features_deps( true ) .form(); @@ -70,9 +71,9 @@ fn package_features_with_features_deps() // Assert assert!( report.contains( "\ -Package _chain_of_packages_b: -\t_chain_of_packages_c: [dep:_chain_of_packages_c] -\tboo: [_chain_of_packages_c] +Package _three_packages_with_features_b: +\t_three_packages_with_features_c: [dep:_three_packages_with_features_c] +\tboo: [_three_packages_with_features_c] \tdefault: [boo] \tenabled: []\ " ) ); @@ -84,7 +85,7 @@ fn workspace_no_features() // Arrange let temp = arrange( "three_packages" ); let options = willbe::action::features::FeaturesOptions::former() - .manifest_dir( willbe::_path::AbsolutePath::try_from( temp.path().to_owned() ).unwrap() ) + .crate_dir( willbe::CrateDir::try_from( temp.path().to_owned() ).unwrap() ) .form(); // Act @@ -93,17 +94,17 @@ fn workspace_no_features() // Assert assert!( report.contains( "\ -Package _chain_of_packages_b:\ +Package _three_packages_b:\ " ) ); assert!( report.contains( "\ -Package _chain_of_packages_c:\ +Package _three_packages_c:\ " ) ); assert!( report.contains( "\ -Package _chain_of_packages_d:\ +Package _three_packages_d:\ " ) ); } @@ -113,7 +114,7 @@ fn workspace_features() // Arrange let temp = arrange( "three_packages_with_features" ); let options = willbe::action::features::FeaturesOptions::former() - .manifest_dir( willbe::_path::AbsolutePath::try_from( temp.path().to_owned() ).unwrap() ) + .crate_dir( willbe::CrateDir::try_from( temp.path().to_owned() ).unwrap() ) .form(); // Act @@ -122,8 +123,8 @@ fn workspace_features() // Assert assert!( report.contains( "\ -Package _chain_of_packages_b: -\t_chain_of_packages_c +Package _three_packages_with_features_b: +\t_three_packages_with_features_c \tboo \tdefault \tenabled\ @@ -131,7 +132,7 @@ Package _chain_of_packages_b: assert!( report.contains( "\ -Package _chain_of_packages_c: +Package _three_packages_with_features_c: \tdefault \tenabled \tfoo\ @@ -139,7 +140,7 @@ Package _chain_of_packages_c: assert!( report.contains( "\ -Package _chain_of_packages_d: +Package _three_packages_with_features_d: \tenabled\ " ) ); } @@ -150,7 +151,7 @@ fn workspace_features_with_features_deps() // Arrange let temp = arrange( "three_packages_with_features" ); let options = willbe::action::features::FeaturesOptions::former() - .manifest_dir( willbe::_path::AbsolutePath::try_from( temp.path().to_owned() ).unwrap() ) + .crate_dir( willbe::CrateDir::try_from( temp.path().to_owned() ).unwrap() ) .with_features_deps( true ) .form(); @@ -160,16 +161,16 @@ fn workspace_features_with_features_deps() // Assert assert!( report.contains( "\ -Package _chain_of_packages_b: -\t_chain_of_packages_c: [dep:_chain_of_packages_c] -\tboo: [_chain_of_packages_c] +Package _three_packages_with_features_b: +\t_three_packages_with_features_c: [dep:_three_packages_with_features_c] +\tboo: [_three_packages_with_features_c] \tdefault: [boo] \tenabled: []\ " ) ); assert!( report.contains( "\ -Package _chain_of_packages_c: +Package _three_packages_with_features_c: \tdefault: [foo] \tenabled: [] \tfoo: []\ @@ -177,7 +178,7 @@ Package _chain_of_packages_c: assert!( report.contains( "\ -Package _chain_of_packages_d: +Package _three_packages_with_features_d: \tenabled: []\ " ) ); } diff --git a/module/move/willbe/tests/inc/action/list.rs b/module/move/willbe/tests/inc/action_tests/list.rs similarity index 100% rename from module/move/willbe/tests/inc/action/list.rs rename to module/move/willbe/tests/inc/action_tests/list.rs diff --git a/module/move/willbe/tests/inc/action/list/data.rs b/module/move/willbe/tests/inc/action_tests/list/data.rs similarity index 87% rename from module/move/willbe/tests/inc/action/list/data.rs rename to module/move/willbe/tests/inc/action_tests/list/data.rs index 17fc6230b6..423baf654c 100644 --- a/module/move/willbe/tests/inc/action/list/data.rs +++ b/module/move/willbe/tests/inc/action_tests/list/data.rs @@ -3,7 +3,7 @@ use super::*; use assert_fs::prelude::*; use the_module::action::{ self, list::* }; use willbe::CrateDir; -use willbe::_path::AbsolutePath; +use willbe::path::AbsolutePath; // @@ -51,13 +51,13 @@ mod chain_of_three_packages assert_eq!( 1, trees.len() ); let tree = &trees[ 0 ]; - assert_eq!( "_chain_of_packages_a", tree.name.as_str() ); + assert_eq!( "_chain_of_packages_a", tree.info.name.as_str() ); - assert_eq!( 1, tree.normal_dependencies.len() ); - assert!( tree.dev_dependencies.is_empty() ); - assert!( tree.build_dependencies.is_empty() ); + assert_eq!( 1, tree.info.normal_dependencies.len() ); + assert!( tree.info.dev_dependencies.is_empty() ); + assert!( tree.info.build_dependencies.is_empty() ); - let sub_tree = &tree.normal_dependencies[ 0 ]; + let sub_tree = &tree.info.normal_dependencies[ 0 ]; assert_eq!( "_chain_of_packages_b", sub_tree.name.as_str() ); assert_eq!( 1, sub_tree.normal_dependencies.len() ); @@ -73,16 +73,16 @@ mod chain_of_three_packages } #[ test ] - fn list_format_for_single_package() + fn list_format_for_single_package_1() { // Arrange let temp = arrange(); let args = ListOptions::former() - .path_to_manifest( crate_dir( &temp.join( "a" ) ) ) - .format( ListFormat::Topological ) - .dependency_sources([ DependencySource::Local ]) - .dependency_categories([ DependencyCategory::Primary ]) - .form(); + .path_to_manifest( crate_dir( &temp.join( "a" ) ) ) + .format( ListFormat::Topological ) + .dependency_sources([ DependencySource::Local ]) + .dependency_categories([ DependencyCategory::Primary ]) + .form(); // Act let output = action::list( args ).unwrap(); @@ -152,13 +152,13 @@ mod package_with_remote_dependency assert_eq!( 1, trees.len() ); let tree = &trees[ 0 ]; - assert_eq!( "_package_with_remote_dep_a", tree.name.as_str() ); + assert_eq!( "_package_with_remote_dep_a", tree.info.name.as_str() ); - assert_eq!( 2, tree.normal_dependencies.len() ); - assert!( tree.dev_dependencies.is_empty() ); - assert!( tree.build_dependencies.is_empty() ); + assert_eq!( 2, tree.info.normal_dependencies.len() ); + assert!( tree.info.dev_dependencies.is_empty() ); + assert!( tree.info.build_dependencies.is_empty() ); - let [ sub_tree_1, sub_tree_2, .. ] = tree.normal_dependencies.as_slice() else { unreachable!() }; + let [ sub_tree_1, sub_tree_2, .. ] = tree.info.normal_dependencies.as_slice() else { unreachable!() }; assert_eq!( "_package_with_remote_dep_b", sub_tree_1.name.as_str() ); assert!( sub_tree_1.normal_dependencies.is_empty() ); assert!( sub_tree_1.dev_dependencies.is_empty() ); @@ -171,7 +171,7 @@ mod package_with_remote_dependency } #[ test ] - fn list_format_for_single_package() + fn list_format_for_single_package_2() { // Arrange let temp = arrange(); @@ -250,14 +250,14 @@ mod workspace_with_cyclic_dependency assert_eq!( 1, trees.len() ); let tree = &trees[ 0 ]; - assert_eq!( "_workspace_with_cyclic_dep_a", tree.name.as_str() ); - assert_eq!( "0.1.0", tree.version.as_ref().unwrap().as_str() ); + assert_eq!( "_workspace_with_cyclic_dep_a", tree.info.name.as_str() ); + assert_eq!( "0.1.0", tree.info.version.as_ref().unwrap().as_str() ); - assert_eq!( 1, tree.normal_dependencies.len() ); - assert!( tree.dev_dependencies.is_empty() ); - assert!( tree.build_dependencies.is_empty() ); + assert_eq!( 1, tree.info.normal_dependencies.len() ); + assert!( tree.info.dev_dependencies.is_empty() ); + assert!( tree.info.build_dependencies.is_empty() ); - let sub_tree = &tree.normal_dependencies[ 0 ]; + let sub_tree = &tree.info.normal_dependencies[ 0 ]; assert_eq!( "_workspace_with_cyclic_dep_b", sub_tree.name.as_str() ); assert_eq!( "*", sub_tree.version.as_ref().unwrap().as_str() ); diff --git a/module/move/willbe/tests/inc/action/list/format.rs b/module/move/willbe/tests/inc/action_tests/list/format.rs similarity index 82% rename from module/move/willbe/tests/inc/action/list/format.rs rename to module/move/willbe/tests/inc/action_tests/list/format.rs index 42d492cf9d..84b7f32a96 100644 --- a/module/move/willbe/tests/inc/action/list/format.rs +++ b/module/move/willbe/tests/inc/action_tests/list/format.rs @@ -1,6 +1,7 @@ use super::*; -use the_module::action::list::ListNodeReport; +use the_module::tree::ListNodeReport; +use willbe::tree::TreePrinter; #[ test ] fn node_with_depth_two_leaves_stop_spacer() @@ -9,7 +10,7 @@ fn node_with_depth_two_leaves_stop_spacer() { name : "node".into(), version : None, - path : None, + crate_dir : None, duplicate : false, normal_dependencies : vec! [ @@ -17,13 +18,13 @@ fn node_with_depth_two_leaves_stop_spacer() { name : "sub_node1".into(), version : None, - path : None, + crate_dir : None, duplicate : false, normal_dependencies : vec![ ListNodeReport { name : "sub_sub_node1".into(), version : None, - path : None, + crate_dir : None, duplicate : false, normal_dependencies : vec![], dev_dependencies : vec![], @@ -36,13 +37,13 @@ fn node_with_depth_two_leaves_stop_spacer() { name : "sub_node2".into(), version : None, - path : None, + crate_dir : None, duplicate : false, normal_dependencies : vec![ ListNodeReport { name : "sub_sub_node2".into(), version : None, - path : None, + crate_dir : None, duplicate : false, normal_dependencies : vec![], dev_dependencies : vec![], @@ -63,7 +64,8 @@ node └─ sub_sub_node2 "#.trim(); - let actual = node.display_with_spacer( "" ).unwrap(); + let printer = TreePrinter::new( &node ); + let actual = printer.display_with_spacer( "" ).unwrap(); let actual = actual.trim(); println!("{actual}"); @@ -77,7 +79,7 @@ fn node_with_depth_two_leaves() { name : "node".into(), version : None, - path : None, + crate_dir : None, duplicate : false, normal_dependencies : vec! [ @@ -85,13 +87,13 @@ fn node_with_depth_two_leaves() { name : "sub_node1".into(), version : None, - path : None, + crate_dir : None, duplicate : false, normal_dependencies : vec![ ListNodeReport { name : "sub_sub_node".into(), version : None, - path : None, + crate_dir : None, duplicate : false, normal_dependencies : vec![], dev_dependencies : vec![], @@ -104,7 +106,7 @@ fn node_with_depth_two_leaves() { name : "sub_node2".into(), version : None, - path : None, + crate_dir : None, duplicate : false, normal_dependencies : vec![], dev_dependencies : vec![], @@ -121,7 +123,8 @@ node └─ sub_node2 "#.trim(); - let actual = node.display_with_spacer( "" ).unwrap(); + let printer = TreePrinter::new( &node ); + let actual = printer.display_with_spacer( "" ).unwrap(); let actual = actual.trim(); println!("{actual}"); @@ -135,19 +138,19 @@ fn node_with_depth_one_leaf() { name : "node".into(), version : None, - path : None, + crate_dir : None, duplicate : false, normal_dependencies : vec![ ListNodeReport { name : "sub_node".into(), version : None, - path : None, + crate_dir : None, duplicate : false, normal_dependencies : vec![ ListNodeReport { name : "sub_sub_node".into(), version : None, - path : None, + crate_dir : None, duplicate : false, normal_dependencies : vec![], dev_dependencies : vec![], @@ -165,7 +168,8 @@ node └─ sub_sub_node "#.trim(); - let actual = node.display_with_spacer( "" ).unwrap(); + let printer = TreePrinter::new( &node ); + let actual = printer.display_with_spacer( "" ).unwrap(); let actual = actual.trim(); println!("{actual}"); @@ -179,7 +183,7 @@ fn node_with_build_dependencies_tree_with_two_leaves() { name : "node".into(), version : None, - path : None, + crate_dir : None, duplicate : false, normal_dependencies : vec![], dev_dependencies : vec![], @@ -189,7 +193,7 @@ fn node_with_build_dependencies_tree_with_two_leaves() { name : "build_sub_node1".into(), version : None, - path : None, + crate_dir : None, duplicate : false, normal_dependencies : vec![], dev_dependencies : vec![], @@ -199,7 +203,7 @@ fn node_with_build_dependencies_tree_with_two_leaves() { name : "build_sub_node2".into(), version : None, - path : None, + crate_dir : None, duplicate : false, normal_dependencies : vec![], dev_dependencies : vec![], @@ -214,7 +218,8 @@ node └─ build_sub_node2 "#.trim(); - let actual = node.display_with_spacer( "" ).unwrap(); + let printer = TreePrinter::new( &node ); + let actual = printer.display_with_spacer( "" ).unwrap(); let actual = actual.trim(); println!("{actual}"); @@ -228,7 +233,7 @@ fn node_with_build_dependencies_tree_with_one_leaf() { name : "node".into(), version : None, - path : None, + crate_dir : None, duplicate : false, normal_dependencies : vec![], dev_dependencies : vec![], @@ -237,7 +242,7 @@ fn node_with_build_dependencies_tree_with_one_leaf() { name : "build_sub_node".into(), version : None, - path : None, + crate_dir : None, duplicate : false, normal_dependencies : vec![], dev_dependencies : vec![], @@ -251,7 +256,8 @@ node └─ build_sub_node "#.trim(); - let actual = node.display_with_spacer( "" ).unwrap(); + let printer = TreePrinter::new( &node ); + let actual = printer.display_with_spacer( "" ).unwrap(); let actual = actual.trim(); println!("{actual}"); @@ -265,7 +271,7 @@ fn node_with_dev_dependencies_tree_with_two_leaves() { name : "node".into(), version : None, - path : None, + crate_dir : None, duplicate : false, normal_dependencies : vec![], dev_dependencies : vec! @@ -274,7 +280,7 @@ fn node_with_dev_dependencies_tree_with_two_leaves() { name : "dev_sub_node1".into(), version : None, - path : None, + crate_dir : None, duplicate : false, normal_dependencies : vec![], dev_dependencies : vec![], @@ -284,7 +290,7 @@ fn node_with_dev_dependencies_tree_with_two_leaves() { name : "dev_sub_node2".into(), version : None, - path : None, + crate_dir : None, duplicate : false, normal_dependencies : vec![], dev_dependencies : vec![], @@ -300,7 +306,8 @@ node └─ dev_sub_node2 "#.trim(); - let actual = node.display_with_spacer( "" ).unwrap(); + let printer = TreePrinter::new( &node ); + let actual = printer.display_with_spacer( "" ).unwrap(); let actual = actual.trim(); println!("{actual}"); @@ -314,7 +321,7 @@ fn node_with_dev_dependencies_tree_with_one_leaf() { name : "node".into(), version : None, - path : None, + crate_dir : None, duplicate : false, normal_dependencies : vec![], dev_dependencies : vec![ @@ -322,7 +329,7 @@ fn node_with_dev_dependencies_tree_with_one_leaf() { name : "dev_sub_node".into(), version : None, - path : None, + crate_dir : None, duplicate : false, normal_dependencies : vec![], dev_dependencies : vec![], @@ -337,7 +344,8 @@ node └─ dev_sub_node "#.trim(); - let actual = node.display_with_spacer( "" ).unwrap(); + let printer = TreePrinter::new( &node ); + let actual = printer.display_with_spacer( "" ).unwrap(); let actual = actual.trim(); println!("{actual}"); @@ -351,7 +359,7 @@ fn node_with_dependencies_tree_with_two_leaves() { name : "node".into(), version : None, - path : None, + crate_dir : None, duplicate : false, normal_dependencies : vec! [ @@ -359,7 +367,7 @@ fn node_with_dependencies_tree_with_two_leaves() { name : "sub_node1".into(), version : None, - path : None, + crate_dir : None, duplicate : false, normal_dependencies : vec![], dev_dependencies : vec![], @@ -369,7 +377,7 @@ fn node_with_dependencies_tree_with_two_leaves() { name : "sub_node2".into(), version : None, - path : None, + crate_dir : None, duplicate : false, normal_dependencies : vec![], dev_dependencies : vec![], @@ -385,7 +393,8 @@ node └─ sub_node2 "#.trim(); - let actual = node.display_with_spacer( "" ).unwrap(); + let printer = TreePrinter::new( &node ); + let actual = printer.display_with_spacer( "" ).unwrap(); let actual = actual.trim(); println!("{actual}"); @@ -399,13 +408,13 @@ fn node_with_dependency_tree_with_one_leaf() { name : "node".into(), version : None, - path : None, + crate_dir : None, duplicate : false, normal_dependencies : vec![ ListNodeReport { name : "sub_node".into(), version : None, - path : None, + crate_dir : None, duplicate : false, normal_dependencies : vec![], dev_dependencies : vec![], @@ -419,7 +428,8 @@ node └─ sub_node "#.trim(); - let actual = node.display_with_spacer( "" ).unwrap(); + let printer = TreePrinter::new( &node ); + let actual = printer.display_with_spacer( "" ).unwrap(); let actual = actual.trim(); println!("{actual}"); @@ -433,7 +443,7 @@ fn one_node_one_line() { name : "node".into(), version : None, - path : None, + crate_dir : None, duplicate : false, normal_dependencies : vec![], dev_dependencies : vec![], @@ -441,7 +451,8 @@ fn one_node_one_line() }; let expected = "node\n"; - let actual = node.display_with_spacer( "" ).unwrap(); + let printer = TreePrinter::new( &node ); + let actual = printer.display_with_spacer( "" ).unwrap(); println!("{actual}"); assert_eq!( expected, actual ); diff --git a/module/move/willbe/tests/inc/action/main_header.rs b/module/move/willbe/tests/inc/action_tests/main_header.rs similarity index 99% rename from module/move/willbe/tests/inc/action/main_header.rs rename to module/move/willbe/tests/inc/action_tests/main_header.rs index abc3e492d4..82f1b89fba 100644 --- a/module/move/willbe/tests/inc/action/main_header.rs +++ b/module/move/willbe/tests/inc/action_tests/main_header.rs @@ -3,7 +3,7 @@ use assert_fs::prelude::*; use the_module::action; use std::io::Read; -use willbe::_path::AbsolutePath; +use willbe::path::AbsolutePath; fn arrange( source : &str ) -> assert_fs::TempDir diff --git a/module/move/willbe/tests/inc/action/mod.rs b/module/move/willbe/tests/inc/action_tests/mod.rs similarity index 100% rename from module/move/willbe/tests/inc/action/mod.rs rename to module/move/willbe/tests/inc/action_tests/mod.rs diff --git a/module/move/willbe/tests/inc/action/readme_health_table_renew.rs b/module/move/willbe/tests/inc/action_tests/readme_health_table_renew.rs similarity index 82% rename from module/move/willbe/tests/inc/action/readme_health_table_renew.rs rename to module/move/willbe/tests/inc/action_tests/readme_health_table_renew.rs index 58a745148e..cce1e9065a 100644 --- a/module/move/willbe/tests/inc/action/readme_health_table_renew.rs +++ b/module/move/willbe/tests/inc/action_tests/readme_health_table_renew.rs @@ -128,7 +128,8 @@ fn module_cell() let mut actual = String::new(); _ = file.read_to_string( &mut actual ).unwrap(); - assert!( actual.contains( "[_willbe_variadic_tag_configurations_c](./_willbe_variadic_tag_configurations_c)" ) ); + // qqq : do not do like that. If it will fail how will I know what went wrong? What is the name of the package here? + assert!( actual.contains( "[_willbe_variadic_tag_configurations_full_config_c](./_willbe_variadic_tag_configurations_full_config_c)" ) ); } #[ test ] @@ -163,7 +164,8 @@ fn branches_cell() let mut actual = String::new(); _ = file.read_to_string( &mut actual ).unwrap(); - assert!( actual.contains( "[![rust-status](https://img.shields.io/github/actions/workflow/status/SomeCrate/C/module_willbe_variadic_tag_configurations_c_push.yml?label=&branch=test_branch1)](https://github.com/SomeName/SomeCrate/C/actions/workflows/module_willbe_variadic_tag_configurations_c_push.yml?query=branch%3Atest_branch1) | [![rust-status](https://img.shields.io/github/actions/workflow/status/SomeCrate/C/module_willbe_variadic_tag_configurations_c_push.yml?label=&branch=test_branch2)](https://github.com/SomeName/SomeCrate/C/actions/workflows/module_willbe_variadic_tag_configurations_c_push.yml?query=branch%3Atest_branch2)" ) ); + // qqq : do not do like that. If it will fail how will I know what went wrong? What is the name of the package here? + assert!( actual.contains( "[![rust-status](https://img.shields.io/github/actions/workflow/status/SomeCrate/C/module_willbe_variadic_tag_configurations_full_config_c_push.yml?label=&branch=test_branch1)](https://github.com/SomeName/SomeCrate/C/actions/workflows/module_willbe_variadic_tag_configurations_full_config_c_push.yml?query=branch%3Atest_branch1) | [![rust-status](https://img.shields.io/github/actions/workflow/status/SomeCrate/C/module_willbe_variadic_tag_configurations_full_config_c_push.yml?label=&branch=test_branch2)](https://github.com/SomeName/SomeCrate/C/actions/workflows/module_willbe_variadic_tag_configurations_full_config_c_push.yml?query=branch%3Atest_branch2)" ) ); } #[ test ] @@ -180,7 +182,8 @@ fn docs_cell() let mut actual = String::new(); _ = file.read_to_string( &mut actual ).unwrap(); - assert!( actual.contains( "[![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/_willbe_variadic_tag_configurations_c)" ) ); + // qqq : do not do like that. If it will fail how will I know what went wrong? What is the name of the package here? + assert!( actual.contains( "[![docs.rs](https://raster.shields.io/static/v1?label=&message=docs&color=eee)](https://docs.rs/_willbe_variadic_tag_configurations_full_config_c)" ) ); } #[ test ] @@ -197,5 +200,6 @@ fn sample_cell() let mut actual = String::new(); _ = file.read_to_string( &mut actual ).unwrap(); - assert!( actual.contains( " [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=.%2F_willbe_variadic_tag_configurations_c%2Fexamples%2F_willbe_variadic_tag_configurations_c_trivial.rs,RUN_POSTFIX=--example%20_willbe_variadic_tag_configurations_c_trivial/https://github.com/SomeName/SomeCrate/C)" ) ); + // qqq : do not do like that. If it will fail how will I know what went wrong? What is the name of the package here? + assert!( actual.contains( " [![Open in Gitpod](https://raster.shields.io/static/v1?label=&message=try&color=eee)](https://gitpod.io/#RUN_PATH=.,SAMPLE_FILE=.%2F_willbe_variadic_tag_configurations_full_config_c%2Fexamples%2F_willbe_variadic_tag_configurations_c_trivial.rs,RUN_POSTFIX=--example%20_willbe_variadic_tag_configurations_c_trivial/https://github.com/SomeName/SomeCrate/C)" ) ); } diff --git a/module/move/willbe/tests/inc/action/readme_modules_headers_renew.rs b/module/move/willbe/tests/inc/action_tests/readme_modules_headers_renew.rs similarity index 83% rename from module/move/willbe/tests/inc/action/readme_modules_headers_renew.rs rename to module/move/willbe/tests/inc/action_tests/readme_modules_headers_renew.rs index 8fe71df94a..db82f365ba 100644 --- a/module/move/willbe/tests/inc/action/readme_modules_headers_renew.rs +++ b/module/move/willbe/tests/inc/action_tests/readme_modules_headers_renew.rs @@ -1,8 +1,12 @@ use super::*; use assert_fs::prelude::*; -use the_module::action; use std::io::Read; -use willbe::_path::AbsolutePath; +use the_module:: +{ + action, + // path::AbsolutePath, + CrateDir, +}; fn arrange( source : &str ) -> assert_fs::TempDir { @@ -28,7 +32,7 @@ fn tags_should_stay() let temp = arrange( "single_module" ); // Act - _ = action::readme_modules_headers_renew( AbsolutePath::try_from( temp.path() ).unwrap() ).unwrap(); + _ = action::readme_modules_headers_renew( CrateDir::try_from( temp.path() ).unwrap() ).unwrap(); let mut file = std::fs::File::open( temp.path().join( "test_module" ).join( "Readme.md" ) ).unwrap(); let mut actual = String::new(); @@ -47,7 +51,7 @@ fn default_stability() let temp = arrange( "single_module" ); // Act - _ = action::readme_modules_headers_renew( AbsolutePath::try_from( temp.path() ).unwrap() ).unwrap(); + _ = action::readme_modules_headers_renew( CrateDir::try_from( temp.path() ).unwrap() ).unwrap(); let mut file = std::fs::File::open( temp.path().join( "test_module" ).join( "Readme.md" ) ).unwrap(); let mut actual = String::new(); @@ -66,7 +70,7 @@ fn docs() let temp = arrange( "single_module" ); // Act - _ = action::readme_modules_headers_renew( AbsolutePath::try_from( temp.path() ).unwrap() ).unwrap(); + _ = action::readme_modules_headers_renew( CrateDir::try_from( temp.path() ).unwrap() ).unwrap(); let mut file = std::fs::File::open( temp.path().join( "test_module" ).join( "Readme.md" ) ).unwrap(); let mut actual = String::new(); @@ -84,7 +88,7 @@ fn no_gitpod() let temp = arrange("single_module"); // Act - _ = action::readme_modules_headers_renew(AbsolutePath::try_from(temp.path()).unwrap()).unwrap(); + _ = action::readme_modules_headers_renew( CrateDir::try_from( temp.path() ).unwrap() ).unwrap(); let mut file = std::fs::File::open(temp.path().join("test_module").join("Readme.md")).unwrap(); let mut actual = String::new(); @@ -101,7 +105,7 @@ fn with_gitpod() let temp = arrange( "single_module_with_example" ); // Act - _ = action::readme_modules_headers_renew( AbsolutePath::try_from( temp.path() ).unwrap() ).unwrap(); + _ = action::readme_modules_headers_renew( CrateDir::try_from( temp.path() ).unwrap() ).unwrap(); let mut file = std::fs::File::open( temp.path().join( "module" ).join( "test_module" ).join( "Readme.md" ) ).unwrap(); let mut actual = String::new(); @@ -119,7 +123,7 @@ fn discord() let temp = arrange( "single_module" ); // Act - _ = action::readme_modules_headers_renew( AbsolutePath::try_from( temp.path() ).unwrap() ).unwrap(); + _ = action::readme_modules_headers_renew( CrateDir::try_from( temp.path() ).unwrap() ).unwrap(); let mut file = std::fs::File::open( temp.path().join( "test_module" ).join( "Readme.md" ) ).unwrap(); let mut actual = String::new(); @@ -137,7 +141,7 @@ fn status() let temp = arrange( "single_module" ); // Act - _ = action::readme_modules_headers_renew( AbsolutePath::try_from( temp.path() ).unwrap() ).unwrap(); + _ = action::readme_modules_headers_renew( CrateDir::try_from( temp.path() ).unwrap() ).unwrap(); let mut file = std::fs::File::open( temp.path().join( "test_module" ).join( "Readme.md" ) ).unwrap(); let mut actual = String::new(); @@ -155,13 +159,13 @@ fn idempotency() let temp = arrange( "single_module" ); // Act - _ = action::readme_modules_headers_renew( AbsolutePath::try_from( temp.path() ).unwrap() ).unwrap(); + _ = action::readme_modules_headers_renew( CrateDir::try_from( temp.path() ).unwrap() ).unwrap(); let mut file = std::fs::File::open( temp.path().join( "test_module" ).join( "Readme.md" ) ).unwrap(); let mut actual1 = String::new(); _ = file.read_to_string( &mut actual1 ).unwrap(); drop( file ); - _ = action::readme_modules_headers_renew( AbsolutePath::try_from( temp.path() ).unwrap() ).unwrap(); + _ = action::readme_modules_headers_renew( CrateDir::try_from( temp.path() ).unwrap() ).unwrap(); let mut file = std::fs::File::open( temp.path().join( "test_module" ).join( "Readme.md" ) ).unwrap(); let mut actual2 = String::new(); _ = file.read_to_string( &mut actual2 ).unwrap(); @@ -176,7 +180,7 @@ fn with_many_members_and_varius_config() { let temp = arrange( "three_packages" ); - _ = action::readme_modules_headers_renew( AbsolutePath::try_from( temp.path() ).unwrap() ).unwrap(); + _ = action::readme_modules_headers_renew( CrateDir::try_from( temp.path() ).unwrap() ).unwrap(); let mut file_b = std::fs::File::open( temp.path().join( "b" ).join( "Readme.md" ) ).unwrap(); let mut file_c = std::fs::File::open( temp.path().join( "c" ).join( "Readme.md" ) ).unwrap(); @@ -203,5 +207,5 @@ fn without_needed_config() let temp = arrange( "variadic_tag_configurations" ); // Act - _ = action::readme_modules_headers_renew( AbsolutePath::try_from( temp.path() ).unwrap() ).unwrap(); + _ = action::readme_modules_headers_renew( CrateDir::try_from( temp.path() ).unwrap() ).unwrap(); } diff --git a/module/move/willbe/tests/inc/action/test.rs b/module/move/willbe/tests/inc/action_tests/test.rs similarity index 68% rename from module/move/willbe/tests/inc/action/test.rs rename to module/move/willbe/tests/inc/action_tests/test.rs index 1233017b05..6d7d7898d9 100644 --- a/module/move/willbe/tests/inc/action/test.rs +++ b/module/move/willbe/tests/inc/action_tests/test.rs @@ -1,14 +1,26 @@ -use std::collections::BTreeSet; -use std::fs::{self, File }; -use std::io::Write; -use std::path::{ Path, PathBuf }; +use super::*; +use the_module::*; + +use inc::helper:: +{ + ProjectBuilder, + WorkspaceBuilder, + // BINARY_NAME, +}; + +use collection::BTreeSet; +// use std:: +// { +// fs::{ self, File }, +// io::Write, +// }; +// use path::{ Path, PathBuf }; use assert_fs::TempDir; -use crate::the_module::*; -use action::test::{test, TestsCommandOptions}; -use _path::AbsolutePath; +use action::test::{ test, TestsCommandOptions }; use channel::*; use optimization::*; +// qqq : for Petro : no astersisks import use willbe::test::TestVariant; #[ test ] @@ -218,109 +230,3 @@ fn backtrace_should_be() assert!( !no_features.clone().unwrap_err().out.contains( "RUST_BACKTRACE" ) ); assert!( no_features.clone().unwrap_err().out.contains( "stack backtrace" ) ); } - -#[ derive( Debug ) ] -pub struct ProjectBuilder -{ - name : String, - lib_content : Option< String >, - test_content : Option< String >, - toml_content : Option< String >, -} - -impl ProjectBuilder -{ - pub fn new( name : &str ) -> Self - { - Self - { - name : String::from( name ), - lib_content : None, - test_content : None, - toml_content : None, - } - } - - pub fn lib_file< S : Into< String > >( mut self, content : S ) -> Self - { - self.lib_content = Some( content.into() ); - self - } - - pub fn test_file< S : Into< String > >( mut self, content : S ) -> Self - { - self.test_content = Some( content.into() ); - self - } - - pub fn toml_file( mut self, content : &str ) -> Self - { - self.toml_content = Some( format!( "[package]\nname = \"{}\"\nversion = \"0.1.0\"\nedition = \"2021\"\n{}", self.name, content ) ); - self - } - - pub fn build< P : AsRef< Path > >( &self, path : P ) -> std::io::Result< PathBuf > - { - let project_path = path.as_ref(); - - fs::create_dir_all( project_path.join( "src" ) )?; - fs::create_dir_all( project_path.join( "tests" ) )?; - - if let Some( content ) = &self.toml_content - { - let mut file = File::create( project_path.join( "Cargo.toml" ) )?; - write!( file, "{}", content )?; - } - - let mut file = File::create( project_path.join( "src/lib.rs" ) )?; - if let Some( content ) = &self.lib_content - { - write!( file, "{}", content )?; - } - - if let Some( content ) = &self.test_content - { - let mut file = File::create( project_path.join( "tests/tests.rs" ) )?; - write!( file, "{}", content )?; - } - - Ok( project_path.to_path_buf() ) - } -} - -struct WorkspaceBuilder -{ - members : Vec< ProjectBuilder >, - toml_content : String, -} - -impl WorkspaceBuilder -{ - fn new() -> Self - { - Self - { - members : vec![], - toml_content : "[workspace]\nresolver = \"2\"\nmembers = [\n \"modules/*\",\n]\n".to_string(), - } - } - - fn member( mut self, project : ProjectBuilder ) -> Self - { - self.members.push( project ); - self - } - - fn build< P : AsRef< Path > >( self, path : P ) -> PathBuf - { - let project_path = path.as_ref(); - fs::create_dir_all( project_path.join( "modules" ) ).unwrap(); - let mut file = File::create( project_path.join( "Cargo.toml" ) ).unwrap(); - write!( file, "{}", self.toml_content ).unwrap(); - for member in self.members - { - member.build( project_path.join( "modules" ).join( &member.name ) ).unwrap(); - } - project_path.into() - } -} diff --git a/module/move/willbe/tests/inc/action/workspace_renew.rs b/module/move/willbe/tests/inc/action_tests/workspace_renew.rs similarity index 100% rename from module/move/willbe/tests/inc/action/workspace_renew.rs rename to module/move/willbe/tests/inc/action_tests/workspace_renew.rs diff --git a/module/move/willbe/tests/inc/command/tests_run.rs b/module/move/willbe/tests/inc/command/tests_run.rs index c540c285d5..67f6b97c9c 100644 --- a/module/move/willbe/tests/inc/command/tests_run.rs +++ b/module/move/willbe/tests/inc/command/tests_run.rs @@ -1,12 +1,11 @@ use super::*; + // use the_module::*; use assert_cmd::Command; -use inc:: +use inc::helper:: { - action::test::ProjectBuilder, - // aaa : for Petro : move to helper. don't reuse test-rs files in command and endpoints - // aaa : move to helper module - helpers::BINARY_NAME, + ProjectBuilder, + BINARY_NAME, }; use assert_fs::TempDir; diff --git a/module/move/willbe/tests/inc/entity/dependencies.rs b/module/move/willbe/tests/inc/entity/dependencies.rs index 28f393d4f5..bf6e0eca94 100644 --- a/module/move/willbe/tests/inc/entity/dependencies.rs +++ b/module/move/willbe/tests/inc/entity/dependencies.rs @@ -2,29 +2,32 @@ use super::*; use assert_fs::prelude::*; use assert_fs::TempDir; -use the_module::Workspace; -use the_module::package::{ dependencies, DependenciesOptions, DependenciesSort }; -use willbe::CrateDir; -use willbe::package::Package; -use willbe::_path::AbsolutePath; +use the_module:: +{ + Workspace, + dependency::{ self, DependenciesOptions, DependenciesSort }, + CrateDir, + package::Package, + path::AbsolutePath, +}; // fn arrange( asset_name : &str ) -> ( TempDir, Workspace ) { - let path = CrateDir::try_from( AbsolutePath::try_from( std::path::Path::new( env!( "CARGO_MANIFEST_DIR" ) ) ).unwrap() ).unwrap(); - let mut metadata = Workspace::with_crate_dir( path ).unwrap(); + let path = CrateDir::try_from( std::path::Path::new( env!( "CARGO_MANIFEST_DIR" ) ) ).unwrap(); + let workspace = Workspace::try_from( path ).unwrap(); - let root_path = metadata.load().unwrap().workspace_root().unwrap(); + let root_path = workspace.workspace_root(); let assets_relative_path = std::path::Path::new( ASSET_PATH ); let assets_path = root_path.join( "module" ).join( "move" ).join( "willbe" ).join( assets_relative_path ); let temp = TempDir::new().unwrap(); temp.copy_from( assets_path.join( asset_name ), &[ "**" ] ).unwrap(); let temp_crate_dir = CrateDir::try_from( AbsolutePath::try_from( temp.to_path_buf() ).unwrap() ).unwrap(); - let metadata = Workspace::with_crate_dir( temp_crate_dir ).unwrap(); + let workspace = Workspace::try_from( temp_crate_dir ).unwrap(); - ( temp, metadata ) + ( temp, workspace ) } // a -> b -> c @@ -32,26 +35,36 @@ fn arrange( asset_name : &str ) -> ( TempDir, Workspace ) fn chain_of_three_packages() { // Arrange - let ( temp, mut metadata ) = arrange( "chain_of_packages" ); + let ( temp, mut workspace ) = arrange( "chain_of_packages" ); - let a = Package::try_from( AbsolutePath::try_from( temp.join( "a" ) ).unwrap() ).unwrap(); - let b = Package::try_from( AbsolutePath::try_from( temp.join( "b" ) ).unwrap() ).unwrap(); - let c = Package::try_from( AbsolutePath::try_from( temp.join( "c" ) ).unwrap() ).unwrap(); + let a = Package::try_from( willbe::CrateDir::try_from( temp.join( "a" ) ).unwrap() ).unwrap(); + let b = Package::try_from( willbe::CrateDir::try_from( temp.join( "b" ) ).unwrap() ).unwrap(); + let c = Package::try_from( willbe::CrateDir::try_from( temp.join( "c" ) ).unwrap() ).unwrap(); // Act - let output = dependencies( &mut metadata, &a, DependenciesOptions::default() ).unwrap(); - let output : Vec< _ > = output.iter().filter_map( | o | o.path.as_ref() ).map( | x | x.as_ref() ).collect(); + let output = dependency::list( &mut workspace, &a, DependenciesOptions::default() ).unwrap(); + let output : Vec< CrateDir > = output + .into_iter() + .filter_map( | p | p.crate_dir ) + .collect(); // Assert assert_eq!( 2, output.len() ); - assert!( ( c.crate_dir().as_ref() == output[ 0 ] && b.crate_dir().as_ref() == output[ 1 ] ) || ( c.crate_dir().as_ref() == output[ 1 ] && b.crate_dir().as_ref() == output[ 0 ] ) ); - - let output = dependencies( &mut metadata, &b, DependenciesOptions::default() ).unwrap(); - let output : Vec< _ > = output.iter().filter_map( | o | o.path.as_ref() ).map( | x | x.as_ref() ).collect(); + assert! + ( + ( c.crate_dir() == output[ 0 ] && b.crate_dir() == output[ 1 ] ) || + ( c.crate_dir() == output[ 1 ] && b.crate_dir() == output[ 0 ] ), + ); + + let output = dependency::list( &mut workspace, &b, DependenciesOptions::default() ).unwrap(); + let output : Vec< CrateDir > = output + .into_iter() + .filter_map( | p | p.crate_dir ) + .collect(); assert_eq!( 1, output.len() ); - assert_eq!( c.crate_dir().as_ref(), output[ 0 ] ); + assert_eq!( c.crate_dir(), output[ 0 ] ); - let output = dependencies( &mut metadata, &c, DependenciesOptions::default() ).unwrap(); + let output = dependency::list( &mut workspace, &c, DependenciesOptions::default() ).unwrap(); assert!( output.is_empty() ); } @@ -60,24 +73,35 @@ fn chain_of_three_packages() fn chain_of_three_packages_topologically_sorted() { // Arrange - let ( temp, mut metadata ) = arrange( "chain_of_packages" ); + let ( temp, mut workspace ) = arrange( "chain_of_packages" ); - let a = Package::try_from( AbsolutePath::try_from( temp.join( "a" ) ).unwrap() ).unwrap(); - let b = Package::try_from( AbsolutePath::try_from( temp.join( "b" ) ).unwrap() ).unwrap(); - let c = Package::try_from( AbsolutePath::try_from( temp.join( "c" ) ).unwrap() ).unwrap(); + let a = Package::try_from( willbe::CrateDir::try_from( temp.join( "a" ) ).unwrap() ).unwrap(); + let b = Package::try_from( willbe::CrateDir::try_from( temp.join( "b" ) ).unwrap() ).unwrap(); + let c = Package::try_from( willbe::CrateDir::try_from( temp.join( "c" ) ).unwrap() ).unwrap(); // Act - let output = dependencies( &mut metadata, &a, DependenciesOptions { sort : DependenciesSort::Topological, ..Default::default() } ).unwrap(); - let output : Vec< _ > = output.iter().filter_map( | o | o.path.as_ref() ).map( | x | x.as_ref() ).collect(); + let output = dependency::list + ( + &mut workspace, + &a, + DependenciesOptions { sort : DependenciesSort::Topological, ..Default::default() }, + ).unwrap(); + let output : Vec< CrateDir > = output + .into_iter() + .filter_map( | p | p.crate_dir ) + .collect(); // Assert - assert_eq!( &[ c.crate_dir().as_ref(), b.crate_dir().as_ref() ], output.as_slice() ); + assert_eq!( &[ c.crate_dir(), b.crate_dir() ], output.as_slice() ); - let output = dependencies( &mut metadata, &b, DependenciesOptions { sort : DependenciesSort::Topological, ..Default::default() } ).unwrap(); - let output : Vec< _ > = output.iter().filter_map( | o | o.path.as_ref() ).map( | x | x.as_ref() ).collect(); - assert_eq!( &[ c.crate_dir().as_ref() ], output.as_slice() ); + let output = dependency::list( &mut workspace, &b, DependenciesOptions { sort : DependenciesSort::Topological, ..Default::default() } ).unwrap(); + let output : Vec< CrateDir > = output + .into_iter() + .filter_map( | p | p.crate_dir ) + .collect(); + assert_eq!( &[ c.crate_dir() ], output.as_slice() ); - let output = dependencies( &mut metadata, &c, DependenciesOptions { sort : DependenciesSort::Topological, ..Default::default() } ).unwrap(); + let output = dependency::list( &mut workspace, &c, DependenciesOptions { sort : DependenciesSort::Topological, ..Default::default() } ).unwrap(); assert!( output.is_empty() ); } @@ -86,18 +110,21 @@ fn chain_of_three_packages_topologically_sorted() fn package_with_remote_dependency() { // Arrange - let ( temp, mut metadata ) = arrange( "package_with_remote_dependency" ); + let ( temp, mut workspace ) = arrange( "package_with_remote_dependency" ); - let a = Package::try_from( AbsolutePath::try_from( temp.join( "a" ) ).unwrap() ).unwrap(); - let b = Package::try_from( AbsolutePath::try_from( temp.join( "b" ) ).unwrap() ).unwrap(); + let a = Package::try_from( willbe::CrateDir::try_from( temp.join( "a" ) ).unwrap() ).unwrap(); + let b = Package::try_from( willbe::CrateDir::try_from( temp.join( "b" ) ).unwrap() ).unwrap(); // Act - let output = dependencies( &mut metadata, &a, DependenciesOptions::default() ).unwrap(); - let output : Vec< _ > = output.iter().filter_map( | o | o.path.as_ref() ).map( | x | x.as_ref() ).collect(); + let output = dependency::list( &mut workspace, &a, DependenciesOptions::default() ).unwrap(); + let output : Vec< CrateDir > = output + .into_iter() + .filter_map( | p | p.crate_dir ) + .collect(); // Assert assert_eq!( 1, output.len() ); - assert_eq!( b.crate_dir().as_ref(), output[ 0 ] ); + assert_eq!( b.crate_dir(), output[ 0 ] ); } // a -> b -> a @@ -105,24 +132,30 @@ fn package_with_remote_dependency() fn workspace_with_cyclic_dependency() { // Arrange - let ( temp, mut metadata ) = arrange( "workspace_with_cyclic_dependency" ); + let ( temp, mut workspace ) = arrange( "workspace_with_cyclic_dependency" ); - let a = Package::try_from( AbsolutePath::try_from( temp.join( "a" ) ).unwrap() ).unwrap(); - let b = Package::try_from( AbsolutePath::try_from( temp.join( "b" ) ).unwrap() ).unwrap(); + let a = Package::try_from( willbe::CrateDir::try_from( temp.join( "a" ) ).unwrap() ).unwrap(); + let b = Package::try_from( willbe::CrateDir::try_from( temp.join( "b" ) ).unwrap() ).unwrap(); // Act - let output = dependencies( &mut metadata, &a, DependenciesOptions::default() ).unwrap(); - let output : Vec< _ > = output.iter().filter_map( | o | o.path.as_ref() ).map( | x | x.as_ref() ).collect(); + let output = dependency::list( &mut workspace, &a, DependenciesOptions::default() ).unwrap(); + let output : Vec< CrateDir > = output + .into_iter() + .filter_map( | p | p.crate_dir ) + .collect(); // Assert assert_eq!( 1, output.len() ); - assert!( b.crate_dir().as_ref() == output[ 0 ] ); + assert!( b.crate_dir() == output[ 0 ] ); // Act - let output = dependencies( &mut metadata, &b, DependenciesOptions::default() ).unwrap(); - let output : Vec< _ > = output.iter().filter_map( | o | o.path.as_ref() ).map( | x | x.as_ref() ).collect(); + let output = dependency::list( &mut workspace, &b, DependenciesOptions::default() ).unwrap(); + let output : Vec< CrateDir > = output + .into_iter() + .filter_map( | p | p.crate_dir ) + .collect(); // Assert assert_eq!( 1, output.len() ); - assert!( a.crate_dir().as_ref() == output[ 0 ] ); + assert!( a.crate_dir() == output[ 0 ] ); } \ No newline at end of file diff --git a/module/move/willbe/tests/inc/entity/diff.rs b/module/move/willbe/tests/inc/entity/diff.rs index b3362ee64d..9c84aa6cc1 100644 --- a/module/move/willbe/tests/inc/entity/diff.rs +++ b/module/move/willbe/tests/inc/entity/diff.rs @@ -1,13 +1,12 @@ use crate::*; +use the_module::*; use std::path::{ Path, PathBuf }; use assert_fs::{ TempDir, prelude::* }; use crates_tools::CrateArchive; -use the_module::*; -use _path::AbsolutePath; use package::Package; use diff::crate_diff; -use the_module::version::{ Version, BumpOptions, version_bump }; +use the_module::version::{ Version, BumpOptions, bump }; const TEST_MODULE_PATH : &str = "../../test/"; @@ -16,17 +15,17 @@ fn no_changes() { let tmp = &TempDir::new().unwrap(); let package_path = package_path( "c" ); - + let left = prepare( tmp, "left", &package_path ); let left_crate = crate_file_path( &left ); let left_archive = CrateArchive::read( &left_crate ).unwrap(); - + let right = prepare( tmp, "right", &package_path ); let right_crate = crate_file_path( &right ); let right_archive = CrateArchive::read( &right_crate ).unwrap(); - + let has_changes = crate_diff( &left_archive, &right_archive ).exclude( diff::PUBLISH_IGNORE_LIST ).has_changes(); - + assert!( !has_changes ); } @@ -47,7 +46,8 @@ fn with_changes() { let right = prepare( tmp, "right", &package_path ); - let absolute = AbsolutePath::try_from( right.as_path() ).unwrap(); + // let absolute = AbsolutePath::try_from( right.as_path() ).unwrap(); + let absolute = CrateDir::try_from( right.as_path() ).unwrap(); let right_package = Package::try_from( absolute ).unwrap(); let right_version = Version::try_from( &right_package.version().unwrap() ).unwrap(); @@ -59,7 +59,7 @@ fn with_changes() dependencies : vec![], dry : false, }; - version_bump( bump_options ).unwrap(); + bump( bump_options ).unwrap(); let right_crate = crate_file_path( &right ); CrateArchive::read( &right_crate ).unwrap() @@ -89,10 +89,11 @@ fn crate_file_path( manifest_dir_path : &Path ) -> PathBuf { _ = cargo::pack( cargo::PackOptions::former().path( manifest_dir_path ).dry( false ).form() ).expect( "Failed to package a package" ); - let absolute = AbsolutePath::try_from( manifest_dir_path ).unwrap(); + let absolute = CrateDir::try_from( manifest_dir_path ).unwrap(); let package = Package::try_from( absolute ).unwrap(); manifest_dir_path - .join( "target" ) - .join( "package" ) - .join( format!( "{}-{}.crate", package.name().unwrap(), package.version().unwrap() ) ) + .join( "target" ) + .join( "package" ) + .join( format!( "{}-{}.crate", package.name().unwrap(), package.version().unwrap() ) ) + } diff --git a/module/move/willbe/tests/inc/entity/features.rs b/module/move/willbe/tests/inc/entity/features.rs index 0eaf8e7c75..14cd845879 100644 --- a/module/move/willbe/tests/inc/entity/features.rs +++ b/module/move/willbe/tests/inc/entity/features.rs @@ -1,15 +1,15 @@ use super::*; -// use the_module::*; -use the_module::features::features_powerset; - -use std::collections::HashMap; +use the_module:: +{ + features::{ features_powerset, estimate_with }, + collection::HashMap, +}; use serde::Deserialize; -use the_module::workspace::WorkspacePackage; -use willbe::features::estimate_with; /// Constructs a mock `Package` with specified features for testing. -fn mock_package( features : Vec< ( &str, Vec< &str > ) > ) -> WorkspacePackage +// fn mock_package( features : Vec< ( &str, Vec< &str > ) > ) -> WorkspacePackageRef< '_ > +fn mock_package( features : Vec< ( &str, Vec< &str > ) > ) -> cargo_metadata::Package { let mut features_map : HashMap< String, Vec< _ > > = HashMap::new(); for ( feature, deps ) in features @@ -34,7 +34,7 @@ fn mock_package( features : Vec< ( &str, Vec< &str > ) > ) -> WorkspacePackage } ); - WorkspacePackage::deserialize( json ).unwrap() + cargo_metadata::Package::deserialize( json ).unwrap() } #[ test ] @@ -57,7 +57,7 @@ fn case_1() let enabled_features = vec![ "f2".to_string() ]; let result = features_powerset ( - &package, + ( &package ).into(), power, &exclude_features, &include_features, @@ -93,7 +93,7 @@ fn case_2() let enabled_features = vec![ "f2".to_string() ]; let result = features_powerset ( - &package, + ( &package ).into(), power, &exclude_features, &include_features, @@ -130,7 +130,7 @@ fn case_3() let enabled_features = vec![ "f2".to_string() ]; let result = features_powerset ( - &package, + ( &package ).into(), power, &exclude_features, &include_features, @@ -167,7 +167,7 @@ fn case_4() let enabled_features = vec![ "f2".to_string() ]; let result = features_powerset ( - &package, + ( &package ).into(), power, &exclude_features, &include_features, @@ -205,7 +205,7 @@ fn case_5() let enabled_features = vec![ "f2".to_string() ]; let result = features_powerset ( - &package, + ( &package ).into(), power, &exclude_features, &include_features, @@ -240,7 +240,7 @@ fn case_6() let enabled_features = vec![ "f2".to_string() ]; let result = features_powerset ( - &package, + ( &package ).into(), power, &exclude_features, &include_features, diff --git a/module/move/willbe/tests/inc/entity/version.rs b/module/move/willbe/tests/inc/entity/version.rs index 6ae36602ce..3251fce27c 100644 --- a/module/move/willbe/tests/inc/entity/version.rs +++ b/module/move/willbe/tests/inc/entity/version.rs @@ -9,9 +9,9 @@ use the_module:: CrateDir, Manifest, version::Version, - _path::AbsolutePath, + path::AbsolutePath, package::Package, - version::{ BumpOptions, version_bump, version_revert }, + version::{ BumpOptions, bump, revert }, }; const TEST_MODULE_PATH : &str = "../../test/"; @@ -110,14 +110,15 @@ fn package_version_bump() std::fs::create_dir( &temp_module ).unwrap(); temp_module.child( "c" ).copy_from( &c, &[ "**" ] ).unwrap(); let c_temp_path = temp_module.join( "c" ); - let c_temp_absolute_path = AbsolutePath::try_from( c_temp_path ).unwrap(); + let c_temp_absolute_path = CrateDir::try_from( c_temp_path ).unwrap(); let c_temp_crate_dir = CrateDir::try_from( c_temp_absolute_path.clone() ).unwrap(); - let c_package = Package::try_from( c_temp_absolute_path.clone() ).unwrap(); + let c_package = Package::try_from( c_temp_crate_dir.clone() ).unwrap(); let version = c_package.version().unwrap(); let root_manifest_path = temp.join( "Cargo.toml" ); let mut cargo_toml = std::fs::File::create( &root_manifest_path ).unwrap(); - let root_manifest_absolute_path = AbsolutePath::try_from( root_manifest_path.as_path() ).unwrap(); + // let root_manifest_absolute_path = AbsolutePath::try_from( root_manifest_path.as_path() ).unwrap(); + let root_manifest_dir_absolute_path = CrateDir::try_from( root_manifest_path.as_path().parent().unwrap() ).unwrap(); write!( cargo_toml, r#" [workspace] resolver = "2" @@ -131,17 +132,17 @@ default-features = true "# ).unwrap(); let version = Version::try_from( &version ).unwrap(); let bumped_version = version.clone().bump(); - + // Act let options = BumpOptions { - crate_dir : c_temp_crate_dir, + crate_dir : c_temp_crate_dir.clone(), old_version : version.clone(), new_version : bumped_version.clone(), - dependencies : vec![ CrateDir::try_from( root_manifest_absolute_path.parent().unwrap() ).unwrap() ], + dependencies : vec![ root_manifest_dir_absolute_path.clone() ], dry : false, }; - let bump_report = version_bump( options ).unwrap(); + let bump_report = bump( options ).unwrap(); // Assert assert_eq!( Some( version.to_string() ), bump_report.old_version ); @@ -149,7 +150,8 @@ default-features = true assert_eq! ( { - let mut v = vec![ root_manifest_absolute_path.clone(), c_temp_absolute_path.join( "Cargo.toml" ) ]; + // let mut v = vec![ root_manifest_absolute_path.clone(), c_temp_absolute_path.join( "Cargo.toml" ) ]; + let mut v = vec![ root_manifest_dir_absolute_path.clone().manifest_file(), c_temp_absolute_path.manifest_file() ]; v.sort(); v }, @@ -159,11 +161,11 @@ default-features = true v } ); - let c_package = Package::try_from( c_temp_absolute_path.clone() ).unwrap(); + let c_package = Package::try_from( c_temp_crate_dir.clone() ).unwrap(); let name = c_package.name().unwrap(); assert_eq!( bumped_version.to_string(), c_package.version().unwrap() ); - let mut root_manifest = Manifest::try_from( root_manifest_absolute_path ).unwrap(); - root_manifest.load().unwrap(); + let mut root_manifest = Manifest::try_from( root_manifest_dir_absolute_path ).unwrap(); + // root_manifest.load().unwrap(); let data = root_manifest.data(); let current_version_item = data.get( "workspace" ).and_then( | w | w.get( "dependencies" ) ).and_then( | d | d.get( &name ) ).and_then( | p | p.get( "version" ) ).unwrap(); let current_version = current_version_item.as_str().unwrap(); @@ -182,12 +184,12 @@ fn package_version_bump_revert() let c_temp_path = temp_module.join( "c" ); let c_temp_absolute_path = AbsolutePath::try_from( c_temp_path ).unwrap(); let c_temp_crate_dir = CrateDir::try_from( c_temp_absolute_path.clone() ).unwrap(); - let c_package = Package::try_from( c_temp_absolute_path.clone() ).unwrap(); + let c_package = Package::try_from( c_temp_crate_dir.clone() ).unwrap(); let version = c_package.version().unwrap(); let root_manifest_path = temp.join( "Cargo.toml" ); let mut cargo_toml = std::fs::File::create( &root_manifest_path ).unwrap(); - let root_manifest_absolute_path = AbsolutePath::try_from( root_manifest_path.as_path() ).unwrap(); + let root_manifest_dir_absolute_path = CrateDir::try_from( root_manifest_path.as_path().parent().unwrap() ).unwrap(); write!( cargo_toml, r#" [workspace] resolver = "2" @@ -205,21 +207,21 @@ default-features = true // Act let options = BumpOptions { - crate_dir : c_temp_crate_dir, + crate_dir : c_temp_crate_dir.clone(), old_version : version.clone(), new_version : bumped_version.clone(), - dependencies : vec![ CrateDir::try_from( root_manifest_absolute_path.parent().unwrap() ).unwrap() ], + dependencies : vec![ root_manifest_dir_absolute_path.clone() ], dry : false, }; - let bump_report = version_bump( options ).unwrap(); - version_revert( &bump_report ).unwrap(); + let bump_report = bump( options ).unwrap(); + revert( &bump_report ).unwrap(); // Assert - let c_package = Package::try_from( c_temp_absolute_path.clone() ).unwrap(); + let c_package = Package::try_from( c_temp_crate_dir.clone() ).unwrap(); let name = c_package.name().unwrap(); assert_eq!( version.to_string(), c_package.version().unwrap() ); - let mut root_manifest = Manifest::try_from( root_manifest_absolute_path ).unwrap(); - root_manifest.load().unwrap(); + let mut root_manifest = Manifest::try_from( root_manifest_dir_absolute_path ).unwrap(); + // root_manifest.load().unwrap(); let data = root_manifest.data(); let current_version_item = data.get( "workspace" ).and_then( | w | w.get( "dependencies" ) ).and_then( | d | d.get( &name ) ).and_then( | p | p.get( "version" ) ).unwrap(); let current_version = current_version_item.as_str().unwrap(); diff --git a/module/move/willbe/tests/inc/helper.rs b/module/move/willbe/tests/inc/helper.rs new file mode 100644 index 0000000000..2efa341f9d --- /dev/null +++ b/module/move/willbe/tests/inc/helper.rs @@ -0,0 +1,116 @@ +use super::*; +use the_module::*; +use path::{ Path, PathBuf }; +use std:: +{ + fs::{ self, File }, + io::Write, +}; + +pub const BINARY_NAME : &'static str = "will"; + +#[ derive( Debug ) ] +pub struct ProjectBuilder +{ + name : String, + lib_content : Option< String >, + test_content : Option< String >, + toml_content : Option< String >, +} + +impl ProjectBuilder +{ + pub fn new( name : &str ) -> Self + { + Self + { + name : String::from( name ), + lib_content : None, + test_content : None, + toml_content : None, + } + } + + pub fn lib_file< S : Into< String > >( mut self, content : S ) -> Self + { + self.lib_content = Some( content.into() ); + self + } + + pub fn test_file< S : Into< String > >( mut self, content : S ) -> Self + { + self.test_content = Some( content.into() ); + self + } + + pub fn toml_file( mut self, content : &str ) -> Self + { + self.toml_content = Some( format!( "[package]\nname = \"{}\"\nversion = \"0.1.0\"\nedition = \"2021\"\n{}", self.name, content ) ); + self + } + + pub fn build< P : AsRef< Path > >( &self, path : P ) -> std::io::Result< PathBuf > + { + let project_path = path.as_ref(); + + fs::create_dir_all( project_path.join( "src" ) )?; + fs::create_dir_all( project_path.join( "tests" ) )?; + + if let Some( content ) = &self.toml_content + { + let mut file = File::create( project_path.join( "Cargo.toml" ) )?; + write!( file, "{}", content )?; + } + + let mut file = File::create( project_path.join( "src/lib.rs" ) )?; + if let Some( content ) = &self.lib_content + { + write!( file, "{}", content )?; + } + + if let Some( content ) = &self.test_content + { + let mut file = File::create( project_path.join( "tests/tests.rs" ) )?; + write!( file, "{}", content )?; + } + + Ok( project_path.to_path_buf() ) + } +} + +pub struct WorkspaceBuilder +{ + pub members : Vec< ProjectBuilder >, + pub toml_content : String, +} + +impl WorkspaceBuilder +{ + pub fn new() -> Self + { + Self + { + members : vec![], + toml_content : "[workspace]\nresolver = \"2\"\nmembers = [\n \"modules/*\",\n]\n".to_string(), + } + } + + pub fn member( mut self, project : ProjectBuilder ) -> Self + { + self.members.push( project ); + self + } + + pub fn build< P : AsRef< Path > >( self, path : P ) -> PathBuf + { + let project_path = path.as_ref(); + fs::create_dir_all( project_path.join( "modules" ) ).unwrap(); + let mut file = File::create( project_path.join( "Cargo.toml" ) ).unwrap(); + write!( file, "{}", self.toml_content ).unwrap(); + for member in self.members + { + member.build( project_path.join( "modules" ).join( &member.name ) ).unwrap(); + } + project_path.into() + } +} diff --git a/module/move/willbe/tests/inc/helpers.rs b/module/move/willbe/tests/inc/helpers.rs deleted file mode 100644 index c2c1ded1d5..0000000000 --- a/module/move/willbe/tests/inc/helpers.rs +++ /dev/null @@ -1 +0,0 @@ -pub const BINARY_NAME : &'static str = "will"; diff --git a/module/move/willbe/tests/inc/mod.rs b/module/move/willbe/tests/inc/mod.rs index b7a5680237..ca9dbda05d 100644 --- a/module/move/willbe/tests/inc/mod.rs +++ b/module/move/willbe/tests/inc/mod.rs @@ -1,10 +1,22 @@ use super::*; -mod action; -mod package; -mod command; +/// Entities of which spaces consists of. mod entity; + +/// Genera-purpose tools which might be moved out one day. mod tool; -mod helpers; -// qqq : for Petro : for Bohdan : sort out test files to be consistent with src files +/// Describes CLI commands. +mod command; + +/// Describes functions that can be called from an interface. +mod action_tests; + +mod helper; + +// aaa : for Petro : for Bohdan : for Nikita : sort out test files to be consistent with src files +// sorted + +// qqq : for Mykyta: to avoid names collisions add postfix _test for all dirs and files in dir `inc` +// query.rs -> query_test.rs + diff --git a/module/move/willbe/tests/inc/package.rs b/module/move/willbe/tests/inc/package.rs index 935069b5e6..8a5fb2a2f0 100644 --- a/module/move/willbe/tests/inc/package.rs +++ b/module/move/willbe/tests/inc/package.rs @@ -2,11 +2,11 @@ // use the_module:: // { // Workspace, -// _path::AbsolutePath, +// path::AbsolutePath, // package::PublishPlan, // }; // use willbe::package::perform_packages_publish; -// +// // #[ test ] // fn plan_publish_many_packages() // { @@ -27,7 +27,7 @@ // // ), // // dry: true, // // }, -// // version_bump: BumpOptions { +// // bump: BumpOptions { // // crate_dir: CrateDir( // // AbsolutePath( // // ".../wTools/module/move/wca", @@ -170,3 +170,5 @@ // // ) // panic!() // } + +// qqq : for Bohdan : fix the test diff --git a/module/move/willbe/tests/inc/tool/graph.rs b/module/move/willbe/tests/inc/tool/graph.rs deleted file mode 100644 index 28c08d7b75..0000000000 --- a/module/move/willbe/tests/inc/tool/graph.rs +++ /dev/null @@ -1,217 +0,0 @@ -mod toposort -{ - use crate::the_module::*; - use graph::toposort; - use std::collections::HashMap; - use petgraph::Graph; - use willbe::graph::topological_sort_with_grouping; - - struct IndexMap< T >( HashMap< T, usize > ); - - impl< T > IndexMap< T > - where - T : std::hash::Hash + Eq, - { - pub fn new( elements : Vec< T > ) -> Self - { - let index_map = elements.into_iter().enumerate().map( |( index, value )| ( value, index ) ).collect(); - Self( index_map ) - } - - pub fn position( &self, element : &T ) -> usize - { - self.0[ element ] - } - } - - #[ test ] - fn no_dependency() - { - let mut graph = Graph::new(); - - let _node1 = graph.add_node( &"A" ); - let _node2 = graph.add_node( &"B" ); - - let sorted = toposort( graph ).unwrap(); - - let index_map = IndexMap::new( sorted ); - let node1_position = index_map.position( &"A" ); - let node2_position = index_map.position( &"B" ); - - assert!( node1_position < node2_position ); - } - - #[ test ] - fn a_depends_on_b() - { - let mut graph = Graph::new(); - - let node1 = graph.add_node( &"A" ); - let node2 = graph.add_node( &"B" ); - - graph.add_edge( node1, node2, &"" ); - - let sorted = toposort( graph ).unwrap(); - - let index_map = IndexMap::new( sorted ); - let node1_position = index_map.position( &"A" ); - let node2_position = index_map.position( &"B" ); - - assert!( node1_position > node2_position ); - } - - #[ test ] - fn multiple_dependencies() - { - let mut graph = Graph::new(); - - let a = graph.add_node( &"A" ); - let b = graph.add_node( &"B" ); - let c = graph.add_node( &"C" ); - - graph.add_edge( a, b, &"" ); - graph.add_edge( a, c, &"" ); - - let sorted = toposort( graph ).unwrap(); - - let index_map = IndexMap::new( sorted ); - let a_position = index_map.position( &"A" ); - let b_position = index_map.position( &"B" ); - let c_position = index_map.position( &"C" ); - - assert!( a_position > b_position ); - assert!( a_position > c_position ); - } - - #[ test ] - fn transitive_dependencies() - { - let mut graph = Graph::new(); - - let a = graph.add_node( &"A" ); - let b = graph.add_node( &"B" ); - let c = graph.add_node( &"C" ); - - graph.add_edge( a, b, &"" ); - graph.add_edge( b, c, &"" ); - - let sorted = toposort( graph ).unwrap(); - - let index_map = IndexMap::new( sorted ); - let a_position = index_map.position( &"A" ); - let b_position = index_map.position( &"B" ); - let c_position = index_map.position( &"C" ); - - assert!( a_position > b_position ); - assert!( b_position > c_position ); - } - - #[ test ] - #[ should_panic( expected = "Cycle" ) ] - fn cycle() - { - let mut graph = Graph::new(); - - let node1 = graph.add_node( &"A" ); - let node2 = graph.add_node( &"B" ); - - graph.add_edge( node1, node2, &"" ); - graph.add_edge( node2, node1, &"" ); - - let _sorted = toposort( graph ).unwrap(); - } - - // input - // B -> A - // C -> A - // output - // [A], [B,C] - #[ test ] - fn simple_case() - { - let mut graph = Graph::new(); - - let a_node = graph.add_node( &"A" ); - let b_node = graph.add_node( &"B" ); - let c_node = graph.add_node( &"C" ); - - graph.add_edge( b_node, a_node, &"B->A"); - graph.add_edge( c_node, a_node, &"C->A"); - - let groups = topological_sort_with_grouping( graph ); - - assert_eq!( groups[ 0 ], vec![ "A" ] ); - assert_eq!( groups[1].len(), 2 ); - assert!( groups[ 1 ].contains( &"C" ) ); - assert!( groups[ 1 ].contains( &"B" ) ); - } - - // input - // digraph { - // 0 [ label = "0" ] - // 1 [ label = "1" ] - // 2 [ label = "2" ] - // 3 [ label = "3" ] - // 4 [ label = "4" ] - // 5 [ label = "5" ] - // 6 [ label = "6" ] - // 7 [ label = "7" ] - // 4 -> 0 [ label = "" ] - // 5 -> 0 [ label = "" ] - // 6 -> 0 [ label = "" ] - // 1 -> 3 [ label = "" ] - // 2 -> 3 [ label = "" ] - // 7 -> 6 [ label = "" ] - // 3 -> 4 [ label = "" ] - // 3 -> 5 [ label = "" ] - // 3 -> 6 [ label = "" ] - // } - // visualization : https://viz-js.com/?dot=ZGlncmFwaCB7CiAgICAwIFsgbGFiZWwgPSAiMCIgXQogICAgMSBbIGxhYmVsID0gIjEiIF0KICAgIDIgWyBsYWJlbCA9ICIyIiBdCiAgICAzIFsgbGFiZWwgPSAiMyIgXQogICAgNCBbIGxhYmVsID0gIjQiIF0KICAgIDUgWyBsYWJlbCA9ICI1IiBdCiAgICA2IFsgbGFiZWwgPSAiNiIgXQogICAgNyBbIGxhYmVsID0gIjciIF0KICAgIDQgLT4gMCBbIGxhYmVsID0gIiIgXQogICAgNSAtPiAwIFsgbGFiZWwgPSAiIiBdCiAgICA2IC0-IDAgWyBsYWJlbCA9ICIiIF0KICAgIDEgLT4gMyBbIGxhYmVsID0gIiIgXQogICAgMiAtPiAzIFsgbGFiZWwgPSAiIiBdCiAgICA3IC0-IDYgWyBsYWJlbCA9ICIiIF0KICAgIDMgLT4gNCBbIGxhYmVsID0gIiIgXQogICAgMyAtPiA1IFsgbGFiZWwgPSAiIiBdCiAgICAzIC0-IDYgWyBsYWJlbCA9ICIiIF0KfQo~ - // output - // [0], [6,5,4], [3], [1,2,7] - #[ test ] - fn complicated_test() - { - let mut graph = Graph::new(); - - let n = graph.add_node( &"0" ); - let n_1 = graph.add_node( &"1" ); - let n_2 = graph.add_node( &"2" ); - let n_3 = graph.add_node( &"3" ); - let n_4 = graph.add_node( &"4" ); - let n_5 = graph.add_node( &"5" ); - let n_6 = graph.add_node( &"6" ); - let n_7 = graph.add_node( &"7" ); - - graph.add_edge( n_1, n_3, &"" ); - graph.add_edge( n_2, n_3, &"" ); - graph.add_edge( n_7, n_6, &"" ); - - graph.add_edge( n_3, n_4, &"" ); - graph.add_edge( n_3, n_5, &"" ); - graph.add_edge( n_3, n_6, &"" ); - - graph.add_edge( n_4, n, &"" ); - graph.add_edge( n_5, n, &"" ); - graph.add_edge( n_6, n, &"" ); - - let groups = topological_sort_with_grouping( graph ); - - dbg!(&groups); - - assert_eq!( groups[ 0 ], vec![ "0" ] ); - - assert_eq!( groups[1].len(), 3 ); - assert!( groups[ 1 ].contains( &"6" ) ); - assert!( groups[ 1 ].contains( &"5" ) ); - assert!( groups[ 1 ].contains( &"4" ) ); - - assert_eq!( groups[ 2 ], vec![ "3" ] ); - - assert_eq!( groups[3].len(), 3 ); - assert!( groups[ 3 ].contains( &"1" ) ); - assert!( groups[ 3 ].contains( &"2" ) ); - assert!( groups[ 3 ].contains( &"7" ) ); - } - -} \ No newline at end of file diff --git a/module/move/willbe/tests/inc/tool/graph_test.rs b/module/move/willbe/tests/inc/tool/graph_test.rs new file mode 100644 index 0000000000..d6f5c38986 --- /dev/null +++ b/module/move/willbe/tests/inc/tool/graph_test.rs @@ -0,0 +1,215 @@ +use super::*; + +use the_module::*; +use graph::toposort; +use collection::HashMap; +use petgraph::Graph; +use willbe::graph::topological_sort_with_grouping; + +struct IndexMap< T >( HashMap< T, usize > ); + +impl< T > IndexMap< T > +where + T : std::hash::Hash + Eq, +{ + pub fn new( elements : Vec< T > ) -> Self + { + let index_map = elements.into_iter().enumerate().map( |( index, value )| ( value, index ) ).collect(); + Self( index_map ) + } + + pub fn position( &self, element : &T ) -> usize + { + self.0[ element ] + } +} + +#[ test ] +fn no_dependency() +{ + let mut graph = Graph::new(); + + let _node1 = graph.add_node( &"A" ); + let _node2 = graph.add_node( &"B" ); + + let sorted = toposort( graph ).unwrap(); + + let index_map = IndexMap::new( sorted ); + let node1_position = index_map.position( &"A" ); + let node2_position = index_map.position( &"B" ); + + assert!( node1_position < node2_position ); +} + +#[ test ] +fn a_depends_on_b() +{ + let mut graph = Graph::new(); + + let node1 = graph.add_node( &"A" ); + let node2 = graph.add_node( &"B" ); + + graph.add_edge( node1, node2, &"" ); + + let sorted = toposort( graph ).unwrap(); + + let index_map = IndexMap::new( sorted ); + let node1_position = index_map.position( &"A" ); + let node2_position = index_map.position( &"B" ); + + assert!( node1_position > node2_position ); +} + +#[ test ] +fn multiple_dependencies() +{ + let mut graph = Graph::new(); + + let a = graph.add_node( &"A" ); + let b = graph.add_node( &"B" ); + let c = graph.add_node( &"C" ); + + graph.add_edge( a, b, &"" ); + graph.add_edge( a, c, &"" ); + + let sorted = toposort( graph ).unwrap(); + + let index_map = IndexMap::new( sorted ); + let a_position = index_map.position( &"A" ); + let b_position = index_map.position( &"B" ); + let c_position = index_map.position( &"C" ); + + assert!( a_position > b_position ); + assert!( a_position > c_position ); +} + +#[ test ] +fn transitive_dependencies() +{ + let mut graph = Graph::new(); + + let a = graph.add_node( &"A" ); + let b = graph.add_node( &"B" ); + let c = graph.add_node( &"C" ); + + graph.add_edge( a, b, &"" ); + graph.add_edge( b, c, &"" ); + + let sorted = toposort( graph ).unwrap(); + + let index_map = IndexMap::new( sorted ); + let a_position = index_map.position( &"A" ); + let b_position = index_map.position( &"B" ); + let c_position = index_map.position( &"C" ); + + assert!( a_position > b_position ); + assert!( b_position > c_position ); +} + +#[ test ] +#[ should_panic( expected = "Cycle" ) ] +fn cycle() +{ + let mut graph = Graph::new(); + + let node1 = graph.add_node( &"A" ); + let node2 = graph.add_node( &"B" ); + + graph.add_edge( node1, node2, &"" ); + graph.add_edge( node2, node1, &"" ); + + let _sorted = toposort( graph ).unwrap(); +} + +// input +// B -> A +// C -> A +// output +// [A], [B,C] +#[ test ] +fn simple_case() +{ + let mut graph = Graph::new(); + + let a_node = graph.add_node( &"A" ); + let b_node = graph.add_node( &"B" ); + let c_node = graph.add_node( &"C" ); + + graph.add_edge( b_node, a_node, &"B->A"); + graph.add_edge( c_node, a_node, &"C->A"); + + let groups = topological_sort_with_grouping( graph ); + + assert_eq!( groups[ 0 ], vec![ "A" ] ); + assert_eq!( groups[1].len(), 2 ); + assert!( groups[ 1 ].contains( &"C" ) ); + assert!( groups[ 1 ].contains( &"B" ) ); +} + +// input +// digraph { +// 0 [ label = "0" ] +// 1 [ label = "1" ] +// 2 [ label = "2" ] +// 3 [ label = "3" ] +// 4 [ label = "4" ] +// 5 [ label = "5" ] +// 6 [ label = "6" ] +// 7 [ label = "7" ] +// 4 -> 0 [ label = "" ] +// 5 -> 0 [ label = "" ] +// 6 -> 0 [ label = "" ] +// 1 -> 3 [ label = "" ] +// 2 -> 3 [ label = "" ] +// 7 -> 6 [ label = "" ] +// 3 -> 4 [ label = "" ] +// 3 -> 5 [ label = "" ] +// 3 -> 6 [ label = "" ] +// } +// visualization : https://viz-js.com/?dot=ZGlncmFwaCB7CiAgICAwIFsgbGFiZWwgPSAiMCIgXQogICAgMSBbIGxhYmVsID0gIjEiIF0KICAgIDIgWyBsYWJlbCA9ICIyIiBdCiAgICAzIFsgbGFiZWwgPSAiMyIgXQogICAgNCBbIGxhYmVsID0gIjQiIF0KICAgIDUgWyBsYWJlbCA9ICI1IiBdCiAgICA2IFsgbGFiZWwgPSAiNiIgXQogICAgNyBbIGxhYmVsID0gIjciIF0KICAgIDQgLT4gMCBbIGxhYmVsID0gIiIgXQogICAgNSAtPiAwIFsgbGFiZWwgPSAiIiBdCiAgICA2IC0-IDAgWyBsYWJlbCA9ICIiIF0KICAgIDEgLT4gMyBbIGxhYmVsID0gIiIgXQogICAgMiAtPiAzIFsgbGFiZWwgPSAiIiBdCiAgICA3IC0-IDYgWyBsYWJlbCA9ICIiIF0KICAgIDMgLT4gNCBbIGxhYmVsID0gIiIgXQogICAgMyAtPiA1IFsgbGFiZWwgPSAiIiBdCiAgICAzIC0-IDYgWyBsYWJlbCA9ICIiIF0KfQo~ +// output +// [0], [6,5,4], [3], [1,2,7] +#[ test ] +fn complicated_test() +{ + let mut graph = Graph::new(); + + let n = graph.add_node( &"0" ); + let n_1 = graph.add_node( &"1" ); + let n_2 = graph.add_node( &"2" ); + let n_3 = graph.add_node( &"3" ); + let n_4 = graph.add_node( &"4" ); + let n_5 = graph.add_node( &"5" ); + let n_6 = graph.add_node( &"6" ); + let n_7 = graph.add_node( &"7" ); + + graph.add_edge( n_1, n_3, &"" ); + graph.add_edge( n_2, n_3, &"" ); + graph.add_edge( n_7, n_6, &"" ); + + graph.add_edge( n_3, n_4, &"" ); + graph.add_edge( n_3, n_5, &"" ); + graph.add_edge( n_3, n_6, &"" ); + + graph.add_edge( n_4, n, &"" ); + graph.add_edge( n_5, n, &"" ); + graph.add_edge( n_6, n, &"" ); + + let groups = topological_sort_with_grouping( graph ); + + dbg!(&groups); + + assert_eq!( groups[ 0 ], vec![ "0" ] ); + + assert_eq!( groups[1].len(), 3 ); + assert!( groups[ 1 ].contains( &"6" ) ); + assert!( groups[ 1 ].contains( &"5" ) ); + assert!( groups[ 1 ].contains( &"4" ) ); + + assert_eq!( groups[ 2 ], vec![ "3" ] ); + + assert_eq!( groups[3].len(), 3 ); + assert!( groups[ 3 ].contains( &"1" ) ); + assert!( groups[ 3 ].contains( &"2" ) ); + assert!( groups[ 3 ].contains( &"7" ) ); +} diff --git a/module/move/willbe/tests/inc/tool/mod.rs b/module/move/willbe/tests/inc/tool/mod.rs index 5766a1e126..08275f5556 100644 --- a/module/move/willbe/tests/inc/tool/mod.rs +++ b/module/move/willbe/tests/inc/tool/mod.rs @@ -1,7 +1,4 @@ -// use super::*; +use super::*; -// pub mod process; - -pub mod graph; - -pub mod query; \ No newline at end of file +pub mod graph_test; +pub mod query_test; diff --git a/module/move/willbe/tests/inc/tool/process.rs b/module/move/willbe/tests/inc/tool/process.rs deleted file mode 100644 index 8d718c38d9..0000000000 --- a/module/move/willbe/tests/inc/tool/process.rs +++ /dev/null @@ -1,65 +0,0 @@ -// use super::*; -// -// use process_tools::process::*; -// -// use std::env::consts::EXE_EXTENSION; -// use std::ffi::OsString; -// use std::path::{ Path, PathBuf }; -// use std::process::Command; -// -// pub fn path_to_exe( name : &Path, temp_path : &Path ) -> PathBuf -// { -// _ = Command::new("rustc") -// .current_dir( temp_path ) -// .arg( name ) -// .status() -// .unwrap(); -// -// PathBuf::from( temp_path ) -// .join( name.file_name().unwrap() ) -// .with_extension( EXE_EXTENSION ) -// } -// -// #[ test ] -// fn err_out_err() -// { -// let temp = assert_fs::TempDir::new().unwrap(); -// let root_path = Path::new( env!( "CARGO_MANIFEST_DIR" ) ); -// let assets_relative_path = Path::new( ASSET_PATH ); -// let assets_path = root_path.join( assets_relative_path ); -// -// let args : [ OsString ; 0 ] = []; -// -// let options = process::Run::former() -// .bin_path( path_to_exe( &assets_path.join( "err_out_test" ).join( "err_out_err.rs" ), temp.path() ) ) -// .args( args.to_vec() ) -// .current_path( temp.to_path_buf() ) -// .joining_streams( true ) -// .form(); -// -// let report = process::run( options ).unwrap().out; -// -// assert_eq!( "This is stderr text\nThis is stdout text\nThis is stderr text\n", report ); -// } -// -// #[ test ] -// fn out_err_out() -// { -// let temp = assert_fs::TempDir::new().unwrap(); -// let root_path = Path::new( env!( "CARGO_MANIFEST_DIR" ) ); -// let assets_relative_path = Path::new( ASSET_PATH ); -// let assets_path = root_path.join( assets_relative_path ); -// -// let args : [ OsString ; 0 ] = []; -// -// let options = process::Run::former() -// .bin_path( path_to_exe( &assets_path.join( "err_out_test" ).join( "out_err_out.rs" ), temp.path() ) ) -// .args( args.to_vec() ) -// .current_path( temp.to_path_buf() ) -// .joining_streams( true ) -// .form(); -// let report = process::run( options ).unwrap().out; -// -// assert_eq!( "This is stdout text\nThis is stderr text\nThis is stdout text\n", report ); -// } -// diff --git a/module/move/willbe/tests/inc/tool/query.rs b/module/move/willbe/tests/inc/tool/query_test.rs similarity index 97% rename from module/move/willbe/tests/inc/tool/query.rs rename to module/move/willbe/tests/inc/tool/query_test.rs index 49c23b0946..fa98f5fab1 100644 --- a/module/move/willbe/tests/inc/tool/query.rs +++ b/module/move/willbe/tests/inc/tool/query_test.rs @@ -1,10 +1,11 @@ -use crate::the_module::query:: +use super::*; +use the_module::query:: { - parse, - ParseResult, - Value, + parse, + ParseResult, + Value, }; -use std::collections::HashMap; +use the_module::collection::HashMap; use std::str::FromStr; #[ test ] diff --git a/module/move/willbe/tests/smoke_test.rs b/module/move/willbe/tests/smoke_test.rs index febf7e83a0..dd681c20c1 100644 --- a/module/move/willbe/tests/smoke_test.rs +++ b/module/move/willbe/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/move/wplot/Cargo.toml b/module/move/wplot/Cargo.toml index fb02fc12fa..a128e4223a 100644 --- a/module/move/wplot/Cargo.toml +++ b/module/move/wplot/Cargo.toml @@ -23,7 +23,7 @@ workspace = true [package.metadata.docs.rs] features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] + include = [ "/rust/impl/plot", "/Cargo.toml", diff --git a/module/move/wplot/src/plot/abs/change.rs b/module/move/wplot/src/plot/abs/change.rs index 3d05cbcdbf..48c1e5cfb4 100644 --- a/module/move/wplot/src/plot/abs/change.rs +++ b/module/move/wplot/src/plot/abs/change.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - // use crate::protected::*; + // use crate::own::*; use core::fmt; use crate::abs::changer::private::ChangerInterface; diff --git a/module/move/wplot/src/plot/abs/changer.rs b/module/move/wplot/src/plot/abs/changer.rs index 8af8e00f03..1a5f9fdaf0 100644 --- a/module/move/wplot/src/plot/abs/changer.rs +++ b/module/move/wplot/src/plot/abs/changer.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - // use crate::protected::*; + // use crate::own::*; use core::fmt; use crate::abs::change::private::ChangeInterface; diff --git a/module/move/wplot/src/plot/abs/context.rs b/module/move/wplot/src/plot/abs/context.rs index 4c2716661d..3ad4970206 100644 --- a/module/move/wplot/src/plot/abs/context.rs +++ b/module/move/wplot/src/plot/abs/context.rs @@ -2,7 +2,7 @@ #[ cfg( not( feature = "no_std" ) ) ] pub( crate ) mod private { - // use crate::protected::*; + // use crate::own::*; use core::fmt; // use wtools::From_0; diff --git a/module/move/wplot/src/plot/abs/identity.rs b/module/move/wplot/src/plot/abs/identity.rs index 4a181d63fe..1ec0802a79 100644 --- a/module/move/wplot/src/plot/abs/identity.rs +++ b/module/move/wplot/src/plot/abs/identity.rs @@ -2,7 +2,7 @@ #[ cfg( not( feature = "no_std" ) ) ] pub( crate ) mod private { - // use crate::protected::*; + // use crate::own::*; use once_cell::sync::Lazy; use std::sync::Mutex; use core::{hash::Hash, fmt}; diff --git a/module/move/wplot/src/plot/abs/registry.rs b/module/move/wplot/src/plot/abs/registry.rs index af48a2062d..8844149feb 100644 --- a/module/move/wplot/src/plot/abs/registry.rs +++ b/module/move/wplot/src/plot/abs/registry.rs @@ -2,7 +2,7 @@ #[ cfg( not( feature = "no_std" ) ) ] pub( crate ) mod private { - // use crate::protected::*; + // use crate::own::*; // use crate::abs::*; use once_cell::sync::Lazy; // use wtools::from; diff --git a/module/move/wplot/src/plot/color.rs b/module/move/wplot/src/plot/color.rs index 9ded69bdfc..6fd07c0bcc 100644 --- a/module/move/wplot/src/plot/color.rs +++ b/module/move/wplot/src/plot/color.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - // use crate::protected::*; + // use crate::own::*; use core::fmt; use num_traits::{ Zero }; /* zzz : consider as submodule for wtools */ @@ -93,7 +93,7 @@ pub( crate ) mod private ::meta_tools::mod_interface! { - protected use ::rgb::*; + own use ::rgb::*; #[ cfg( not( feature = "no_std" ) ) ] exposed use Rgba; diff --git a/module/move/wplot/src/plot/sys/context.rs b/module/move/wplot/src/plot/sys/context.rs index 8a7ed41bc9..904b0f03e3 100644 --- a/module/move/wplot/src/plot/sys/context.rs +++ b/module/move/wplot/src/plot/sys/context.rs @@ -2,7 +2,7 @@ pub( crate ) mod private { use crate::abs::registry::private::Registry; - use crate::protected::*; + use crate::own::*; // use crate::abs::*; use once_cell::sync::Lazy; @@ -90,6 +90,6 @@ pub( crate ) mod private crate::mod_interface! { - protected use { REGISTRY, current }; + own use { REGISTRY, current }; exposed use { Context, current as context }; } diff --git a/module/move/wplot/src/plot/sys/context_changer.rs b/module/move/wplot/src/plot/sys/context_changer.rs index 202be58c58..48f1784ff7 100644 --- a/module/move/wplot/src/plot/sys/context_changer.rs +++ b/module/move/wplot/src/plot/sys/context_changer.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - // use crate::protected::*; + // use crate::own::*; use core::fmt; use crate::{abs::{identity::private::{Id, HasIdInterface}, change::private::ChangeInterface, changer::private::ChangerInterface}, StrokeBrushChanger, sys::drawing::changer::private::DrawChanger}; diff --git a/module/move/wplot/src/plot/sys/drawing.rs b/module/move/wplot/src/plot/sys/drawing.rs index 0c997329c8..4c6df7c8c5 100644 --- a/module/move/wplot/src/plot/sys/drawing.rs +++ b/module/move/wplot/src/plot/sys/drawing.rs @@ -3,7 +3,7 @@ pub(crate) mod changer; /// Internal namespace. pub( crate ) mod private { - // use crate::protected::*; + // use crate::own::*; use crate::abs::identity::private::{Id, HasIdInterface}; diff --git a/module/move/wplot/src/plot/sys/drawing/change_new.rs b/module/move/wplot/src/plot/sys/drawing/change_new.rs index 44d47fd981..af0ae7f483 100644 --- a/module/move/wplot/src/plot/sys/drawing/change_new.rs +++ b/module/move/wplot/src/plot/sys/drawing/change_new.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - // use crate::protected::*; + // use crate::own::*; use crate::abs::{change::private::ChangeInterface, identity::private::Id}; /// ChangerInterface of brush stroke. diff --git a/module/move/wplot/src/plot/sys/drawing/changer.rs b/module/move/wplot/src/plot/sys/drawing/changer.rs index 5ddb3e5f3a..2540cc9bb4 100644 --- a/module/move/wplot/src/plot/sys/drawing/changer.rs +++ b/module/move/wplot/src/plot/sys/drawing/changer.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - // use crate::protected::*; + // use crate::own::*; use crate::{abs::{identity::private::{Id, HasIdInterface}, changer::private::ChangerInterface}, ContextChanger, sys::drawing::{rect_changer::private::RectChanger, change_new::private::DrawingChangeNew}}; use crate::abs::change::private::ChangeInterface; diff --git a/module/move/wplot/src/plot/sys/drawing/command.rs b/module/move/wplot/src/plot/sys/drawing/command.rs index 8108cbcf17..e10b140493 100644 --- a/module/move/wplot/src/plot/sys/drawing/command.rs +++ b/module/move/wplot/src/plot/sys/drawing/command.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - // use crate::protected::*; + // use crate::own::*; // /// Interface of command to draw something. // pub trait DrawCommandInterface diff --git a/module/move/wplot/src/plot/sys/drawing/queue.rs b/module/move/wplot/src/plot/sys/drawing/queue.rs index 6b9ba83b3c..06367a519a 100644 --- a/module/move/wplot/src/plot/sys/drawing/queue.rs +++ b/module/move/wplot/src/plot/sys/drawing/queue.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - // use crate::protected::*; + // use crate::own::*; // use crate::drawing_changer::*; // // /// Queue of draw commands. diff --git a/module/move/wplot/src/plot/sys/drawing/rect_change_new.rs b/module/move/wplot/src/plot/sys/drawing/rect_change_new.rs index c7af894d1c..7d088c86de 100644 --- a/module/move/wplot/src/plot/sys/drawing/rect_change_new.rs +++ b/module/move/wplot/src/plot/sys/drawing/rect_change_new.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - // use crate::protected::*; + // use crate::own::*; use crate::abs::{identity::private::Id, change::private::ChangeInterface}; /// Command to draw rectangle. diff --git a/module/move/wplot/src/plot/sys/drawing/rect_change_region.rs b/module/move/wplot/src/plot/sys/drawing/rect_change_region.rs index aa70c4947f..3035a71215 100644 --- a/module/move/wplot/src/plot/sys/drawing/rect_change_region.rs +++ b/module/move/wplot/src/plot/sys/drawing/rect_change_region.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - use crate::protected::*; + use crate::own::*; use crate::abs::change::private::ChangeInterface; use crate::abs::identity::private::Id; diff --git a/module/move/wplot/src/plot/sys/drawing/rect_changer.rs b/module/move/wplot/src/plot/sys/drawing/rect_changer.rs index f3ac913f77..5f8d13e3a3 100644 --- a/module/move/wplot/src/plot/sys/drawing/rect_changer.rs +++ b/module/move/wplot/src/plot/sys/drawing/rect_changer.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - use crate::protected::*; + use crate::own::*; use crate::abs::identity::private::Id; use crate::sys::context_changer::private::ContextChanger; use crate::sys::drawing::changer::private::DrawChanger; diff --git a/module/move/wplot/src/plot/sys/stroke_brush.rs b/module/move/wplot/src/plot/sys/stroke_brush.rs index 8cfe8c0b10..295b3be13d 100644 --- a/module/move/wplot/src/plot/sys/stroke_brush.rs +++ b/module/move/wplot/src/plot/sys/stroke_brush.rs @@ -4,7 +4,7 @@ mod change_new; /// Internal namespace. pub( crate ) mod private { - use crate::protected::*; + use crate::own::*; use crate::abs::identity::private::Id; use crate::abs::identity::private::HasIdInterface; diff --git a/module/move/wplot/src/plot/sys/stroke_brush/change_color.rs b/module/move/wplot/src/plot/sys/stroke_brush/change_color.rs index 98d55ffbaa..42a2e6f486 100644 --- a/module/move/wplot/src/plot/sys/stroke_brush/change_color.rs +++ b/module/move/wplot/src/plot/sys/stroke_brush/change_color.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - use crate::protected::*; + use crate::own::*; /// ChangerInterface of brush stroke. #[ allow( dead_code ) ] diff --git a/module/move/wplot/src/plot/sys/stroke_brush/change_new.rs b/module/move/wplot/src/plot/sys/stroke_brush/change_new.rs index 1a1160de67..43caacdae9 100644 --- a/module/move/wplot/src/plot/sys/stroke_brush/change_new.rs +++ b/module/move/wplot/src/plot/sys/stroke_brush/change_new.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - // use crate::protected::*; + // use crate::own::*; use crate::abs::{identity::private::Id, change::private::ChangeInterface}; diff --git a/module/move/wplot/src/plot/sys/stroke_brush/change_width.rs b/module/move/wplot/src/plot/sys/stroke_brush/change_width.rs index 1a6fa4aeed..b832e4b38d 100644 --- a/module/move/wplot/src/plot/sys/stroke_brush/change_width.rs +++ b/module/move/wplot/src/plot/sys/stroke_brush/change_width.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - // use crate::protected::*; + // use crate::own::*; use crate::abs::{change::private::ChangeInterface, identity::private::Id}; diff --git a/module/move/wplot/src/plot/sys/stroke_brush/changer.rs b/module/move/wplot/src/plot/sys/stroke_brush/changer.rs index 33ef3969e1..7195588297 100644 --- a/module/move/wplot/src/plot/sys/stroke_brush/changer.rs +++ b/module/move/wplot/src/plot/sys/stroke_brush/changer.rs @@ -1,7 +1,7 @@ /// Internal namespace. pub( crate ) mod private { - use crate::protected::*; + use crate::own::*; /// ChangerInterface of brush stroke. #[ allow( dead_code ) ] diff --git a/module/move/wplot/src/plot/wplot_lib.rs b/module/move/wplot/src/plot/wplot_lib.rs index c33e8463dd..3d0e411b7e 100644 --- a/module/move/wplot/src/plot/wplot_lib.rs +++ b/module/move/wplot/src/plot/wplot_lib.rs @@ -46,7 +46,7 @@ pub mod dependency // layer sys; use super::math; - protected use ::wmath as math; - protected( crate ) use ::wtools::prelude::*; + own use ::wmath as math; + own use ::wtools::prelude::*; } diff --git a/module/move/wplot/tests/smoke_test.rs b/module/move/wplot/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/move/wplot/tests/smoke_test.rs +++ b/module/move/wplot/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/postponed/_video_experiment/Cargo.toml b/module/postponed/_video_experiment/Cargo.toml index b167ebec39..b5b8409690 100644 --- a/module/postponed/_video_experiment/Cargo.toml +++ b/module/postponed/_video_experiment/Cargo.toml @@ -23,7 +23,7 @@ workspace = true [package.metadata.docs.rs] features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] + include = [ "/rust/impl/_blank", "/Cargo.toml", diff --git a/module/postponed/_video_experiment/tests/smoke_test.rs b/module/postponed/_video_experiment/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/postponed/_video_experiment/tests/smoke_test.rs +++ b/module/postponed/_video_experiment/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/postponed/automata_tools/tests/smoke_test.rs b/module/postponed/automata_tools/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/postponed/automata_tools/tests/smoke_test.rs +++ b/module/postponed/automata_tools/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/postponed/non_std/Cargo.toml b/module/postponed/non_std/Cargo.toml index 4b9d85d843..516d197d99 100644 --- a/module/postponed/non_std/Cargo.toml +++ b/module/postponed/non_std/Cargo.toml @@ -170,19 +170,19 @@ string_split = [ "string", "wtools/string_split" ] error = [ "wtools/error" ] error_default = [ "error", - "error_for_lib", - "error_for_app", + "error_typed", + "error_untyped", ] error_full = [ "error", - "error_for_lib", - "error_for_app", + "error_typed", + "error_untyped", ] error_no_std = [ "error", "wtools/error_no_std" ] error_use_alloc = [ "error", "wtools/error_use_alloc" ] -error_for_lib = [ "error", "wtools/error_for_lib" ] -error_for_app = [ "error", "wtools/error_for_app" ] +error_typed = [ "error", "wtools/error_typed" ] +error_untyped = [ "error", "wtools/error_untyped" ] # derive diff --git a/module/postponed/non_std/tests/smoke_test.rs b/module/postponed/non_std/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/postponed/non_std/tests/smoke_test.rs +++ b/module/postponed/non_std/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/postponed/std_tools/Cargo.toml b/module/postponed/std_tools/Cargo.toml index e785849ad9..44d29afa00 100644 --- a/module/postponed/std_tools/Cargo.toml +++ b/module/postponed/std_tools/Cargo.toml @@ -171,19 +171,19 @@ string_split = [ "string", "wtools/string_split" ] error = [ "wtools/error" ] error_default = [ "error", - "error_for_lib", - "error_for_app", + "error_typed", + "error_untyped", ] error_full = [ "error", - "error_for_lib", - "error_for_app", + "error_typed", + "error_untyped", ] error_no_std = [ "error", "wtools/error_no_std" ] error_use_alloc = [ "error", "wtools/error_use_alloc" ] -error_for_lib = [ "error", "wtools/error_for_lib" ] -error_for_app = [ "error", "wtools/error_for_app" ] +error_typed = [ "error", "wtools/error_typed" ] +error_untyped = [ "error", "wtools/error_untyped" ] # derive diff --git a/module/postponed/std_tools/tests/smoke_test.rs b/module/postponed/std_tools/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/postponed/std_tools/tests/smoke_test.rs +++ b/module/postponed/std_tools/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/postponed/std_x/Cargo.toml b/module/postponed/std_x/Cargo.toml index 4795beee5e..5693aa40a1 100644 --- a/module/postponed/std_x/Cargo.toml +++ b/module/postponed/std_x/Cargo.toml @@ -173,19 +173,19 @@ string_split = [ "string", "wtools/string_split" ] error = [ "wtools/error" ] error_default = [ "error", - "error_for_lib", - "error_for_app", + "error_typed", + "error_untyped", ] error_full = [ "error", - "error_for_lib", - "error_for_app", + "error_typed", + "error_untyped", ] error_no_std = [ "error", "wtools/error_no_std" ] error_use_alloc = [ "error", "wtools/error_use_alloc" ] -error_for_lib = [ "error", "wtools/error_for_lib" ] -error_for_app = [ "error", "wtools/error_for_app" ] +error_typed = [ "error", "wtools/error_typed" ] +error_untyped = [ "error", "wtools/error_untyped" ] # derive diff --git a/module/postponed/std_x/tests/smoke_test.rs b/module/postponed/std_x/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/postponed/std_x/tests/smoke_test.rs +++ b/module/postponed/std_x/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/postponed/type_constructor/Cargo.toml b/module/postponed/type_constructor/Cargo.toml index 0c12790c65..52dbcd6b95 100644 --- a/module/postponed/type_constructor/Cargo.toml +++ b/module/postponed/type_constructor/Cargo.toml @@ -24,7 +24,7 @@ workspace = true features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] + include = [ "/rust/impl/dt/type_constructor", "/Cargo.toml", diff --git a/module/postponed/type_constructor/src/lib.rs b/module/postponed/type_constructor/src/lib.rs index 600458bfd0..d850d048e5 100644 --- a/module/postponed/type_constructor/src/lib.rs +++ b/module/postponed/type_constructor/src/lib.rs @@ -54,35 +54,41 @@ pub mod dependency #[ doc( inline ) ] #[ allow( unused_imports ) ] #[ cfg( feature = "enabled" ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. +/// Own namespace of the module. #[ cfg( feature = "enabled" ) ] -pub mod protected +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::orphan::*; - pub use super::type_constuctor::protected::*; + pub use orphan::*; + pub use super::type_constuctor::own::*; } /// Shared with parent namespace of the module #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; pub use super::type_constuctor::orphan::*; } /// Exposed namespace of the module. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::type_constuctor::exposed::*; @@ -90,7 +96,9 @@ pub mod exposed /// Prelude to use essentials: `use my_module::prelude::*`. #[ cfg( feature = "enabled" ) ] +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; pub use super::type_constuctor::prelude::*; } diff --git a/module/postponed/type_constructor/src/type_constuctor/enumerable.rs b/module/postponed/type_constructor/src/type_constuctor/enumerable.rs index 31b7e3b352..9a7471c718 100644 --- a/module/postponed/type_constructor/src/type_constuctor/enumerable.rs +++ b/module/postponed/type_constructor/src/type_constuctor/enumerable.rs @@ -229,35 +229,40 @@ pub( crate ) mod private } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { EnumerableIteratorCopy, EnumerableIteratorRef, @@ -267,11 +272,12 @@ pub mod exposed /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { Enumerable, EnumerableMut, diff --git a/module/postponed/type_constructor/src/type_constuctor/helper.rs b/module/postponed/type_constructor/src/type_constuctor/helper.rs index e671e69bbc..fce61374b3 100644 --- a/module/postponed/type_constructor/src/type_constuctor/helper.rs +++ b/module/postponed/type_constructor/src/type_constuctor/helper.rs @@ -37,41 +37,48 @@ pub( crate ) mod private pub use _if_make; } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { _if_make, }; diff --git a/module/postponed/type_constructor/src/type_constuctor/make.rs b/module/postponed/type_constructor/src/type_constuctor/make.rs index 17ad9add6b..f10ff21b96 100644 --- a/module/postponed/type_constructor/src/type_constuctor/make.rs +++ b/module/postponed/type_constructor/src/type_constuctor/make.rs @@ -234,24 +234,24 @@ // pub use make; // } // -// /// Protected namespace of the module. -// pub mod protected +// /// Own namespace of the module. +// pub mod own // { // #[ doc( inline ) ] // #[ allow( unused_imports ) ] -// pub use super::orphan::*; +// pub use orphan::*; // } // // #[ doc( inline ) ] // #[ allow( unused_imports ) ] -// pub use protected::*; +// pub use own::*; // // /// Orphan namespace of the module. // pub mod orphan // { // #[ doc( inline ) ] // #[ allow( unused_imports ) ] -// pub use super::exposed::*; +// pub use exposed::*; // } // // /// Exposed namespace of the module. @@ -259,7 +259,7 @@ // { // #[ doc( inline ) ] // #[ allow( unused_imports ) ] -// pub use super::prelude::*; +// pub use prelude::*; // } // // #[ doc( inline ) ] @@ -272,7 +272,7 @@ // #[ cfg( feature = "make" ) ] // #[ doc( inline ) ] // // #[ allow( unused_imports ) ] -// pub use super::private:: +// pub use private:: // { // // From_0, diff --git a/module/postponed/type_constructor/src/type_constuctor/many.rs b/module/postponed/type_constructor/src/type_constuctor/many.rs index 0544dac8c0..b387c8e8e9 100644 --- a/module/postponed/type_constructor/src/type_constuctor/many.rs +++ b/module/postponed/type_constructor/src/type_constuctor/many.rs @@ -542,35 +542,40 @@ pub( crate ) mod private pub use _many; } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { _many, _vec, @@ -580,11 +585,12 @@ pub mod exposed /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { Many, }; diff --git a/module/postponed/type_constructor/src/type_constuctor/mod.rs b/module/postponed/type_constructor/src/type_constuctor/mod.rs index df047d149f..ce54e5f7fe 100644 --- a/module/postponed/type_constructor/src/type_constuctor/mod.rs +++ b/module/postponed/type_constructor/src/type_constuctor/mod.rs @@ -44,12 +44,14 @@ pub mod enumerable; #[ cfg( feature = "make" ) ] pub mod make; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::many::orphan::*; @@ -84,22 +86,26 @@ pub mod protected #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::many::exposed::*; @@ -133,8 +139,10 @@ pub mod exposed } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] pub use super::many::prelude::*; diff --git a/module/postponed/type_constructor/src/type_constuctor/no_many.rs b/module/postponed/type_constructor/src/type_constuctor/no_many.rs index 8e615be58b..e71f1a25e3 100644 --- a/module/postponed/type_constructor/src/type_constuctor/no_many.rs +++ b/module/postponed/type_constructor/src/type_constuctor/no_many.rs @@ -28,36 +28,41 @@ pub( crate ) mod private pub use _many; } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { _many, }; @@ -66,6 +71,8 @@ pub mod exposed /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; } diff --git a/module/postponed/type_constructor/src/type_constuctor/pair.rs b/module/postponed/type_constructor/src/type_constuctor/pair.rs index 18dfb74a30..7d1d3e35d0 100644 --- a/module/postponed/type_constructor/src/type_constuctor/pair.rs +++ b/module/postponed/type_constructor/src/type_constuctor/pair.rs @@ -195,35 +195,40 @@ pub( crate ) mod private // pub use type_constructor_meta; } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { _pair, }; @@ -231,11 +236,12 @@ pub mod exposed /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { Pair, HomoPair, diff --git a/module/postponed/type_constructor/src/type_constuctor/single.rs b/module/postponed/type_constructor/src/type_constuctor/single.rs index 23aecddbc7..84cf70165b 100644 --- a/module/postponed/type_constructor/src/type_constuctor/single.rs +++ b/module/postponed/type_constructor/src/type_constuctor/single.rs @@ -530,35 +530,40 @@ pub( crate ) mod private pub use _single; } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { _single, }; @@ -566,11 +571,12 @@ pub mod exposed /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { Single, }; diff --git a/module/postponed/type_constructor/src/type_constuctor/traits.rs b/module/postponed/type_constructor/src/type_constuctor/traits.rs index 97c74c822d..a08293166a 100644 --- a/module/postponed/type_constructor/src/type_constuctor/traits.rs +++ b/module/postponed/type_constructor/src/type_constuctor/traits.rs @@ -54,41 +54,48 @@ pub( crate ) mod private } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { CloneAsTuple, CloneAsArray, diff --git a/module/postponed/type_constructor/src/type_constuctor/types.rs b/module/postponed/type_constructor/src/type_constuctor/types.rs index c6c3aa2224..d13a02becf 100644 --- a/module/postponed/type_constructor/src/type_constuctor/types.rs +++ b/module/postponed/type_constructor/src/type_constuctor/types.rs @@ -810,41 +810,48 @@ pub( crate ) mod private pub use types; } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { types, }; diff --git a/module/postponed/type_constructor/src/type_constuctor/vectorized_from.rs b/module/postponed/type_constructor/src/type_constuctor/vectorized_from.rs index 3621b81c7e..10342de9e4 100644 --- a/module/postponed/type_constructor/src/type_constuctor/vectorized_from.rs +++ b/module/postponed/type_constructor/src/type_constuctor/vectorized_from.rs @@ -138,41 +138,48 @@ pub( crate ) mod private } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; } #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { VectorizedFrom, VectorizedInto, diff --git a/module/postponed/type_constructor/tests/smoke_test.rs b/module/postponed/type_constructor/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/postponed/type_constructor/tests/smoke_test.rs +++ b/module/postponed/type_constructor/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/postponed/wautomata/tests/smoke_test.rs b/module/postponed/wautomata/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/postponed/wautomata/tests/smoke_test.rs +++ b/module/postponed/wautomata/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/postponed/wpublisher/Cargo.toml b/module/postponed/wpublisher/Cargo.toml index 720a12fc59..194b0b7719 100644 --- a/module/postponed/wpublisher/Cargo.toml +++ b/module/postponed/wpublisher/Cargo.toml @@ -23,7 +23,7 @@ workspace = true [package.metadata.docs.rs] features = [ "full" ] all-features = false -# exclude = [ "/tests", "/examples", "-*" ] + include = [ "/rust/impl/publisher", "/Cargo.toml", diff --git a/module/postponed/wpublisher/tests/smoke_test.rs b/module/postponed/wpublisher/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/postponed/wpublisher/tests/smoke_test.rs +++ b/module/postponed/wpublisher/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/step/meta/src/meta/_template_procedural_macro/front/lib.rs b/module/step/meta/src/meta/_template_procedural_macro/front/lib.rs index 68e7399466..15e73ee498 100644 --- a/module/step/meta/src/meta/_template_procedural_macro/front/lib.rs +++ b/module/step/meta/src/meta/_template_procedural_macro/front/lib.rs @@ -23,24 +23,30 @@ pub mod dependency pub use procedural_macro_meta; } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { - pub use super::exposed::*; + use super::*; + pub use exposed::*; pub use procedural_macro_runtime as runtime; pub use procedural_macro_meta as meta; } -pub use protected::*; +pub use own::*; /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { - pub use super::prelude::*; + use super::*; + pub use prelude::*; pub use meta::*; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; } diff --git a/module/step/meta/src/meta/_template_procedural_macro/runtime/lib.rs b/module/step/meta/src/meta/_template_procedural_macro/runtime/lib.rs index 3afe6ce196..7c78810f2a 100644 --- a/module/step/meta/src/meta/_template_procedural_macro/runtime/lib.rs +++ b/module/step/meta/src/meta/_template_procedural_macro/runtime/lib.rs @@ -18,21 +18,27 @@ pub mod dependency { } -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { - pub use super::exposed::*; + use super::*; + pub use exposed::*; } -pub use protected::*; +pub use own::*; /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { - pub use super::prelude::*; + use super::*; + pub use prelude::*; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; } diff --git a/module/step/meta/tests/smoke_test.rs b/module/step/meta/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/step/meta/tests/smoke_test.rs +++ b/module/step/meta/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/template/layer/layer.rs b/module/template/layer/layer.rs index e3d184e4a0..960e56e28b 100644 --- a/module/template/layer/layer.rs +++ b/module/template/layer/layer.rs @@ -9,49 +9,54 @@ pub( crate ) mod private #[ doc( inline ) ] #[ allow( unused_imports ) ] -pub use protected::*; +pub use own::*; -/// Protected namespace of the module. -pub mod protected +/// Own namespace of the module. +#[ allow( unused_imports ) ] +pub mod own { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::orphan::*; + pub use orphan::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { // ... list all items of private which should be visible outside }; } /// Orphan namespace of the module. +#[ allow( unused_imports ) ] pub mod orphan { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::exposed::*; + pub use exposed::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { }; } /// Exposed namespace of the module. +#[ allow( unused_imports ) ] pub mod exposed { + use super::*; #[ doc( inline ) ] #[ allow( unused_imports ) ] - pub use super::prelude::*; + pub use prelude::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use super::private:: + pub use private:: { }; } /// Prelude to use essentials: `use my_module::prelude::*`. +#[ allow( unused_imports ) ] pub mod prelude { + use super::*; } diff --git a/module/template/template_alias/Cargo.toml.template b/module/template/template_alias/Cargo.toml.template index 3558c25ac2..33d69895ee 100644 --- a/module/template/template_alias/Cargo.toml.template +++ b/module/template/template_alias/Cargo.toml.template @@ -26,8 +26,6 @@ all-features = false [features] default = [ "enabled" ] full = [ "enabled" ] -no_std = [] -use_alloc = [ "no_std" ] enabled = [] [dependencies] diff --git a/module/template/template_alias/src/lib.rs b/module/template/template_alias/src/lib.rs index df4781f926..91af3152ee 100644 --- a/module/template/template_alias/src/lib.rs +++ b/module/template/template_alias/src/lib.rs @@ -1,4 +1,3 @@ -#![ cfg_attr( feature = "no_std", no_std ) ] #![ 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/{{template_blank}}/latest/{{template_blank}}/" ) ] diff --git a/module/template/template_alias/src/main.rs b/module/template/template_alias/src/main.rs index 24a55f0b95..4d9da5bfe8 100644 --- a/module/template/template_alias/src/main.rs +++ b/module/template/template_alias/src/main.rs @@ -1,4 +1,3 @@ -#![ cfg_attr( feature = "no_std", no_std ) ] #![ 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/{{template_blank}}/latest/{{template_blank}}/" ) ] diff --git a/module/template/template_alias/tests/smoke_test.rs b/module/template/template_alias/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/template/template_alias/tests/smoke_test.rs +++ b/module/template/template_alias/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/template/template_blank/Cargo.toml.template b/module/template/template_blank/Cargo.toml.template index 26aa549abe..1cc7fb96d0 100644 --- a/module/template/template_blank/Cargo.toml.template +++ b/module/template/template_blank/Cargo.toml.template @@ -26,8 +26,6 @@ all-features = false [features] default = [ "enabled" ] full = [ "enabled" ] -no_std = [] -use_alloc = [ "no_std" ] enabled = [] [dependencies] diff --git a/module/template/template_blank/src/lib.rs b/module/template/template_blank/src/lib.rs index ed1c86148e..42dd41b610 100644 --- a/module/template/template_blank/src/lib.rs +++ b/module/template/template_blank/src/lib.rs @@ -1,4 +1,3 @@ -#![ cfg_attr( feature = "no_std", no_std ) ] #![ 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/{{template_blank}}/latest/{{template_blank}}/" ) ] diff --git a/module/template/template_blank/tests/smoke_test.rs b/module/template/template_blank/tests/smoke_test.rs index 7fd288e61d..663dd6fb9f 100644 --- a/module/template/template_blank/tests/smoke_test.rs +++ b/module/template/template_blank/tests/smoke_test.rs @@ -1,12 +1,10 @@ -// #[ cfg( feature = "default" ) ] #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] #[ test ] fn published_smoke_test() { diff --git a/module/template/template_procedural_macro/tests/smoke_test.rs b/module/template/template_procedural_macro/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/template/template_procedural_macro/tests/smoke_test.rs +++ b/module/template/template_procedural_macro/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/template/template_procedural_macro_meta/tests/smoke_test.rs b/module/template/template_procedural_macro_meta/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/template/template_procedural_macro_meta/tests/smoke_test.rs +++ b/module/template/template_procedural_macro_meta/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/module/template/template_procedural_macro_runtime/tests/smoke_test.rs b/module/template/template_procedural_macro_runtime/tests/smoke_test.rs index 7fd288e61d..828e9b016b 100644 --- a/module/template/template_procedural_macro_runtime/tests/smoke_test.rs +++ b/module/template/template_procedural_macro_runtime/tests/smoke_test.rs @@ -1,12 +1,12 @@ -// #[ cfg( feature = "default" ) ] + #[ test ] fn local_smoke_test() { ::test_tools::smoke_test_for_local_run(); } -// #[ cfg( feature = "default" ) ] + #[ test ] fn published_smoke_test() { diff --git a/step/Cargo.toml b/step/Cargo.toml new file mode 100644 index 0000000000..70f00c8c96 --- /dev/null +++ b/step/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "step" +version = "0.0.0" +edition = "2021" +license = "MIT" +publish = false +readme = "Readme.md" +description = """ +Build and deploy steps. +""" + +[lints] +workspace = true + +[package.metadata.docs.rs] +features = [ "full" ] +all-features = false + +[dependencies] +# former = { workspace = true, features = [ "full" ] } +willbe = { workspace = true, features = [ "full" ] } + +[dev-dependencies] +test_tools = { workspace = true } diff --git a/step/src/bin/sources.rs b/step/src/bin/sources.rs new file mode 100644 index 0000000000..676fc25d02 --- /dev/null +++ b/step/src/bin/sources.rs @@ -0,0 +1,66 @@ +//! List all sources + +use willbe::exposed::*; +use willbe::{ Entries, Sources, CodeItems}; +use std:: +{ + fs, + fs::File, + io::Write, +}; + +fn main() -> Result< () > +{ + + let workspace = Workspace::try_from( CurrentPath )?; + + let package = workspace + .packages_which() + .crate_dir( CrateDir::transitive_try_from::< AbsolutePath >( CurrentPath )? ) + .find() + .expect( "No workspace at current path" ) + ; + + println!( " = package - {}", package.crate_dir().unwrap() ); + +// let ins = r#" +// pub mod exposed +// { +// "#; +// +// let sub = r#" +// pub mod exposed +// { +// #[ allow( unused_imports ) ] +// use super::*; +// "#; + + package.sources().for_each( | source | + { + println!( " - {source}" ); + + // let code = source.as_code().unwrap(); + // let code2 = code.replace( ins, sub ); + + // source + // .items() + // .for_each( | item | + // { + // println!( " - {}", std::any::type_name_of_val( &item ) ); + // // println!( " - item : {item:?}" ); + // }); + + }); + + // println!( "{}", package.as_code().unwrap() ); + + // let dst_path = format!( "{}.rs", package.name() ); + // let _ = fs::remove_file( &dst_path ); + // let code = package.as_code().unwrap(); + // let mut file = File::create( dst_path )?; + // file.write_all( code.as_bytes() )?; + + dbg!( &workspace.crate_dir ); + + return Ok( () ); +}