diff options
Diffstat (limited to 'mingling_core/src/program')
| -rw-r--r-- | mingling_core/src/program/config.rs | 62 | ||||
| -rw-r--r-- | mingling_core/src/program/exec.rs | 40 | ||||
| -rw-r--r-- | mingling_core/src/program/setup.rs | 5 | ||||
| -rw-r--r-- | mingling_core/src/program/setup/general_renderer.rs | 61 |
4 files changed, 157 insertions, 11 deletions
diff --git a/mingling_core/src/program/config.rs b/mingling_core/src/program/config.rs index 6ad0a38..2f5de4c 100644 --- a/mingling_core/src/program/config.rs +++ b/mingling_core/src/program/config.rs @@ -17,7 +17,7 @@ impl Default for ProgramStdoutSetting { } } -/// Program stdout settings +/// Program user context #[derive(Debug, Clone, Default)] pub struct ProgramUserContext { /// View help information instead of running the command @@ -26,3 +26,63 @@ pub struct ProgramUserContext { /// Skip user confirmation step pub confirm: bool, } + +#[cfg(feature = "general_renderer")] +#[derive(Debug, Clone, Default)] +pub enum GeneralRendererSetting { + #[default] + Disable, + Json, + JsonPretty, + Yaml, + Toml, + Ron, + RonPretty, +} + +#[cfg(feature = "general_renderer")] +impl std::str::FromStr for GeneralRendererSetting { + type Err = String; + + fn from_str(s: &str) -> Result<Self, Self::Err> { + match just_fmt::kebab_case!(s).as_str() { + "disable" => Ok(GeneralRendererSetting::Disable), + "json" => Ok(GeneralRendererSetting::Json), + "json-pretty" => Ok(GeneralRendererSetting::JsonPretty), + "yaml" => Ok(GeneralRendererSetting::Yaml), + "toml" => Ok(GeneralRendererSetting::Toml), + "ron" => Ok(GeneralRendererSetting::Ron), + "ron-pretty" => Ok(GeneralRendererSetting::RonPretty), + _ => Err(format!("Invalid renderer: '{}'", s)), + } + } +} + +#[cfg(feature = "general_renderer")] +impl From<&str> for GeneralRendererSetting { + fn from(s: &str) -> Self { + s.parse().unwrap_or(GeneralRendererSetting::Disable) + } +} + +#[cfg(feature = "general_renderer")] +impl From<String> for GeneralRendererSetting { + fn from(s: String) -> Self { + s.as_str().into() + } +} + +#[cfg(feature = "general_renderer")] +impl std::fmt::Display for GeneralRendererSetting { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + GeneralRendererSetting::Disable => write!(f, "disable"), + GeneralRendererSetting::Json => write!(f, "json"), + GeneralRendererSetting::JsonPretty => write!(f, "json-pretty"), + GeneralRendererSetting::Yaml => write!(f, "yaml"), + GeneralRendererSetting::Toml => write!(f, "toml"), + GeneralRendererSetting::Ron => write!(f, "ron"), + GeneralRendererSetting::RonPretty => write!(f, "ron-pretty"), + } + } +} diff --git a/mingling_core/src/program/exec.rs b/mingling_core/src/program/exec.rs index 29cfa1d..1a4f6ff 100644 --- a/mingling_core/src/program/exec.rs +++ b/mingling_core/src/program/exec.rs @@ -23,14 +23,16 @@ where Ok((dispatcher, args)) => { // Entry point current = match dispatcher.begin(args) { - ChainProcess::Ok((any, Next::Renderer)) => return Ok(render::<C, G>(any)), + ChainProcess::Ok((any, Next::Renderer)) => { + return Ok(render::<C, G>(&program, any)); + } ChainProcess::Ok((any, Next::Chain)) => any, ChainProcess::Err(e) => return Err(e.into()), }; } Err(ProgramInternalExecuteError::DispatcherNotFound) => { // No matching Dispatcher is found - current = C::build_dispatcher_not_found(program.args); + current = C::build_dispatcher_not_found(program.args.clone()); } Err(e) => return Err(e), }; @@ -42,16 +44,16 @@ where // If a chain exists, execute as a chain if C::has_chain(¤t) { match C::do_chain(current).await { - ChainProcess::Ok((any, Next::Renderer)) => return Ok(render::<C, G>(any)), + ChainProcess::Ok((any, Next::Renderer)) => { + return Ok(render::<C, G>(&program, any)); + } ChainProcess::Ok((any, Next::Chain)) => any, ChainProcess::Err(e) => return Err(e.into()), } } // If no chain exists, attempt to render else if C::has_renderer(¤t) { - let mut render_result = RenderResult::default(); - C::render(current, &mut render_result); - return Ok(render_result); + return Ok(render::<C, G>(&program, current)); } // No renderer exists else { @@ -113,10 +115,28 @@ where } #[inline(always)] -fn render<C: ProgramCollect<Enum = G>, G: Display>(any: AnyOutput<G>) -> RenderResult { - let mut render_result = RenderResult::default(); - C::render(any, &mut render_result); - render_result +#[allow(unused_variables)] +fn render<C: ProgramCollect<Enum = G>, G: Display>( + program: &Program<C, G>, + any: AnyOutput<G>, +) -> RenderResult { + #[cfg(not(feature = "general_renderer"))] + { + let mut render_result = RenderResult::default(); + C::render(any, &mut render_result); + render_result + } + #[cfg(feature = "general_renderer")] + { + match program.general_renderer_name { + super::GeneralRendererSetting::Disable => { + let mut render_result = RenderResult::default(); + C::render(any, &mut render_result); + render_result + } + _ => C::general_render(any, &program.general_renderer_name).unwrap(), + } + } } // Get all registered dispatcher names from the program diff --git a/mingling_core/src/program/setup.rs b/mingling_core/src/program/setup.rs index 1f16f80..7b534f3 100644 --- a/mingling_core/src/program/setup.rs +++ b/mingling_core/src/program/setup.rs @@ -5,6 +5,11 @@ use crate::{ProgramCollect, program::Program}; mod basic; pub use basic::*; +#[cfg(feature = "general_renderer")] +mod general_renderer; +#[cfg(feature = "general_renderer")] +pub use general_renderer::*; + pub trait ProgramSetup<C, G> where C: ProgramCollect, diff --git a/mingling_core/src/program/setup/general_renderer.rs b/mingling_core/src/program/setup/general_renderer.rs new file mode 100644 index 0000000..8b41b68 --- /dev/null +++ b/mingling_core/src/program/setup/general_renderer.rs @@ -0,0 +1,61 @@ +use std::fmt::Display; + +use crate::{ + ProgramCollect, + program::{Program, setup::ProgramSetup}, +}; + +/// Sets up the general renderer for the program: +/// +/// - Adds a `--renderer` global argument to specify the renderer type +pub struct GeneralRendererSimpleSetup; + +impl<C, G> ProgramSetup<C, G> for GeneralRendererSimpleSetup +where + C: ProgramCollect, + G: Display, +{ + fn setup(&mut self, program: &mut Program<C, G>) { + program.global_argument("--renderer", |p, renderer| { + p.general_renderer_name = renderer.into(); + }); + } +} + +/// Sets up the general renderer for the program: +/// +/// - Adds global flags to specify the renderer type: +/// * `--json` for JSON output +/// * `--json-pretty` for pretty-printed JSON output +/// * `--yaml` for YAML output +/// * `--toml` for TOML output +/// * `--ron` for RON output +/// * `--ron-pretty` for pretty-printed RON output +pub struct GeneralRendererSetup; + +impl<C, G> ProgramSetup<C, G> for GeneralRendererSetup +where + C: ProgramCollect, + G: Display, +{ + fn setup(&mut self, program: &mut Program<C, G>) { + program.global_flag("--json", |p| { + p.general_renderer_name = crate::GeneralRendererSetting::Json + }); + program.global_flag("--json-pretty", |p| { + p.general_renderer_name = crate::GeneralRendererSetting::JsonPretty.into(); + }); + program.global_flag("--yaml", |p| { + p.general_renderer_name = crate::GeneralRendererSetting::Yaml.into(); + }); + program.global_flag("--toml", |p| { + p.general_renderer_name = crate::GeneralRendererSetting::Toml.into(); + }); + program.global_flag("--ron", |p| { + p.general_renderer_name = crate::GeneralRendererSetting::Ron.into(); + }); + program.global_flag("--ron-pretty", |p| { + p.general_renderer_name = crate::GeneralRendererSetting::RonPretty.into(); + }); + } +} |
