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/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/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/error.rs b/module/core/error_tools/src/error.rs index e74d61810e..7e23f88150 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. @@ -90,7 +183,7 @@ pub( crate ) mod private } } - impl ErrorInterface for BasicError + impl ErrorTrait for BasicError { fn description( &self ) -> &str { @@ -139,17 +232,24 @@ pub mod orphan pub mod exposed { use super::*; + + pub use private::ErrWith; + pub use private::ResultWithReport; + #[ doc( inline ) ] - pub use super::prelude::*; + pub use super::prelude::*; // xxx } /// Prelude to use essentials: `use my_module::prelude::*`. #[ allow( unused_imports ) ] pub mod prelude { + // xxx + pub use super::private::err; pub use super::private::return_err; - pub use super::private::ErrorInterface; + pub use super::private::ErrorTrait; pub use super::private::BasicError; + } // xxx : review \ No newline at end of file diff --git a/module/core/error_tools/src/lib.rs b/module/core/error_tools/src/lib.rs index 63e47efe76..635ed84dc7 100644 --- a/module/core/error_tools/src/lib.rs +++ b/module/core/error_tools/src/lib.rs @@ -14,7 +14,6 @@ pub mod assert; pub mod error; /// Namespace with dependencies. - #[ cfg( feature = "enabled" ) ] pub mod dependency { diff --git a/module/core/error_tools/src/untyped.rs b/module/core/error_tools/src/untyped.rs index 4c1da33d36..64e3fc2cd1 100644 --- a/module/core/error_tools/src/untyped.rs +++ b/module/core/error_tools/src/untyped.rs @@ -14,6 +14,17 @@ pub mod protected { #[ doc( inline ) ] pub use super::orphan::*; + + #[ doc( inline ) ] + pub use ::anyhow:: + { + Chain, + Context, + Error, + Ok, + Result, + }; + } /// Shared with parent namespace of the module @@ -27,10 +38,13 @@ pub mod orphan pub use super::exposed::*; #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use ::anyhow::*; - - // xxx : qqq : be specific + pub use ::anyhow:: + { + anyhow, + format_err, + ensure, + bail, + }; } @@ -43,14 +57,6 @@ pub mod exposed #[ doc( inline ) ] pub use super::prelude::*; - #[ doc( inline ) ] - #[ allow( unused_imports ) ] - pub use ::anyhow::Result; - - // #[ doc( inline ) ] - // #[ allow( unused_imports ) ] - // pub use ::anyhow::prelude::*; - } /// Prelude to use essentials: `use my_module::prelude::*`. 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..bc9f8edfe5 100644 --- a/module/core/error_tools/tests/inc/mod.rs +++ b/module/core/error_tools/tests/inc/mod.rs @@ -1,6 +1,7 @@ #[ allow( unused_imports ) ] use super::*; -mod basic_test; -mod for_app_test; mod assert_test; +mod basic_test; +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 73% rename from module/core/error_tools/tests/inc/for_app_test.rs rename to module/core/error_tools/tests/inc/untyped_test.rs index b76e52a16b..0705f598b5 100644 --- a/module/core/error_tools/tests/inc/for_app_test.rs +++ b/module/core/error_tools/tests/inc/untyped_test.rs @@ -10,8 +10,8 @@ tests_impls! { // 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::anyhow!( "err" ); + a_id!( the_module::untyped::Error::is::< &str >( &err ), true ); a_id!( err.is::< &str >(), true ); a_id!( err.to_string(), "err" ); } diff --git a/module/core/mod_interface_meta/src/lib.rs b/module/core/mod_interface_meta/src/lib.rs index eefcd860de..f06407f56b 100644 --- a/module/core/mod_interface_meta/src/lib.rs +++ b/module/core/mod_interface_meta/src/lib.rs @@ -38,6 +38,23 @@ // pub mod item_struct; // } +// xxx : check +// +// - does not work +// exposed use +// { +// ::former::Former, +// ::former::Assign, +// }; +// +// - work +// +// exposed use ::former:: +// { +// Former, +// Assign, +// }; + mod impls; #[ allow( unused_imports ) ] use impls::exposed::*; diff --git a/module/core/process_tools/src/process.rs b/module/core/process_tools/src/process.rs index 6c34f298f5..9786e183dc 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, anyhow }, + // Result, }; use former::Former; use iter_tools::iter::Itertools; diff --git a/module/move/unitore/src/action/config.rs b/module/move/unitore/src/action/config.rs index fae3bcf67d..eef632b981 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, 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/feed_config.rs b/module/move/unitore/src/feed_config.rs index 88b5f8a791..4cb2661fb3 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, 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..b41c466c2d 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::{ Result, untyped::Context }; // qqq : purpose of trait if any? // aaa : removed unnecessary trait diff --git a/module/move/unitore/src/sled_adapter/feed.rs b/module/move/unitore/src/sled_adapter/feed.rs index fb38e02075..273cafd2bd 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::{ Result, untyped::Context }; use gluesql:: { core:: @@ -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..43eccb8d8c 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::{ Result, untyped::Context }; use gluesql:: { core:: @@ -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..a07c44d942 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, Result }; use tokio::sync::Mutex; use gluesql:: { 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..a18b4ff26a 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,20 @@ 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::anyhow!( "{e:?}" )) + } + } } // 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..62b119c5ab 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. /// 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..4887618ccb 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::anyhow; 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" ) @@ -281,7 +281,7 @@ pub( crate ) mod private } }; - Ok::< _, error_tools::for_app::Error >( () ) + Ok::< _, error_tools::untyped::Error >( () ) }; let help = Command::former() diff --git a/module/move/wca/src/ca/mod.rs b/module/move/wca/src/ca/mod.rs index 9333e5ac5b..c8c75253cf 100644 --- a/module/move/wca/src/ca/mod.rs +++ b/module/move/wca/src/ca/mod.rs @@ -13,9 +13,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 +23,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..c6fa61165d 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 ) } } 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..41d75a3c19 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/" ) ] @@ -8,18 +7,17 @@ #![ allow( where_clauses_object_safety ) ] // https://github.com/chris-morgan/anymap/issues/31 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 +mod ca; crate::mod_interface! { - /// Commands aggregator library. - #[ cfg( not( feature = "no_std" ) ) ] - layer ca; + // #![ debug ] + + // xxx : syntax for that, please + use super::ca; + protected use super::ca::protected::*; + + // /// Commands aggregator library. + // layer ca; } diff --git a/module/move/wca/src/wtools.rs b/module/move/wca/src/wtools.rs index a5bf769f74..75a1392519 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::*; +// protected use ::iter_tools::Itertools; +// +// // protected use ::error_tools::err; +// // protected use ::error_tools::dependency::*; +// +// protected 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/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/src/action/cicd_renew.rs b/module/move/willbe/src/action/cicd_renew.rs index 989b9238d1..be3da20e6a 100644 --- a/module/move/willbe/src/action/cicd_renew.rs +++ b/module/move/willbe/src/action/cicd_renew.rs @@ -15,9 +15,9 @@ mod private use toml_edit::Document; use entity::PathError; - use error::typed::Error; + use error::typed::Error; // xxx - use error::untyped::{ Result, Error as wError }; + use error::untyped::{ Error as wError }; // xxx use entity::WorkspaceInitError; use error::err; @@ -325,7 +325,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() { @@ -355,7 +355,8 @@ mod private cargo_toml_path : &AbsolutePath, packages : impl Iterator< Item = WorkspacePackageRef< 'a > >, ) - -> Result< UsernameAndRepository > + -> error::untyped::Result< UsernameAndRepository > + // qqq : use typed error { let mut contents = String::new(); File::open( cargo_toml_path )?.read_to_string( &mut contents )?; diff --git a/module/move/willbe/src/action/deploy_renew.rs b/module/move/willbe/src/action/deploy_renew.rs index 8c45a714cb..2a6d3b52fd 100644 --- a/module/move/willbe/src/action/deploy_renew.rs +++ b/module/move/willbe/src/action/deploy_renew.rs @@ -2,7 +2,7 @@ mod private { use crate::*; use std::path::Path; - use error::{ untyped::Context, Result }; + use error::{ untyped::Context }; use tool::template::*; // /// Template for creating deploy files. @@ -21,7 +21,7 @@ mod private // impl Template< DeployTemplateFiles > for DeployTemplate // { - // fn create_all( self, path : &Path ) -> Result< () > + // fn create_all( self, path : &Path ) -> error::untyped::Result< () > // { // self.files.create_all( path, &self.values ) // } @@ -159,7 +159,9 @@ mod private ( path : &Path, mut template : TemplateHolder - ) -> Result< () > + ) + -> error::untyped::Result< () > + // qqq : typed error { if let None = template.load_existing_params( path ) { diff --git a/module/move/willbe/src/action/features.rs b/module/move/willbe/src/action/features.rs index 6560d1982b..26b8701cc2 100644 --- a/module/move/willbe/src/action/features.rs +++ b/module/move/willbe/src/action/features.rs @@ -10,7 +10,7 @@ mod private // // use path::AbsolutePath; use former::Former; - use error::{ untyped::Context, Result }; + use error::{ untyped::Context }; // use workspace::Workspace; /// Options available for the .features command @@ -68,7 +68,8 @@ mod private /// List features pub fn features( FeaturesOptions { crate_dir, with_features_deps } : FeaturesOptions ) - -> Result< FeaturesReport > + -> error::untyped::Result< FeaturesReport > + // qqq : typed error { let workspace = Workspace::try_from( crate_dir.clone() ).context( "Failed to find workspace" )?; let packages = workspace.packages().filter diff --git a/module/move/willbe/src/action/list.rs b/module/move/willbe/src/action/list.rs index f9931850a9..b25cf877a3 100644 --- a/module/move/willbe/src/action/list.rs +++ b/module/move/willbe/src/action/list.rs @@ -11,17 +11,13 @@ mod private visit::Topo, Graph, }; - use + use error:: { - error::{ Context, untyped, format_err, err }, - error::ErrWith, + ErrWith, err, + untyped::{ Context, format_err }, }; use tool::{ TreePrinter, ListNodeReport }; -// use petgraph::prelude::{ Dfs, EdgeRef }; -// use former::Former; -// use workspace::Workspace; - /// Args for `list` action. #[ derive( Debug, Default, Copy, Clone ) ] pub enum ListFormat @@ -35,7 +31,7 @@ mod private impl str::FromStr for ListFormat { - type Err = untyped::Error; + type Err = error::untyped::Error; fn from_str( s : &str ) -> Result< Self, Self::Err > { @@ -101,7 +97,7 @@ mod private impl str::FromStr for ListFilter { - type Err = untyped::Error; + type Err = error::untyped::Error; fn from_str( s : &str ) -> Result< Self, Self::Err > { @@ -440,19 +436,20 @@ 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 ) -> ResultWithReport< ListReport, untyped::Error > // qqq : should be specific 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::try_from( args.path_to_manifest.absolute_path() ) - // dbg!( &args.path_to_manifest ); let manifest = Manifest::try_from( args.path_to_manifest.clone() ) .context( "List of packages by specified manifest path" ) - .err_with( || report.clone() )?; + .err_with_report( &report )?; let workspace = Workspace::try_from( manifest.crate_dir() ) .context( "Reading workspace" ) - .err_with( || report.clone() )?; + .err_with_report( &report )?; let is_package = manifest.package_is(); // let is_package = manifest.package_is().context( "try to identify manifest type" ).err_with( report.clone() )?; @@ -461,21 +458,21 @@ mod private | manifest_file : ManifestFile, report : &mut ListReport, visited : &mut HashSet< DependencyId > | { - // aaa : is it safe to use unwrap here? // aaa : done let package = workspace .package_find_by_manifest( manifest_file ) .ok_or_else( || format_err!( "Package not found in the workspace" ) ) - .err_with( || report.clone() )?; + .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 }, + // 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.clone() )?, - // aaa : is it safe to use unwrap here? // aaa : now returns an error + .err_with_report( report )?, duplicate : false, normal_dependencies : vec![], dev_dependencies : vec![], @@ -595,7 +592,7 @@ mod private ) } ) - .err_with( || report.clone() )?; + .err_with_report( &report )?; let packages_info : collection::HashMap< String, WorkspacePackageRef< '_ > > = packages.map( | p | ( p.name().to_string(), p ) ).collect(); @@ -628,7 +625,7 @@ mod private } ) .collect::< Result< _, _ >>() - .err_with( || report.clone() )?; + .err_with_report( &report )?; report = ListReport::List( names ); } diff --git a/module/move/willbe/src/action/main_header.rs b/module/move/willbe/src/action/main_header.rs index 1f4359961a..32b10d6823 100644 --- a/module/move/willbe/src/action/main_header.rs +++ b/module/move/willbe/src/action/main_header.rs @@ -20,7 +20,7 @@ mod private use error:: { err, - Result, + // Result, untyped:: { Error, @@ -201,7 +201,8 @@ mod private /// /// ``` pub fn readme_header_renew( crate_dir : CrateDir ) - -> Result< MainHeaderRenewReport, ( MainHeaderRenewReport, MainHeaderRenewError ) > + // -> Result< MainHeaderRenewReport, ( MainHeaderRenewReport, MainHeaderRenewError ) > + -> ResultWithReport< MainHeaderRenewReport, MainHeaderRenewError > { let mut report = MainHeaderRenewReport::default(); regexes_initialize(); @@ -210,18 +211,18 @@ mod private ( crate_dir ) - .err_with( || report.clone() )?; + .err_with_report( &report )?; let workspace_root = workspace .workspace_root(); let header_param = HeaderParameters::from_cargo_toml( &workspace ) - .err_with( || report.clone() )?; + .err_with_report( &report )?; let read_me_path = workspace_root.join ( repository::readme_path( &workspace_root ) - .err_with( || report.clone() )? + .err_with_report( &report )? ); report.found_file = Some( read_me_path.clone().to_path_buf() ); @@ -230,10 +231,10 @@ mod private .read( true ) .write( true ) .open( &read_me_path ) - .err_with( || report.clone() )?; + .err_with_report( &report )?; let mut content = String::new(); - file.read_to_string( &mut content ).err_with( || report.clone() )?; + file.read_to_string( &mut content ).err_with_report( &report )?; let raw_params = TAGS_TEMPLATE .get() @@ -244,8 +245,9 @@ mod private .unwrap_or_default(); _ = query::parse( raw_params ).context( "Fail to parse arguments" ); + // qqq : for Petro : why ignored? - let header = header_param.to_header().err_with( || report.clone() )?; + let header = header_param.to_header().err_with_report( &report )?; let content : String = TAGS_TEMPLATE.get().unwrap().replace ( &content, @@ -257,9 +259,9 @@ mod private ) ).into(); - file.set_len( 0 ).err_with( || report.clone() )?; - file.seek( SeekFrom::Start( 0 ) ).err_with( || report.clone() )?; - file.write_all( content.as_bytes() ).err_with( || report.clone() )?; + 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 ) diff --git a/module/move/willbe/src/action/publish.rs b/module/move/willbe/src/action/publish.rs index a0b6aa0675..58412a2d7a 100644 --- a/module/move/willbe/src/action/publish.rs +++ b/module/move/willbe/src/action/publish.rs @@ -6,19 +6,10 @@ mod private use std::{ env, fmt, fs }; use { - error::untyped, + // error::untyped, error::ErrWith, }; -// use collection::{ HashSet, HashMap }; -// use core::fmt::Formatter; -// use std::{ env, fs }; - -// use error::untyped::Error; -// use workspace::Workspace; -// use package::Package; -// use channel::Channel; - /// Represents a report of publishing packages #[ derive( Debug, Default, Clone ) ] pub struct PublishReport @@ -130,7 +121,9 @@ mod private channel : channel::Channel, dry : bool, temp : bool - ) -> Result< publish::PublishPlan, untyped::Error > + ) + -> Result< publish::PublishPlan, error::untyped::Error > + // qqq : use typed error { let mut paths = collection::HashSet::new(); // find all packages by specified folders @@ -253,13 +246,16 @@ mod private /// #[ cfg_attr( feature = "tracing", tracing::instrument ) ] - pub fn publish( plan : publish::PublishPlan ) -> ResultWithReport< PublishReport, untyped::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 publish::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 )); @@ -267,7 +263,7 @@ 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 ) 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 b7a7736b03..325fbc3819 100644 --- a/module/move/willbe/src/action/readme_health_table_renew.rs +++ b/module/move/willbe/src/action/readme_health_table_renew.rs @@ -18,8 +18,8 @@ mod private Error, untyped:: { - Error as wError, - Result, + Error as wError, // xxx + // Result, Context, format_err, } 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 b44e6de2d5..5370a9d0fa 100644 --- a/module/move/willbe/src/action/readme_modules_headers_renew.rs +++ b/module/move/willbe/src/action/readme_modules_headers_renew.rs @@ -23,7 +23,7 @@ mod private err, untyped:: { - Result, + // Result, Error as wError, Context, }, @@ -242,12 +242,11 @@ mod private pub fn readme_modules_headers_renew( crate_dir : CrateDir ) -> ResultWithReport< ModulesHeadersRenewReport, ModulesHeadersRenewError > // -> Result< ModulesHeadersRenewReport, ( ModulesHeadersRenewReport, ModulesHeadersRenewError ) > - // xxx : newtype { let mut report = ModulesHeadersRenewReport::default(); regexes_initialize(); let workspace = Workspace::try_from( crate_dir ) - .err_with( || report.clone() )?; // xxx : qqq : use trait. everywhere + .err_with_report( &report )?; let discord_url = workspace.discord_url(); // qqq : inspect each collect in willbe and rid of most of them @@ -271,7 +270,7 @@ mod private ( repository::readme_path( path.parent().unwrap().as_ref() ) // .ok_or_else::< wError, _ >( || err!( "Fail to find README.md at {}", &path ) ) - .err_with( || report.clone() )? + .err_with_report( &report )? ); let pakage = Package::try_from @@ -282,21 +281,21 @@ mod private .parent() .unwrap() ) - .err_with( || report.clone() )? + .err_with_report( &report )? ) - .err_with( || report.clone() )?; + .err_with_report( &report )?; let header = ModuleHeader::from_cargo_toml( pakage.into(), &discord_url ) - .err_with( || report.clone() )?; + .err_with_report( &report )?; let mut file = OpenOptions::new() .read( true ) .write( true ) .open( &read_me_path ) - .err_with( || report.clone() )?; + .err_with_report( &report )?; let mut content = String::new(); - file.read_to_string( &mut content ).err_with( || report.clone() )?; + file.read_to_string( &mut content ).err_with_report( &report )?; let raw_params = TAGS_TEMPLATE .get() @@ -307,6 +306,7 @@ 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 ( @@ -314,11 +314,11 @@ mod private header, raw_params, workspace.workspace_root().to_str().unwrap() - ).err_with( || report.clone() )?; + ).err_with_report( &report )?; - file.set_len( 0 ).err_with( || report.clone() )?; - file.seek( SeekFrom::Start( 0 ) ).err_with( || report.clone() )?; - file.write_all( content.as_bytes() ).err_with( || report.clone() )?; + 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 ) @@ -330,7 +330,9 @@ mod private header : ModuleHeader, raw_params : &str, workspace_root : &str - ) -> Result< Cow< 'a, str > > + ) + // qqq : use typed error + -> error::untyped::Result< Cow< 'a, str > > { let header = header.to_header( workspace_root )?; let result = TAGS_TEMPLATE diff --git a/module/move/willbe/src/action/test.rs b/module/move/willbe/src/action/test.rs index 86d9a09f95..aa6e8c5b42 100644 --- a/module/move/willbe/src/action/test.rs +++ b/module/move/willbe/src/action/test.rs @@ -19,7 +19,7 @@ mod private Error, format_err }, - Result + // Result }; use iter::Itertools; @@ -65,7 +65,10 @@ mod private /// The result of the tests is written to the structure `TestsReport` and returned as a result of the function execution. // zzz : it probably should not be here // xxx : use newtype - pub fn test( o : TestsCommandOptions, dry : bool ) -> Result< TestsReport, ( TestsReport, Error ) > + pub fn test( o : TestsCommandOptions, dry : bool ) + -> ResultWithReport< TestsReport, Error > + // qqq : for Petro : typed error + // -> Result< TestsReport, ( TestsReport, Error ) > { // qqq : incapsulate progress bar logic into some function of struct. don't keep it here @@ -74,7 +77,7 @@ mod private let mut report = TestsReport::default(); // fail fast if some additional installations required let channels = channel::available_channels( o.dir.as_ref() ) - .err_with( || report.clone() )?; + .err_with_report( &report )?; let channels_diff : Vec< _ > = o.channels.difference( &channels ).collect(); if !channels_diff.is_empty() { @@ -121,8 +124,8 @@ Try to install it with `rustup install {}` command(-s)", }; let workspace = Workspace - ::try_from( CrateDir::try_from( path.clone() ).err_with( || report.clone() )? ) - .err_with( || report.clone() )? + ::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.! @@ -158,7 +161,7 @@ Try to install it with `rustup install {}` command(-s)", with_all_features, with_none_features, variants_cap, - ).err_with( || report.clone() )?; + ).err_with_report( &report )?; println!( "{plan}" ); // aaa : split on two functions for create plan and for execute @@ -169,7 +172,7 @@ Try to install it with `rustup install {}` command(-s)", let mut unique_name = format! ( "temp_dir_for_test_command_{}", - path::unique_folder_name().err_with( || report.clone() )? + path::unique_folder_name().err_with_report( &report )? ); let mut temp_dir = env::temp_dir().join( unique_name ); @@ -179,12 +182,12 @@ Try to install it with `rustup install {}` command(-s)", unique_name = format! ( "temp_dir_for_test_command_{}", - path::unique_folder_name().err_with( || report.clone() )? + path::unique_folder_name().err_with_report( &report )? ); temp_dir = env::temp_dir().join( unique_name ); } - fs::create_dir( &temp_dir ).err_with( || report.clone() )?; + fs::create_dir( &temp_dir ).err_with_report( &report )?; Some( temp_dir ) } else @@ -204,7 +207,7 @@ Try to install it with `rustup install {}` command(-s)", if temp { - fs::remove_dir_all( options.temp_path.unwrap() ).err_with( || report.clone() )?; + fs::remove_dir_all( options.temp_path.unwrap() ).err_with_report( &report )?; } result.map_err( | ( report, e) | ( report, e.into() ) ) diff --git a/module/move/willbe/src/action/workspace_renew.rs b/module/move/willbe/src/action/workspace_renew.rs index 707ea7423d..58e4ad61ea 100644 --- a/module/move/willbe/src/action/workspace_renew.rs +++ b/module/move/willbe/src/action/workspace_renew.rs @@ -4,7 +4,7 @@ mod private use std::fs; use std::path::Path; use error::untyped::bail; - use error::Result; + // use error::Result; // qqq : group dependencies use iter::Itertools; use template:: @@ -30,46 +30,6 @@ mod private } } - // impl Template for WorkspaceTemplate - // { - // 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 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 { fn default() -> Self @@ -181,8 +141,7 @@ mod private repository_url : String, branches : Vec< String > ) - -> Result< () > - // qqq : don't use 1-prameter Result + -> error::untyped::Result< () > // qqq : use typed error { if fs::read_dir( path )?.count() != 0 { diff --git a/module/move/willbe/src/command/cicd_renew.rs b/module/move/willbe/src/command/cicd_renew.rs index 70d824c40c..50b1a8de91 100644 --- a/module/move/willbe/src/command/cicd_renew.rs +++ b/module/move/willbe/src/command/cicd_renew.rs @@ -2,16 +2,17 @@ mod private { use crate::*; - use error::{ untyped::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()? + ( + &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 4013cb4d05..c66107fe8d 100644 --- a/module/move/willbe/src/command/deploy_renew.rs +++ b/module/move/willbe/src/command/deploy_renew.rs @@ -3,7 +3,7 @@ mod private use crate::*; use wca::VerifiedCommand; - use error::{ untyped::Context, Result }; + use error::{ untyped::Context }; use tool::TemplateHolder; //use tool::template::Template; // use action::deploy_renew::*; @@ -12,7 +12,8 @@ mod private /// 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()?; diff --git a/module/move/willbe/src/command/features.rs b/module/move/willbe/src/command/features.rs index 50a7356dfc..d57a8a7dc0 100644 --- a/module/move/willbe/src/command/features.rs +++ b/module/move/willbe/src/command/features.rs @@ -7,15 +7,14 @@ mod private use std::path::PathBuf; // // use path::AbsolutePath; use wca::VerifiedCommand; - use error::Result; + // use error::Result; // qqq : group dependencies /// /// List features of a package. /// - // qqq : don't use 1-prameter Result - 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 crate_dir = CrateDir::try_from( fs::canonicalize( path )? )?; diff --git a/module/move/willbe/src/command/list.rs b/module/move/willbe/src/command/list.rs index 0e1fd8a653..c1bb086099 100644 --- a/module/move/willbe/src/command/list.rs +++ b/module/move/willbe/src/command/list.rs @@ -9,7 +9,7 @@ mod private path::PathBuf, }; use wca::VerifiedCommand; - use error::{ untyped::Context, Result }; + use error::{ untyped::Context }; use collection::HashSet; use action:: @@ -47,7 +47,8 @@ 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 ) diff --git a/module/move/willbe/src/command/main_header.rs b/module/move/willbe/src/command/main_header.rs index 5a957a79d1..efd23e67c4 100644 --- a/module/move/willbe/src/command/main_header.rs +++ b/module/move/willbe/src/command/main_header.rs @@ -2,10 +2,11 @@ mod private { use crate::*; use action; - use error::untyped::{ Error, Result }; + 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 ( diff --git a/module/move/willbe/src/command/publish.rs b/module/move/willbe/src/command/publish.rs index dfc8bb4a61..a70af4265d 100644 --- a/module/move/willbe/src/command/publish.rs +++ b/module/move/willbe/src/command/publish.rs @@ -5,7 +5,7 @@ mod private use colored::Colorize; use wca::VerifiedCommand; - use error::{ Result, untyped::Context }; + use error::{ untyped::Context }; // xxx use former::Former; use std::fmt::Write; use channel::Channel; @@ -25,19 +25,19 @@ 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() + .unwrap_or( std::path::PathBuf::from( "" ) ).display() ); let prop_line = format! - ( - "{}", + ( + "{}", o .props .iter() @@ -49,11 +49,11 @@ mod private .get_owned( 0 ) .unwrap_or_else( || vec![ "./".into() ] ); - let PublishProperties - { - channel, - dry, - temp + 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" )?; @@ -103,13 +103,13 @@ mod private let mut this = Self::former(); this = if let Some( v ) = value - .get_owned( "channel" ) - { - this.channel::< Channel >( { let v : String = v; Channel::try_from( v )? } ) - } - else + .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 diff --git a/module/move/willbe/src/command/publish_diff.rs b/module/move/willbe/src/command/publish_diff.rs index d34d72968b..4691331866 100644 --- a/module/move/willbe/src/command/publish_diff.rs +++ b/module/move/willbe/src/command/publish_diff.rs @@ -6,7 +6,7 @@ mod private use std::path::PathBuf; use wca::VerifiedCommand; - use error::Result; + // use error::Result; // qqq : group dependencies // use path::AbsolutePath; @@ -30,8 +30,7 @@ mod private /// /// Returns an error if there is an issue with the command. - // qqq : don't use 1-prameter Result - 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()?; diff --git a/module/move/willbe/src/command/readme_headers_renew.rs b/module/move/willbe/src/command/readme_headers_renew.rs index 015399ae9d..9a79a2b144 100644 --- a/module/move/willbe/src/command/readme_headers_renew.rs +++ b/module/move/willbe/src/command/readme_headers_renew.rs @@ -1,10 +1,8 @@ mod private { use crate::*; - // use path::AbsolutePath; use action; - // use error::untyped::Error; - use error::{ Result, err }; + use error::{ err }; use std::fmt::{ Display, Formatter }; #[ derive( Debug, Default ) ] @@ -68,7 +66,7 @@ mod private /// 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()? )?; 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 a1b100dd4b..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,16 +2,17 @@ mod private { use crate::*; - use error::{ untyped::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()? + ( + &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 f71e4cf916..391205210e 100644 --- a/module/move/willbe/src/command/readme_modules_headers_renew.rs +++ b/module/move/willbe/src/command/readme_modules_headers_renew.rs @@ -2,10 +2,11 @@ mod private { use crate::*; // use path::AbsolutePath; - use error::{ untyped::Error, Result }; + // 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( CrateDir::transitive_try_from::< AbsolutePath >( CurrentPath )? ) { @@ -17,7 +18,8 @@ mod private 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 0a65952d20..9a05c92c89 100644 --- a/module/move/willbe/src/command/test.rs +++ b/module/move/willbe/src/command/test.rs @@ -7,7 +7,7 @@ mod private use std::fs; use colored::Colorize; use wca::VerifiedCommand; - use error::Result; + // use error::Result; // qqq : group dependencies use path::{ AbsolutePath, PathBuf }; use action::test::TestsCommandOptions; @@ -49,7 +49,7 @@ mod private /// run tests in specified crate // qqq : don't use 1-prameter Result - pub fn test( o : VerifiedCommand ) -> Result< () > + pub fn test( o : VerifiedCommand ) -> error::untyped::Result< () > // qqq : use typed error { let args_line = format! ( diff --git a/module/move/willbe/src/command/workspace_renew.rs b/module/move/willbe/src/command/workspace_renew.rs index ea28f5d631..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 error::{ untyped::Context, Result }; + use error::{ untyped::Context }; use action::WorkspaceTemplate; #[ derive( Former ) ] @@ -18,16 +18,17 @@ 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 + ( + &std::env::current_dir()?, + template, + repository_url, + branches ) .context( "Fail to create workspace" ) } diff --git a/module/move/willbe/src/entity/channel.rs b/module/move/willbe/src/entity/channel.rs index 57e1eede8a..5228930459 100644 --- a/module/move/willbe/src/entity/channel.rs +++ b/module/move/willbe/src/entity/channel.rs @@ -8,7 +8,7 @@ mod private }; use path::Path; use collection::HashSet; - use error::untyped::{ Error, Result }; + use error::untyped::{ Error }; use process_tools::process::*; /// The `Channel` enum represents different release channels for rust. @@ -51,7 +51,8 @@ mod private /// 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 >, { diff --git a/module/move/willbe/src/entity/dependency.rs b/module/move/willbe/src/entity/dependency.rs index d3e807f374..bf7f785d52 100644 --- a/module/move/willbe/src/entity/dependency.rs +++ b/module/move/willbe/src/entity/dependency.rs @@ -168,7 +168,8 @@ mod private graph : &mut collection::HashMap< CrateId, collection::HashSet< CrateId > >, opts : DependenciesOptions ) - -> Result< CrateId > + // qqq : use typed error + -> error::untyped::Result< CrateId > { let DependenciesOptions { @@ -235,7 +236,8 @@ mod private package : &Package< 'a >, opts : DependenciesOptions ) - -> Result< Vec< CrateId > > + // qqq : use typed error + -> error::untyped::Result< Vec< CrateId > > { let mut graph = collection::HashMap::new(); let root = _list( workspace, package, &mut graph, opts.clone() )?; diff --git a/module/move/willbe/src/entity/features.rs b/module/move/willbe/src/entity/features.rs index 1e4b80746a..e0dedd9f99 100644 --- a/module/move/willbe/src/entity/features.rs +++ b/module/move/willbe/src/entity/features.rs @@ -2,7 +2,7 @@ mod private { use crate::*; use collection::{ BTreeSet, HashSet }; - use error::untyped::{ bail, Result }; + use error::untyped::{ bail }; // xxx use iter::Itertools; /// Generates a powerset of the features available in the given `package`, @@ -50,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(); diff --git a/module/move/willbe/src/entity/files/crate_dir.rs b/module/move/willbe/src/entity/files/crate_dir.rs index 1c0165947b..7ea3424e56 100644 --- a/module/move/willbe/src/entity/files/crate_dir.rs +++ b/module/move/willbe/src/entity/files/crate_dir.rs @@ -19,10 +19,10 @@ use std:: path::{ Path, PathBuf }, io, }; -use error:: -{ - Result, -}; +// use error:: +// { +// Result, +// }; use path::{ AbsolutePath, Utf8Path, Utf8PathBuf }; /// Path to crate directory diff --git a/module/move/willbe/src/entity/files/either.rs b/module/move/willbe/src/entity/files/either.rs index 922110964e..aa7fdb5863 100644 --- a/module/move/willbe/src/entity/files/either.rs +++ b/module/move/willbe/src/entity/files/either.rs @@ -11,10 +11,10 @@ use std:: { path::Path, }; -use error:: -{ - Result, -}; +// use error:: +// { +// Result, +// }; /// Wrapper over `data_type::Either< CrateDir, ManifestFile >` with utils methods. #[ derive( Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug ) ] diff --git a/module/move/willbe/src/entity/files/manifest_file.rs b/module/move/willbe/src/entity/files/manifest_file.rs index d0a82fe907..78af49e41b 100644 --- a/module/move/willbe/src/entity/files/manifest_file.rs +++ b/module/move/willbe/src/entity/files/manifest_file.rs @@ -22,10 +22,10 @@ use std:: use path::{ AbsolutePath, Utf8Path, Utf8PathBuf }; -use error:: -{ - Result, -}; +// use error:: +// { +// Result, +// }; /// Path to crate directory #[ derive( Clone, Ord, PartialOrd, Eq, PartialEq, Hash ) ] diff --git a/module/move/willbe/src/entity/files/source_file.rs b/module/move/willbe/src/entity/files/source_file.rs index 0ffba70092..b895d3eec2 100644 --- a/module/move/willbe/src/entity/files/source_file.rs +++ b/module/move/willbe/src/entity/files/source_file.rs @@ -20,10 +20,10 @@ use std:: path::{ Path, PathBuf }, borrow::Cow, }; -use error:: -{ - Result, -}; +// use error:: +// { +// Result, +// }; use path::{ AbsolutePath, Utf8Path, Utf8PathBuf }; /// Path to a source file diff --git a/module/move/willbe/src/entity/git.rs b/module/move/willbe/src/entity/git.rs index 3e9d0239d0..df8c7fb4c9 100644 --- a/module/move/willbe/src/entity/git.rs +++ b/module/move/willbe/src/entity/git.rs @@ -1,12 +1,11 @@ mod private { use crate::*; - + use std::fmt; use process_tools::process; use error:: { - Result, untyped::{ format_err, Context }, }; @@ -53,14 +52,14 @@ mod private pub dry : bool, } - // aaa : for Bohdan : should not be here // aaa : done - // aaa : for Bohdan : documentation // aaa : done /// Performs a Git commit operation using the provided options - pub fn perform_git_commit( o : GitOptions ) -> Result< ExtendedGitReport > + 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 = o + let items : error::untyped::Result< Vec< _ > > = o .items .iter() .map @@ -68,10 +67,11 @@ mod private | 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::< Result< Vec< _ > > >()?; - let res = tool::git::add( &o.git_root, &items, o.dry ).map_err( | e | format_err!( "{report}\n{e}" ) )?; + .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 = tool::git::commit( &o.git_root, &o.message, o.dry ).map_err( | e | format_err!( "{report}\n{e}" ) )?; + 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 ) diff --git a/module/move/willbe/src/entity/manifest.rs b/module/move/willbe/src/entity/manifest.rs index 75a4f3f8f0..dcaea64ed8 100644 --- a/module/move/willbe/src/entity/manifest.rs +++ b/module/move/willbe/src/entity/manifest.rs @@ -11,7 +11,7 @@ pub( crate ) mod private use error:: { typed::Error, - untyped::{ Result, format_err }, + untyped::{ format_err }, }; /// Represents errors related to manifest data processing. @@ -146,7 +146,8 @@ pub( crate ) mod private } /// Retrieves the repository URL of a package from its `Cargo.toml` file. - pub fn repo_url( crate_dir : &CrateDir ) -> Result< String > + // qqq : use typed error + pub fn repo_url( crate_dir : &CrateDir ) -> error::untyped::Result< String > { let path = crate_dir.clone().manifest_file().inner().inner(); if path.exists() diff --git a/module/move/willbe/src/entity/package.rs b/module/move/willbe/src/entity/package.rs index 6639904f2b..f972e8b627 100644 --- a/module/move/willbe/src/entity/package.rs +++ b/module/move/willbe/src/entity/package.rs @@ -10,7 +10,7 @@ mod private use crates_tools::CrateArchive; use error:: { - Result, + // Result, typed::Error, }; diff --git a/module/move/willbe/src/entity/packed_crate.rs b/module/move/willbe/src/entity/packed_crate.rs index f75db6b0c7..e8bd052b1e 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 error::{ untyped::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. @@ -21,7 +21,8 @@ mod private /// /// # 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::try_from( crate_dir )?; @@ -36,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 ) ) diff --git a/module/move/willbe/src/entity/publish.rs b/module/move/willbe/src/entity/publish.rs index ad5632782b..75ac067653 100644 --- a/module/move/willbe/src/entity/publish.rs +++ b/module/move/willbe/src/entity/publish.rs @@ -9,7 +9,7 @@ mod private iter::Itertools, error:: { - Result, + // Result, untyped::{ format_err, Error }, } }; @@ -365,9 +365,9 @@ mod private git_options.dry = dry; publish.dry = dry; - report.get_info = Some( cargo::pack( pack ).err_with( || report.clone() )? ); + 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.clone() )?; + 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 ) @@ -377,7 +377,7 @@ mod private { 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.clone() )?; + .err_with_report( &report )?; return Err(( report, e )); } }; @@ -394,12 +394,12 @@ mod private | 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.clone() )?; + .err_with_report( &report )?; return Err(( report, e )); } }; - let res = tool::git::push( &git_root, dry ).err_with( || report.clone() )?; + let res = tool::git::push( &git_root, dry ).err_with_report( &report )?; report.push = Some( res ); Ok( report ) @@ -414,7 +414,8 @@ mod private /// # Returns /// /// Returns a `Result` containing a vector of `PublishReport` if successful, else an error. - pub fn perform_packages_publish( plan : PublishPlan ) -> Result< Vec< PublishReport > > + 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 diff --git a/module/move/willbe/src/entity/test.rs b/module/move/willbe/src/entity/test.rs index 0e4afc5c2d..c58c78bafb 100644 --- a/module/move/willbe/src/entity/test.rs +++ b/module/move/willbe/src/entity/test.rs @@ -6,7 +6,6 @@ mod private // qqq : for Bohdan no asterisk imports, but in special cases use std:: { - // collections, fmt, sync, }; @@ -638,7 +637,9 @@ 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, TestError ) > + pub fn run( options : &PackageTestOptions< '_ > ) + -> ResultWithReport< TestReport, TestError > + // -> Result< TestReport, ( TestReport, TestError ) > { let mut report = TestReport::default(); report.dry = options.dry; @@ -711,7 +712,9 @@ mod private } /// Run tests for given packages. - pub fn tests_run( args : &TestOptions ) -> Result< TestsReport, ( TestsReport, TestError ) > + pub fn tests_run( args : &TestOptions ) + -> ResultWithReport< TestsReport, TestError > + // -> Result< TestsReport, ( TestsReport, TestError ) > { #[ cfg( feature = "progress_bar" ) ] let multi_progress = progress_bar::MultiProgress::default(); diff --git a/module/move/willbe/src/entity/version.rs b/module/move/willbe/src/entity/version.rs index c911a5b7e1..8e05fa1efa 100644 --- a/module/move/willbe/src/entity/version.rs +++ b/module/move/willbe/src/entity/version.rs @@ -257,7 +257,7 @@ mod private /// /// Returns `Ok(())` if the version is reverted successfully. Returns `Err` with an error message if there is any issue with reverting the version. // qqq : don't use 1-prameter Result - pub fn revert( report : &ExtendedBumpReport ) -> 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( () ) }; diff --git a/module/move/willbe/src/tool/cargo.rs b/module/move/willbe/src/tool/cargo.rs index 3463201de5..7b3668acbf 100644 --- a/module/move/willbe/src/tool/cargo.rs +++ b/module/move/willbe/src/tool/cargo.rs @@ -93,8 +93,8 @@ mod private tracing::instrument( fields( caller = ?{ let x = std::panic::Location::caller(); ( x.file(), x.line() ) } ) ) )] // qqq : should be typed error, apply err_with - // qqq : don't use 1-prameter Result - pub fn pack( args : PackOptions ) -> Result< process::Report > + // qqq : use typed error + pub fn pack( args : PackOptions ) -> error::untyped::Result< process::Report > { let ( program, options ) = ( "rustup", args.to_pack_args() ); @@ -159,8 +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< process::Report > - // qqq : don't use 1-prameter Result + pub fn publish( args : PublishOptions ) -> error::untyped::Result< process::Report > + // qqq : use typed error { let ( program, arguments) = ( "cargo", args.as_publish_args() ); diff --git a/module/move/willbe/src/tool/error.rs b/module/move/willbe/src/tool/error.rs index ff6f01b439..1572a2ca13 100644 --- a/module/move/willbe/src/tool/error.rs +++ b/module/move/willbe/src/tool/error.rs @@ -1,44 +1,10 @@ /// Internal namespace. +#[ allow( unused_imports ) ] pub( crate ) mod private { - #[ allow( unused_imports ) ] use crate::tool::*; - use ::error_tools::protected::*; - // qqq : for for Petro : for Bohdan : good one, apply it to all code - - /// This trait can be used to add extra information to an error, creating a tuple of the additional - /// context and the original error. This can be particularly useful for error handling where you - /// want to include more context or details in the error without losing the original error value. - pub trait ErrWith< V, R, E > - { - /// Takes a closure `f` that returns a value of type `V`, and uses it to wrap an error of type `(V, E1)` - /// in the context of a `Result` of type `R`. - fn err_with< F >( self, f : F ) -> std::result::Result< R, ( V, E ) > - where - F : FnOnce() -> V; - } - - impl< V, R, E1, E2 > ErrWith< V, R, E1 > for std::result::Result< R, E2 > - where - E2 : Into< E1 >, - { - fn err_with< F >( self, f : F ) -> std::result::Result< R, ( V, E1 ) > - where - F : FnOnce() -> V, - { - self.map_err( | e | ( f(), 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 ) >; - - } crate::mod_interface! @@ -48,8 +14,8 @@ crate::mod_interface! use ::error_tools; protected use ::error_tools::protected::*; - exposed use ErrWith; - exposed use ResultWithReport; - exposed use ::error_tools::Result; + // exposed use ErrWith; + // exposed use ResultWithReport; + // exposed use ::error_tools::Result; } diff --git a/module/move/willbe/src/tool/git.rs b/module/move/willbe/src/tool/git.rs index e85532b3b4..5f9772d374 100644 --- a/module/move/willbe/src/tool/git.rs +++ b/module/move/willbe/src/tool/git.rs @@ -23,8 +23,9 @@ mod private /// 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 > - // qqq : don't use 1-prameter Result + 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 ] >, @@ -32,6 +33,7 @@ mod private { let objects = objects.as_ref().iter().map( | x | x.as_ref() ); + // qqq : for Bohdan : don't enlarge length of lines artificially let ( program, args ) : ( _, Vec< _ > ) = ( "git", Some( "add" ).into_iter().chain( objects ).collect() ); if dry @@ -72,7 +74,7 @@ mod private /// 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 >, @@ -119,7 +121,7 @@ mod private // 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 >, @@ -165,7 +167,8 @@ mod private // qqq : should be typed error, apply err_with - pub fn reset< P >( path : P, hard : bool, commits_count : usize, dry : bool ) -> Result< Report > + 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 >, @@ -219,7 +222,7 @@ mod private // qqq : should be typed error, apply err_with // qqq : don't use 1-prameter Result - pub fn ls_remote_url< P >( path : P ) -> Result< Report > + pub fn ls_remote_url< P >( path : P ) -> error::untyped::Result< Report > where P : AsRef< Path >, { diff --git a/module/move/willbe/src/tool/graph.rs b/module/move/willbe/src/tool/graph.rs index 8e9f51ac91..d3068f318e 100644 --- a/module/move/willbe/src/tool/graph.rs +++ b/module/move/willbe/src/tool/graph.rs @@ -96,7 +96,7 @@ pub( crate ) mod private ( graph : Graph< &'a PackageIdentifier, &'a PackageIdentifier > ) - -> error::Result< Vec< PackageIdentifier >, GraphError< PackageIdentifier > > + -> Result< Vec< PackageIdentifier >, GraphError< PackageIdentifier > > { match pg_toposort( &graph, None ) { @@ -255,8 +255,8 @@ pub( crate ) mod private roots : &[ String ], temp_path : Option< PathBuf >, ) - -> error::Result< Graph< String, String > > - // qqq : don't use 1-prameter Result + -> error::untyped::Result< Graph< String, String > > + // qqq : use typed error! { let mut nodes = HashSet::new(); let mut cleared_graph = Graph::new(); diff --git a/module/move/willbe/src/tool/http.rs b/module/move/willbe/src/tool/http.rs index 6527044e75..6819edf305 100644 --- a/module/move/willbe/src/tool/http.rs +++ b/module/move/willbe/src/tool/http.rs @@ -10,13 +10,14 @@ pub( crate ) mod private fmt::Write, time::Duration }; - use error::{ untyped::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 index 3c75db35f0..2c6e19f54a 100644 --- a/module/move/willbe/src/tool/iter.rs +++ b/module/move/willbe/src/tool/iter.rs @@ -10,7 +10,3 @@ crate::mod_interface! use ::iter_tools; protected use ::iter_tools::protected::*; } - -// use ::iter_tools::protected::iter as xxx; -// use ::iter_tools::protected::iter2 as xxx2; -// use iter as xxx3; diff --git a/module/move/willbe/src/tool/macros.rs b/module/move/willbe/src/tool/macros.rs index b69d25643d..1a59faa9f7 100644 --- a/module/move/willbe/src/tool/macros.rs +++ b/module/move/willbe/src/tool/macros.rs @@ -10,6 +10,3 @@ crate::mod_interface! protected use ::macro_tools::protected::*; } - -// use protected::macro_tools as xxx; -// use protected::macro_tools2 as xxx2; diff --git a/module/move/willbe/src/tool/mod.rs b/module/move/willbe/src/tool/mod.rs index b104c31de3..060a323c2f 100644 --- a/module/move/willbe/src/tool/mod.rs +++ b/module/move/willbe/src/tool/mod.rs @@ -67,11 +67,4 @@ crate::mod_interface! Assign, }; - // xxx : check - // exposed use - // { - // ::former::Former, - // ::former::Assign, - // }; - -} +} \ No newline at end of file diff --git a/module/move/willbe/src/tool/query.rs b/module/move/willbe/src/tool/query.rs index 61b1f5013e..cdf1989078 100644 --- a/module/move/willbe/src/tool/query.rs +++ b/module/move/willbe/src/tool/query.rs @@ -11,7 +11,7 @@ mod private use error:: { untyped::{ Error, bail }, - Result, + // Result, }; use collection::HashMap; @@ -148,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 { @@ -199,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 @@ -250,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() ) } diff --git a/module/move/willbe/src/tool/template.rs b/module/move/willbe/src/tool/template.rs index 411777dad5..affe4072be 100644 --- a/module/move/willbe/src/tool/template.rs +++ b/module/move/willbe/src/tool/template.rs @@ -50,7 +50,7 @@ mod private /// # Returns /// /// A `Result` which is `Ok` if the files are created successfully, or an `Err` otherwise. - pub fn create_all( self, path : &path::Path ) -> Result< () > + pub fn create_all( self, path : &path::Path ) -> error::untyped::Result< () > // qqq : use typed error { self.files.create_all( path, &self.values ) } @@ -184,74 +184,6 @@ mod private } } - // /// Trait for creating a template for a file structure. - // pub trait Template< F > : Sized - // where - // F : TemplateFiles + Default - // { - // /// Creates all files in the template. - // /// - // /// Path is the base path for the template to be created in. - // fn create_all( self, path : &Path ) -> Result< () >; - - // /// Returns all parameters used by the template. - // fn parameters( &self ) -> &TemplateParameters; - - // /// Sets values for provided parameters. - // fn set_values( &mut self, values : TemplateValues ); - - // /// Relative path for parameter values storage. - // fn parameter_storage( &self ) -> &Path; - - // /// - // fn template_name( &self ) -> &'static str; - - // /// Loads provided parameters from previous run. - // 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 : Vec< _ > = self.parameters().descriptors.iter().map( | d | &d.parameter ).cloned().collect(); - // let template_table = document.get( self.template_name() )?; - // for parameter in parameters - // { - // let value = template_table.get( ¶meter ) - // .and_then - // ( - // | item | - // match item - // { - // toml_edit::Item::Value( toml_edit::Value::String( val ) ) => Some( val.value() ), - // _ => None - // } - // ); - // if let Some( value ) = value - // { - // self.get_values_mut().insert_if_empty( ¶meter, 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 > - // { - // let values = self.get_values(); - // self - // .parameters() - // .list_mandatory() - // .into_iter() - // .filter( | key | values.0.get( *key ).map( | val | val.as_ref() ).flatten().is_none() ) - // .collect() - // } - // } - /// Files stored in a template. /// /// Can be iterated over, consuming the owner of the files. @@ -260,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() @@ -393,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 { @@ -431,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 ); @@ -439,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(); @@ -505,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 } // 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" )?; @@ -526,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" ) diff --git a/module/move/willbe/src/tool/url.rs b/module/move/willbe/src/tool/url.rs index f9635d56db..f527589579 100644 --- a/module/move/willbe/src/tool/url.rs +++ b/module/move/willbe/src/tool/url.rs @@ -7,7 +7,7 @@ mod private use error::untyped:: { format_err, - Result, + // Result, }; /// Extracts the repository URL from a full URL. @@ -29,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