diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-05-10 15:29:19 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-05-10 15:29:19 +0900 |
| commit | 46845eff8d1398f35099a0ef914f77bcaf473287 (patch) | |
| tree | 12c4850f1d2f438d0ba6c363fdc0e5036cd4601d /crates/mozart-core/src/console.rs | |
| parent | 212506c364b2342dd9e5fa789e8cff38835dfe52 (diff) | |
| download | php-mozart-46845eff8d1398f35099a0ef914f77bcaf473287.tar.gz php-mozart-46845eff8d1398f35099a0ef914f77bcaf473287.tar.zst php-mozart-46845eff8d1398f35099a0ef914f77bcaf473287.zip | |
refactor(io): introduce IoInterface trait mirroring Composer IOInterface
Add an `IoInterface` trait in mozart-core::console that mirrors
`\Composer\IO\IOInterface`, implement it for `Console`, and switch
commands, the auditor, and the suggested-packages reporter to accept
the abstracted IO (typically `Arc<Mutex<Box<dyn IoInterface>>>` at the
command boundary, `&dyn IoInterface` deeper down) instead of
`&Console`. The console_writeln\!/write\! macros now go through
`IoInterface::verbosity()` via the lock so any implementor works.
Diffstat (limited to 'crates/mozart-core/src/console.rs')
| -rw-r--r-- | crates/mozart-core/src/console.rs | 194 |
1 files changed, 184 insertions, 10 deletions
diff --git a/crates/mozart-core/src/console.rs b/crates/mozart-core/src/console.rs index e036b11..3379307 100644 --- a/crates/mozart-core/src/console.rs +++ b/crates/mozart-core/src/console.rs @@ -67,6 +67,46 @@ pub fn hyperlink(url: &str, text: &str, decorated: bool) -> String { } // --------------------------------------------------------------------------- +// IoInterface +// --------------------------------------------------------------------------- + +/// The central IO abstraction, mirroring `\Composer\IO\IOInterface`. +/// +/// All Mozart commands and library functions that need to produce output +/// or interact with the user accept `&dyn IoInterface` (or an +/// `Arc<Mutex<Box<dyn IoInterface>>>` at the top-level command boundary). +pub trait IoInterface: Send + Sync { + fn write(&self, msg: &str, required: Verbosity); + fn write_stdout(&self, msg: &str, required: Verbosity); + fn write_error(&self, msg: &str); + + fn info(&self, msg: &str); + fn verbose(&self, msg: &str); + fn very_verbose(&self, msg: &str); + fn debug(&self, msg: &str); + fn error(&self, msg: &str); + + fn is_interactive(&self) -> bool; + fn is_decorated(&self) -> bool; + fn verbosity(&self) -> Verbosity; + + fn is_verbose(&self) -> bool; + fn is_very_verbose(&self) -> bool; + fn is_debug(&self) -> bool; + fn is_quiet(&self) -> bool; + + fn ask(&self, prompt: &str, default: &str) -> String; + #[allow(clippy::type_complexity)] + fn ask_validated( + &self, + prompt: &str, + default: &str, + validator: Box<dyn Fn(&str) -> Result<(), String>>, + ) -> Result<String, String>; + fn confirm(&self, prompt: &str) -> bool; +} + +// --------------------------------------------------------------------------- // Verbosity // --------------------------------------------------------------------------- @@ -212,6 +252,18 @@ impl Console { // Query methods // ----------------------------------------------------------------------- + pub fn verbosity(&self) -> Verbosity { + self.verbosity + } + + pub fn is_interactive(&self) -> bool { + self.interactive + } + + pub fn is_decorated(&self) -> bool { + self.decorated + } + pub fn is_verbose(&self) -> bool { self.verbosity >= Verbosity::Verbose } @@ -245,15 +297,13 @@ impl Console { .unwrap_or_else(|_| default.to_string()) } - pub fn ask_validated<F>( + #[allow(clippy::type_complexity)] + pub fn ask_validated( &self, prompt: &str, default: &str, - validator: F, - ) -> Result<String, String> - where - F: Fn(&str) -> Result<(), String>, - { + validator: Box<dyn Fn(&str) -> Result<(), String>>, + ) -> Result<String, String> { if !self.interactive { validator(default)?; return Ok(default.to_string()); @@ -289,6 +339,130 @@ impl Console { } } +impl<T: IoInterface + ?Sized> IoInterface for Box<T> { + fn write(&self, msg: &str, required: Verbosity) { + (**self).write(msg, required) + } + fn write_stdout(&self, msg: &str, required: Verbosity) { + (**self).write_stdout(msg, required) + } + fn write_error(&self, msg: &str) { + (**self).write_error(msg) + } + fn info(&self, msg: &str) { + (**self).info(msg) + } + fn verbose(&self, msg: &str) { + (**self).verbose(msg) + } + fn very_verbose(&self, msg: &str) { + (**self).very_verbose(msg) + } + fn debug(&self, msg: &str) { + (**self).debug(msg) + } + fn error(&self, msg: &str) { + (**self).error(msg) + } + fn is_interactive(&self) -> bool { + (**self).is_interactive() + } + fn is_decorated(&self) -> bool { + (**self).is_decorated() + } + fn verbosity(&self) -> Verbosity { + (**self).verbosity() + } + fn is_verbose(&self) -> bool { + (**self).is_verbose() + } + fn is_very_verbose(&self) -> bool { + (**self).is_very_verbose() + } + fn is_debug(&self) -> bool { + (**self).is_debug() + } + fn is_quiet(&self) -> bool { + (**self).is_quiet() + } + fn ask(&self, prompt: &str, default: &str) -> String { + (**self).ask(prompt, default) + } + fn ask_validated( + &self, + prompt: &str, + default: &str, + validator: Box<dyn Fn(&str) -> Result<(), String>>, + ) -> Result<String, String> { + (**self).ask_validated(prompt, default, validator) + } + fn confirm(&self, prompt: &str) -> bool { + (**self).confirm(prompt) + } +} + +impl IoInterface for Console { + fn write(&self, msg: &str, required: Verbosity) { + self.write(msg, required) + } + fn write_stdout(&self, msg: &str, required: Verbosity) { + self.write_stdout(msg, required) + } + fn write_error(&self, msg: &str) { + self.write_error(msg) + } + fn info(&self, msg: &str) { + self.info(msg) + } + fn verbose(&self, msg: &str) { + self.verbose(msg) + } + fn very_verbose(&self, msg: &str) { + self.very_verbose(msg) + } + fn debug(&self, msg: &str) { + self.debug(msg) + } + fn error(&self, msg: &str) { + self.error(msg) + } + fn is_interactive(&self) -> bool { + self.is_interactive() + } + fn is_decorated(&self) -> bool { + self.is_decorated() + } + fn verbosity(&self) -> Verbosity { + self.verbosity() + } + fn is_verbose(&self) -> bool { + self.is_verbose() + } + fn is_very_verbose(&self) -> bool { + self.is_very_verbose() + } + fn is_debug(&self) -> bool { + self.is_debug() + } + fn is_quiet(&self) -> bool { + self.is_quiet() + } + fn ask(&self, prompt: &str, default: &str) -> String { + self.ask(prompt, default) + } + fn ask_validated( + &self, + prompt: &str, + default: &str, + validator: Box<dyn Fn(&str) -> Result<(), String>>, + ) -> Result<String, String> { + self.ask_validated(prompt, default, validator) + } + fn confirm(&self, prompt: &str) -> bool { + self.confirm(prompt) + } +} + /// Writes a message to the output. /// /// ref: \Composer\IO\IOInterface::write() @@ -304,7 +478,7 @@ macro_rules! console_writeln { $crate::console_writeln!($console, $verbosity, $fmt, $($arg)*,) }; ($console:expr, $verbosity:expr, $fmt:literal, $($arg:tt)*) => { - if ($console).verbosity >= $verbosity { + if $console.lock().unwrap().verbosity() >= $verbosity { ::std::println!("{}", &::mozart_console_macros::console_format!($fmt, $($arg)*)); } }; @@ -325,7 +499,7 @@ macro_rules! console_write { $crate::console_writeln!($console, $verbosity, $fmt, $($arg)*,) }; ($console:expr, $verbosity:expr, $fmt:literal, $($arg:tt)*) => { - if ($console).verbosity >= $verbosity { + if $console.lock().unwrap().verbosity() >= $verbosity { ::std::print!("{}", &::mozart_console_macros::console_format!($fmt, $($arg)*)); } }; @@ -346,7 +520,7 @@ macro_rules! console_writeln_error { $crate::console_writeln!($console, $verbosity, $fmt, $($arg)*,) }; ($console:expr, $verbosity:expr, $fmt:literal, $($arg:tt)*) => { - if ($console).verbosity >= $verbosity { + if $console.lock().unwrap().verbosity() >= $verbosity { ::std::eprintln!("{}", &::mozart_console_macros::console_format!($fmt, $($arg)*)); } }; @@ -367,7 +541,7 @@ macro_rules! console_write_error { $crate::console_writeln!($console, $verbosity, $fmt, $($arg)*,) }; ($console:expr, $verbosity:expr, $fmt:literal, $($arg:tt)*) => { - if ($console).verbosity >= $verbosity { + if $console.lock().unwrap().verbosity() >= $verbosity { ::std::eprint!("{}", &::mozart_console_macros::console_format!($fmt, $($arg)*)); } }; |
