diff options
Diffstat (limited to 'mingling_core')
| -rw-r--r-- | mingling_core/src/any.rs | 22 | ||||
| -rw-r--r-- | mingling_core/src/any/group.rs | 20 | ||||
| -rw-r--r-- | mingling_core/src/asset.rs | 3 | ||||
| -rw-r--r-- | mingling_core/src/asset/global_resource.rs | 7 | ||||
| -rw-r--r-- | mingling_core/src/asset/routable.rs | 22 | ||||
| -rw-r--r-- | mingling_core/src/comp.rs | 2 | ||||
| -rw-r--r-- | mingling_core/src/lib.rs | 1 | ||||
| -rw-r--r-- | mingling_core/src/program.rs | 27 | ||||
| -rw-r--r-- | mingling_core/src/program/collection.rs | 8 | ||||
| -rw-r--r-- | mingling_core/src/program/collection/mock.rs | 4 | ||||
| -rw-r--r-- | mingling_core/src/program/hook.rs | 4 | ||||
| -rw-r--r-- | mingling_core/src/program/setup.rs | 17 | ||||
| -rw-r--r-- | mingling_core/src/renderer/render_result.rs | 50 |
13 files changed, 160 insertions, 27 deletions
diff --git a/mingling_core/src/any.rs b/mingling_core/src/any.rs index 2680f43..e6b7406 100644 --- a/mingling_core/src/any.rs +++ b/mingling_core/src/any.rs @@ -1,12 +1,12 @@ use crate::error::ChainProcessError; -use crate::{Groupped, ProgramCollect}; +use crate::{Grouped, ProgramCollect}; #[doc(hidden)] pub mod group; /// Any type output /// -/// Accepts any type that implements `Send + Groupped<G>` +/// Accepts any type that implements `Send + Grouped<G>` /// After being passed into `AnyOutput`, it will be converted to `Box<dyn Any + Send + 'static>` /// /// Note: @@ -22,10 +22,10 @@ pub struct AnyOutput<G> { } impl<G> AnyOutput<G> { - /// Create an `AnyOutput` from a `Send + Groupped<G>` type + /// Create an `AnyOutput` from a `Send + Grouped<G>` type pub fn new<T>(value: T) -> Self where - T: Send + Groupped<G> + 'static, + T: Send + Grouped<G> + 'static, { Self { inner: Box::new(value), @@ -148,7 +148,7 @@ where #[cfg(test)] mod tests { use super::*; - use crate::Groupped; + use crate::Grouped; /// Mock enum for testing AnyOutput #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -175,7 +175,7 @@ mod tests { value: i32, } - impl Groupped<MockGroup> for AlphaData { + impl Grouped<MockGroup> for AlphaData { fn member_id() -> MockGroup { MockGroup::Alpha } @@ -187,7 +187,7 @@ mod tests { name: String, } - impl Groupped<MockGroup> for BetaData { + impl Grouped<MockGroup> for BetaData { fn member_id() -> MockGroup { MockGroup::Beta } @@ -198,7 +198,7 @@ mod tests { #[cfg_attr(feature = "structural_renderer", derive(serde::Serialize))] struct GammaData; - impl Groupped<MockGroup> for GammaData { + impl Grouped<MockGroup> for GammaData { fn member_id() -> MockGroup { MockGroup::Gamma } @@ -354,7 +354,7 @@ mod tests { x: i32, } - impl Groupped<MockGroup> for SerData { + impl Grouped<MockGroup> for SerData { fn member_id() -> MockGroup { MockGroup::Gamma } @@ -381,13 +381,13 @@ mod tests { b: String, } - impl Groupped<MockGroup> for SerA { + impl Grouped<MockGroup> for SerA { fn member_id() -> MockGroup { MockGroup::Alpha } } - impl Groupped<MockGroup> for SerB { + impl Grouped<MockGroup> for SerB { fn member_id() -> MockGroup { MockGroup::Beta } diff --git a/mingling_core/src/any/group.rs b/mingling_core/src/any/group.rs index cb847d9..90ef9fc 100644 --- a/mingling_core/src/any/group.rs +++ b/mingling_core/src/any/group.rs @@ -1,11 +1,11 @@ -use crate::{AnyOutput, ChainProcess}; +use crate::{AnyOutput, ChainProcess, ProgramCollect, Routable}; /// Used to mark a type with a unique enum ID, assisting dynamic dispatch /// -/// **Note:** Unlike earlier versions, `Groupped` no longer requires `Serialize` +/// **Note:** Unlike earlier versions, `Grouped` no longer requires `Serialize` /// even when the `structural_renderer` feature is enabled. Structured output is /// controlled separately via the \[`StructuralData`\] trait. -pub trait Groupped<Group> +pub trait Grouped<Group> where Self: Sized + 'static, { @@ -32,3 +32,17 @@ where AnyOutput::new(self).route_renderer() } } + +impl<T, C> Routable<C> for T +where + C: ProgramCollect<Enum = C>, + T: Grouped<C> + Send, +{ + fn to_chain(self) -> ChainProcess<C> { + T::to_chain(self) + } + + fn to_render(self) -> ChainProcess<C> { + T::to_render(self) + } +} diff --git a/mingling_core/src/asset.rs b/mingling_core/src/asset.rs index b1fd617..9b9a5d4 100644 --- a/mingling_core/src/asset.rs +++ b/mingling_core/src/asset.rs @@ -21,3 +21,6 @@ pub mod node; #[doc(hidden)] pub mod renderer; + +#[doc(hidden)] +pub mod routable; diff --git a/mingling_core/src/asset/global_resource.rs b/mingling_core/src/asset/global_resource.rs index 3d0af7b..29e1136 100644 --- a/mingling_core/src/asset/global_resource.rs +++ b/mingling_core/src/asset/global_resource.rs @@ -45,13 +45,12 @@ where /// Internal syntax for the `&mut MyResource` syntax of #[chain], do not use directly #[doc(hidden)] - pub fn __modify_res_and_return_route<Res, Return>( + pub fn __modify_res_and_return_route<Res>( &self, - f: impl FnOnce(&mut Res) -> Return, - ) -> impl Into<ChainProcess<C>> + f: impl FnOnce(&mut Res) -> ChainProcess<C>, + ) -> ChainProcess<C> where Res: 'static + Default + ResourceMarker + Send + Sync, - Return: Into<ChainProcess<C>>, { let Ok(mut guard) = self.resources.lock() else { let mut default_res = Res::res_default(); diff --git a/mingling_core/src/asset/routable.rs b/mingling_core/src/asset/routable.rs new file mode 100644 index 0000000..24b7bb1 --- /dev/null +++ b/mingling_core/src/asset/routable.rs @@ -0,0 +1,22 @@ +use crate::ChainProcess; + +/// Provides routing capabilities for converting an item into a `ChainProcess` +/// directed to either the chain or render processing pipeline. +/// +/// This trait enables items to be dispatched to different processing routes +/// (chain or render) by wrapping them into an `AnyOutput` and routing them +/// through the appropriate pipeline. +pub trait Routable<Group> +where + Self: Sized + 'static, +{ + /// Converts the routable item into a `ChainProcess` directed to the chain route. + /// + /// This wraps the item into an `AnyOutput` and routes it to the chain processing pipeline. + fn to_chain(self) -> ChainProcess<Group>; + + /// Converts the routable item into a `ChainProcess` directed to the render route. + /// + /// This wraps the item into an `AnyOutput` and routes it to the render processing pipeline. + fn to_render(self) -> ChainProcess<Group>; +} diff --git a/mingling_core/src/comp.rs b/mingling_core/src/comp.rs index f6fecd1..55e9952 100644 --- a/mingling_core/src/comp.rs +++ b/mingling_core/src/comp.rs @@ -96,7 +96,7 @@ impl CompletionHelper { trace!("entry type: {}", any.member_id); let dispatcher_not_found = - <P::ErrorDispatcherNotFound as crate::Groupped<P>>::member_id(); + <P::ErrorDispatcherNotFound as crate::Grouped<P>>::member_id(); if dispatcher_not_found == any.member_id { debug!("dispatcher_not_found matched"); diff --git a/mingling_core/src/lib.rs b/mingling_core/src/lib.rs index 3c2cf9b..4996b19 100644 --- a/mingling_core/src/lib.rs +++ b/mingling_core/src/lib.rs @@ -36,6 +36,7 @@ pub use crate::asset::help::*; pub use crate::asset::lazy_resource::*; pub use crate::asset::node::*; pub use crate::asset::renderer::*; +pub use crate::asset::routable::*; /// All error types of `Mingling` pub mod error { diff --git a/mingling_core/src/program.rs b/mingling_core/src/program.rs index 71d5290..0d409b7 100644 --- a/mingling_core/src/program.rs +++ b/mingling_core/src/program.rs @@ -130,6 +130,33 @@ where &self.args } + /// Returns a mutable reference to the program's command-line arguments. + #[must_use] + pub fn get_args_mut(&mut self) -> &mut [String] { + &mut self.args + } + + /// Takes ownership of the program's command-line arguments, replacing them with an empty Vec. + /// This is useful when you need to transfer the arguments to another context or process them + /// and then replace them later. + #[must_use] + pub fn take_args(&mut self) -> Vec<String> { + std::mem::take(&mut self.args) + } + + /// Replaces the program's command-line arguments with a new set and returns the old ones. + /// + /// # Arguments + /// + /// * `args` - The new command-line arguments to set. + /// + /// # Returns + /// + /// The previous command-line arguments. + pub fn replace_args(&mut self, args: Vec<String>) -> Vec<String> { + std::mem::replace(&mut self.args, args) + } + /// Get all registered dispatcher names from the program #[must_use] pub fn get_nodes( diff --git a/mingling_core/src/program/collection.rs b/mingling_core/src/program/collection.rs index d5aab4b..fe78979 100644 --- a/mingling_core/src/program/collection.rs +++ b/mingling_core/src/program/collection.rs @@ -4,7 +4,7 @@ use std::pin::Pin; #[cfg(feature = "dispatch_tree")] use crate::Dispatcher; -use crate::{AnyOutput, ChainProcess, Groupped, RenderResult}; +use crate::{AnyOutput, ChainProcess, Grouped, RenderResult}; #[cfg(feature = "structural_renderer")] use crate::{StructuralRendererSetting, error::StructuralRendererSerializeError}; @@ -21,9 +21,9 @@ pub use mock::*; pub trait ProgramCollect { /// Enum type representing internal IDs for the program type Enum; - type ErrorDispatcherNotFound: Groupped<Self::Enum>; - type ErrorRendererNotFound: Groupped<Self::Enum>; - type ResultEmpty: Groupped<Self::Enum>; + type ErrorDispatcherNotFound: Grouped<Self::Enum>; + type ErrorRendererNotFound: Grouped<Self::Enum>; + type ResultEmpty: Grouped<Self::Enum>; /// Use a prefix tree to quickly match arguments and dispatch to an Entry #[cfg(feature = "dispatch_tree")] diff --git a/mingling_core/src/program/collection/mock.rs b/mingling_core/src/program/collection/mock.rs index 9b2e7af..5847f10 100644 --- a/mingling_core/src/program/collection/mock.rs +++ b/mingling_core/src/program/collection/mock.rs @@ -4,7 +4,7 @@ use std::pin::Pin; #[cfg(feature = "dispatch_tree")] use crate::Dispatcher; -use crate::{AnyOutput, ChainProcess, Groupped, ProgramCollect, RenderResult}; +use crate::{AnyOutput, ChainProcess, Grouped, ProgramCollect, RenderResult}; #[cfg(feature = "structural_renderer")] use crate::{StructuralRendererSetting, error::StructuralRendererSerializeError}; @@ -23,7 +23,7 @@ pub enum MockProgramCollect { Bar, } -impl Groupped<MockProgramCollect> for MockProgramCollect { +impl Grouped<MockProgramCollect> for MockProgramCollect { fn member_id() -> MockProgramCollect { MockProgramCollect::Foo } diff --git a/mingling_core/src/program/hook.rs b/mingling_core/src/program/hook.rs index 56d8e0e..db1691b 100644 --- a/mingling_core/src/program/hook.rs +++ b/mingling_core/src/program/hook.rs @@ -678,7 +678,7 @@ where #[cfg(test)] mod tests { use super::*; - use crate::Groupped; + use crate::Grouped; use std::sync::atomic::{AtomicBool, Ordering}; #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -694,7 +694,7 @@ mod tests { } } - impl Groupped<MockHookEnum> for MockHookEnum { + impl Grouped<MockHookEnum> for MockHookEnum { fn member_id() -> MockHookEnum { MockHookEnum::A } diff --git a/mingling_core/src/program/setup.rs b/mingling_core/src/program/setup.rs index f248fb6..838c29a 100644 --- a/mingling_core/src/program/setup.rs +++ b/mingling_core/src/program/setup.rs @@ -1,9 +1,26 @@ use crate::{ProgramCollect, program::Program}; +/// Trait for defining initialization/setup logic for a `Program`. +/// +/// Implementors can define custom setup behavior that will be executed +/// when the program is initialized via [`Program::with_setup`]. +/// +/// # Type Parameters +/// +/// * `C` - The program collect type, which must implement [`ProgramCollect`] +/// and have `Enum = C` (i.e., it collects itself). pub trait ProgramSetup<C> where C: ProgramCollect<Enum = C>, { + /// Perform setup on the given program. + /// + /// This method consumes the setup instance (`self`) and is called once + /// during program initialization. + /// + /// # Arguments + /// + /// * `program` - A mutable reference to the [`Program`] being set up. fn setup(self, program: &mut Program<C>); } diff --git a/mingling_core/src/renderer/render_result.rs b/mingling_core/src/renderer/render_result.rs index 82a745c..e57a5b9 100644 --- a/mingling_core/src/renderer/render_result.rs +++ b/mingling_core/src/renderer/render_result.rs @@ -39,6 +39,56 @@ impl Deref for RenderResult { } } +impl From<()> for RenderResult { + fn from(_value: ()) -> Self { + RenderResult::new() + } +} + +macro_rules! impl_from_int { + ($($ty:ty),+ $(,)?) => { + $( + impl From<$ty> for RenderResult { + fn from(exit_code: $ty) -> Self { + RenderResult { + exit_code: exit_code as i32, + ..Default::default() + } + } + } + )+ + }; +} + +impl_from_int!(i32, i16, i8, u32, u16, u8, usize); + +impl From<&String> for RenderResult { + fn from(value: &String) -> Self { + RenderResult { + render_text: value.clone(), + exit_code: 0, + } + } +} + +impl From<String> for RenderResult { + fn from(value: String) -> Self { + RenderResult { + render_text: value, + exit_code: 0, + } + } +} + +impl From<&str> for RenderResult { + fn from(value: &str) -> Self { + RenderResult { + render_text: value.to_string(), + exit_code: 0, + } + } +} + impl From<RenderResult> for String { fn from(result: RenderResult) -> Self { result.render_text |
