aboutsummaryrefslogtreecommitdiff
path: root/mingling_core/src/program
diff options
context:
space:
mode:
Diffstat (limited to 'mingling_core/src/program')
-rw-r--r--mingling_core/src/program/exec.rs76
-rw-r--r--mingling_core/src/program/setup.rs4
-rw-r--r--mingling_core/src/program/string_vec.rs56
3 files changed, 85 insertions, 51 deletions
diff --git a/mingling_core/src/program/exec.rs b/mingling_core/src/program/exec.rs
index 8ab2036..68a694e 100644
--- a/mingling_core/src/program/exec.rs
+++ b/mingling_core/src/program/exec.rs
@@ -1,7 +1,5 @@
#![allow(clippy::borrowed_box)]
-use std::fmt::Display;
-
use crate::{
AnyOutput, ChainProcess, Dispatcher, Next, Program, ProgramCollect, RenderResult,
error::ProgramInternalExecuteError,
@@ -16,30 +14,10 @@ pub async fn exec<C, G>(
) -> Result<RenderResult, ProgramInternalExecuteError>
where
C: ProgramCollect<Enum = G>,
- G: Display,
{
- let mut current;
+ let mut current = dispatch_args_dynamic(program, program.args.clone())?;
let mut stop_next = false;
- // Match user input
- match match_user_input(program, program.args.clone()) {
- Ok((dispatcher, args)) => {
- // Entry point
- current = match dispatcher.begin(args) {
- 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.clone());
- }
- Err(e) => return Err(e),
- };
-
loop {
let final_exec = stop_next;
@@ -76,30 +54,10 @@ where
pub fn exec<C, G>(program: &Program<C, G>) -> Result<RenderResult, ProgramInternalExecuteError>
where
C: ProgramCollect<Enum = G>,
- G: Display,
{
- let mut current;
+ let mut current = dispatch_args_dynamic(program, program.args.clone())?;
let mut stop_next = false;
- // Match user input
- match match_user_input(program, program.args.clone()) {
- Ok((dispatcher, args)) => {
- // Entry point
- current = match dispatcher.begin(args) {
- 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.clone());
- }
- Err(e) => return Err(e),
- };
-
loop {
let final_exec = stop_next;
@@ -132,15 +90,39 @@ where
Ok(RenderResult::default())
}
+/// Dynamically dispatch input arguments to registered entry types
+pub(crate) fn dispatch_args_dynamic<C, G>(
+ program: &Program<C, G>,
+ args: Vec<String>,
+) -> Result<AnyOutput<G>, ProgramInternalExecuteError>
+where
+ C: ProgramCollect<Enum = G>,
+{
+ let next = match match_user_input(program, args) {
+ Ok((dispatcher, args)) => {
+ // Entry point
+ match dispatcher.begin(args) {
+ ChainProcess::Ok((any, _)) => any,
+ ChainProcess::Err(e) => return Err(e.into()),
+ }
+ }
+ Err(ProgramInternalExecuteError::DispatcherNotFound) => {
+ // No matching Dispatcher is found
+ C::build_dispatcher_not_found(program.args.clone())
+ }
+ Err(e) => return Err(e),
+ };
+ Ok(next)
+}
+
/// Match user input against registered dispatchers and return the matched dispatcher and remaining arguments.
#[allow(clippy::type_complexity)]
-pub fn match_user_input<C, G>(
+pub(crate) fn match_user_input<C, G>(
program: &Program<C, G>,
args: Vec<String>,
) -> Result<(&(dyn Dispatcher<G> + Send + Sync), Vec<String>), ProgramInternalExecuteError>
where
C: ProgramCollect<Enum = G>,
- G: Display,
{
let nodes = program.get_nodes();
let command = format!("{} ", args.join(" "));
@@ -180,7 +162,7 @@ where
#[inline(always)]
#[allow(unused_variables)]
-fn render<C: ProgramCollect<Enum = G>, G: Display>(
+fn render<C: ProgramCollect<Enum = G>, G>(
program: &Program<C, G>,
any: AnyOutput<G>,
) -> RenderResult {
diff --git a/mingling_core/src/program/setup.rs b/mingling_core/src/program/setup.rs
index 7b534f3..f095ed3 100644
--- a/mingling_core/src/program/setup.rs
+++ b/mingling_core/src/program/setup.rs
@@ -1,5 +1,3 @@
-use std::fmt::Display;
-
use crate::{ProgramCollect, program::Program};
mod basic;
@@ -13,7 +11,6 @@ pub use general_renderer::*;
pub trait ProgramSetup<C, G>
where
C: ProgramCollect,
- G: Display,
{
fn setup(&mut self, program: &mut Program<C, G>);
}
@@ -21,7 +18,6 @@ where
impl<C, G> Program<C, G>
where
C: ProgramCollect,
- G: Display,
{
/// Load and execute init logic
pub fn with_setup<S: ProgramSetup<C, G> + 'static>(&mut self, mut setup: S) -> S {
diff --git a/mingling_core/src/program/string_vec.rs b/mingling_core/src/program/string_vec.rs
new file mode 100644
index 0000000..478ad74
--- /dev/null
+++ b/mingling_core/src/program/string_vec.rs
@@ -0,0 +1,56 @@
+#[derive(Debug, Clone)]
+pub struct StringVec {
+ vec: Vec<String>,
+}
+
+impl std::ops::Deref for StringVec {
+ type Target = Vec<String>;
+
+ fn deref(&self) -> &Self::Target {
+ &self.vec
+ }
+}
+
+impl From<StringVec> for Vec<String> {
+ fn from(val: StringVec) -> Self {
+ val.vec
+ }
+}
+
+impl<const N: usize> From<[&str; N]> for StringVec {
+ fn from(slice: [&str; N]) -> Self {
+ StringVec {
+ vec: slice.iter().map(|&s| s.to_string()).collect(),
+ }
+ }
+}
+
+impl From<&[&str]> for StringVec {
+ fn from(slice: &[&str]) -> Self {
+ StringVec {
+ vec: slice.iter().map(|&s| s.to_string()).collect(),
+ }
+ }
+}
+
+impl From<Vec<String>> for StringVec {
+ fn from(vec: Vec<String>) -> Self {
+ StringVec { vec }
+ }
+}
+
+impl From<&[String]> for StringVec {
+ fn from(slice: &[String]) -> Self {
+ StringVec {
+ vec: slice.to_vec(),
+ }
+ }
+}
+
+impl From<Vec<&str>> for StringVec {
+ fn from(vec: Vec<&str>) -> Self {
+ StringVec {
+ vec: vec.iter().map(|&s| s.to_string()).collect(),
+ }
+ }
+}