aboutsummaryrefslogtreecommitdiff
path: root/mingling
diff options
context:
space:
mode:
Diffstat (limited to 'mingling')
-rw-r--r--mingling/src/docs/lib.md2
-rw-r--r--mingling/src/example_docs.rs6
-rw-r--r--mingling/src/gen_program.rs12
-rw-r--r--mingling/src/picker/global.rs72
-rw-r--r--mingling/src/setups/picker/basic.rs8
-rw-r--r--mingling/src/setups/picker/structural_renderer.rs19
6 files changed, 74 insertions, 45 deletions
diff --git a/mingling/src/docs/lib.md b/mingling/src/docs/lib.md
index a7a583b..697f6c5 100644
--- a/mingling/src/docs/lib.md
+++ b/mingling/src/docs/lib.md
@@ -51,7 +51,7 @@ fn render_name(name: ResultName) -> RenderResult {
}
#[renderer]
-fn render_dispatcher_not_found(err: ErrorDispatcherNotFound) -> RenderResult {
+fn render_entry_fallback(err: EntryFallback) -> RenderResult {
let mut result = RenderResult::default();
if err.len() > 0 {
result.println(&format!("Command not found: [{}]", err.join(" ")));
diff --git a/mingling/src/example_docs.rs b/mingling/src/example_docs.rs
index 6f37a13..cb6bbe7 100644
--- a/mingling/src/example_docs.rs
+++ b/mingling/src/example_docs.rs
@@ -1500,7 +1500,7 @@ pub mod example_enum_tag {}
///
/// /// Renders the error when the dispatcher (subcommand) is not found.
/// #[renderer]
-/// fn render_dispatcher_not_found(err: ErrorDispatcherNotFound) -> RenderResult {
+/// fn render_entry_fallback(err: EntryFallback) -> RenderResult {
/// let mut render_result = RenderResult::new();
/// writeln!(
/// render_result,
@@ -2580,7 +2580,7 @@ pub mod example_pathfinder {}
/// /// Handle dispatcher not found event
/// /// Renders the error when a command is not found.
/// #[renderer]
-/// fn dispatcher_not_found(prev: ErrorDispatcherNotFound) -> RenderResult {
+/// fn dispatcher_not_found(prev: EntryFallback) -> RenderResult {
/// let mut render_result = RenderResult::new();
/// writeln!(render_result, "Command not found: \"{}\"", prev.join(", ")).ok();
/// render_result
@@ -2970,7 +2970,7 @@ pub mod example_structural_renderer {}
///
/// /// Renders the error when the dispatcher (subcommand) is not found.
/// #[renderer]
-/// fn render_dispatcher_not_found(err: ErrorDispatcherNotFound) -> RenderResult {
+/// fn render_entry_fallback(err: EntryFallback) -> RenderResult {
/// let mut render_result = RenderResult::new();
/// writeln!(
/// render_result,
diff --git a/mingling/src/gen_program.rs b/mingling/src/gen_program.rs
index aa0c4b5..a3b7e29 100644
--- a/mingling/src/gen_program.rs
+++ b/mingling/src/gen_program.rs
@@ -28,7 +28,7 @@ pub enum ThisProgram {
/// Indicates that no matching renderer was found for the given output.
ErrorRendererNotFound,
/// Indicates that no matching dispatcher was found for the given arguments.
- ErrorDispatcherNotFound,
+ EntryFallback,
/// Indicates that the result is empty.
ResultEmpty,
/// Indicates the completion suggestions computed by the program for rendering.
@@ -52,7 +52,7 @@ pub struct ErrorRendererNotFound {
///
/// This type is created by the `pack!` macro as a variant of the
/// program's output type set (`ThisProgram`).
-pub struct ErrorDispatcherNotFound {
+pub struct EntryFallback {
/// The arguments provided by the user
pub(crate) inner: Vec<String>,
}
@@ -139,9 +139,9 @@ unsafe impl Grouped<ThisProgram> for ErrorRendererNotFound {
// However, these are marked `unsafe` because the `Grouped` trait requires the
// implementor to guarantee that the type is the only one associated with the
// given enum variant — a guarantee that should be carefully verified in production code.
-unsafe impl Grouped<ThisProgram> for ErrorDispatcherNotFound {
+unsafe impl Grouped<ThisProgram> for EntryFallback {
fn member_id() -> ThisProgram {
- ThisProgram::ErrorDispatcherNotFound
+ ThisProgram::EntryFallback
}
}
@@ -186,7 +186,7 @@ unsafe impl Grouped<ThisProgram> for CompletionSuggest {
impl ProgramCollect for ThisProgram {
type Enum = ThisProgram;
- type ErrorDispatcherNotFound = ErrorDispatcherNotFound;
+ type EntryFallback = EntryFallback;
type ErrorRendererNotFound = ErrorRendererNotFound;
@@ -196,7 +196,7 @@ impl ProgramCollect for ThisProgram {
todo!()
}
- fn build_dispatcher_not_found(_args: Vec<String>) -> mingling_core::AnyOutput<Self::Enum> {
+ fn build_entry_fallback(_args: Vec<String>) -> mingling_core::AnyOutput<Self::Enum> {
todo!()
}
diff --git a/mingling/src/picker/global.rs b/mingling/src/picker/global.rs
index c203524..f062671 100644
--- a/mingling/src/picker/global.rs
+++ b/mingling/src/picker/global.rs
@@ -3,33 +3,65 @@ use mingling_core::{Program, ProgramCollect};
use crate::consts::REMAINS;
-/// Picks a global flag from the program's arguments.
+/// Provides helper methods for picking arguments from a [`Program`]'s argument list.
///
-/// This function takes ownership of the program's current arguments, picks the specified `flag`
-/// from them, and then returns the remaining arguments back to the program. It returns the
-/// boolean value of the flag.
-pub fn pick_global_flag<C>(program: &mut Program<C>, flag: &PickerArg<Flag>) -> bool
+/// This trait abstracts the functionality of extracting specific arguments or flags
+/// from the program's current arguments, while restoring any remaining arguments
+/// back into the program.
+pub trait PickerHelper<C>
where
C: ProgramCollect<Enum = C>,
{
- let args = program.take_args();
- let (flag, args) = args.pick(flag).pick(&REMAINS).unwrap();
- program.replace_args(args.into());
- *flag
+ /// Takes ownership of the program's current arguments.
+ ///
+ /// Returns the program's argument list as a [`Vec<String>`], leaving the program
+ /// with no arguments until [`replace_args`] is called.
+ ///
+ /// [`replace_args`]: PickerHelper::replace_args
+ fn take_args(&mut self) -> Vec<String>;
+
+ /// Replaces the program's current arguments with the provided list.
+ ///
+ /// Returns the previous argument list that was replaced.
+ fn replace_args(&mut self, args: Vec<String>) -> Vec<String>;
+
+ /// Picks a flag from the program's arguments.
+ ///
+ /// This function takes ownership of the program's current arguments, picks the specified `flag`
+ /// from them, and then returns the remaining arguments back to the program. It returns the
+ /// boolean value of the flag.
+ fn pick_flag(&mut self, flag: &PickerArg<Flag>) -> bool {
+ let args = self.take_args();
+ let (flag, args) = args.pick(flag).pick(&REMAINS).unwrap();
+ self.replace_args(args.into());
+ *flag
+ }
+
+ /// Picks a argument from the program's arguments.
+ ///
+ /// This function takes ownership of the program's current arguments, picks the specified `arg`
+ /// from them, and then returns the remaining arguments back to the program. It returns the
+ /// picked argument value, or `None` if the argument was not present.
+ fn pick_argument<A>(&mut self, arg: &PickerArg<A>) -> Option<A>
+ where
+ A: for<'a> Pickable<'a> + Default,
+ {
+ let args = self.take_args();
+ let (arg, remains) = args.pick(arg).pick(&REMAINS).unpack();
+ self.replace_args(remains.unwrap().into());
+ arg
+ }
}
-/// Picks a global argument from the program's arguments.
-///
-/// This function takes ownership of the program's current arguments, picks the specified `arg`
-/// from them, and then returns the remaining arguments back to the program. It returns the
-/// picked argument value, or `None` if the argument was not present.
-pub fn pick_global_argument<C, A>(program: &mut Program<C>, arg: &PickerArg<A>) -> Option<A>
+impl<C> PickerHelper<C> for Program<C>
where
- A: for<'a> Pickable<'a> + Default,
C: ProgramCollect<Enum = C>,
{
- let args = program.take_args();
- let (arg, remains) = args.pick(arg).pick(&REMAINS).unpack();
- program.replace_args(remains.unwrap().into());
- arg
+ fn take_args(&mut self) -> Vec<String> {
+ self.take_args()
+ }
+
+ fn replace_args(&mut self, args: Vec<String>) -> Vec<String> {
+ self.replace_args(args)
+ }
}
diff --git a/mingling/src/setups/picker/basic.rs b/mingling/src/setups/picker/basic.rs
index c9f82b3..52bda3d 100644
--- a/mingling/src/setups/picker/basic.rs
+++ b/mingling/src/setups/picker/basic.rs
@@ -3,7 +3,7 @@ use mingling_core::{Program, ProgramCollect, setup::ProgramSetup};
use crate::{
consts::{CONFIRM_FLAG, HELP_FLAG, QUIET_FLAG},
- picker::pick_global_flag,
+ picker::PickerHelper,
};
/// Performs basic program initialization:
@@ -43,7 +43,7 @@ where
C: ProgramCollect<Enum = C>,
{
fn setup(self, program: &mut Program<C>) {
- let help = pick_global_flag(program, self.flag);
+ let help = program.pick_flag(self.flag);
if help {
program.user_context.help = true;
}
@@ -75,7 +75,7 @@ where
C: ProgramCollect<Enum = C>,
{
fn setup(self, program: &mut Program<C>) {
- let help = pick_global_flag(program, self.flag);
+ let help = program.pick_flag(self.flag);
if help {
program.stdout_setting.quiet = true;
}
@@ -107,7 +107,7 @@ where
C: ProgramCollect<Enum = C>,
{
fn setup(self, program: &mut Program<C>) {
- let help = pick_global_flag(program, self.flag);
+ let help = program.pick_flag(self.flag);
if help {
program.user_context.confirm = true;
}
diff --git a/mingling/src/setups/picker/structural_renderer.rs b/mingling/src/setups/picker/structural_renderer.rs
index 1fa48fd..91848e4 100644
--- a/mingling/src/setups/picker/structural_renderer.rs
+++ b/mingling/src/setups/picker/structural_renderer.rs
@@ -1,9 +1,6 @@
use mingling_core::{Program, ProgramCollect, setup::ProgramSetup};
-use crate::{
- consts::RENDERER_ARG,
- picker::{pick_global_argument, pick_global_flag},
-};
+use crate::{consts::RENDERER_ARG, picker::PickerHelper};
/// Sets up the structural renderer for the program:
///
@@ -15,7 +12,7 @@ where
C: ProgramCollect<Enum = C>,
{
fn setup(self, program: &mut Program<C>) {
- if let Some(renderer) = pick_global_argument(program, &RENDERER_ARG) {
+ if let Some(renderer) = program.pick_argument(&RENDERER_ARG) {
program.structural_renderer_name = renderer.into();
}
}
@@ -49,27 +46,27 @@ where
{
fn setup(self, program: &mut Program<C>) {
#[cfg(feature = "json_serde_fmt")]
- if pick_global_flag(program, &crate::consts::JSON_FLAG) {
+ if program.pick_flag(&crate::consts::JSON_FLAG) {
program.structural_renderer_name = crate::StructuralRendererSetting::Json;
}
#[cfg(feature = "json_serde_fmt")]
- if pick_global_flag(program, &crate::consts::JSON_PRETTY_FLAG) {
+ if program.pick_flag(&crate::consts::JSON_PRETTY_FLAG) {
program.structural_renderer_name = crate::StructuralRendererSetting::JsonPretty;
}
#[cfg(feature = "yaml_serde_fmt")]
- if pick_global_flag(program, &crate::consts::YAML_FLAG) {
+ if program.pick_flag(&crate::consts::YAML_FLAG) {
program.structural_renderer_name = crate::StructuralRendererSetting::Yaml;
}
#[cfg(feature = "toml_serde_fmt")]
- if pick_global_flag(program, &crate::consts::TOML_FLAG) {
+ if program.pick_flag(&crate::consts::TOML_FLAG) {
program.structural_renderer_name = crate::StructuralRendererSetting::Toml;
}
#[cfg(feature = "ron_serde_fmt")]
- if pick_global_flag(program, &crate::consts::RON_FLAG) {
+ if program.pick_flag(&crate::consts::RON_FLAG) {
program.structural_renderer_name = crate::StructuralRendererSetting::Ron;
}
#[cfg(feature = "ron_serde_fmt")]
- if pick_global_flag(program, &crate::consts::RON_PRETTY_FLAG) {
+ if program.pick_flag(&crate::consts::RON_PRETTY_FLAG) {
program.structural_renderer_name = crate::StructuralRendererSetting::RonPretty;
}
}