aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe-external-packages/src/symfony/console/helper/descriptor_helper.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/shirabe-external-packages/src/symfony/console/helper/descriptor_helper.rs')
-rw-r--r--crates/shirabe-external-packages/src/symfony/console/helper/descriptor_helper.rs135
1 files changed, 135 insertions, 0 deletions
diff --git a/crates/shirabe-external-packages/src/symfony/console/helper/descriptor_helper.rs b/crates/shirabe-external-packages/src/symfony/console/helper/descriptor_helper.rs
new file mode 100644
index 0000000..64c166c
--- /dev/null
+++ b/crates/shirabe-external-packages/src/symfony/console/helper/descriptor_helper.rs
@@ -0,0 +1,135 @@
+use crate::symfony::console::descriptor::descriptor_interface::DescriptorInterface;
+use crate::symfony::console::descriptor::json_descriptor::JsonDescriptor;
+use crate::symfony::console::descriptor::markdown_descriptor::MarkdownDescriptor;
+use crate::symfony::console::descriptor::text_descriptor::TextDescriptor;
+use crate::symfony::console::descriptor::xml_descriptor::XmlDescriptor;
+use crate::symfony::console::exception::invalid_argument_exception::InvalidArgumentException;
+use crate::symfony::console::helper::helper::Helper;
+use crate::symfony::console::helper::helper_interface::HelperInterface;
+use crate::symfony::console::helper::helper_set::HelperSet;
+use crate::symfony::console::output::output_interface::OutputInterface;
+use indexmap::IndexMap;
+use std::cell::RefCell;
+use std::rc::Rc;
+
+/// 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(),
+ };
+ // The XML/JSON/Markdown descriptors do not yet expose a constructor
+ // (no `Default`/`new`); their construction is deferred until those
+ // descriptor types provide one.
+ let xml: Box<dyn DescriptorInterface> = todo!();
+ let json: Box<dyn DescriptorInterface> = todo!();
+ let md: Box<dyn DescriptorInterface> = todo!();
+ this.register("txt", Box::new(TextDescriptor::default()))
+ .register("xml", xml)
+ .register("json", json)
+ .register("md", md);
+ 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(
+ &self,
+ output: &dyn OutputInterface,
+ object: Option<shirabe_php_shim::PhpMixed>,
+ options: IndexMap<String, shirabe_php_shim::PhpMixed>,
+ ) -> Result<(), InvalidArgumentException> {
+ 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(
+ shirabe_php_shim::InvalidArgumentException {
+ message: shirabe_php_shim::sprintf(
+ "Unsupported format \"%s\".",
+ &[shirabe_php_shim::PhpMixed::String(format.clone())],
+ ),
+ code: 0,
+ },
+ ));
+ }
+
+ let _ = (&self.descriptors[&format], output, object, options);
+ // `DescriptorInterface::describe` takes an owned
+ // `Rc<RefCell<dyn OutputInterface>>` and `&mut self`, while the helper
+ // only holds a shared `&dyn OutputInterface` and `&self`. Reconciling
+ // this ownership/mutability gap is a Phase C decision.
+ todo!("dispatch to DescriptorInterface::describe (Phase C ownership)");
+ }
+
+ /// Registers a descriptor.
+ ///
+ /// @return $this
+ 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<Rc<RefCell<HelperSet>>>) {
+ self.inner.set_helper_set(helper_set);
+ }
+
+ fn get_helper_set(&self) -> Option<Rc<RefCell<HelperSet>>> {
+ self.inner.get_helper_set()
+ }
+
+ fn get_name(&self) -> String {
+ "descriptor".to_string()
+ }
+}