diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-06-12 01:01:35 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-06-12 01:01:43 +0900 |
| commit | 1e44f5723e4c0e0903d00a61f254901e612fe5e1 (patch) | |
| tree | 9c2e1eec364bbf6418a4072ee7767b04c3df0297 /crates/shirabe-external-packages/src/symfony/console/output/output.rs | |
| parent | ddf0a624145b618c05c2ee47414545b99b685f37 (diff) | |
| download | php-shirabe-1e44f5723e4c0e0903d00a61f254901e612fe5e1.tar.gz php-shirabe-1e44f5723e4c0e0903d00a61f254901e612fe5e1.tar.zst php-shirabe-1e44f5723e4c0e0903d00a61f254901e612fe5e1.zip | |
feat(symfony-console): port Symfony Console and make the workspace compile
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe-external-packages/src/symfony/console/output/output.rs')
| -rw-r--r-- | crates/shirabe-external-packages/src/symfony/console/output/output.rs | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/crates/shirabe-external-packages/src/symfony/console/output/output.rs b/crates/shirabe-external-packages/src/symfony/console/output/output.rs new file mode 100644 index 0000000..e2469e9 --- /dev/null +++ b/crates/shirabe-external-packages/src/symfony/console/output/output.rs @@ -0,0 +1,157 @@ +use crate::symfony::console::formatter::OutputFormatter; +use crate::symfony::console::formatter::OutputFormatterInterface; +use crate::symfony::console::output::output_interface::{ + OUTPUT_NORMAL, OUTPUT_PLAIN, OUTPUT_RAW, VERBOSITY_DEBUG, VERBOSITY_NORMAL, VERBOSITY_QUIET, + VERBOSITY_VERBOSE, VERBOSITY_VERY_VERBOSE, +}; + +/// Base class for output classes. +/// +/// There are five levels of verbosity: +/// +/// * normal: no option passed (normal output) +/// * verbose: -v (more output) +/// * very verbose: -vv (highly extended output) +/// * debug: -vvv (all debug output) +/// * quiet: -q (no output) +pub struct Output { + verbosity: std::cell::Cell<i64>, + formatter: std::cell::RefCell<std::rc::Rc<std::cell::RefCell<dyn OutputFormatterInterface>>>, +} + +impl std::fmt::Debug for Output { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("Output") + .field("verbosity", &self.verbosity) + .finish_non_exhaustive() + } +} + +/// Subclasses provide the concrete sink by implementing `do_write`. +/// +/// This mirrors the PHP `abstract protected function doWrite(string $message, bool $newline)`. +pub trait DoWrite { + fn do_write(&self, message: &str, newline: bool); +} + +impl Output { + pub fn new( + verbosity: Option<i64>, + decorated: bool, + formatter: Option<std::rc::Rc<std::cell::RefCell<dyn OutputFormatterInterface>>>, + ) -> Self { + let verbosity = verbosity.unwrap_or(VERBOSITY_NORMAL); + let formatter = formatter.unwrap_or_else(|| { + std::rc::Rc::new(std::cell::RefCell::new(OutputFormatter::new( + false, + indexmap::IndexMap::new(), + ))) + }); + formatter.borrow_mut().set_decorated(decorated); + Self { + verbosity: std::cell::Cell::new(verbosity), + formatter: std::cell::RefCell::new(formatter), + } + } + + pub fn set_formatter( + &self, + formatter: std::rc::Rc<std::cell::RefCell<dyn OutputFormatterInterface>>, + ) { + *self.formatter.borrow_mut() = formatter; + } + + pub fn get_formatter(&self) -> std::rc::Rc<std::cell::RefCell<dyn OutputFormatterInterface>> { + self.formatter.borrow().clone() + } + + pub fn set_decorated(&self, decorated: bool) { + self.formatter + .borrow() + .borrow_mut() + .set_decorated(decorated); + } + + pub fn is_decorated(&self) -> bool { + self.formatter.borrow().borrow().is_decorated() + } + + pub fn set_verbosity(&self, level: i64) { + self.verbosity.set(level); + } + + pub fn get_verbosity(&self) -> i64 { + self.verbosity.get() + } + + pub fn is_quiet(&self) -> bool { + VERBOSITY_QUIET == self.verbosity.get() + } + + pub fn is_verbose(&self) -> bool { + VERBOSITY_VERBOSE <= self.verbosity.get() + } + + pub fn is_very_verbose(&self) -> bool { + VERBOSITY_VERY_VERBOSE <= self.verbosity.get() + } + + pub fn is_debug(&self) -> bool { + VERBOSITY_DEBUG <= self.verbosity.get() + } + + pub fn writeln(&self, do_writer: &dyn DoWrite, messages: &[String], options: i64) { + self.write(do_writer, messages, true, options); + } + + pub fn write(&self, do_writer: &dyn DoWrite, messages: &[String], newline: bool, options: i64) { + let types = OUTPUT_NORMAL | OUTPUT_RAW | OUTPUT_PLAIN; + let r#type = { + let masked = types & options; + if masked != 0 { masked } else { OUTPUT_NORMAL } + }; + + let verbosities = VERBOSITY_QUIET + | VERBOSITY_NORMAL + | VERBOSITY_VERBOSE + | VERBOSITY_VERY_VERBOSE + | VERBOSITY_DEBUG; + let verbosity = { + let masked = verbosities & options; + if masked != 0 { + masked + } else { + VERBOSITY_NORMAL + } + }; + + if verbosity > self.get_verbosity() { + return; + } + + for message in messages { + let message = match r#type { + OUTPUT_NORMAL => self + .formatter + .borrow() + .borrow_mut() + .format(Some(message)) + .unwrap() + .unwrap_or_default(), + OUTPUT_RAW => message.clone(), + OUTPUT_PLAIN => shirabe_php_shim::strip_tags( + &self + .formatter + .borrow() + .borrow_mut() + .format(Some(message)) + .unwrap() + .unwrap_or_default(), + ), + _ => message.clone(), + }; + + do_writer.do_write(&message, newline); + } + } +} |
