aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe-symfony-console/src/helper/descriptor_helper.rs
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-08-09 11:19:03 +0900
committernsfisis <nsfisis@gmail.com>2026-08-09 11:19:03 +0900
commit6051927c8fa32cfffa102d2a170c5a6cf747a1b9 (patch)
tree3fe6769c90cb03ca8f1b9b825e38ad459182361e /crates/shirabe-symfony-console/src/helper/descriptor_helper.rs
parente3e8806aec771e482899ed3470e920f7b291fa95 (diff)
downloadphp-shirabe-6051927c8fa32cfffa102d2a170c5a6cf747a1b9.tar.gz
php-shirabe-6051927c8fa32cfffa102d2a170c5a6cf747a1b9.tar.zst
php-shirabe-6051927c8fa32cfffa102d2a170c5a6cf747a1b9.zip
refactor(symfony-console): extract symfony/console into the shirabe-symfony-console crate
Move `Symfony\Component\Console` out of shirabe-external-packages and into its own crate, so the path is `shirabe_symfony_console::application::Application` instead of `shirabe_external_packages::symfony::console::application::Application`. The `delegate_to_inner!` and `delegate_command_trait_impls_to_inner!` macros move with it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Diffstat (limited to 'crates/shirabe-symfony-console/src/helper/descriptor_helper.rs')
-rw-r--r--crates/shirabe-symfony-console/src/helper/descriptor_helper.rs119
1 files changed, 119 insertions, 0 deletions
diff --git a/crates/shirabe-symfony-console/src/helper/descriptor_helper.rs b/crates/shirabe-symfony-console/src/helper/descriptor_helper.rs
new file mode 100644
index 00000000..23bb4f66
--- /dev/null
+++ b/crates/shirabe-symfony-console/src/helper/descriptor_helper.rs
@@ -0,0 +1,119 @@
+//! ref: composer/vendor/symfony/console/Helper/DescriptorHelper.php
+
+use crate::descriptor::descriptor_interface::{DescribableObject, DescriptorInterface};
+use crate::descriptor::json_descriptor::JsonDescriptor;
+use crate::descriptor::markdown_descriptor::MarkdownDescriptor;
+use crate::descriptor::text_descriptor::TextDescriptor;
+use crate::descriptor::xml_descriptor::XmlDescriptor;
+use crate::exception::invalid_argument_exception::InvalidArgumentException;
+use crate::helper::helper::Helper;
+use crate::helper::helper_interface::HelperInterface;
+use crate::helper::helper_set::HelperSet;
+use crate::output::output_interface::OutputInterface;
+use indexmap::IndexMap;
+
+/// This class adds helper method to describe objects in various formats.
+#[derive(Default)]
+pub struct DescriptorHelper {
+ inner: Helper,
+ /// @var DescriptorInterface[]
+ descriptors: IndexMap<String, Box<dyn DescriptorInterface>>,
+}
+
+// `DescriptorInterface` does not require `Debug`, so the derive cannot see
+// through the trait object; provide a minimal manual impl.
+impl std::fmt::Debug for DescriptorHelper {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ f.debug_struct("DescriptorHelper")
+ .field("inner", &self.inner)
+ .field("descriptors", &self.descriptors.keys().collect::<Vec<_>>())
+ .finish()
+ }
+}
+
+impl DescriptorHelper {
+ pub fn new() -> Self {
+ let mut this = Self {
+ inner: Helper::default(),
+ descriptors: IndexMap::new(),
+ };
+ this.register("txt", Box::new(TextDescriptor::default()))
+ .register("xml", Box::new(XmlDescriptor::default()))
+ .register("json", Box::new(JsonDescriptor::default()))
+ .register("md", Box::new(MarkdownDescriptor::default()));
+ this
+ }
+
+ /// Describes an object if supported.
+ ///
+ /// Available options are:
+ /// * format: string, the output format name
+ /// * raw_text: boolean, sets output type as raw
+ ///
+ /// @throws InvalidArgumentException when the given format is not supported
+ pub fn describe2(
+ &mut self,
+ output: std::rc::Rc<std::cell::RefCell<dyn OutputInterface>>,
+ object: DescribableObject,
+ options: IndexMap<String, shirabe_php_shim::PhpMixed>,
+ ) -> anyhow::Result<()> {
+ let mut merged: IndexMap<String, shirabe_php_shim::PhpMixed> = IndexMap::new();
+ merged.insert(
+ "raw_text".to_string(),
+ shirabe_php_shim::PhpMixed::Bool(false),
+ );
+ merged.insert(
+ "format".to_string(),
+ shirabe_php_shim::PhpMixed::String("txt".to_string()),
+ );
+ for (key, value) in options {
+ merged.insert(key, value);
+ }
+ let options = merged;
+
+ let format = match &options["format"] {
+ shirabe_php_shim::PhpMixed::String(format) => format.clone(),
+ _ => String::new(),
+ };
+
+ if !self.descriptors.contains_key(&format) {
+ return Err(InvalidArgumentException::new(format!(
+ "Unsupported format \"{}\".",
+ format.clone()
+ ))
+ .into());
+ }
+
+ let descriptor = self.descriptors.get_mut(&format).unwrap();
+ descriptor.describe(output, object, options)
+ }
+
+ /// Registers a descriptor.
+ pub fn register(
+ &mut self,
+ format: &str,
+ descriptor: Box<dyn DescriptorInterface>,
+ ) -> &mut Self {
+ self.descriptors.insert(format.to_string(), descriptor);
+
+ self
+ }
+
+ pub fn get_formats(&self) -> Vec<String> {
+ self.descriptors.keys().cloned().collect()
+ }
+}
+
+impl HelperInterface for DescriptorHelper {
+ fn set_helper_set(&mut self, helper_set: Option<std::rc::Rc<std::cell::RefCell<HelperSet>>>) {
+ self.inner.set_helper_set(helper_set);
+ }
+
+ fn get_helper_set(&self) -> Option<std::rc::Rc<std::cell::RefCell<HelperSet>>> {
+ self.inner.get_helper_set()
+ }
+
+ fn get_name(&self) -> String {
+ "descriptor".to_string()
+ }
+}