diff --git a/CHANGELOG.md b/CHANGELOG.md index 8367f2586..ad25b3dbb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,12 +7,15 @@ * Remove requirement to import `peace::cfg::FlowId` when using `flow_id!("..")` macro. ([#157], [#176]) * Remove requirement to import `peace::cfg::ItemId` when using `item_id!("..")` macro. ([#157], [#176]) * Remove requirement to import `peace::cfg::Profile` when using `profile!("..")` macro. ([#157], [#176]) +* Add `CmdCtxTypes` to group error, output, and params keys into one type parameter. ([#166], [#177]) [#172]: https://github.com/azriel91/peace/issues/172 [#173]: https://github.com/azriel91/peace/pull/173 [#157]: https://github.com/azriel91/peace/issues/157 [#176]: https://github.com/azriel91/peace/pull/176 +[#166]: https://github.com/azriel91/peace/issues/166 +[#177]: https://github.com/azriel91/peace/pull/177 ## 0.0.12 (2023-12-30) diff --git a/Cargo.toml b/Cargo.toml index 52ea9e62f..e5b5992e1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -93,6 +93,7 @@ peace_rt_model_hack = { path = "crate/rt_model_hack", version = "0.0.12" } peace_rt_model_native = { path = "crate/rt_model_native", version = "0.0.12" } peace_rt_model_web = { path = "crate/rt_model_web", version = "0.0.12" } peace_static_check_macros = { path = "crate/static_check_macros", version = "0.0.12" } +peace_value_traits = { path = "crate/value_traits", version = "0.0.12" } # Item crates peace_items = { path = "items", version = "0.0.12" } @@ -107,11 +108,11 @@ peace_item_tar_x = { path = "items/tar_x", version = "0.0.12" } # This does not include examples' dependencies, because we want it to be easy for # developers to see the dependencies to create an automation tool. async-trait = "0.1.77" -base64 = "0.21.5" +base64 = "0.21.7" bytes = "1.5.0" cfg-if = "1.0.0" -chrono = { version = "0.4.31", default-features = false, features = ["clock", "serde"] } -console = "0.15.7" +chrono = { version = "0.4.33", default-features = false, features = ["clock", "serde"] } +console = "0.15.8" derivative = "2.2.0" diff-struct = "0.5.3" downcast-rs = "1.2.0" @@ -124,19 +125,19 @@ heck = "0.4.1" indexmap = "2.1.0" indicatif = "0.17.7" interruptible = "0.2.1" -libc = "0.2.151" +libc = "0.2.152" miette = "5.10.0" pretty_assertions = "1.4.0" -proc-macro2 = "1.0.75" +proc-macro2 = "1.0.78" quote = "1.0.35" raw_tty = "0.1.0" reqwest = "0.11.23" resman = "0.17.0" -serde = "1.0.194" +serde = "1.0.196" serde-wasm-bindgen = "0.6.3" -serde_json = "1.0.110" +serde_json = "1.0.112" serde_yaml = "0.9.30" -syn = "2.0.47" +syn = "2.0.48" tar = "0.4.40" tempfile = "3.9.0" thiserror = "1.0.56" @@ -145,5 +146,5 @@ tokio-util = "0.7.10" tynm = "0.1.9" type_reg = { version = "0.7.0", features = ["debug", "untagged", "ordered"] } url = "2.5.0" -wasm-bindgen = "0.2.89" -web-sys = "0.3.66" +wasm-bindgen = "0.2.90" +web-sys = "0.3.67" diff --git a/crate/cmd/Cargo.toml b/crate/cmd/Cargo.toml index 83aa899e7..1c1ddc420 100644 --- a/crate/cmd/Cargo.toml +++ b/crate/cmd/Cargo.toml @@ -27,6 +27,7 @@ peace_core = { workspace = true } peace_params = { workspace = true } peace_resources = { workspace = true } peace_rt_model = { workspace = true } +peace_value_traits = { workspace = true } serde = { workspace = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] diff --git a/crate/cmd/src/ctx.rs b/crate/cmd/src/ctx.rs index 89bd5b1df..104e51a44 100644 --- a/crate/cmd/src/ctx.rs +++ b/crate/cmd/src/ctx.rs @@ -1,6 +1,15 @@ //! Types relating to command context. -pub use self::{cmd_ctx::CmdCtx, cmd_ctx_builder::CmdCtxBuilder}; +pub use self::{ + cmd_ctx::CmdCtx, + cmd_ctx_builder::CmdCtxBuilder, + cmd_ctx_builder_types::{ + CmdCtxBuilderTypes, CmdCtxBuilderTypesCollector, CmdCtxTypesCollectorEmpty, + }, + cmd_ctx_types::{CmdCtxTypes, CmdCtxTypesCollector, CmdCtxTypesConstrained}, +}; mod cmd_ctx; mod cmd_ctx_builder; +mod cmd_ctx_builder_types; +mod cmd_ctx_types; diff --git a/crate/cmd/src/ctx/cmd_ctx.rs b/crate/cmd/src/ctx/cmd_ctx.rs index 94462d639..a0eada3a8 100644 --- a/crate/cmd/src/ctx/cmd_ctx.rs +++ b/crate/cmd/src/ctx/cmd_ctx.rs @@ -3,10 +3,7 @@ use std::ops::{Deref, DerefMut}; use peace_resources::Resources; -use peace_rt_model::{ - params::{KeyUnknown, ParamsKeys, ParamsKeysImpl}, - Workspace, -}; +use peace_rt_model::Workspace; use crate::{ ctx::{ @@ -14,17 +11,13 @@ use crate::{ MultiProfileNoFlowBuilder, MultiProfileSingleFlowBuilder, NoProfileNoFlowBuilder, SingleProfileNoFlowBuilder, SingleProfileSingleFlowBuilder, }, - CmdCtxBuilder, - }, - scopes::{ - type_params::{ - FlowNotSelected, FlowParamsNone, ProfileNotSelected, ProfileParamsNone, - WorkspaceParamsNone, - }, - SingleProfileSingleFlow, + CmdCtxBuilder, CmdCtxTypes, }, + scopes::SingleProfileSingleFlow, }; +use super::CmdCtxTypesCollectorEmpty; + /// Information needed to execute a command. /// /// Importantly, as commands have different purposes, different command scopes @@ -50,108 +43,76 @@ impl CmdCtx { impl CmdCtx<()> { /// Returns a `CmdCtxBuilder` for a single profile and no flow. - pub fn builder_no_profile_no_flow<'ctx, E, O>( - output: &'ctx mut O, + pub fn builder_no_profile_no_flow<'ctx, AppError, Output>( + output: &'ctx mut Output, workspace: &'ctx Workspace, ) -> CmdCtxBuilder< 'ctx, - O, - NoProfileNoFlowBuilder< - E, - ParamsKeysImpl, - WorkspaceParamsNone, - >, + CmdCtxTypesCollectorEmpty, + NoProfileNoFlowBuilder>, > { CmdCtxBuilder::no_profile_no_flow(output, workspace) } /// Returns a `CmdCtxBuilder` for multiple profiles and no flow. - pub fn builder_multi_profile_no_flow<'ctx, E, O>( - output: &'ctx mut O, + pub fn builder_multi_profile_no_flow<'ctx, AppError, Output>( + output: &'ctx mut Output, workspace: &'ctx Workspace, ) -> CmdCtxBuilder< 'ctx, - O, - MultiProfileNoFlowBuilder< - E, - ProfileNotSelected, - ParamsKeysImpl, - WorkspaceParamsNone, - ProfileParamsNone, - >, + CmdCtxTypesCollectorEmpty, + MultiProfileNoFlowBuilder>, > { CmdCtxBuilder::multi_profile_no_flow(output, workspace) } /// Returns a `CmdCtxBuilder` for multiple profiles and one flow. - pub fn builder_multi_profile_single_flow<'ctx, E, O>( - output: &'ctx mut O, + pub fn builder_multi_profile_single_flow<'ctx, AppError, Output>( + output: &'ctx mut Output, workspace: &'ctx Workspace, ) -> CmdCtxBuilder< 'ctx, - O, - MultiProfileSingleFlowBuilder< - E, - ProfileNotSelected, - FlowNotSelected, - ParamsKeysImpl, - WorkspaceParamsNone, - ProfileParamsNone, - FlowParamsNone, - >, + CmdCtxTypesCollectorEmpty, + MultiProfileSingleFlowBuilder>, > { CmdCtxBuilder::multi_profile_single_flow(output, workspace) } /// Returns a `CmdCtxBuilder` for a single profile and flow. - pub fn builder_single_profile_no_flow<'ctx, E, O>( - output: &'ctx mut O, + pub fn builder_single_profile_no_flow<'ctx, AppError, Output>( + output: &'ctx mut Output, workspace: &'ctx Workspace, ) -> CmdCtxBuilder< 'ctx, - O, - SingleProfileNoFlowBuilder< - E, - ProfileNotSelected, - ParamsKeysImpl, - WorkspaceParamsNone, - ProfileParamsNone, - >, + CmdCtxTypesCollectorEmpty, + SingleProfileNoFlowBuilder>, > { CmdCtxBuilder::single_profile_no_flow(output, workspace) } /// Returns a `CmdCtxBuilder` for a single profile and flow. - pub fn builder_single_profile_single_flow<'ctx, E, O>( - output: &'ctx mut O, + pub fn builder_single_profile_single_flow<'ctx, AppError, Output>( + output: &'ctx mut Output, workspace: &'ctx Workspace, ) -> CmdCtxBuilder< 'ctx, - O, - SingleProfileSingleFlowBuilder< - E, - ProfileNotSelected, - FlowNotSelected, - ParamsKeysImpl, - WorkspaceParamsNone, - ProfileParamsNone, - FlowParamsNone, - >, + CmdCtxTypesCollectorEmpty, + SingleProfileSingleFlowBuilder>, > { CmdCtxBuilder::single_profile_single_flow(output, workspace) } } -impl<'ctx, E, O, PKeys, ResTs0> CmdCtx> +impl<'ctx, CmdCtxTypesT, ResTs0> CmdCtx> where - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypes, { /// Updates `resources` to a different type state based on the given /// function. pub fn resources_update( self, f: F, - ) -> CmdCtx> + ) -> CmdCtx> where F: FnOnce(Resources) -> Resources, { diff --git a/crate/cmd/src/ctx/cmd_ctx_builder.rs b/crate/cmd/src/ctx/cmd_ctx_builder.rs index 6a5a127a0..8ceef338e 100644 --- a/crate/cmd/src/ctx/cmd_ctx_builder.rs +++ b/crate/cmd/src/ctx/cmd_ctx_builder.rs @@ -15,8 +15,8 @@ use peace_resources::{ use peace_rt_model::{ fn_graph::resman::Resource, params::{FlowParams, ProfileParams, WorkspaceParams}, - Error, Flow, ItemGraph, ParamsSpecsSerializer, ParamsSpecsTypeReg, StatesTypeReg, Storage, - Workspace, WorkspaceInitializer, + Flow, ItemGraph, ParamsSpecsSerializer, ParamsSpecsTypeReg, StatesTypeReg, Storage, Workspace, + WorkspaceInitializer, }; use serde::{de::DeserializeOwned, Serialize}; @@ -28,6 +28,8 @@ pub use self::{ single_profile_single_flow_builder::SingleProfileSingleFlowBuilder, }; +use crate::ctx::CmdCtxBuilderTypes; + mod multi_profile_no_flow_builder; mod multi_profile_single_flow_builder; mod no_profile_no_flow_builder; @@ -36,14 +38,17 @@ mod single_profile_single_flow_builder; /// Collects parameters and initializes values relevant to the built [`CmdCtx`]. #[derive(Debug)] -pub struct CmdCtxBuilder<'ctx, O, ScopeBuilder> { +pub struct CmdCtxBuilder<'ctx, CmdCtxBuilderTypesT, ScopeBuilder> +where + CmdCtxBuilderTypesT: CmdCtxBuilderTypes, +{ /// Output endpoint to return values / errors, and write progress /// information to. /// /// See [`OutputWrite`]. /// /// [`OutputWrite`]: peace_rt_model_core::OutputWrite - output: &'ctx mut O, + output: &'ctx mut CmdCtxBuilderTypesT::Output, /// The interrupt channel receiver if this `CmdExecution` is interruptible. interruptibility: Interruptibility<'static>, /// Workspace that the `peace` tool runs in. @@ -57,7 +62,7 @@ async fn workspace_params_serialize( workspace_params: &WorkspaceParams, storage: &Storage, workspace_params_file: &WorkspaceParamsFile, -) -> Result<(), Error> +) -> Result<(), peace_rt_model::Error> where WorkspaceParamsK: Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + 'static, @@ -94,7 +99,7 @@ async fn profile_params_serialize( profile_params: &ProfileParams, storage: &Storage, profile_params_file: &ProfileParamsFile, -) -> Result<(), Error> +) -> Result<(), peace_rt_model::Error> where ProfileParamsK: Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + 'static, @@ -125,7 +130,7 @@ async fn flow_params_serialize( flow_params: &FlowParams, storage: &Storage, flow_params_file: &FlowParamsFile, -) -> Result<(), Error> +) -> Result<(), peace_rt_model::Error> where FlowParamsK: Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + 'static, { @@ -139,7 +144,7 @@ async fn params_specs_serialize( params_specs: &ParamsSpecs, storage: &Storage, params_specs_file: &ParamsSpecsFile, -) -> Result<(), Error> { +) -> Result<(), peace_rt_model::Error> { ParamsSpecsSerializer::serialize(storage, params_specs, params_specs_file).await } @@ -267,9 +272,9 @@ fn params_specs_merge( flow: &Flow, mut params_specs_provided: ParamsSpecs, params_specs_stored: Option, -) -> Result +) -> Result where - E: From + 'static, + E: From + 'static, { // Combine provided and stored params specs. Provided params specs take // precedence. @@ -364,7 +369,7 @@ where if params_no_issues { Ok(params_specs) } else { - Err(Error::ParamsSpecsMismatch { + Err(peace_rt_model::Error::ParamsSpecsMismatch { item_ids_with_no_params_specs, params_specs_provided_mismatches, params_specs_stored_mismatches, diff --git a/crate/cmd/src/ctx/cmd_ctx_builder/multi_profile_no_flow_builder.rs b/crate/cmd/src/ctx/cmd_ctx_builder/multi_profile_no_flow_builder.rs index db9d8552d..cce5f0178 100644 --- a/crate/cmd/src/ctx/cmd_ctx_builder/multi_profile_no_flow_builder.rs +++ b/crate/cmd/src/ctx/cmd_ctx_builder/multi_profile_no_flow_builder.rs @@ -1,5 +1,9 @@ +use crate::ctx::CmdCtxBuilderTypes; + /// Data stored by `CmdCtxBuilder` while building a /// `CmdCtx`.` #[peace_code_gen::cmd_ctx_builder_impl] #[derive(Debug)] -pub struct MultiProfileNoFlowBuilder; +pub struct MultiProfileNoFlowBuilder +where + CmdCtxBuilderTypesT: CmdCtxBuilderTypes; diff --git a/crate/cmd/src/ctx/cmd_ctx_builder/multi_profile_single_flow_builder.rs b/crate/cmd/src/ctx/cmd_ctx_builder/multi_profile_single_flow_builder.rs index ba62b1fd0..be5ef15d8 100644 --- a/crate/cmd/src/ctx/cmd_ctx_builder/multi_profile_single_flow_builder.rs +++ b/crate/cmd/src/ctx/cmd_ctx_builder/multi_profile_single_flow_builder.rs @@ -1,5 +1,9 @@ +use crate::ctx::CmdCtxBuilderTypes; + /// Data stored by `CmdCtxBuilder` while building a /// `CmdCtx`. #[peace_code_gen::cmd_ctx_builder_impl] #[derive(Debug)] -pub struct MultiProfileSingleFlowBuilder; +pub struct MultiProfileSingleFlowBuilder +where + CmdCtxBuilderTypesT: CmdCtxBuilderTypes; diff --git a/crate/cmd/src/ctx/cmd_ctx_builder/no_profile_no_flow_builder.rs b/crate/cmd/src/ctx/cmd_ctx_builder/no_profile_no_flow_builder.rs index 31556a84f..a9b2a92c4 100644 --- a/crate/cmd/src/ctx/cmd_ctx_builder/no_profile_no_flow_builder.rs +++ b/crate/cmd/src/ctx/cmd_ctx_builder/no_profile_no_flow_builder.rs @@ -1,5 +1,9 @@ +use crate::ctx::CmdCtxBuilderTypes; + /// Data stored by `CmdCtxBuilder` while building a /// `CmdCtx`. #[peace_code_gen::cmd_ctx_builder_impl] #[derive(Debug)] -pub struct NoProfileNoFlowBuilder; +pub struct NoProfileNoFlowBuilder +where + CmdCtxBuilderTypesT: CmdCtxBuilderTypes; diff --git a/crate/cmd/src/ctx/cmd_ctx_builder/single_profile_no_flow_builder.rs b/crate/cmd/src/ctx/cmd_ctx_builder/single_profile_no_flow_builder.rs index 433e55631..cbba78e32 100644 --- a/crate/cmd/src/ctx/cmd_ctx_builder/single_profile_no_flow_builder.rs +++ b/crate/cmd/src/ctx/cmd_ctx_builder/single_profile_no_flow_builder.rs @@ -1,5 +1,9 @@ +use crate::ctx::CmdCtxBuilderTypes; + /// Data stored by `CmdCtxBuilder` while building a /// `CmdCtx`. #[peace_code_gen::cmd_ctx_builder_impl] #[derive(Debug)] -pub struct SingleProfileNoFlowBuilder; +pub struct SingleProfileNoFlowBuilder +where + CmdCtxBuilderTypesT: CmdCtxBuilderTypes; diff --git a/crate/cmd/src/ctx/cmd_ctx_builder/single_profile_single_flow_builder.rs b/crate/cmd/src/ctx/cmd_ctx_builder/single_profile_single_flow_builder.rs index d5ea906d6..94d772cfa 100644 --- a/crate/cmd/src/ctx/cmd_ctx_builder/single_profile_single_flow_builder.rs +++ b/crate/cmd/src/ctx/cmd_ctx_builder/single_profile_single_flow_builder.rs @@ -1,5 +1,9 @@ +use crate::ctx::CmdCtxBuilderTypes; + /// Data stored by `CmdCtxBuilder` while building a /// `CmdCtx`. #[peace_code_gen::cmd_ctx_builder_impl] #[derive(Debug)] -pub struct SingleProfileSingleFlowBuilder; +pub struct SingleProfileSingleFlowBuilder +where + CmdCtxBuilderTypesT: CmdCtxBuilderTypes; diff --git a/crate/cmd/src/ctx/cmd_ctx_builder_types.rs b/crate/cmd/src/ctx/cmd_ctx_builder_types.rs new file mode 100644 index 000000000..609e79385 --- /dev/null +++ b/crate/cmd/src/ctx/cmd_ctx_builder_types.rs @@ -0,0 +1,140 @@ +use std::marker::PhantomData; + +use peace_rt_model::params::{KeyUnknown, ParamsKeys, ParamsKeysImpl}; + +use crate::scopes::type_params::{ + FlowNotSelected, FlowParamsNone, ProfileNotSelected, ProfileParamsNone, WorkspaceParamsNone, +}; + +/// Trait so that a single type parameter can be used in `CmdCtx` and `Scopes`. +/// +/// The associated types linked to the concrete type can all be queried through +/// this trait. +pub trait CmdCtxBuilderTypes { + /// Error type of the automation software. + type AppError; + /// Output to write progress or outcome to. + type Output; + /// Parameter key types for workspace params, profile params, and flow + /// params. + type ParamsKeys: ParamsKeys; + /// Whether workspace params keys have been selected. + /// + /// One of: + /// + /// * [`WorkspaceParamsNone`] + /// * [`WorkspaceParamsSome`] + /// + /// [`WorkspaceParamsNone`]: crate::scopes::type_params::WorkspaceParamsNone + /// [`WorkspaceParamsSome`]: crate::scopes::type_params::WorkspaceParamsSome + type WorkspaceParamsSelection; + /// Whether profile params keys have been selected. + /// + /// One of: + /// + /// * [`ProfileParamsNone`] + /// * [`ProfileParamsSome`] + /// * [`ProfileParamsSomeMulti`] + /// + /// Only applicable to `SingleProfile*` scopes. + /// + /// [`ProfileParamsNone`]: crate::scopes::type_params::ProfileParamsNone + /// [`ProfileParamsSome`]: crate::scopes::type_params::ProfileParamsSome + /// [`ProfileParamsSomeMulti`]: crate::scopes::type_params::ProfileParamsSomeMulti + type ProfileParamsSelection; + /// Whether flow params keys have been selected. + /// + /// One of: + /// + /// * [`FlowParamsNone`] + /// * [`FlowParamsSome`] + /// * [`FlowParamsSomeMulti`] + /// + /// Only applicable to `*SingleFlow` scopes. + /// + /// [`FlowParamsNone`]: crate::scopes::type_params::FlowParamsNone + /// [`FlowParamsSome`]: crate::scopes::type_params::FlowParamsSome + /// [`FlowParamsSomeMulti`]: crate::scopes::type_params::FlowParamsSomeMulti + type FlowParamsSelection; + /// The profile this command operates on. + /// + /// Only applicable to `SingleProfile*` scopes. + type ProfileSelection; + /// Identifier or name of the chosen process flow. + /// + /// Only applicable to `*SingleFlow` scopes. + type FlowSelection; +} + +/// Concrete struct to collect `CmdCtxBuilderTypes`. +#[derive(Debug)] +pub struct CmdCtxBuilderTypesCollector< + AppError, + Output, + ParamsKeys, + WorkspaceParamsSelection, + ProfileParamsSelection, + FlowParamsSelection, + ProfileSelection, + FlowSelection, +>( + #[allow(clippy::type_complexity)] + pub PhantomData<( + AppError, + Output, + ParamsKeys, + WorkspaceParamsSelection, + ProfileParamsSelection, + FlowParamsSelection, + ProfileSelection, + FlowSelection, + )>, +); + +/// `CmdCtxBuilderTypesCollector` with `Output` and `AppError` needing to +/// be specified. +/// +/// The remainder of the type arguments use *none* type values. +pub type CmdCtxTypesCollectorEmpty = CmdCtxBuilderTypesCollector< + AppError, + Output, + ParamsKeysImpl, + WorkspaceParamsNone, + ProfileParamsNone, + FlowParamsNone, + ProfileNotSelected, + FlowNotSelected, +>; + +impl< + AppError, + Output, + ParamsKeysT, + WorkspaceParamsSelection, + ProfileParamsSelection, + FlowParamsSelection, + ProfileSelection, + FlowSelection, +> CmdCtxBuilderTypes + for CmdCtxBuilderTypesCollector< + AppError, + Output, + ParamsKeysT, + WorkspaceParamsSelection, + ProfileParamsSelection, + FlowParamsSelection, + ProfileSelection, + FlowSelection, + > +where + ParamsKeysT: ParamsKeys, +{ + type AppError = AppError; + type FlowParamsSelection = FlowParamsSelection; + type FlowSelection = FlowSelection; + type Output = Output; + type ParamsKeys = ParamsKeysT; + type ProfileParamsSelection = ProfileParamsSelection; + type ProfileSelection = ProfileSelection; + type WorkspaceParamsSelection = WorkspaceParamsSelection; +} diff --git a/crate/cmd/src/ctx/cmd_ctx_types.rs b/crate/cmd/src/ctx/cmd_ctx_types.rs new file mode 100644 index 000000000..db45e5c0b --- /dev/null +++ b/crate/cmd/src/ctx/cmd_ctx_types.rs @@ -0,0 +1,68 @@ +use std::{fmt::Debug, marker::PhantomData}; + +use peace_rt_model::{output::OutputWrite, params::ParamsKeys}; +use peace_value_traits::AppError; + +/// Trait so that a single type parameter can be used in `CmdCtx` and `Scopes`. +/// +/// The associated types linked to the concrete type can all be queried through +/// this trait. +pub trait CmdCtxTypes { + /// Error type of the automation software. + type AppError: Debug; + /// Output to write progress or outcome to. + type Output; + /// Parameter key types for workspace params, profile params, and flow + /// params. + type ParamsKeys: ParamsKeys; +} + +/// Trait so that a single type parameter can be used in `CmdCtx` and `Scopes`. +/// +/// The associated types linked to the concrete type can all be queried through +/// this trait. +pub trait CmdCtxTypesConstrained: + CmdCtxTypes< + AppError = ::AppError, + Output = ::Output, + ParamsKeys = ::ParamsKeys, + > + Debug + + Unpin +{ + /// Error type of the automation software. + type AppError: AppError + From; + /// Output to write progress or outcome to. + type Output: OutputWrite<::AppError>; + /// Parameter key types for workspace params, profile params, and flow + /// params. + type ParamsKeys: ParamsKeys; +} + +impl CmdCtxTypesConstrained for T +where + T: CmdCtxTypes + Debug + Unpin, + T::AppError: AppError + From, + T::Output: OutputWrite, + T::ParamsKeys: ParamsKeys, +{ + type AppError = T::AppError; + type Output = T::Output; + type ParamsKeys = T::ParamsKeys; +} + +/// Concrete struct to collect `CmdCtxTypes`. +#[derive(Debug)] +pub struct CmdCtxTypesCollector( + pub PhantomData<(AppError, Output, ParamsKeys)>, +); + +impl CmdCtxTypes + for CmdCtxTypesCollector +where + AppError: Debug, + ParamsKeysT: ParamsKeys, +{ + type AppError = AppError; + type Output = Output; + type ParamsKeys = ParamsKeysT; +} diff --git a/crate/cmd/src/scopes/multi_profile_no_flow.rs b/crate/cmd/src/scopes/multi_profile_no_flow.rs index 57b215119..692ebff75 100644 --- a/crate/cmd/src/scopes/multi_profile_no_flow.rs +++ b/crate/cmd/src/scopes/multi_profile_no_flow.rs @@ -1,4 +1,4 @@ -use std::{collections::BTreeMap, fmt::Debug, hash::Hash, marker::PhantomData}; +use std::{collections::BTreeMap, fmt::Debug, hash::Hash}; use interruptible::InterruptibilityState; use peace_core::Profile; @@ -12,6 +12,8 @@ use peace_rt_model::{ }; use serde::{de::DeserializeOwned, Serialize}; +use crate::ctx::CmdCtxTypes; + /// A command that works with multiple profiles, without any items. /// /// ```bash @@ -43,14 +45,14 @@ use serde::{de::DeserializeOwned, Serialize}; /// /// This kind of command cannot: /// -/// * Read or write flow parameters -- see `SingleProfileSingleFlow` or +/// * Read or write flow parameters -- see `MultiProfileNoFlow` or /// `MultiProfileSingleFlow`. -/// * Read or write flow state -- see `SingleProfileSingleFlow` or +/// * Read or write flow state -- see `MultiProfileNoFlow` or /// `MultiProfileSingleFlow`. #[derive(Debug)] -pub struct MultiProfileNoFlow<'ctx, E, O, PKeys> +pub struct MultiProfileNoFlow<'ctx, CmdCtxTypesT> where - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypes, { /// Output endpoint to return values / errors, and write progress /// information to. @@ -58,11 +60,11 @@ where /// See [`OutputWrite`]. /// /// [`OutputWrite`]: peace_rt_model_core::OutputWrite - output: &'ctx mut O, + output: &'ctx mut CmdCtxTypesT::Output, /// Whether the `CmdExecution` is interruptible. /// /// If it is, this holds the interrupt channel receiver. - interruptibility_state: InterruptibilityState<'ctx, 'ctx>, + interruptibility_state: InterruptibilityState<'static, 'static>, /// Workspace that the `peace` tool runs in. workspace: &'ctx Workspace, /// The profiles that are accessible by this command. @@ -77,14 +79,18 @@ where /// [`WorkspaceParams`]: peace_rt_model::params::WorkspaceParams /// [`ProfileParams`]: peace_rt_model::params::ProfileParams /// [`FlowParams`]: peace_rt_model::params::FlowParams - params_type_regs: ParamsTypeRegs, + params_type_regs: ParamsTypeRegs, /// Workspace params. - workspace_params: WorkspaceParams<::Key>, + workspace_params: WorkspaceParams< + <::WorkspaceParamsKMaybe as KeyMaybe>::Key, + >, /// Profile params for the profile. - profile_to_profile_params: - BTreeMap::Key>>, - /// Marker. - marker: PhantomData, + profile_to_profile_params: BTreeMap< + Profile, + ProfileParams< + <::ProfileParamsKMaybe as KeyMaybe>::Key, + >, + >, } /// A command that works with multiple profiles, without any items. @@ -118,14 +124,14 @@ where /// /// This kind of command cannot: /// -/// * Read or write flow parameters -- see `SingleProfileSingleFlow` or +/// * Read or write flow parameters -- see `MultiProfileNoFlow` or /// `MultiProfileSingleFlow`. -/// * Read or write flow state -- see `SingleProfileSingleFlow` or +/// * Read or write flow state -- see `MultiProfileNoFlow` or /// `MultiProfileSingleFlow`. #[derive(Debug)] -pub struct MultiProfileNoFlowView<'view, O, PKeys> +pub struct MultiProfileNoFlowView<'view, CmdCtxTypesT> where - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypes, { /// Output endpoint to return values / errors, and write progress /// information to. @@ -133,7 +139,7 @@ where /// See [`OutputWrite`]. /// /// [`OutputWrite`]: peace_rt_model_core::OutputWrite - pub output: &'view mut O, + pub output: &'view mut CmdCtxTypesT::Output, /// Whether the `CmdExecution` is interruptible. /// /// If it is, this holds the interrupt channel receiver. @@ -152,32 +158,42 @@ where /// [`WorkspaceParams`]: peace_rt_model::params::WorkspaceParams /// [`ProfileParams`]: peace_rt_model::params::ProfileParams /// [`FlowParams`]: peace_rt_model::params::FlowParams - pub params_type_regs: &'view ParamsTypeRegs, + pub params_type_regs: &'view ParamsTypeRegs, /// Workspace params. - pub workspace_params: &'view WorkspaceParams<::Key>, + pub workspace_params: &'view WorkspaceParams< + <::WorkspaceParamsKMaybe as KeyMaybe>::Key, + >, /// Profile params for the profile. - pub profile_to_profile_params: - &'view BTreeMap::Key>>, + pub profile_to_profile_params: &'view BTreeMap< + Profile, + ProfileParams< + <::ProfileParamsKMaybe as KeyMaybe>::Key, + >, + >, } -impl<'ctx, E, O, PKeys> MultiProfileNoFlow<'ctx, E, O, PKeys> +impl<'ctx, CmdCtxTypesT> MultiProfileNoFlow<'ctx, CmdCtxTypesT> where - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypes, { /// Returns a new `MultiProfileNoFlow` scope. #[allow(clippy::too_many_arguments)] // Constructed by proc macro pub(crate) fn new( - output: &'ctx mut O, - interruptibility_state: InterruptibilityState<'ctx, 'ctx>, + output: &'ctx mut CmdCtxTypesT::Output, + interruptibility_state: InterruptibilityState<'static, 'static>, workspace: &'ctx Workspace, profiles: Vec, profile_dirs: BTreeMap, profile_history_dirs: BTreeMap, - params_type_regs: ParamsTypeRegs, - workspace_params: WorkspaceParams<::Key>, + params_type_regs: ParamsTypeRegs, + workspace_params: WorkspaceParams< + <::WorkspaceParamsKMaybe as KeyMaybe>::Key, + >, profile_to_profile_params: BTreeMap< Profile, - ProfileParams<::Key>, + ProfileParams< + <::ProfileParamsKMaybe as KeyMaybe>::Key, + >, >, ) -> Self { Self { @@ -190,12 +206,11 @@ where params_type_regs, workspace_params, profile_to_profile_params, - marker: PhantomData, } } /// Returns a view struct of this scope. - pub fn view(&mut self) -> MultiProfileNoFlowView<'_, O, PKeys> { + pub fn view(&mut self) -> MultiProfileNoFlowView<'_, CmdCtxTypesT> { let Self { output, interruptibility_state, @@ -206,7 +221,6 @@ where params_type_regs, workspace_params, profile_to_profile_params, - marker: PhantomData, } = self; let interruptibility_state = interruptibility_state.reborrow(); @@ -225,12 +239,12 @@ where } /// Returns a reference to the output. - pub fn output(&self) -> &O { + pub fn output(&self) -> &CmdCtxTypesT::Output { self.output } /// Returns a mutable reference to the output. - pub fn output_mut(&mut self) -> &mut O { + pub fn output_mut(&mut self) -> &mut CmdCtxTypesT::Output { self.output } @@ -283,19 +297,21 @@ where /// [`WorkspaceParams`]: peace_rt_model::params::WorkspaceParams /// [`ProfileParams`]: peace_rt_model::params::ProfileParams /// [`FlowParams`]: peace_rt_model::params::FlowParams - pub fn params_type_regs(&self) -> &ParamsTypeRegs { + pub fn params_type_regs(&self) -> &ParamsTypeRegs { &self.params_type_regs } } -impl<'ctx, E, O, WorkspaceParamsK, ProfileParamsKMaybe, FlowParamsKMaybe> - MultiProfileNoFlow< - 'ctx, - E, - O, - ParamsKeysImpl, ProfileParamsKMaybe, FlowParamsKMaybe>, - > +impl<'ctx, CmdCtxTypesT, WorkspaceParamsK, ProfileParamsKMaybe, FlowParamsKMaybe> + MultiProfileNoFlow<'ctx, CmdCtxTypesT> where + CmdCtxTypesT: CmdCtxTypes< + ParamsKeys = ParamsKeysImpl< + KeyKnown, + ProfileParamsKMaybe, + FlowParamsKMaybe, + >, + >, WorkspaceParamsK: Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + Unpin + 'static, ProfileParamsKMaybe: KeyMaybe, @@ -307,14 +323,16 @@ where } } -impl<'ctx, E, O, WorkspaceParamsKMaybe, ProfileParamsK, FlowParamsKMaybe> - MultiProfileNoFlow< - 'ctx, - E, - O, - ParamsKeysImpl, FlowParamsKMaybe>, - > +impl<'ctx, CmdCtxTypesT, WorkspaceParamsKMaybe, ProfileParamsK, FlowParamsKMaybe> + MultiProfileNoFlow<'ctx, CmdCtxTypesT> where + CmdCtxTypesT: CmdCtxTypes< + ParamsKeys = ParamsKeysImpl< + WorkspaceParamsKMaybe, + KeyKnown, + FlowParamsKMaybe, + >, + >, WorkspaceParamsKMaybe: KeyMaybe, ProfileParamsK: Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + Unpin + 'static, diff --git a/crate/cmd/src/scopes/multi_profile_single_flow.rs b/crate/cmd/src/scopes/multi_profile_single_flow.rs index eb519bc38..5c442938c 100644 --- a/crate/cmd/src/scopes/multi_profile_single_flow.rs +++ b/crate/cmd/src/scopes/multi_profile_single_flow.rs @@ -18,6 +18,8 @@ use peace_rt_model::{ }; use serde::{de::DeserializeOwned, Serialize}; +use crate::ctx::CmdCtxTypes; + /// A command that works with multiple profiles, and a single flow. /// /// ```bash @@ -71,9 +73,9 @@ use serde::{de::DeserializeOwned, Serialize}; /// * Read or write flow parameters for different flows. /// * Read or write flow state for different flows. #[derive(Debug)] -pub struct MultiProfileSingleFlow<'ctx, E, O, PKeys, TS> +pub struct MultiProfileSingleFlow<'ctx, CmdCtxTypesT, TS> where - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypes, { /// Output endpoint to return values / errors, and write progress /// information to. @@ -81,11 +83,11 @@ where /// See [`OutputWrite`]. /// /// [`OutputWrite`]: peace_rt_model_core::OutputWrite - output: &'ctx mut O, + output: &'ctx mut CmdCtxTypesT::Output, /// Whether the `CmdExecution` is interruptible. /// /// If it is, this holds the interrupt channel receiver. - interruptibility_state: InterruptibilityState<'ctx, 'ctx>, + interruptibility_state: InterruptibilityState<'static, 'static>, /// Workspace that the `peace` tool runs in. workspace: &'ctx Workspace, /// The profiles that are accessible by this command. @@ -95,7 +97,7 @@ where /// Directories of each profile's execution history. profile_history_dirs: BTreeMap, /// The chosen process flow. - flow: &'ctx Flow, + flow: &'ctx Flow, /// Flow directory that stores params and states. flow_dirs: BTreeMap, /// Type registries for [`WorkspaceParams`], [`ProfileParams`], and @@ -104,15 +106,23 @@ where /// [`WorkspaceParams`]: peace_rt_model::params::WorkspaceParams /// [`ProfileParams`]: peace_rt_model::params::ProfileParams /// [`FlowParams`]: peace_rt_model::params::FlowParams - params_type_regs: ParamsTypeRegs, + params_type_regs: ParamsTypeRegs, /// Workspace params. - workspace_params: WorkspaceParams<::Key>, + workspace_params: WorkspaceParams< + <::WorkspaceParamsKMaybe as KeyMaybe>::Key, + >, /// Profile params for the profile. - profile_to_profile_params: - BTreeMap::Key>>, + profile_to_profile_params: BTreeMap< + Profile, + ProfileParams< + <::ProfileParamsKMaybe as KeyMaybe>::Key, + >, + >, /// Flow params for the selected flow. - profile_to_flow_params: - BTreeMap::Key>>, + profile_to_flow_params: BTreeMap< + Profile, + FlowParams<<::FlowParamsKMaybe as KeyMaybe>::Key>, + >, /// Stored current states for each profile for the selected flow. profile_to_states_current_stored: BTreeMap>, /// Type registry for each item's [`Params`]`::Spec`. @@ -139,9 +149,9 @@ where /// Access to fields in `MultiProfileSingleFlow` so that multiple borrows can /// happen simultaneously. #[derive(Debug)] -pub struct MultiProfileSingleFlowView<'view, E, O, PKeys, TS> +pub struct MultiProfileSingleFlowView<'view, CmdCtxTypesT, TS> where - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypes, { /// Output endpoint to return values / errors, and write progress /// information to. @@ -149,7 +159,7 @@ where /// See [`OutputWrite`]. /// /// [`OutputWrite`]: peace_rt_model_core::OutputWrite - pub output: &'view mut O, + pub output: &'view mut CmdCtxTypesT::Output, /// Whether the `CmdExecution` is interruptible. /// /// If it is, this holds the interrupt channel receiver. @@ -163,7 +173,7 @@ where /// Directories of each profile's execution history. pub profile_history_dirs: &'view BTreeMap, /// The chosen process flow. - pub flow: &'view Flow, + pub flow: &'view Flow, /// Flow directory that stores params and states. pub flow_dirs: &'view BTreeMap, /// Type registries for [`WorkspaceParams`], [`ProfileParams`], and @@ -172,15 +182,23 @@ where /// [`WorkspaceParams`]: peace_rt_model::params::WorkspaceParams /// [`ProfileParams`]: peace_rt_model::params::ProfileParams /// [`FlowParams`]: peace_rt_model::params::FlowParams - pub params_type_regs: &'view ParamsTypeRegs, + pub params_type_regs: &'view ParamsTypeRegs, /// Workspace params. - pub workspace_params: &'view WorkspaceParams<::Key>, + pub workspace_params: &'view WorkspaceParams< + <::WorkspaceParamsKMaybe as KeyMaybe>::Key, + >, /// Profile params for the profile. - pub profile_to_profile_params: - &'view BTreeMap::Key>>, + pub profile_to_profile_params: &'view BTreeMap< + Profile, + ProfileParams< + <::ProfileParamsKMaybe as KeyMaybe>::Key, + >, + >, /// Flow params for the selected flow. - pub profile_to_flow_params: - &'view BTreeMap::Key>>, + pub profile_to_flow_params: &'view BTreeMap< + Profile, + FlowParams<<::FlowParamsKMaybe as KeyMaybe>::Key>, + >, /// Stored current states for each profile for the selected flow. pub profile_to_states_current_stored: &'view BTreeMap>, /// Type registry for each item's [`Params`]`::Spec`. @@ -204,30 +222,36 @@ where pub resources: &'view mut Resources, } -impl<'ctx, E, O, PKeys> MultiProfileSingleFlow<'ctx, E, O, PKeys, SetUp> +impl<'ctx, CmdCtxTypesT> MultiProfileSingleFlow<'ctx, CmdCtxTypesT, SetUp> where - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypes, { /// Returns a new `MultiProfileSingleFlow` scope. #[allow(clippy::too_many_arguments)] // Constructed by proc macro pub(crate) fn new( - output: &'ctx mut O, - interruptibility_state: InterruptibilityState<'ctx, 'ctx>, + output: &'ctx mut CmdCtxTypesT::Output, + interruptibility_state: InterruptibilityState<'static, 'static>, workspace: &'ctx Workspace, profiles: Vec, profile_dirs: BTreeMap, profile_history_dirs: BTreeMap, - flow: &'ctx Flow, + flow: &'ctx Flow, flow_dirs: BTreeMap, - params_type_regs: ParamsTypeRegs, - workspace_params: WorkspaceParams<::Key>, + params_type_regs: ParamsTypeRegs, + workspace_params: WorkspaceParams< + <::WorkspaceParamsKMaybe as KeyMaybe>::Key, + >, profile_to_profile_params: BTreeMap< Profile, - ProfileParams<::Key>, + ProfileParams< + <::ProfileParamsKMaybe as KeyMaybe>::Key, + >, >, profile_to_flow_params: BTreeMap< Profile, - FlowParams<::Key>, + FlowParams< + <::FlowParamsKMaybe as KeyMaybe>::Key, + >, >, profile_to_states_current_stored: BTreeMap>, params_specs_type_reg: ParamsSpecsTypeReg, @@ -258,14 +282,14 @@ where } } -impl<'ctx, E, O, PKeys, TS> MultiProfileSingleFlow<'ctx, E, O, PKeys, TS> +impl<'ctx, CmdCtxTypesT, TS> MultiProfileSingleFlow<'ctx, CmdCtxTypesT, TS> where - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypes, { /// Returns a view struct of this scope. /// /// This allows the flow and resources to be borrowed concurrently. - pub fn view(&mut self) -> MultiProfileSingleFlowView<'_, E, O, PKeys, TS> { + pub fn view(&mut self) -> MultiProfileSingleFlowView<'_, CmdCtxTypesT, TS> { let Self { output, interruptibility_state, @@ -312,12 +336,12 @@ where } /// Returns a reference to the output. - pub fn output(&self) -> &O { + pub fn output(&self) -> &CmdCtxTypesT::Output { self.output } /// Returns a mutable reference to the output. - pub fn output_mut(&mut self) -> &mut O { + pub fn output_mut(&mut self) -> &mut CmdCtxTypesT::Output { self.output } @@ -365,7 +389,7 @@ where } /// Returns the flow. - pub fn flow(&self) -> &Flow { + pub fn flow(&self) -> &Flow { self.flow } @@ -381,7 +405,7 @@ where /// [`ItemParams`]: peace_rt_model::ItemParams /// [`ProfileParams`]: peace_rt_model::params::ProfileParams /// [`WorkspaceParams`]: peace_rt_model::params::WorkspaceParams - pub fn params_type_regs(&self) -> &ParamsTypeRegs { + pub fn params_type_regs(&self) -> &ParamsTypeRegs { &self.params_type_regs } @@ -431,15 +455,16 @@ where } } -impl<'ctx, E, O, WorkspaceParamsK, ProfileParamsKMaybe, FlowParamsKMaybe, TS> - MultiProfileSingleFlow< - 'ctx, - E, - O, - ParamsKeysImpl, ProfileParamsKMaybe, FlowParamsKMaybe>, - TS, - > +impl<'ctx, CmdCtxTypesT, TS, WorkspaceParamsK, ProfileParamsKMaybe, FlowParamsKMaybe> + MultiProfileSingleFlow<'ctx, CmdCtxTypesT, TS> where + CmdCtxTypesT: CmdCtxTypes< + ParamsKeys = ParamsKeysImpl< + KeyKnown, + ProfileParamsKMaybe, + FlowParamsKMaybe, + >, + >, WorkspaceParamsK: Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + Unpin + 'static, ProfileParamsKMaybe: KeyMaybe, @@ -451,15 +476,16 @@ where } } -impl<'ctx, E, O, WorkspaceParamsKMaybe, ProfileParamsK, FlowParamsKMaybe, TS> - MultiProfileSingleFlow< - 'ctx, - E, - O, - ParamsKeysImpl, FlowParamsKMaybe>, - TS, - > +impl<'ctx, CmdCtxTypesT, TS, WorkspaceParamsKMaybe, ProfileParamsK, FlowParamsKMaybe> + MultiProfileSingleFlow<'ctx, CmdCtxTypesT, TS> where + CmdCtxTypesT: CmdCtxTypes< + ParamsKeys = ParamsKeysImpl< + WorkspaceParamsKMaybe, + KeyKnown, + FlowParamsKMaybe, + >, + >, WorkspaceParamsKMaybe: KeyMaybe, ProfileParamsK: Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + Unpin + 'static, @@ -471,15 +497,16 @@ where } } -impl<'ctx, E, O, WorkspaceParamsKMaybe, ProfileParamsKMaybe, FlowParamsK, TS> - MultiProfileSingleFlow< - 'ctx, - E, - O, - ParamsKeysImpl>, - TS, - > +impl<'ctx, CmdCtxTypesT, TS, WorkspaceParamsKMaybe, ProfileParamsKMaybe, FlowParamsK> + MultiProfileSingleFlow<'ctx, CmdCtxTypesT, TS> where + CmdCtxTypesT: CmdCtxTypes< + ParamsKeys = ParamsKeysImpl< + WorkspaceParamsKMaybe, + ProfileParamsKMaybe, + KeyKnown, + >, + >, WorkspaceParamsKMaybe: KeyMaybe, ProfileParamsKMaybe: KeyMaybe, FlowParamsK: diff --git a/crate/cmd/src/scopes/no_profile_no_flow.rs b/crate/cmd/src/scopes/no_profile_no_flow.rs index 89478b759..7eab6c904 100644 --- a/crate/cmd/src/scopes/no_profile_no_flow.rs +++ b/crate/cmd/src/scopes/no_profile_no_flow.rs @@ -1,4 +1,4 @@ -use std::{fmt::Debug, hash::Hash, marker::PhantomData}; +use std::{fmt::Debug, hash::Hash}; use interruptible::InterruptibilityState; use peace_resources::paths::{PeaceAppDir, PeaceDir, WorkspaceDir}; @@ -8,6 +8,8 @@ use peace_rt_model::{ }; use serde::{de::DeserializeOwned, Serialize}; +use crate::ctx::CmdCtxTypes; + /// A command that only works with workspace parameters. /// /// ```bash @@ -28,12 +30,12 @@ use serde::{de::DeserializeOwned, Serialize}; /// * Read or write profile parameters -- see `SingleProfileNoFlow` or /// `MultiProfileNoFlow`. /// * Read or write flow parameters -- see `MultiProfileNoFlow`. -/// * Read or write flow state -- see `SingleProfileSingleFlow` or +/// * Read or write flow state -- see `NoProfileSingleFlow` or /// `MultiProfileSingleFlow`. #[derive(Debug)] -pub struct NoProfileNoFlow<'ctx, E, O, PKeys> +pub struct NoProfileNoFlow<'ctx, CmdCtxTypesT> where - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypes, { /// Output endpoint to return values / errors, and write progress /// information to. @@ -41,11 +43,11 @@ where /// See [`OutputWrite`]. /// /// [`OutputWrite`]: peace_rt_model_core::OutputWrite - output: &'ctx mut O, + output: &'ctx mut CmdCtxTypesT::Output, /// Whether the `CmdExecution` is interruptible. /// /// If it is, this holds the interrupt channel receiver. - interruptibility_state: InterruptibilityState<'ctx, 'ctx>, + interruptibility_state: InterruptibilityState<'static, 'static>, /// Workspace that the `peace` tool runs in. workspace: &'ctx Workspace, /// Type registries for [`WorkspaceParams`], [`ProfileParams`], and @@ -54,23 +56,25 @@ where /// [`WorkspaceParams`]: peace_rt_model::params::WorkspaceParams /// [`ProfileParams`]: peace_rt_model::params::ProfileParams /// [`FlowParams`]: peace_rt_model::params::FlowParams - params_type_regs: ParamsTypeRegs, + params_type_regs: ParamsTypeRegs, /// Workspace params. - workspace_params: WorkspaceParams<::Key>, - /// Marker. - marker: PhantomData, + workspace_params: WorkspaceParams< + <::WorkspaceParamsKMaybe as KeyMaybe>::Key, + >, } -impl<'ctx, E, O, PKeys> NoProfileNoFlow<'ctx, E, O, PKeys> +impl<'ctx, CmdCtxTypesT> NoProfileNoFlow<'ctx, CmdCtxTypesT> where - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypes, { pub(crate) fn new( - output: &'ctx mut O, - interruptibility_state: InterruptibilityState<'ctx, 'ctx>, + output: &'ctx mut CmdCtxTypesT::Output, + interruptibility_state: InterruptibilityState<'static, 'static>, workspace: &'ctx Workspace, - params_type_regs: ParamsTypeRegs, - workspace_params: WorkspaceParams<::Key>, + params_type_regs: ParamsTypeRegs, + workspace_params: WorkspaceParams< + <::WorkspaceParamsKMaybe as KeyMaybe>::Key, + >, ) -> Self { Self { output, @@ -78,17 +82,16 @@ where workspace, params_type_regs, workspace_params, - marker: PhantomData, } } /// Returns a reference to the output. - pub fn output(&self) -> &O { + pub fn output(&self) -> &CmdCtxTypesT::Output { self.output } /// Returns a mutable reference to the output. - pub fn output_mut(&mut self) -> &mut O { + pub fn output_mut(&mut self) -> &mut CmdCtxTypesT::Output { self.output } @@ -123,19 +126,21 @@ where /// [`WorkspaceParams`]: peace_rt_model::params::WorkspaceParams /// [`ProfileParams`]: peace_rt_model::params::ProfileParams /// [`FlowParams`]: peace_rt_model::params::FlowParams - pub fn params_type_regs(&self) -> &ParamsTypeRegs { + pub fn params_type_regs(&self) -> &ParamsTypeRegs { &self.params_type_regs } } -impl<'ctx, E, O, WorkspaceParamsK, ProfileParamsKMaybe, FlowParamsKMaybe> - NoProfileNoFlow< - 'ctx, - E, - O, - ParamsKeysImpl, ProfileParamsKMaybe, FlowParamsKMaybe>, - > +impl<'ctx, CmdCtxTypesT, WorkspaceParamsK, ProfileParamsKMaybe, FlowParamsKMaybe> + NoProfileNoFlow<'ctx, CmdCtxTypesT> where + CmdCtxTypesT: CmdCtxTypes< + ParamsKeys = ParamsKeysImpl< + KeyKnown, + ProfileParamsKMaybe, + FlowParamsKMaybe, + >, + >, WorkspaceParamsK: Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + Unpin + 'static, ProfileParamsKMaybe: KeyMaybe, diff --git a/crate/cmd/src/scopes/single_profile_no_flow.rs b/crate/cmd/src/scopes/single_profile_no_flow.rs index 5d2ef11bb..d10c23f24 100644 --- a/crate/cmd/src/scopes/single_profile_no_flow.rs +++ b/crate/cmd/src/scopes/single_profile_no_flow.rs @@ -1,4 +1,4 @@ -use std::{fmt::Debug, hash::Hash, marker::PhantomData}; +use std::{fmt::Debug, hash::Hash}; use interruptible::InterruptibilityState; use peace_core::Profile; @@ -12,6 +12,8 @@ use peace_rt_model::{ }; use serde::{de::DeserializeOwned, Serialize}; +use crate::ctx::CmdCtxTypes; + /// A command that works with a single profile, without any items. /// /// ```bash @@ -36,14 +38,14 @@ use serde::{de::DeserializeOwned, Serialize}; /// /// This kind of command cannot: /// -/// * Read or write flow parameters -- see `SingleProfileSingleFlow` or +/// * Read or write flow parameters -- see `SingleProfileNoFlow` or /// `MultiProfileSingleFlow`. -/// * Read or write flow state -- see `SingleProfileSingleFlow` or +/// * Read or write flow state -- see `SingleProfileNoFlow` or /// `MultiProfileSingleFlow`. #[derive(Debug)] -pub struct SingleProfileNoFlow<'ctx, E, O, PKeys> +pub struct SingleProfileNoFlow<'ctx, CmdCtxTypesT> where - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypes, { /// Output endpoint to return values / errors, and write progress /// information to. @@ -51,11 +53,11 @@ where /// See [`OutputWrite`]. /// /// [`OutputWrite`]: peace_rt_model_core::OutputWrite - output: &'ctx mut O, + output: &'ctx mut CmdCtxTypesT::Output, /// Whether the `CmdExecution` is interruptible. /// /// If it is, this holds the interrupt channel receiver. - interruptibility_state: InterruptibilityState<'ctx, 'ctx>, + interruptibility_state: InterruptibilityState<'static, 'static>, /// Workspace that the `peace` tool runs in. workspace: &'ctx Workspace, /// The profile this command operates on. @@ -70,13 +72,15 @@ where /// [`WorkspaceParams`]: peace_rt_model::params::WorkspaceParams /// [`ProfileParams`]: peace_rt_model::params::ProfileParams /// [`FlowParams`]: peace_rt_model::params::FlowParams - params_type_regs: ParamsTypeRegs, + params_type_regs: ParamsTypeRegs, /// Workspace params. - workspace_params: WorkspaceParams<::Key>, + workspace_params: WorkspaceParams< + <::WorkspaceParamsKMaybe as KeyMaybe>::Key, + >, /// Profile params for the profile. - profile_params: ProfileParams<::Key>, - /// Marker. - marker: PhantomData, + profile_params: ProfileParams< + <::ProfileParamsKMaybe as KeyMaybe>::Key, + >, } /// A command that works with a single profile, without any items. @@ -103,14 +107,14 @@ where /// /// This kind of command cannot: /// -/// * Read or write flow parameters -- see `SingleProfileSingleFlow` or +/// * Read or write flow parameters -- see `SingleProfileNoFlow` or /// `MultiProfileSingleFlow`. -/// * Read or write flow state -- see `SingleProfileSingleFlow` or +/// * Read or write flow state -- see `SingleProfileNoFlow` or /// `MultiProfileSingleFlow`. #[derive(Debug)] -pub struct SingleProfileNoFlowView<'view, O, PKeys> +pub struct SingleProfileNoFlowView<'view, CmdCtxTypesT> where - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypes, { /// Output endpoint to return values / errors, and write progress /// information to. @@ -118,7 +122,7 @@ where /// See [`OutputWrite`]. /// /// [`OutputWrite`]: peace_rt_model_core::OutputWrite - pub output: &'view mut O, + pub output: &'view mut CmdCtxTypesT::Output, /// Whether the `CmdExecution` is interruptible. /// /// If it is, this holds the interrupt channel receiver. @@ -137,29 +141,37 @@ where /// [`WorkspaceParams`]: peace_rt_model::params::WorkspaceParams /// [`ProfileParams`]: peace_rt_model::params::ProfileParams /// [`FlowParams`]: peace_rt_model::params::FlowParams - pub params_type_regs: &'view ParamsTypeRegs, + pub params_type_regs: &'view ParamsTypeRegs, /// Workspace params. - pub workspace_params: &'view WorkspaceParams<::Key>, + pub workspace_params: &'view WorkspaceParams< + <::WorkspaceParamsKMaybe as KeyMaybe>::Key, + >, /// Profile params for the profile. - pub profile_params: &'view ProfileParams<::Key>, + pub profile_params: &'view ProfileParams< + <::ProfileParamsKMaybe as KeyMaybe>::Key, + >, } -impl<'ctx, E, O, PKeys> SingleProfileNoFlow<'ctx, E, O, PKeys> +impl<'ctx, CmdCtxTypesT> SingleProfileNoFlow<'ctx, CmdCtxTypesT> where - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypes, { /// Returns a new `SingleProfileNoFlow` scope. #[allow(clippy::too_many_arguments)] // Constructed by proc macro pub(crate) fn new( - output: &'ctx mut O, - interruptibility_state: InterruptibilityState<'ctx, 'ctx>, + output: &'ctx mut CmdCtxTypesT::Output, + interruptibility_state: InterruptibilityState<'static, 'static>, workspace: &'ctx Workspace, profile: Profile, profile_dir: ProfileDir, profile_history_dir: ProfileHistoryDir, - params_type_regs: ParamsTypeRegs, - workspace_params: WorkspaceParams<::Key>, - profile_params: ProfileParams<::Key>, + params_type_regs: ParamsTypeRegs, + workspace_params: WorkspaceParams< + <::WorkspaceParamsKMaybe as KeyMaybe>::Key, + >, + profile_params: ProfileParams< + <::ProfileParamsKMaybe as KeyMaybe>::Key, + >, ) -> Self { Self { output, @@ -171,12 +183,11 @@ where params_type_regs, workspace_params, profile_params, - marker: PhantomData, } } /// Returns a view struct of this scope. - pub fn view(&mut self) -> SingleProfileNoFlowView<'_, O, PKeys> { + pub fn view(&mut self) -> SingleProfileNoFlowView<'_, CmdCtxTypesT> { let Self { output, interruptibility_state, @@ -187,7 +198,6 @@ where params_type_regs, workspace_params, profile_params, - marker: PhantomData, } = self; let interruptibility_state = interruptibility_state.reborrow(); @@ -206,12 +216,12 @@ where } /// Returns a reference to the output. - pub fn output(&self) -> &O { + pub fn output(&self) -> &CmdCtxTypesT::Output { self.output } /// Returns a mutable reference to the output. - pub fn output_mut(&mut self) -> &mut O { + pub fn output_mut(&mut self) -> &mut CmdCtxTypesT::Output { self.output } @@ -261,19 +271,21 @@ where /// [`WorkspaceParams`]: peace_rt_model::params::WorkspaceParams /// [`ProfileParams`]: peace_rt_model::params::ProfileParams /// [`FlowParams`]: peace_rt_model::params::FlowParams - pub fn params_type_regs(&self) -> &ParamsTypeRegs { + pub fn params_type_regs(&self) -> &ParamsTypeRegs { &self.params_type_regs } } -impl<'ctx, E, O, WorkspaceParamsK, ProfileParamsKMaybe, FlowParamsKMaybe> - SingleProfileNoFlow< - 'ctx, - E, - O, - ParamsKeysImpl, ProfileParamsKMaybe, FlowParamsKMaybe>, - > +impl<'ctx, CmdCtxTypesT, WorkspaceParamsK, ProfileParamsKMaybe, FlowParamsKMaybe> + SingleProfileNoFlow<'ctx, CmdCtxTypesT> where + CmdCtxTypesT: CmdCtxTypes< + ParamsKeys = ParamsKeysImpl< + KeyKnown, + ProfileParamsKMaybe, + FlowParamsKMaybe, + >, + >, WorkspaceParamsK: Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + Unpin + 'static, ProfileParamsKMaybe: KeyMaybe, @@ -285,14 +297,16 @@ where } } -impl<'ctx, E, O, WorkspaceParamsKMaybe, ProfileParamsK, FlowParamsKMaybe> - SingleProfileNoFlow< - 'ctx, - E, - O, - ParamsKeysImpl, FlowParamsKMaybe>, - > +impl<'ctx, CmdCtxTypesT, WorkspaceParamsKMaybe, ProfileParamsK, FlowParamsKMaybe> + SingleProfileNoFlow<'ctx, CmdCtxTypesT> where + CmdCtxTypesT: CmdCtxTypes< + ParamsKeys = ParamsKeysImpl< + WorkspaceParamsKMaybe, + KeyKnown, + FlowParamsKMaybe, + >, + >, WorkspaceParamsKMaybe: KeyMaybe, ProfileParamsK: Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + Unpin + 'static, diff --git a/crate/cmd/src/scopes/single_profile_single_flow.rs b/crate/cmd/src/scopes/single_profile_single_flow.rs index fcdd1a92e..d20011533 100644 --- a/crate/cmd/src/scopes/single_profile_single_flow.rs +++ b/crate/cmd/src/scopes/single_profile_single_flow.rs @@ -17,6 +17,8 @@ use peace_rt_model::{ }; use serde::{de::DeserializeOwned, Serialize}; +use crate::ctx::CmdCtxTypes; + /// A command that works with one profile and one flow. /// /// ```bash @@ -50,10 +52,9 @@ use serde::{de::DeserializeOwned, Serialize}; /// * Read or write flow state -- see `SingleProfileSingleFlow` or /// `MultiProfileSingleFlow`. #[derive(Debug)] -pub struct SingleProfileSingleFlow<'ctx, E, O, PKeys, TS> +pub struct SingleProfileSingleFlow<'ctx, CmdCtxTypesT, TS> where - E: 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypes, { /// Output endpoint to return values / errors, and write progress /// information to. @@ -61,7 +62,7 @@ where /// See [`OutputWrite`]. /// /// [`OutputWrite`]: peace_rt_model_core::OutputWrite - output: &'ctx mut O, + output: &'ctx mut CmdCtxTypesT::Output, /// Whether the `CmdExecution` is interruptible. /// /// If it is, this holds the interrupt channel receiver. @@ -78,7 +79,7 @@ where /// Directory to store profile execution history. profile_history_dir: ProfileHistoryDir, /// The chosen process flow. - flow: &'ctx Flow, + flow: &'ctx Flow, /// Flow directory that stores params and states. flow_dir: FlowDir, /// Type registries for [`WorkspaceParams`], [`ProfileParams`], and @@ -87,13 +88,18 @@ where /// [`WorkspaceParams`]: peace_rt_model::params::WorkspaceParams /// [`ProfileParams`]: peace_rt_model::params::ProfileParams /// [`FlowParams`]: peace_rt_model::params::FlowParams - params_type_regs: ParamsTypeRegs, + params_type_regs: ParamsTypeRegs, /// Workspace params. - workspace_params: WorkspaceParams<::Key>, + workspace_params: WorkspaceParams< + <::WorkspaceParamsKMaybe as KeyMaybe>::Key, + >, /// Profile params for the profile. - profile_params: ProfileParams<::Key>, + profile_params: ProfileParams< + <::ProfileParamsKMaybe as KeyMaybe>::Key, + >, /// Flow params for the selected flow. - flow_params: FlowParams<::Key>, + flow_params: + FlowParams<<::FlowParamsKMaybe as KeyMaybe>::Key>, /// Type registry for each item's [`Params`]`::Spec`. /// /// This is used to deserialize [`ParamsSpecsFile`]. @@ -148,10 +154,9 @@ where /// * Read or write flow state -- see `SingleProfileSingleFlow` or /// `MultiProfileSingleFlow`. #[derive(Debug)] -pub struct SingleProfileSingleFlowView<'view, E, PKeys, TS> +pub struct SingleProfileSingleFlowView<'view, CmdCtxTypesT, TS> where - E: 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypes, { /// Whether the `CmdExecution` is interruptible. /// @@ -166,7 +171,7 @@ where /// Directory to store profile execution history. pub profile_history_dir: &'view ProfileHistoryDir, /// The chosen process flow. - pub flow: &'view Flow, + pub flow: &'view Flow, /// Flow directory that stores params and states. pub flow_dir: &'view FlowDir, /// Type registries for [`WorkspaceParams`], [`ProfileParams`], and @@ -175,13 +180,19 @@ where /// [`WorkspaceParams`]: peace_rt_model::params::WorkspaceParams /// [`ProfileParams`]: peace_rt_model::params::ProfileParams /// [`FlowParams`]: peace_rt_model::params::FlowParams - pub params_type_regs: &'view ParamsTypeRegs, + pub params_type_regs: &'view ParamsTypeRegs, /// Workspace params. - pub workspace_params: &'view WorkspaceParams<::Key>, + pub workspace_params: &'view WorkspaceParams< + <::WorkspaceParamsKMaybe as KeyMaybe>::Key, + >, /// Profile params for the profile. - pub profile_params: &'view ProfileParams<::Key>, + pub profile_params: &'view ProfileParams< + <::ProfileParamsKMaybe as KeyMaybe>::Key, + >, /// Flow params for the selected flow. - pub flow_params: &'view FlowParams<::Key>, + pub flow_params: &'view FlowParams< + <::FlowParamsKMaybe as KeyMaybe>::Key, + >, /// Type registry for each item's [`Params`]`::Spec`. /// /// This is used to deserialize [`ParamsSpecsFile`]. @@ -210,10 +221,9 @@ where /// `cmd_progress_tracker` mutably, while the flow information is passed through /// to sub commands.. #[derive(Debug)] -pub struct SingleProfileSingleFlowViewAndOutput<'view, E, O, PKeys, TS> +pub struct SingleProfileSingleFlowViewAndOutput<'view, CmdCtxTypesT, TS> where - E: 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypes, { /// Output endpoint to return values / errors, and write progress /// information to. @@ -221,22 +231,22 @@ where /// See [`OutputWrite`]. /// /// [`OutputWrite`]: peace_rt_model_core::OutputWrite - pub output: &'view mut O, + pub output: &'view mut CmdCtxTypesT::Output, /// Tracks progress of each function execution. #[cfg(feature = "output_progress")] pub cmd_progress_tracker: &'view mut peace_rt_model::CmdProgressTracker, /// Flow and parameter related information. - pub cmd_view: SingleProfileSingleFlowView<'view, E, PKeys, TS>, + pub cmd_view: SingleProfileSingleFlowView<'view, CmdCtxTypesT, TS>, } -impl<'ctx, E, O, PKeys> SingleProfileSingleFlow<'ctx, E, O, PKeys, SetUp> +impl<'ctx, CmdCtxTypesT> SingleProfileSingleFlow<'ctx, CmdCtxTypesT, SetUp> where - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypes, { /// Returns a new `SingleProfileSingleFlow` scope. #[allow(clippy::too_many_arguments)] // Constructed by proc macro pub(crate) fn new( - output: &'ctx mut O, + output: &'ctx mut CmdCtxTypesT::Output, interruptibility_state: InterruptibilityState<'static, 'static>, workspace: &'ctx Workspace, #[cfg(feature = "output_progress")] @@ -244,12 +254,18 @@ where profile: Profile, profile_dir: ProfileDir, profile_history_dir: ProfileHistoryDir, - flow: &'ctx Flow, + flow: &'ctx Flow, flow_dir: FlowDir, - params_type_regs: ParamsTypeRegs, - workspace_params: WorkspaceParams<::Key>, - profile_params: ProfileParams<::Key>, - flow_params: FlowParams<::Key>, + params_type_regs: ParamsTypeRegs, + workspace_params: WorkspaceParams< + <::WorkspaceParamsKMaybe as KeyMaybe>::Key, + >, + profile_params: ProfileParams< + <::ProfileParamsKMaybe as KeyMaybe>::Key, + >, + flow_params: FlowParams< + <::FlowParamsKMaybe as KeyMaybe>::Key, + >, params_specs_type_reg: ParamsSpecsTypeReg, params_specs: ParamsSpecs, states_type_reg: StatesTypeReg, @@ -278,14 +294,14 @@ where } } -impl<'ctx, E, O, PKeys, TS> SingleProfileSingleFlow<'ctx, E, O, PKeys, TS> +impl<'ctx, CmdCtxTypesT, TS> SingleProfileSingleFlow<'ctx, CmdCtxTypesT, TS> where - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypes, { /// Returns a view struct of this scope. /// /// This allows the flow and resources to be borrowed concurrently. - pub fn view(&mut self) -> SingleProfileSingleFlowView<'_, E, PKeys, TS> { + pub fn view(&mut self) -> SingleProfileSingleFlowView<'_, CmdCtxTypesT, TS> { let Self { output: _, interruptibility_state, @@ -331,7 +347,9 @@ where /// Returns a view and output struct of this scope. /// /// This allows the flow and resources to be borrowed concurrently. - pub fn view_and_output(&mut self) -> SingleProfileSingleFlowViewAndOutput<'_, E, O, PKeys, TS> { + pub fn view_and_output( + &mut self, + ) -> SingleProfileSingleFlowViewAndOutput<'_, CmdCtxTypesT, TS> { let Self { output, interruptibility_state, @@ -380,12 +398,12 @@ where } /// Returns a reference to the output. - pub fn output(&self) -> &O { + pub fn output(&self) -> &CmdCtxTypesT::Output { self.output } /// Returns a mutable reference to the output. - pub fn output_mut(&mut self) -> &mut O { + pub fn output_mut(&mut self) -> &mut CmdCtxTypesT::Output { self.output } @@ -443,7 +461,7 @@ where } /// Returns a reference to the flow. - pub fn flow(&self) -> &Flow { + pub fn flow(&self) -> &Flow { self.flow } @@ -459,7 +477,7 @@ where /// [`ItemParams`]: peace_rt_model::ItemParams /// [`ProfileParams`]: peace_rt_model::params::ProfileParams /// [`WorkspaceParams`]: peace_rt_model::params::WorkspaceParams - pub fn params_type_regs(&self) -> &ParamsTypeRegs { + pub fn params_type_regs(&self) -> &ParamsTypeRegs { &self.params_type_regs } @@ -504,7 +522,7 @@ where pub fn resources_update( self, f: F, - ) -> SingleProfileSingleFlow<'ctx, E, O, PKeys, ResTs1> + ) -> SingleProfileSingleFlow<'ctx, CmdCtxTypesT, ResTs1> where F: FnOnce(Resources) -> Resources, { @@ -554,15 +572,16 @@ where } } -impl<'ctx, E, O, WorkspaceParamsK, ProfileParamsKMaybe, FlowParamsKMaybe, TS> - SingleProfileSingleFlow< - 'ctx, - E, - O, - ParamsKeysImpl, ProfileParamsKMaybe, FlowParamsKMaybe>, - TS, - > +impl<'ctx, CmdCtxTypesT, TS, WorkspaceParamsK, ProfileParamsKMaybe, FlowParamsKMaybe> + SingleProfileSingleFlow<'ctx, CmdCtxTypesT, TS> where + CmdCtxTypesT: CmdCtxTypes< + ParamsKeys = ParamsKeysImpl< + KeyKnown, + ProfileParamsKMaybe, + FlowParamsKMaybe, + >, + >, WorkspaceParamsK: Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + Unpin + 'static, ProfileParamsKMaybe: KeyMaybe, @@ -574,15 +593,16 @@ where } } -impl<'ctx, E, O, WorkspaceParamsKMaybe, ProfileParamsK, FlowParamsKMaybe, TS> - SingleProfileSingleFlow< - 'ctx, - E, - O, - ParamsKeysImpl, FlowParamsKMaybe>, - TS, - > +impl<'ctx, CmdCtxTypesT, TS, WorkspaceParamsKMaybe, ProfileParamsK, FlowParamsKMaybe> + SingleProfileSingleFlow<'ctx, CmdCtxTypesT, TS> where + CmdCtxTypesT: CmdCtxTypes< + ParamsKeys = ParamsKeysImpl< + WorkspaceParamsKMaybe, + KeyKnown, + FlowParamsKMaybe, + >, + >, WorkspaceParamsKMaybe: KeyMaybe, ProfileParamsK: Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + Unpin + 'static, @@ -594,21 +614,22 @@ where } } -impl<'ctx, E, O, WorkspaceParamsKMaybe, ProfileParamsKMaybe, FlowParamsK, TS> - SingleProfileSingleFlow< - 'ctx, - E, - O, - ParamsKeysImpl>, - TS, - > +impl<'ctx, CmdCtxTypesT, TS, WorkspaceParamsKMaybe, ProfileParamsKMaybe, FlowParamsK> + SingleProfileSingleFlow<'ctx, CmdCtxTypesT, TS> where + CmdCtxTypesT: CmdCtxTypes< + ParamsKeys = ParamsKeysImpl< + WorkspaceParamsKMaybe, + ProfileParamsKMaybe, + KeyKnown, + >, + >, WorkspaceParamsKMaybe: KeyMaybe, ProfileParamsKMaybe: KeyMaybe, FlowParamsK: Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + Unpin + 'static, { - /// Returns the flow params for the selected flow. + /// Returns the flow params. pub fn flow_params(&self) -> &FlowParams { &self.flow_params } diff --git a/crate/cmd/src/scopes/type_params.rs b/crate/cmd/src/scopes/type_params.rs index afa2fa19a..5964123b8 100644 --- a/crate/cmd/src/scopes/type_params.rs +++ b/crate/cmd/src/scopes/type_params.rs @@ -1,7 +1,7 @@ //! Types used for parameters type state for scopes. pub use self::{ - flow_params_selection::{FlowParamsNone, FlowParamsSome}, + flow_params_selection::{FlowParamsNone, FlowParamsSome, FlowParamsSomeMulti}, flow_selection::{FlowNotSelected, FlowSelected}, profile_params_selection::{ProfileParamsNone, ProfileParamsSome, ProfileParamsSomeMulti}, profile_selection::{ diff --git a/crate/cmd/src/scopes/type_params/flow_params_selection.rs b/crate/cmd/src/scopes/type_params/flow_params_selection.rs index 56fe78650..8a8ebff9a 100644 --- a/crate/cmd/src/scopes/type_params/flow_params_selection.rs +++ b/crate/cmd/src/scopes/type_params/flow_params_selection.rs @@ -14,8 +14,26 @@ pub struct FlowParamsSome(pub(crate) FlowParams) where FlowParamsK: Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + 'static; +impl Default for FlowParamsSome +where + FlowParamsK: Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + 'static, +{ + fn default() -> Self { + FlowParamsSome(FlowParams::default()) + } +} + /// The application has flow parameters from multiple profiles. #[derive(Debug)] pub struct FlowParamsSomeMulti(pub(crate) BTreeMap>) where FlowParamsK: Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + 'static; + +impl Default for FlowParamsSomeMulti +where + FlowParamsK: Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + 'static, +{ + fn default() -> Self { + FlowParamsSomeMulti(BTreeMap::default()) + } +} diff --git a/crate/cmd/src/scopes/type_params/profile_params_selection.rs b/crate/cmd/src/scopes/type_params/profile_params_selection.rs index 77a63cddc..208aabefa 100644 --- a/crate/cmd/src/scopes/type_params/profile_params_selection.rs +++ b/crate/cmd/src/scopes/type_params/profile_params_selection.rs @@ -15,6 +15,16 @@ where ProfileParamsK: Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + 'static; +impl Default for ProfileParamsSome +where + ProfileParamsK: + Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + 'static, +{ + fn default() -> Self { + ProfileParamsSome(ProfileParams::default()) + } +} + /// The application has profile parameters from multiple profiles. #[derive(Debug)] pub struct ProfileParamsSomeMulti( @@ -23,3 +33,13 @@ pub struct ProfileParamsSomeMulti( where ProfileParamsK: Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + 'static; + +impl Default for ProfileParamsSomeMulti +where + ProfileParamsK: + Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + 'static, +{ + fn default() -> Self { + ProfileParamsSomeMulti(BTreeMap::default()) + } +} diff --git a/crate/cmd/src/scopes/type_params/workspace_params_selection.rs b/crate/cmd/src/scopes/type_params/workspace_params_selection.rs index 2ea2446c7..e92660c51 100644 --- a/crate/cmd/src/scopes/type_params/workspace_params_selection.rs +++ b/crate/cmd/src/scopes/type_params/workspace_params_selection.rs @@ -13,3 +13,13 @@ pub struct WorkspaceParamsSome(pub(crate) WorkspaceParams Default for WorkspaceParamsSome +where + WorkspaceParamsK: + Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + 'static, +{ + fn default() -> Self { + WorkspaceParamsSome(WorkspaceParams::default()) + } +} diff --git a/crate/cmd_rt/src/cmd_block.rs b/crate/cmd_rt/src/cmd_block.rs index caf6f628c..7f45d5825 100644 --- a/crate/cmd_rt/src/cmd_block.rs +++ b/crate/cmd_rt/src/cmd_block.rs @@ -1,10 +1,9 @@ use std::fmt::Debug; use async_trait::async_trait; -use peace_cmd::scopes::SingleProfileSingleFlowView; +use peace_cmd::{ctx::CmdCtxTypesConstrained, scopes::SingleProfileSingleFlowView}; use peace_cmd_model::CmdBlockOutcome; use peace_resources::{resources::ts::SetUp, Resource, ResourceFetchError, Resources}; -use peace_rt_model::params::ParamsKeys; cfg_if::cfg_if! { if #[cfg(feature = "output_progress")] { @@ -45,10 +44,10 @@ mod cmd_block_wrapper; /// [`Item::*`]: peace_cfg::Item #[async_trait(?Send)] pub trait CmdBlock: Debug { - /// Automation software error type. - type Error: std::error::Error + From + Send + 'static; - /// Types used for params keys. - type PKeys: ParamsKeys + 'static; + /// Type parameters passed to the `CmdCtx`. + /// + /// `CmdBlock` uses the `AppError` and `ParamsKeys` associated type. + type CmdCtxTypes: CmdCtxTypesConstrained; /// Outcome type of the command block, e.g. `(StatesCurrent, StatesGoal)`. type Outcome: Debug + Send + Sync + 'static; /// Input type of the command block, e.g. `StatesCurrent`. @@ -177,7 +176,10 @@ pub trait CmdBlock: Debug { async fn exec( &self, input: Self::InputT, - cmd_view: &mut SingleProfileSingleFlowView<'_, Self::Error, Self::PKeys, SetUp>, + cmd_view: &mut SingleProfileSingleFlowView<'_, Self::CmdCtxTypes, SetUp>, #[cfg(feature = "output_progress")] progress_tx: &Sender, - ) -> Result, Self::Error>; + ) -> Result< + CmdBlockOutcome::AppError>, + ::AppError, + >; } diff --git a/crate/cmd_rt/src/cmd_block/cmd_block_rt.rs b/crate/cmd_rt/src/cmd_block/cmd_block_rt.rs index c662f6c11..43d3e6c15 100644 --- a/crate/cmd_rt/src/cmd_block/cmd_block_rt.rs +++ b/crate/cmd_rt/src/cmd_block/cmd_block_rt.rs @@ -2,10 +2,9 @@ use std::fmt::Debug; use async_trait::async_trait; -use peace_cmd::scopes::SingleProfileSingleFlowView; +use peace_cmd::{ctx::CmdCtxTypesConstrained, scopes::SingleProfileSingleFlowView}; use peace_cmd_model::CmdBlockDesc; use peace_resources::resources::ts::SetUp; -use peace_rt_model::params::ParamsKeys; use crate::CmdBlockError; @@ -21,19 +20,23 @@ cfg_if::cfg_if! { /// [`CmdBlock`]: crate::CmdBlock #[async_trait(?Send)] pub trait CmdBlockRt: Debug + Unpin { - /// Automation software error type. - type Error: std::error::Error + From + Send + 'static; - /// Types used for params keys. - type PKeys: ParamsKeys + 'static; + /// Type parameters passed to the `CmdCtx`. + type CmdCtxTypes: CmdCtxTypesConstrained; /// Outcome type of the command execution. type ExecutionOutcome: Debug + 'static; /// Executes this command block. async fn exec( &self, - view: &mut SingleProfileSingleFlowView<'_, Self::Error, Self::PKeys, SetUp>, + view: &mut SingleProfileSingleFlowView<'_, Self::CmdCtxTypes, SetUp>, #[cfg(feature = "output_progress")] progress_tx: Sender, - ) -> Result<(), CmdBlockError>; + ) -> Result< + (), + CmdBlockError< + Self::ExecutionOutcome, + ::AppError, + >, + >; /// Returns the `String` representation of the `CmdBlock` in a /// `CmdExecution`. diff --git a/crate/cmd_rt/src/cmd_block/cmd_block_rt_box.rs b/crate/cmd_rt/src/cmd_block/cmd_block_rt_box.rs index 79c2f44c9..e3e1efb29 100644 --- a/crate/cmd_rt/src/cmd_block/cmd_block_rt_box.rs +++ b/crate/cmd_rt/src/cmd_block/cmd_block_rt_box.rs @@ -11,5 +11,6 @@ use crate::CmdBlockRt; /// * `Outcome`: [`CmdBlock`] outcome type, e.g. `(StatesCurrent, StatesGoal)`. /// /// [`CmdBlock`]: crate::CmdBlock -pub type CmdBlockRtBox = - Pin>>; +pub type CmdBlockRtBox<'types, CmdCtxTypesT, ExecutionOutcome> = Pin< + Box + 'types>, +>; diff --git a/crate/cmd_rt/src/cmd_block/cmd_block_wrapper.rs b/crate/cmd_rt/src/cmd_block/cmd_block_wrapper.rs index 43d36c9d7..51e9157ff 100644 --- a/crate/cmd_rt/src/cmd_block/cmd_block_wrapper.rs +++ b/crate/cmd_rt/src/cmd_block/cmd_block_wrapper.rs @@ -2,10 +2,10 @@ use std::{fmt::Debug, marker::PhantomData}; use async_trait::async_trait; use fn_graph::StreamOutcomeState; -use peace_cmd::scopes::SingleProfileSingleFlowView; +use peace_cmd::{ctx::CmdCtxTypesConstrained, scopes::SingleProfileSingleFlowView}; use peace_cmd_model::{CmdBlockDesc, CmdBlockOutcome}; use peace_resources::{resources::ts::SetUp, Resource}; -use peace_rt_model::params::ParamsKeys; + use tynm::TypeParamsFmtOpts; use crate::{CmdBlock, CmdBlockError, CmdBlockRt}; @@ -29,7 +29,7 @@ cfg_if::cfg_if! { /// /// [`CmdBlockRt`]: crate::CmdBlockRt #[derive(Debug)] -pub struct CmdBlockWrapper { +pub struct CmdBlockWrapper { /// Underlying `CmdBlock` implementation. /// /// The trait constraints are applied on impl blocks. @@ -38,13 +38,13 @@ pub struct CmdBlockWrapper /// executing this `CmdBlock`. fn_partial_exec_handler: fn(BlockOutcome) -> ExecutionOutcome, /// Marker. - marker: PhantomData<(E, PKeys, BlockOutcome, InputT)>, + marker: PhantomData<(CmdCtxTypesT, BlockOutcome, InputT)>, } -impl - CmdBlockWrapper +impl + CmdBlockWrapper where - CB: CmdBlock, + CB: CmdBlock, { /// Returns a new `CmdBlockWrapper`. /// @@ -69,25 +69,26 @@ where } #[async_trait(?Send)] -impl CmdBlockRt - for CmdBlockWrapper +impl CmdBlockRt + for CmdBlockWrapper where - CB: CmdBlock + Unpin, - E: Debug + std::error::Error + From + Send + Unpin + 'static, - PKeys: ParamsKeys + 'static, + CB: CmdBlock + Unpin, + CmdCtxTypesT: CmdCtxTypesConstrained, ExecutionOutcome: Debug + Unpin + Send + Sync + 'static, BlockOutcome: Debug + Unpin + Send + Sync + 'static, InputT: Debug + Resource + Unpin + 'static, { - type Error = E; + type CmdCtxTypes = CmdCtxTypesT; type ExecutionOutcome = ExecutionOutcome; - type PKeys = PKeys; async fn exec( &self, - cmd_view: &mut SingleProfileSingleFlowView<'_, Self::Error, Self::PKeys, SetUp>, + cmd_view: &mut SingleProfileSingleFlowView<'_, CmdCtxTypesT, SetUp>, #[cfg(feature = "output_progress")] progress_tx: Sender, - ) -> Result<(), CmdBlockError> { + ) -> Result< + (), + CmdBlockError::AppError>, + > { let cmd_block = &self.cmd_block; let input = cmd_block.input_fetch(cmd_view.resources)?; diff --git a/crate/cmd_rt/src/cmd_execution.rs b/crate/cmd_rt/src/cmd_execution.rs index b709bbe17..61bd71e62 100644 --- a/crate/cmd_rt/src/cmd_execution.rs +++ b/crate/cmd_rt/src/cmd_execution.rs @@ -3,21 +3,20 @@ use std::{collections::VecDeque, fmt::Debug}; use futures::{future, stream, Future, StreamExt, TryStreamExt}; use interruptible::InterruptSignal; use peace_cmd::{ - ctx::CmdCtx, + ctx::{CmdCtx, CmdCtxTypes, CmdCtxTypesConstrained}, scopes::{ SingleProfileSingleFlow, SingleProfileSingleFlowView, SingleProfileSingleFlowViewAndOutput, }, }; use peace_cmd_model::{CmdBlockDesc, CmdOutcome}; use peace_resources::{resources::ts::SetUp, Resources}; -use peace_rt_model::{output::OutputWrite, params::ParamsKeys}; use crate::{CmdBlockError, CmdBlockRtBox, ItemStreamOutcomeMapper}; cfg_if::cfg_if! { if #[cfg(feature = "output_progress")] { use peace_cfg::progress::CmdProgressUpdate; - use peace_rt_model::CmdProgressTracker; + use peace_rt_model::{output::OutputWrite, CmdProgressTracker}; use tokio::sync::mpsc::{self, Sender}; use crate::Progress; @@ -45,13 +44,12 @@ mod cmd_execution_error_builder; /// /// [`CmdBlock`]: crate::CmdBlock #[derive(Debug)] -pub struct CmdExecution +pub struct CmdExecution<'types, ExecutionOutcome, CmdCtxTypesT> where - E: 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypes, { /// Blocks of commands to run. - cmd_blocks: VecDeque>, + cmd_blocks: VecDeque>, /// Logic to extract the `ExecutionOutcome` from `Resources`. execution_outcome_fetch: fn(&mut Resources) -> Option, /// Whether or not to render progress. @@ -59,24 +57,23 @@ where progress_render_enabled: bool, } -impl CmdExecution +impl<'types, ExecutionOutcome, CmdCtxTypesT> CmdExecution<'types, ExecutionOutcome, CmdCtxTypesT> where ExecutionOutcome: Debug + Send + Sync + Unpin + 'static, - E: std::error::Error + From + Send + Sync + Unpin + 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained + 'types, { - pub fn builder() -> CmdExecutionBuilder { + pub fn builder() -> CmdExecutionBuilder<'types, ExecutionOutcome, CmdCtxTypesT> { CmdExecutionBuilder::new() } /// Returns the result of executing the command. - pub async fn exec<'ctx, O>( + pub async fn exec<'ctx>( &mut self, - cmd_ctx: &mut CmdCtx>, - ) -> Result, E> - where - O: OutputWrite, - { + cmd_ctx: &mut CmdCtx>, + ) -> Result< + CmdOutcome::AppError>, + ::AppError, + > { let Self { cmd_blocks, execution_outcome_fetch, @@ -188,26 +185,28 @@ where } } -async fn cmd_outcome_task<'view, 'view_ref, ExecutionOutcome, E, PKeys>( - cmd_blocks: &VecDeque>, +async fn cmd_outcome_task<'types: 'view, 'view, 'view_ref, ExecutionOutcome, CmdCtxTypesT>( + cmd_blocks: &VecDeque>, execution_outcome_fetch: &mut fn(&mut Resources) -> Option, - cmd_view: &mut SingleProfileSingleFlowView<'view, E, PKeys, SetUp>, + cmd_view: &mut SingleProfileSingleFlowView<'view, CmdCtxTypesT, SetUp>, #[cfg(feature = "output_progress")] cmd_progress_tx: Sender, -) -> Result, E> +) -> Result< + CmdOutcome::AppError>, + ::AppError, +> where - E: std::error::Error + From + Send + Sync + Unpin + 'static, - PKeys: ParamsKeys + 'static, ExecutionOutcome: Debug + Send + Sync + Unpin + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { let cmd_view_and_progress_result: Result< - CmdViewAndProgress<'_, '_, _, _>, - CmdBlockStreamBreak<'_, '_, _, _, _>, + CmdViewAndProgress<'_, '_, _>, + CmdBlockStreamBreak<'_, '_, _, _>, > = stream::unfold(cmd_blocks.iter(), |mut cmd_blocks| { let cmd_block_next = cmd_blocks.next(); future::ready(cmd_block_next.map(|cmd_block_next| (cmd_block_next, cmd_blocks))) }) .enumerate() - .map(Result::<_, CmdBlockStreamBreak<'_, '_, ExecutionOutcome, E, PKeys>>::Ok) + .map(Result::<_, CmdBlockStreamBreak<'_, '_, ExecutionOutcome, CmdCtxTypesT>>::Ok) .try_fold( CmdViewAndProgress { cmd_view, @@ -277,7 +276,7 @@ where ) .await; - outcome_extract::( + outcome_extract::( cmd_view_and_progress_result, cmd_blocks, execution_outcome_fetch, @@ -294,18 +293,20 @@ where /// * `cmd_blocks`: `CmdBlock`s in this execution, used to build a useful error /// message if needed. /// * `execution_outcome_fetch`: Logic to extract the `ExecutionOutcome` type. -fn outcome_extract<'view, 'view_ref, ExecutionOutcome, E, PKeys>( +fn outcome_extract<'types: 'view, 'view, 'view_ref, ExecutionOutcome, CmdCtxTypesT>( cmd_view_and_progress_result: Result< - CmdViewAndProgress<'view, 'view_ref, E, PKeys>, - CmdBlockStreamBreak<'view, 'view_ref, ExecutionOutcome, E, PKeys>, + CmdViewAndProgress<'view, 'view_ref, CmdCtxTypesT>, + CmdBlockStreamBreak<'view, 'view_ref, ExecutionOutcome, CmdCtxTypesT>, >, - cmd_blocks: &'view_ref VecDeque>, + cmd_blocks: &'view_ref VecDeque>, execution_outcome_fetch: &mut fn(&mut Resources) -> Option, -) -> Result, E> +) -> Result< + CmdOutcome::AppError>, + ::AppError, +> where - E: std::error::Error + From + Send + Sync + Unpin + 'static, - PKeys: ParamsKeys + 'static, ExecutionOutcome: Debug + Send + Sync + Unpin + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { let (cmd_view_and_progress, cmd_block_index_and_error, cmd_block_index_next) = match cmd_view_and_progress_result { @@ -341,13 +342,15 @@ where if let Some((cmd_block_index, cmd_block_error)) = cmd_block_index_and_error { match cmd_block_error { - CmdBlockError::InputFetch(resource_fetch_error) => Err(E::from( - peace_rt_model::Error::from(CmdExecutionErrorBuilder::build::<_, _, _, _>( - cmd_blocks.iter(), - cmd_block_index, - resource_fetch_error, - )), - )), + CmdBlockError::InputFetch(resource_fetch_error) => { + Err(::AppError::from( + peace_rt_model::Error::from(CmdExecutionErrorBuilder::build::<_, _, _>( + cmd_blocks.iter(), + cmd_block_index, + resource_fetch_error, + )), + )) + } CmdBlockError::Exec(error) => Err(error), CmdBlockError::Interrupt { stream_outcome } => { let item_stream_outcome = ItemStreamOutcomeMapper::map(flow, stream_outcome); @@ -435,42 +438,40 @@ where } } -struct CmdViewAndProgress<'view, 'view_ref, E, PKeys> +struct CmdViewAndProgress<'view, 'view_ref, CmdCtxTypesT> where - E: 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { - cmd_view: &'view_ref mut SingleProfileSingleFlowView<'view, E, PKeys, SetUp>, + cmd_view: &'view_ref mut SingleProfileSingleFlowView<'view, CmdCtxTypesT, SetUp>, #[cfg(feature = "output_progress")] cmd_progress_tx: Sender, } /// Reasons to stop processing `CmdBlock`s. -enum CmdBlockStreamBreak<'view, 'view_ref, ExecutionOutcome, E, PKeys> +enum CmdBlockStreamBreak<'view, 'view_ref, ExecutionOutcome, CmdCtxTypesT> where ExecutionOutcome: Debug, - E: Debug + 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { /// An interruption happened between `CmdBlock` executions. Interrupt { - cmd_view_and_progress: CmdViewAndProgress<'view, 'view_ref, E, PKeys>, + cmd_view_and_progress: CmdViewAndProgress<'view, 'view_ref, CmdCtxTypesT>, /// Index of the next `CmdBlock` that hasn't been processed. cmd_block_index_next: usize, interrupt_signal: InterruptSignal, }, /// A `CmdBlockError` was returned from `CmdBlockRt::exec`. - BlockErr(CmdViewAndErr<'view, 'view_ref, ExecutionOutcome, E, PKeys>), + BlockErr(CmdViewAndErr<'view, 'view_ref, ExecutionOutcome, CmdCtxTypesT>), } -struct CmdViewAndErr<'view, 'view_ref, ExecutionOutcome, E, PKeys> +struct CmdViewAndErr<'view, 'view_ref, ExecutionOutcome, CmdCtxTypesT> where ExecutionOutcome: Debug, - E: Debug + 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { - cmd_view_and_progress: CmdViewAndProgress<'view, 'view_ref, E, PKeys>, + cmd_view_and_progress: CmdViewAndProgress<'view, 'view_ref, CmdCtxTypesT>, /// Index of the `CmdBlock` that erred. cmd_block_index: usize, - cmd_block_error: CmdBlockError, + cmd_block_error: + CmdBlockError::AppError>, } diff --git a/crate/cmd_rt/src/cmd_execution/cmd_execution_builder.rs b/crate/cmd_rt/src/cmd_execution/cmd_execution_builder.rs index f3622c1f9..9b0f89dde 100644 --- a/crate/cmd_rt/src/cmd_execution/cmd_execution_builder.rs +++ b/crate/cmd_rt/src/cmd_execution/cmd_execution_builder.rs @@ -1,7 +1,7 @@ use std::{collections::VecDeque, fmt::Debug}; +use peace_cmd::ctx::CmdCtxTypesConstrained; use peace_resources::{resources::ts::SetUp, Resource, Resources}; -use peace_rt_model::params::ParamsKeys; use crate::{CmdBlock, CmdBlockRtBox, CmdBlockWrapper, CmdExecution}; @@ -10,14 +10,13 @@ use crate::{CmdBlock, CmdBlockRtBox, CmdBlockWrapper, CmdExecution}; /// [`CmdBlock`]: crate::CmdBlock /// [`CmdExecution`]: crate::CmdExecution #[derive(Debug)] -pub struct CmdExecutionBuilder +pub struct CmdExecutionBuilder<'types, ExecutionOutcome, CmdCtxTypesT> where ExecutionOutcome: Debug + Send + Sync + 'static, - E: 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { /// Blocks of commands to run. - cmd_blocks: VecDeque>, + cmd_blocks: VecDeque>, /// Logic to extract the `ExecutionOutcome` from `Resources`. execution_outcome_fetch: fn(&mut Resources) -> Option, /// Whether or not to render progress. @@ -31,11 +30,11 @@ where progress_render_enabled: bool, } -impl CmdExecutionBuilder +impl<'types, ExecutionOutcome, CmdCtxTypesT> + CmdExecutionBuilder<'types, ExecutionOutcome, CmdCtxTypesT> where ExecutionOutcome: Debug + Send + Sync + 'static, - E: Debug + std::error::Error + From + Send + Unpin + 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained + 'types, { pub fn new() -> Self { Self::default() @@ -44,12 +43,12 @@ where /// Adds a `CmdBlock` to this execution. pub fn with_cmd_block( self, - cmd_block: CmdBlockWrapper, - ) -> CmdExecutionBuilder + cmd_block: CmdBlockWrapper, + ) -> CmdExecutionBuilder<'types, ExecutionOutcome, CmdCtxTypesT> where - CB: CmdBlock + CB: CmdBlock + Unpin - + 'static, + + 'types, ExecutionOutcome: Debug + Resource + Unpin + 'static, BlockOutcomeNext: Debug + Resource + Unpin + 'static, InputT: Debug + Resource + Unpin + 'static, @@ -102,7 +101,10 @@ where } /// Returns the `CmdExecution` to execute. - pub fn build(self) -> CmdExecution { + pub fn build(self) -> CmdExecution<'types, ExecutionOutcome, CmdCtxTypesT> + where + CmdCtxTypesT: CmdCtxTypesConstrained, + { let CmdExecutionBuilder { cmd_blocks, execution_outcome_fetch, @@ -119,11 +121,11 @@ where } } -impl Default for CmdExecutionBuilder +impl<'types, ExecutionOutcome, CmdCtxTypesT> Default + for CmdExecutionBuilder<'types, ExecutionOutcome, CmdCtxTypesT> where - E: Debug + std::error::Error + From + Send + Unpin + 'static, - PKeys: ParamsKeys + 'static, ExecutionOutcome: Debug + Resource + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { fn default() -> Self { Self { diff --git a/crate/cmd_rt/src/cmd_execution/cmd_execution_error_builder.rs b/crate/cmd_rt/src/cmd_execution/cmd_execution_error_builder.rs index 1c098c27e..16d40029d 100644 --- a/crate/cmd_rt/src/cmd_execution/cmd_execution_error_builder.rs +++ b/crate/cmd_rt/src/cmd_execution/cmd_execution_error_builder.rs @@ -1,8 +1,8 @@ use std::fmt::Debug; +use peace_cmd::ctx::CmdCtxTypesConstrained; use peace_cmd_model::{CmdBlockDesc, CmdExecutionError}; use peace_resources::ResourceFetchError; -use peace_rt_model::params::ParamsKeys; use crate::CmdBlockRtBox; @@ -46,16 +46,16 @@ impl CmdExecutionErrorBuilder { /// Input: (States, States) /// Outcome: (States, States, States) /// ``` - pub fn build<'f, ExecutionOutcome, E, PKeys, CmdBlockIterator>( + pub fn build<'types: 'f, 'f, ExecutionOutcome, CmdCtxTypesT, CmdBlockIterator>( cmd_blocks: CmdBlockIterator, cmd_block_index: usize, resource_fetch_error: ResourceFetchError, ) -> CmdExecutionError where - E: std::error::Error + From + Send + Sync + Unpin + 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained + 'f, ExecutionOutcome: Debug + Send + Sync + Unpin + 'static, - CmdBlockIterator: Iterator>, + CmdBlockIterator: + Iterator>, { let ResourceFetchError { resource_name_short: input_name_short, @@ -67,9 +67,11 @@ impl CmdExecutionErrorBuilder { .collect::>(); #[cfg(feature = "error_reporting")] - let (cmd_execution_src, input_span) = - cmd_execution_src::(&cmd_block_descs, &input_name_short) - .expect("Failed to write to `cmd_execution_src` buffer."); + let (cmd_execution_src, input_span) = cmd_execution_src::( + &cmd_block_descs, + &input_name_short, + ) + .expect("Failed to write to `cmd_execution_src` buffer."); #[cfg(feature = "error_reporting")] let full_span = SourceSpan::from((0, cmd_execution_src.len())); @@ -89,19 +91,19 @@ impl CmdExecutionErrorBuilder { } #[cfg(feature = "error_reporting")] -fn cmd_execution_src( +fn cmd_execution_src( cmd_block_descs: &[CmdBlockDesc], input_name_short: &str, ) -> Result<(String, Option), fmt::Error> where - E: std::error::Error + From + Send + Sync + Unpin + 'static, - PKeys: ParamsKeys + 'static, ExecutionOutcome: Debug + Send + Sync + Unpin + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { let mut cmd_execution_src = String::with_capacity(2048); - let cmd_execution_name = - tynm::type_name_opts::>(TypeParamsFmtOpts::Std); + let cmd_execution_name = tynm::type_name_opts::>( + TypeParamsFmtOpts::Std, + ); let execution_outcome_types_name = tynm::type_name_opts::(TypeParamsFmtOpts::All); diff --git a/crate/code_gen/Cargo.toml b/crate/code_gen/Cargo.toml index 47274755d..40a766963 100644 --- a/crate/code_gen/Cargo.toml +++ b/crate/code_gen/Cargo.toml @@ -18,6 +18,6 @@ doctest = true test = false [dependencies] -syn = { workspace = true, features = ["full"] } +syn = { workspace = true, features = ["extra-traits", "full"] } quote = { workspace = true } proc-macro2 = { workspace = true } diff --git a/crate/code_gen/src/cmd.rs b/crate/code_gen/src/cmd.rs index 2c1ebb65e..636ebfc43 100644 --- a/crate/code_gen/src/cmd.rs +++ b/crate/code_gen/src/cmd.rs @@ -4,15 +4,18 @@ use syn::parse_macro_input; use crate::cmd::scope_struct::ScopeStruct; pub use self::{ - flow_count::FlowCount, impl_build::impl_build, impl_common_fns::impl_common_fns, - impl_constructor::impl_constructor, impl_params_deserialize::impl_params_deserialize, - impl_params_merge::impl_params_merge, impl_with_flow::impl_with_flow, - impl_with_param::impl_with_param, impl_with_params_k::impl_with_params_k, - impl_with_profile::impl_with_profile, impl_with_profile_filter::impl_with_profile_filter, - params_scope::ParamsScope, profile_count::ProfileCount, scope::Scope, - struct_definition::struct_definition, + cmd_ctx_builder_type_builder::CmdCtxBuilderTypeBuilder, flow_count::FlowCount, + impl_build::impl_build, impl_common_fns::impl_common_fns, impl_constructor::impl_constructor, + impl_params_deserialize::impl_params_deserialize, impl_params_merge::impl_params_merge, + impl_with_flow::impl_with_flow, impl_with_param::impl_with_param, + impl_with_params_k::impl_with_params_k, impl_with_profile::impl_with_profile, + impl_with_profile_filter::impl_with_profile_filter, params_scope::ParamsScope, + profile_count::ProfileCount, scope::Scope, struct_definition::struct_definition, }; +pub(crate) use impl_header_builder::ImplHeaderBuilder; + +mod cmd_ctx_builder_type_builder; mod flow_count; mod impl_build; mod impl_common_fns; @@ -23,17 +26,17 @@ mod impl_with_param; mod impl_with_params_k; mod impl_with_profile; mod impl_with_profile_filter; -mod param_key_impl; mod params_scope; mod profile_count; mod scope; mod scope_struct; mod struct_definition; -mod type_parameters_impl; mod impl_constructor; +pub(crate) mod impl_header_builder; pub(crate) mod scope_builder_fields; pub(crate) mod type_params_selection; +pub(crate) mod with_params; /// Generates the command context builder implementation for the given scope. pub fn cmd_ctx_builder_impl(input: proc_macro::TokenStream) -> proc_macro::TokenStream { diff --git a/crate/code_gen/src/cmd/cmd_ctx_builder_type_builder.rs b/crate/code_gen/src/cmd/cmd_ctx_builder_type_builder.rs new file mode 100644 index 000000000..1ecf4f95a --- /dev/null +++ b/crate/code_gen/src/cmd/cmd_ctx_builder_type_builder.rs @@ -0,0 +1,234 @@ +use quote::quote; +use syn::{parse_quote, Ident, Path, TypePath}; + +/// Collects the tokens to build the `CmdCtxBuilder` return type. +/// +/// By default, this references the associated types from the passed in +/// `CmdCtxBuilderTypesT`. +#[derive(Clone, Debug)] +pub struct CmdCtxBuilderTypeBuilder { + /// Name of the scope builder struct. + scope_builder_name: Ident, + /// Path of the app error type. + /// + /// Defaults to `AppError`. + /// + /// You may want to set this to be one of: + /// + /// * `AppError` + app_error: TypePath, + /// Path of the output type. + /// + /// Defaults to `Output`. + /// + /// You may want to set this to be one of: + /// + /// * `O` + output: TypePath, + /// Path of the params keys type. + /// + /// By default this is not set, and the `ParamsKeysImpl` type is used as the + /// `ParamsKeys` type parameter, delegating the `*KeyMaybe` to the + /// `*_params_k` fields. + /// + /// You may want to set this to `ParamsKeysT`, so that `ParamsKeysT` can be + /// referenced by another trait bound in the `quote!` macro. + params_keys: Option, + /// Path of the workspace params key type. + /// + /// Defaults to `WorkspaceParamsKMaybe`. + /// + /// You may want to set this to be one of: + /// + /// * `peace_rt_model::params::KeyKnown` + /// * `peace_rt_model::params::KeyUnknown` + workspace_params_k_maybe: TypePath, + /// Path of the profile params key type. + /// + /// Defaults to `ProfileParamsKMaybe`. + /// + /// You may want to set this to be one of: + /// + /// * `peace_rt_model::params::KeyKnown` + /// * `peace_rt_model::params::KeyUnknown` + profile_params_k_maybe: TypePath, + /// Path of the flow params key type. + /// + /// Defaults to `FlowParamsKMaybe` + /// + /// You may want to set this to be one of: + /// + /// * `peace_rt_model::params::KeyKnown` + /// * `peace_rt_model::params::KeyUnknown` + flow_params_k_maybe: TypePath, + + /// Type state to track whether workspace params has been selected. + /// + /// Defaults to `WorkspaceParamsSelection` + /// + /// You may want to set this to be one of: + /// + /// * `crate::scopes::type_params::WorkspaceParamsNone` + /// * `crate::scopes::type_params::WorkspaceParamsSome` + workspace_params_selection: TypePath, + /// Type state to track whether profile params has been selected. + /// + /// Defaults to `ProfileParamsSelection` + /// + /// You may want to set this to be one of: + /// + /// * `crate::scopes::type_params::ProfileParamsNone` + /// * `crate::scopes::type_params::ProfileParamsSome` + /// * `crate::scopes::type_params::ProfileParamsSomeMulti` + profile_params_selection: TypePath, + /// Type state to track whether flow params has been selected. + /// + /// Defaults to `FlowParamsSelection` + /// + /// You may want to set this to be one of: + /// + /// * `crate::scopes::type_params::FlowParamsNone` + /// * `crate::scopes::type_params::FlowParamsSome` + /// * `crate::scopes::type_params::FlowParamsSomeMulti` + flow_params_selection: TypePath, + + /// Type state to track whether profile params has been selected. + /// + /// Defaults to `ProfileSelection` + /// + /// You may want to set this to be one of: + /// + /// * `crate::scopes::type_params::ProfileNotSelected` + /// * `crate::scopes::type_params::ProfileSelected` + /// * `crate::scopes::type_params::ProfileFromWorkspaceParam<'_, + /// WorkspaceParamsK>` + /// * `crate::scopes::type_params::ProfileFilterFn<'_>` + profile_selection: TypePath, + /// Type state to track whether flow params has been selected. + /// + /// Defaults to `FlowSelection` + /// + /// You may want to set this to be one of: + /// + /// * `crate::scopes::type_params::FlowParamsNone` + /// * `crate::scopes::type_params::FlowParamsSome` + /// * `crate::scopes::type_params::FlowParamsSomeMulti` + flow_selection: TypePath, +} + +impl CmdCtxBuilderTypeBuilder { + pub fn new(scope_builder_name: Ident) -> Self { + Self { + scope_builder_name, + output: parse_quote!(Output), + app_error: parse_quote!(AppError), + params_keys: None, + workspace_params_k_maybe: parse_quote!(WorkspaceParamsKMaybe), + profile_params_k_maybe: parse_quote!(ProfileParamsKMaybe), + flow_params_k_maybe: parse_quote!(FlowParamsKMaybe), + workspace_params_selection: parse_quote!(WorkspaceParamsSelection), + profile_params_selection: parse_quote!(ProfileParamsSelection), + flow_params_selection: parse_quote!(FlowParamsSelection), + profile_selection: parse_quote!(ProfileSelection), + flow_selection: parse_quote!(FlowSelection), + } + } + + pub fn with_output(mut self, output: TypePath) -> Self { + self.output = output; + self + } + + pub fn with_app_error(mut self, app_error: TypePath) -> Self { + self.app_error = app_error; + self + } + + pub fn with_workspace_params_k_maybe(mut self, workspace_params_k_maybe: TypePath) -> Self { + self.workspace_params_k_maybe = workspace_params_k_maybe; + self + } + + pub fn with_profile_params_k_maybe(mut self, profile_params_k_maybe: TypePath) -> Self { + self.profile_params_k_maybe = profile_params_k_maybe; + self + } + + pub fn with_flow_params_k_maybe(mut self, flow_params_k_maybe: TypePath) -> Self { + self.flow_params_k_maybe = flow_params_k_maybe; + self + } + + pub fn with_workspace_params_selection(mut self, workspace_params_selection: TypePath) -> Self { + self.workspace_params_selection = workspace_params_selection; + self + } + + pub fn with_profile_params_selection(mut self, profile_params_selection: TypePath) -> Self { + self.profile_params_selection = profile_params_selection; + self + } + + pub fn with_flow_params_selection(mut self, flow_params_selection: TypePath) -> Self { + self.flow_params_selection = flow_params_selection; + self + } + + pub fn with_profile_selection(mut self, profile_selection: TypePath) -> Self { + self.profile_selection = profile_selection; + self + } + + pub fn with_flow_selection(mut self, flow_selection: TypePath) -> Self { + self.flow_selection = flow_selection; + self + } + + pub fn build(self) -> Path { + let CmdCtxBuilderTypeBuilder { + app_error, + output, + params_keys, + scope_builder_name, + workspace_params_k_maybe, + profile_params_k_maybe, + flow_params_k_maybe, + workspace_params_selection, + profile_params_selection, + flow_params_selection, + profile_selection, + flow_selection, + } = self; + + let params_keys = params_keys.unwrap_or_else(|| { + parse_quote! { + peace_rt_model::params::ParamsKeysImpl< + #workspace_params_k_maybe, + #profile_params_k_maybe, + #flow_params_k_maybe, + > + } + }); + + let cmd_ctx_builder_types_collector = quote! { + crate::ctx::CmdCtxBuilderTypesCollector< + #app_error, + #output, + #params_keys, + #workspace_params_selection, + #profile_params_selection, + #flow_params_selection, + #profile_selection, + #flow_selection, + > + }; + let cmd_ctx_builder_types_collector = &cmd_ctx_builder_types_collector; + parse_quote! { + crate::ctx::CmdCtxBuilder< + 'ctx, + #cmd_ctx_builder_types_collector, + #scope_builder_name<#cmd_ctx_builder_types_collector>, + > + } + } +} diff --git a/crate/code_gen/src/cmd/impl_build.rs b/crate/code_gen/src/cmd/impl_build.rs index 15e0a8748..a3a1f82f5 100644 --- a/crate/code_gen/src/cmd/impl_build.rs +++ b/crate/code_gen/src/cmd/impl_build.rs @@ -1,14 +1,13 @@ use quote::quote; -use syn::{ - parse_quote, punctuated::Punctuated, token::Comma, FieldValue, GenericArgument, Path, Token, -}; +use syn::{parse_quote, punctuated::Punctuated, token::Comma, FieldValue, GenericArgument, Token}; use crate::cmd::{ type_params_selection::{ FlowParamsSelection, FlowSelection, ProfileParamsSelection, ProfileSelection, WorkspaceParamsSelection, }, - FlowCount, ParamsScope, ProfileCount, Scope, ScopeStruct, + CmdCtxBuilderTypeBuilder, FlowCount, ImplHeaderBuilder, ParamsScope, ProfileCount, Scope, + ScopeStruct, }; /// Generates the `CmdCtxBuilder::build` methods for each type param selection. @@ -27,7 +26,9 @@ pub fn impl_build(scope_struct: &ScopeStruct) -> proc_macro2::TokenStream { ProfileSelection::iter().fold( proc_macro2::TokenStream::new(), |tokens, profile_selection| { - match (scope_struct.scope().profile_count(), profile_selection) { + let scope = scope_struct.scope(); + let profile_count = scope.profile_count(); + match (profile_count, profile_selection) { // For `ProfileCount::None` it only makes sense to have `ProfileSelection::NotSelected` ( ProfileCount::None, @@ -54,6 +55,35 @@ pub fn impl_build(scope_struct: &ScopeStruct) -> proc_macro2::TokenStream { } FlowSelection::iter().fold(tokens, |tokens, flow_selection| { + match (scope, profile_selection, flow_selection) { + ( + Scope::NoProfileNoFlow, + ProfileSelection::NotSelected, + FlowSelection::NotSelected, + ) + | ( + Scope::SingleProfileNoFlow, + ProfileSelection::Selected | ProfileSelection::FromWorkspaceParam, + FlowSelection::NotSelected, + ) + | ( + Scope::SingleProfileSingleFlow, + ProfileSelection::Selected | ProfileSelection::FromWorkspaceParam, + FlowSelection::Selected, + ) + | ( + Scope::MultiProfileNoFlow, + ProfileSelection::NotSelected | ProfileSelection::FilterFunction, + FlowSelection::NotSelected, + ) + | ( + Scope::MultiProfileSingleFlow, + ProfileSelection::NotSelected | ProfileSelection::FilterFunction, + FlowSelection::Selected, + ) => {} + _ => return tokens, + } + WorkspaceParamsSelection::iter().fold( tokens, |tokens, workspace_params_selection| { @@ -119,31 +149,7 @@ fn impl_build_for( let scope = scope_struct.scope(); let scope_builder_name = &scope_struct.item_struct().ident; let scope_type_path = scope.type_path(); - let params_module: Path = parse_quote!(peace_rt_model::params); - - let scope_builder_type_params = { - let mut type_params = Punctuated::::new(); - match scope.profile_count() { - ProfileCount::None => {} - ProfileCount::One | ProfileCount::Multiple => { - type_params.push(profile_selection.type_param()); - } - } - if scope.flow_count() == FlowCount::One { - type_params.push(flow_selection.type_param()); - } - - type_params.push(parse_quote!(PKeys)); - type_params.push(workspace_params_selection.type_param()); - if scope.profile_params_supported() { - type_params.push(profile_params_selection.type_param()); - } - if scope.flow_params_supported() { - type_params.push(flow_params_selection.type_param()); - } - type_params - }; let scope_type_params = { let mut type_params = Punctuated::::new(); @@ -188,25 +194,126 @@ fn impl_build_for( flow_params_selection, ); - quote! { - impl<'ctx, 'key, E, O, PKeys> - crate::ctx::CmdCtxBuilder< + let workspace_params_selection_type_param = workspace_params_selection.type_param(); + let profile_params_selection_type_param = + profile_params_selection.type_param(scope.profile_count()); + let flow_params_selection_type_param = flow_params_selection.type_param(scope.profile_count()); + let profile_selection_type_param = profile_selection.type_param(); + let flow_selection_type_param = flow_selection.type_param(); + + let workspace_params_selection_k_maybe_type_param = + workspace_params_selection.k_maybe_type_param(); + let profile_params_selection_k_maybe_type_param = profile_params_selection.k_maybe_type_param(); + let flow_params_selection_k_maybe_type_param = flow_params_selection.k_maybe_type_param(); + + // ```rust,ignore + // crate::ctx::CmdCtxBuilder< + // 'ctx, + // crate::ctx::CmdCtxBuilderTypesCollector< + // Output, + // AppError, + // peace_rt_model::params::ParamsKeysImpl< + // WorkspaceParamsKMaybe = ??, + // ProfileParamsKMaybe = ??, + // FlowParamsKMaybe = ??, + // >, + // crate::scopes::type_params::WorkspaceParams??, + // crate::scopes::type_params::ProfileParamsSome< + // ::Key + // >, + // crate::scopes::type_params::FlowParamsSome< + // ::Key + // >, + // crate::scopes::type_params::ProfileFromWorkspaceParam< + // 'key, + // ::Key, + // >, + // crate::scopes::type_params::FlowNotSelected, + // >, + // > + // ``` + + let params_keys_impl = quote! { + peace_rt_model::params::ParamsKeysImpl< + #workspace_params_selection_k_maybe_type_param, + #profile_params_selection_k_maybe_type_param, + #flow_params_selection_k_maybe_type_param, + > + }; + + let builder_type = CmdCtxBuilderTypeBuilder::new(scope_builder_name.clone()) + .with_app_error(parse_quote!(AppError)) + .with_output(parse_quote!(Output)) + .with_workspace_params_k_maybe(workspace_params_selection_k_maybe_type_param) + .with_profile_params_k_maybe(profile_params_selection_k_maybe_type_param) + .with_flow_params_k_maybe(flow_params_selection_k_maybe_type_param) + .with_workspace_params_selection(parse_quote!(#workspace_params_selection_type_param)) + .with_profile_params_selection(parse_quote!(#profile_params_selection_type_param)) + .with_flow_params_selection(parse_quote!(#flow_params_selection_type_param)) + .with_profile_selection(parse_quote!(#profile_selection_type_param)) + .with_flow_selection(parse_quote!(#flow_selection_type_param)) + .build(); + + let (impl_header, impl_into_future_header) = { + let mut impl_header_builder = ImplHeaderBuilder::new(builder_type) + .with_lifetimes(parse_quote!('ctx, 'key)) + .with_workspace_params_k_maybe(None) + .with_profile_params_k_maybe(None) + .with_flow_params_k_maybe(None) + .with_workspace_params_selection(None) + .with_profile_params_selection(None) + .with_flow_params_selection(None) + .with_profile_selection(None) + .with_flow_selection(None); + + impl_header_builder = match workspace_params_selection { + WorkspaceParamsSelection::None => impl_header_builder, + WorkspaceParamsSelection::Some => { + impl_header_builder.with_workspace_params_k(parse_quote!(WorkspaceParamsK)) + } + }; + impl_header_builder = match profile_params_selection { + ProfileParamsSelection::None => impl_header_builder, + ProfileParamsSelection::Some => { + impl_header_builder.with_profile_params_k(parse_quote!(ProfileParamsK)) + } + }; + impl_header_builder = match flow_params_selection { + FlowParamsSelection::None => impl_header_builder, + FlowParamsSelection::Some => { + impl_header_builder.with_flow_params_k(parse_quote!(FlowParamsK)) + } + }; + + let impl_into_future_builder = impl_header_builder + .clone() + .with_lifetimes(parse_quote!('ctx, 'key: 'ctx)) + .with_trait_name(Some(parse_quote!(std::future::IntoFuture))); + ( + impl_header_builder.build(), + impl_into_future_builder.build(), + ) + }; + + let cmd_ctx_return_type = quote! { + crate::ctx::CmdCtx< + #scope_type_path< 'ctx, - O, - #scope_builder_name< - E, - // ProfileFromWorkspaceParam<'key, ::Key>, - // FlowSelected<'ctx, E>, - // PKeys, - // WorkspaceParamsSome<::Key>, - // ProfileParamsSome<::Key>, - // FlowParamsNone, - #scope_builder_type_params + crate::ctx::CmdCtxTypesCollector< + AppError, + Output, + #params_keys_impl, >, - > - where - E: std::error::Error + From + 'static, - PKeys: #params_module::ParamsKeys + 'static, + + // MultiProfileSingleFlow / SingleProfileSingleFlow + // peace_resources::resources::ts::SetUp + #scope_type_params + >, + > + }; + + quote! { + #impl_header { /// Builds the command context. /// @@ -214,25 +321,7 @@ fn impl_build_for( /// given parameters pub async fn build( mut self, - ) -> Result< - crate::ctx::CmdCtx< - #scope_type_path< - 'ctx, - E, - O, - #params_module::ParamsKeysImpl< - PKeys::WorkspaceParamsKMaybe, - PKeys::ProfileParamsKMaybe, - PKeys::FlowParamsKMaybe, - >, - - // MultiProfileSingleFlow / SingleProfileSingleFlow - // peace_resources::resources::ts::SetUp - #scope_type_params - >, - >, - E, - > + ) -> Result<#cmd_ctx_return_type, AppError> { use futures::stream::TryStreamExt; @@ -425,8 +514,6 @@ fn impl_build_for( // // // === SingleProfileSingleFlow === // // params_specs_provided, - // - // marker: std::marker::PhantomData, // }, // } = self; #scope_builder_deconstruct @@ -737,24 +824,13 @@ fn impl_build_for( } } - impl<'ctx, 'key: 'ctx, E, O, PKeys> std::future::IntoFuture - for crate::ctx::CmdCtxBuilder< - 'ctx, - O, - #scope_builder_name< - E, - // ProfileFromWorkspaceParam<'key, ::Key>, - // FlowSelected<'ctx, E>, - // PKeys, - // WorkspaceParamsSome<::Key>, - // ProfileParamsSome<::Key>, - // FlowParamsNone, - #scope_builder_type_params + #impl_into_future_header, + crate::ctx::CmdCtxTypesCollector: + crate::ctx::CmdCtxTypesConstrained< + AppError = AppError, + Output = Output, + ParamsKeys = #params_keys_impl >, - > - where - E: std::error::Error + From + 'static, - PKeys: #params_module::ParamsKeys + 'static, { /// Future that returns the `CmdCtx`. /// @@ -764,25 +840,7 @@ fn impl_build_for( type IntoFuture = std::pin::Pin< Box< dyn std::future::Future< - Output = Result< - crate::ctx::CmdCtx< - #scope_type_path< - 'ctx, - E, - O, - #params_module::ParamsKeysImpl< - PKeys::WorkspaceParamsKMaybe, - PKeys::ProfileParamsKMaybe, - PKeys::FlowParamsKMaybe, - >, - - // MultiProfileSingleFlow / SingleProfileSingleFlow - // peace_resources::resources::ts::SetUp - #scope_type_params - >, - >, - E, - > + Output = Result<#cmd_ctx_return_type, AppError> > + 'ctx, >, @@ -833,6 +891,9 @@ fn scope_builder_deconstruct( if scope.flow_count() == FlowCount::One { match flow_selection { + FlowSelection::NotSelected => scope_builder_fields.push(parse_quote! { + flow_selection: crate::scopes::type_params::FlowNotSelected + }), FlowSelection::Selected => scope_builder_fields.push(parse_quote! { flow_selection: crate::scopes::type_params::FlowSelected(flow) }), @@ -842,10 +903,10 @@ fn scope_builder_deconstruct( scope_builder_fields.push(parse_quote!(params_type_regs_builder)); scope_builder_fields.push(workspace_params_selection.deconstruct()); if scope.profile_params_supported() { - scope_builder_fields.push(profile_params_selection.deconstruct()); + scope_builder_fields.push(profile_params_selection.deconstruct(scope.profile_count())); } if scope.flow_params_supported() { - scope_builder_fields.push(flow_params_selection.deconstruct()); + scope_builder_fields.push(flow_params_selection.deconstruct(scope.profile_count())); } if scope.flow_count() == FlowCount::One { @@ -854,10 +915,6 @@ fn scope_builder_deconstruct( }); } - scope_builder_fields.push(parse_quote! { - marker: std::marker::PhantomData - }); - quote! { let crate::ctx::CmdCtxBuilder { output, @@ -874,7 +931,6 @@ fn scope_builder_deconstruct( // // === SingleProfileSingleFlow === // // params_specs_provided, - // marker: std::marker::PhantomData, #scope_builder_fields, }, } = self; @@ -892,11 +948,14 @@ fn workspace_params_load_save( ) { match workspace_params_selection { WorkspaceParamsSelection::None => { + let workspace_params_k_maybe_type_param = + workspace_params_selection.k_maybe_type_param(); + let workspace_params_deserialize = quote! { let workspace_params = peace_rt_model::params::WorkspaceParams::< < - PKeys::WorkspaceParamsKMaybe - as peace_rt_model::params::KeyMaybe + #workspace_params_k_maybe_type_param as + peace_rt_model::params::KeyMaybe >::Key >::new(); }; @@ -954,11 +1013,13 @@ fn profile_params_load_save( ), ProfileCount::One => match profile_params_selection { ProfileParamsSelection::None => { + let profile_params_k_maybe_type_param = + profile_params_selection.k_maybe_type_param(); let profile_params_deserialize = quote! { let profile_params = peace_rt_model::params::ProfileParams::< < - PKeys::ProfileParamsKMaybe - as peace_rt_model::params::KeyMaybe + #profile_params_k_maybe_type_param as + peace_rt_model::params::KeyMaybe >::Key >::new(); }; @@ -997,13 +1058,15 @@ fn profile_params_load_save( } }, ProfileCount::Multiple => { + let profile_params_k_maybe_type_param = profile_params_selection.k_maybe_type_param(); + let profile_params_deserialize = match profile_params_selection { ProfileParamsSelection::None => quote! { let profile_to_profile_params = std::collections::BTreeMap::< peace_core::Profile, peace_rt_model::params::ProfileParams< < - PKeys::ProfileParamsKMaybe as + #profile_params_k_maybe_type_param as peace_rt_model::params::KeyMaybe >::Key > @@ -1040,7 +1103,7 @@ fn profile_params_load_save( peace_core::Profile, peace_rt_model::params::ProfileParams< < - PKeys::ProfileParamsKMaybe as + #profile_params_k_maybe_type_param as peace_rt_model::params::KeyMaybe >::Key > @@ -1084,10 +1147,11 @@ fn flow_params_load_save( ), ProfileCount::One => match flow_params_selection { FlowParamsSelection::None => { + let flow_params_k_maybe_type_param = flow_params_selection.k_maybe_type_param(); let flow_params_deserialize = quote! { let flow_params = peace_rt_model::params::FlowParams::< < - PKeys::FlowParamsKMaybe as + #flow_params_k_maybe_type_param as peace_rt_model::params::KeyMaybe >::Key >::new(); @@ -1127,13 +1191,15 @@ fn flow_params_load_save( } }, ProfileCount::Multiple => { + let flow_params_k_maybe_type_param = flow_params_selection.k_maybe_type_param(); + let flow_params_deserialize = match flow_params_selection { FlowParamsSelection::None => quote! { let profile_to_flow_params = std::collections::BTreeMap::< peace_core::Profile, peace_rt_model::params::FlowParams< < - PKeys::FlowParamsKMaybe as + #flow_params_k_maybe_type_param as peace_rt_model::params::KeyMaybe >::Key > @@ -1169,7 +1235,7 @@ fn flow_params_load_save( peace_core::Profile, peace_rt_model::params::FlowParams< < - PKeys::FlowParamsKMaybe as + #flow_params_k_maybe_type_param as peace_rt_model::params::KeyMaybe >::Key > diff --git a/crate/code_gen/src/cmd/impl_common_fns.rs b/crate/code_gen/src/cmd/impl_common_fns.rs index 689e62ed4..ad58c50fb 100644 --- a/crate/code_gen/src/cmd/impl_common_fns.rs +++ b/crate/code_gen/src/cmd/impl_common_fns.rs @@ -1,43 +1,21 @@ use quote::quote; -use syn::{parse_quote, punctuated::Punctuated, GenericArgument, Path, Token}; -use crate::cmd::{type_parameters_impl, FlowCount, ScopeStruct}; +use crate::cmd::{CmdCtxBuilderTypeBuilder, FlowCount, ImplHeaderBuilder, ScopeStruct}; /// Generates functions for the command context builder that are not constrained /// by type parameters. pub fn impl_common_fns(scope_struct: &ScopeStruct) -> proc_macro2::TokenStream { let scope = scope_struct.scope(); let scope_builder_name = &scope_struct.item_struct().ident; - let params_module: Path = parse_quote!(peace_rt_model::params); - let scope_builder_type_params = { - let mut type_params = Punctuated::::new(); - - type_parameters_impl::profile_and_flow_selection_push(&mut type_params, scope); - type_parameters_impl::params_selection_push(&mut type_params, scope); - - type_params - }; + let return_type = CmdCtxBuilderTypeBuilder::new(scope_builder_name.clone()).build(); let mut common_fns = quote! { /// Sets the interrupt receiver and strategy so `CmdExecution`s can be interrupted. pub fn with_interruptibility( mut self, interruptibility: interruptible::Interruptibility<'static>, - ) -> crate::ctx::CmdCtxBuilder< - 'ctx, - O, - #scope_builder_name< - E, - // ProfileFromWorkspaceParam<'key, ::Key>, - // FlowSelected<'ctx, E>, - // PKeys, - // WorkspaceParamsSome<::Key>, - // ProfileParamsSome<::Key>, - // FlowParamsNone, - #scope_builder_type_params - >, - > { + ) -> #return_type { let crate::ctx::CmdCtxBuilder { output, interruptibility: _, @@ -66,7 +44,7 @@ pub fn impl_common_fns(scope_struct: &ScopeStruct) -> proc_macro2::TokenStream { ) -> Self where I: peace_cfg::Item, - E: From, + AppError: From, { self.scope_builder.params_specs_provided.insert(item_id, params_spec); self @@ -74,37 +52,11 @@ pub fn impl_common_fns(scope_struct: &ScopeStruct) -> proc_macro2::TokenStream { }); }; + let builder_type = CmdCtxBuilderTypeBuilder::new(scope_builder_name.clone()).build(); + let impl_header = ImplHeaderBuilder::new(builder_type).build(); + quote! { - impl< - 'ctx, - E, - O, - // ProfileSelection, - // FlowSelection, - // PKeys, - // WorkspaceParamsSelection, - // ProfileParamsSelection, - // FlowParamsSelection, - #scope_builder_type_params - > - crate::ctx::CmdCtxBuilder< - 'ctx, - O, - // SingleProfileSingleFlowBuilder< - #scope_builder_name< - E, - // ProfileSelection, - // FlowSelection, - // PKeys, - // WorkspaceParamsSelection, - // ProfileParamsSelection, - // FlowParamsSelection, - #scope_builder_type_params - >, - > - where - E: std::error::Error + From + 'static, - PKeys: #params_module::ParamsKeys + 'static, + #impl_header { #common_fns } diff --git a/crate/code_gen/src/cmd/impl_constructor.rs b/crate/code_gen/src/cmd/impl_constructor.rs index a2a17ab02..44f3b0012 100644 --- a/crate/code_gen/src/cmd/impl_constructor.rs +++ b/crate/code_gen/src/cmd/impl_constructor.rs @@ -1,8 +1,8 @@ use proc_macro2::{Ident, Span}; use quote::quote; -use syn::{parse_quote, punctuated::Punctuated, FieldValue, GenericArgument, Token}; +use syn::{parse_quote, punctuated::Punctuated, FieldValue, Token}; -use crate::cmd::{FlowCount, ScopeStruct}; +use crate::cmd::{CmdCtxBuilderTypeBuilder, FlowCount, ImplHeaderBuilder, ScopeStruct}; /// Generates the constructor for the command context builder for a given scope. pub fn impl_constructor(scope_struct: &ScopeStruct) -> proc_macro2::TokenStream { @@ -10,15 +10,6 @@ pub fn impl_constructor(scope_struct: &ScopeStruct) -> proc_macro2::TokenStream let scope_builder_name = &scope_struct.item_struct().ident; let constructor_method_name = Ident::new(scope.as_str(), Span::call_site()); - let scope_builder_type_params = { - let mut type_params = Punctuated::::new(); - - scope_builder_type_params::profile_and_flow_selection_push(&mut type_params, scope); - scope_builder_type_params::params_selection_push(&mut type_params, scope); - - type_params - }; - let scope_field_values = { let mut type_params = Punctuated::::new(); @@ -30,35 +21,59 @@ pub fn impl_constructor(scope_struct: &ScopeStruct) -> proc_macro2::TokenStream params_specs_provided: peace_params::ParamsSpecs::new() )); } - type_params.push(parse_quote!(marker: std::marker::PhantomData)); type_params }; + // crate::ctx::CmdCtxBuilder< + // 'ctx, + // crate::ctx::CmdCtxBuilderTypesCollector< + // AppError, + // Output, + // peace_rt_model::params::ParamsKeysImpl< + // peace_rt_model::params::KeyUnknown, + // peace_rt_model::params::KeyUnknown, + // peace_rt_model::params::KeyUnknown, + // >, + // crate::scopes::type_params::WorkspaceParamsNone, + // crate::scopes::type_params::ProfileParamsNone, + // crate::scopes::type_params::FlowParamsNone, + // crate::scopes::type_params::ProfileNotSelected, + // crate::scopes::type_params::FlowNotSelected, + // >, + // > + + let builder_type = CmdCtxBuilderTypeBuilder::new(scope_builder_name.clone()) + .with_workspace_params_k_maybe(parse_quote!(peace_rt_model::params::KeyUnknown)) + .with_profile_params_k_maybe(parse_quote!(peace_rt_model::params::KeyUnknown)) + .with_flow_params_k_maybe(parse_quote!(peace_rt_model::params::KeyUnknown)) + .with_workspace_params_selection(parse_quote!( + crate::scopes::type_params::WorkspaceParamsNone + )) + .with_profile_params_selection(parse_quote!(crate::scopes::type_params::ProfileParamsNone)) + .with_flow_params_selection(parse_quote!(crate::scopes::type_params::FlowParamsNone)) + .with_profile_selection(parse_quote!(crate::scopes::type_params::ProfileNotSelected)) + .with_flow_selection(parse_quote!(crate::scopes::type_params::FlowNotSelected)) + .build(); + let impl_header = ImplHeaderBuilder::new(builder_type) + .with_output_constraint_enabled(false) + .with_app_error_constraint_enabled(false) + .with_workspace_params_k_maybe(None) + .with_profile_params_k_maybe(None) + .with_flow_params_k_maybe(None) + .with_workspace_params_selection(None) + .with_profile_params_selection(None) + .with_flow_params_selection(None) + .with_profile_selection(None) + .with_flow_selection(None) + .build(); + quote! { - impl<'ctx, E, O> - crate::ctx::CmdCtxBuilder< - 'ctx, - O, - // SingleProfileSingleFlowBuilder< - #scope_builder_name< - E, - // ProfileNotSelected, - // FlowNotSelected, - // peace_rt_model::params::ParamsKeysImpl< - // peace_rt_model::params::KeyUnknown, - // peace_rt_model::params::KeyUnknown, - // peace_rt_model::params::KeyUnknown, - // >, - // WorkspaceParamsNone, - // ProfileParamsNone, - #scope_builder_type_params - >, - > + #impl_header { /// Returns a `CmdCtxBuilder` for a single profile and flow. pub fn #constructor_method_name( - output: &'ctx mut O, + output: &'ctx mut Output, workspace: &'ctx peace_rt_model::Workspace, ) -> Self { @@ -79,7 +94,6 @@ pub fn impl_constructor(scope_struct: &ScopeStruct) -> proc_macro2::TokenStream // // === SingleProfileSingleFlow === // // params_specs_provided: peace_params::ParamsSpecs::new() - // marker: std::marker::PhantomData, #scope_field_values }; @@ -94,58 +108,6 @@ pub fn impl_constructor(scope_struct: &ScopeStruct) -> proc_macro2::TokenStream } } -mod scope_builder_type_params { - use syn::{parse_quote, punctuated::Punctuated, GenericArgument, Token}; - - use crate::cmd::{FlowCount, ProfileCount, Scope}; - - /// Appends profile / flow ID selection type parameters if applicable to the - /// given scope. - pub fn profile_and_flow_selection_push( - type_params: &mut Punctuated, - scope: Scope, - ) { - match scope.profile_count() { - ProfileCount::None => {} - ProfileCount::One | ProfileCount::Multiple => { - type_params.push(parse_quote!(crate::scopes::type_params::ProfileNotSelected)); - } - } - if scope.flow_count() == FlowCount::One { - type_params.push(parse_quote!(crate::scopes::type_params::FlowNotSelected)); - } - } - - /// Appends workspace / profile / flow params selection type parameters if - /// applicable to the given scope. - pub fn params_selection_push( - type_params: &mut Punctuated, - scope: Scope, - ) { - // Always collect PKeys - type_params.push(parse_quote! { - peace_rt_model::params::ParamsKeysImpl< - peace_rt_model::params::KeyUnknown, - peace_rt_model::params::KeyUnknown, - peace_rt_model::params::KeyUnknown, - > - }); - - // Workspace params are supported by all scopes. - type_params.push(parse_quote!( - crate::scopes::type_params::WorkspaceParamsNone - )); - - if scope.profile_params_supported() { - type_params.push(parse_quote!(crate::scopes::type_params::ProfileParamsNone)); - } - - if scope.flow_params_supported() { - type_params.push(parse_quote!(crate::scopes::type_params::FlowParamsNone)); - } - } -} - mod scope_field_values { use syn::{parse_quote, punctuated::Punctuated, FieldValue, Token}; diff --git a/crate/code_gen/src/cmd/impl_header_builder.rs b/crate/code_gen/src/cmd/impl_header_builder.rs new file mode 100644 index 000000000..de2fbd16d --- /dev/null +++ b/crate/code_gen/src/cmd/impl_header_builder.rs @@ -0,0 +1,275 @@ +use quote::quote; +use syn::{ + parse_quote, punctuated::Punctuated, token::Comma, Ident, LifetimeParam, Path, TypePath, + WherePredicate, +}; + +#[derive(Clone, Debug)] +pub(crate) struct ImplHeaderBuilder { + /// Defaults to `'ctx`. + lifetimes: Punctuated, + /// Defaults to `None`. + trait_name: Option, + /// Defaults to `AppError`. + app_error: Option, + /// Whether the `AppError` type param should be constrained. + app_error_constraint_enabled: bool, + /// Defaults to `Output`. + output: Option, + /// Whether the `OutputWrite` type param should be constrained. + output_constraint_enabled: bool, + /// Defaults to `WorkspaceParamsKMaybe`. + workspace_params_k_maybe: Option, + /// Defaults to `None`, you may wish to set this to `WorkspaceParamsK`. + workspace_params_k: Option, + /// Defaults to `ProfileParamsKMaybe`. + profile_params_k_maybe: Option, + /// Defaults to `None`, you may wish to set this to `ProfileParamsK`. + profile_params_k: Option, + /// Defaults to `FlowParamsKMaybe`. + flow_params_k_maybe: Option, + /// Defaults to `None`, you may wish to set this to `FlowParamsK`. + flow_params_k: Option, + /// Defaults to `WorkspaceParamsSelection`. + workspace_params_selection: Option, + /// Defaults to `ProfileParamsSelection`. + profile_params_selection: Option, + /// Defaults to `FlowParamsSelection`. + flow_params_selection: Option, + /// Defaults to `ProfileSelection`. + profile_selection: Option, + /// Defaults to `FlowSelection`. + flow_selection: Option, + /// The `CtxCtxBuilder` with type parameters all filled in. + builder_type: Path, +} + +impl ImplHeaderBuilder { + pub fn new(builder_type: Path) -> Self { + Self { + lifetimes: parse_quote!('ctx), + trait_name: None, + app_error: Some(parse_quote!(AppError)), + app_error_constraint_enabled: true, + output: Some(parse_quote!(Output)), + output_constraint_enabled: true, + workspace_params_k_maybe: Some(parse_quote!(WorkspaceParamsKMaybe)), + workspace_params_k: None, + profile_params_k_maybe: Some(parse_quote!(ProfileParamsKMaybe)), + profile_params_k: None, + flow_params_k_maybe: Some(parse_quote!(FlowParamsKMaybe)), + flow_params_k: None, + workspace_params_selection: Some(parse_quote!(WorkspaceParamsSelection)), + profile_params_selection: Some(parse_quote!(ProfileParamsSelection)), + flow_params_selection: Some(parse_quote!(FlowParamsSelection)), + profile_selection: Some(parse_quote!(ProfileSelection)), + flow_selection: Some(parse_quote!(FlowSelection)), + builder_type, + } + } + + pub fn with_output_constraint_enabled(mut self, output_constraint_enabled: bool) -> Self { + self.output_constraint_enabled = output_constraint_enabled; + self + } + + pub fn with_app_error_constraint_enabled(mut self, app_error_constraint_enabled: bool) -> Self { + self.app_error_constraint_enabled = app_error_constraint_enabled; + self + } + + pub fn with_lifetimes(mut self, lifetimes: Punctuated) -> Self { + self.lifetimes = lifetimes; + self + } + + pub fn with_trait_name(mut self, trait_name: Option) -> Self { + self.trait_name = trait_name; + self + } + + pub fn with_workspace_params_k_maybe( + mut self, + workspace_params_k_maybe: Option, + ) -> Self { + self.workspace_params_k_maybe = workspace_params_k_maybe; + self + } + + pub fn with_workspace_params_k(mut self, workspace_params_k: Option) -> Self { + self.workspace_params_k = workspace_params_k; + self + } + + pub fn with_profile_params_k_maybe(mut self, profile_params_k_maybe: Option) -> Self { + self.profile_params_k_maybe = profile_params_k_maybe; + self + } + + pub fn with_profile_params_k(mut self, profile_params_k: Option) -> Self { + self.profile_params_k = profile_params_k; + self + } + + pub fn with_flow_params_k_maybe(mut self, flow_params_k_maybe: Option) -> Self { + self.flow_params_k_maybe = flow_params_k_maybe; + self + } + + pub fn with_flow_params_k(mut self, flow_params_k: Option) -> Self { + self.flow_params_k = flow_params_k; + self + } + + pub fn with_workspace_params_selection( + mut self, + workspace_params_selection: Option, + ) -> Self { + self.workspace_params_selection = workspace_params_selection; + self + } + + pub fn with_profile_params_selection( + mut self, + profile_params_selection: Option, + ) -> Self { + self.profile_params_selection = profile_params_selection; + self + } + + pub fn with_flow_params_selection(mut self, flow_params_selection: Option) -> Self { + self.flow_params_selection = flow_params_selection; + self + } + + pub fn with_profile_selection(mut self, profile_selection: Option) -> Self { + self.profile_selection = profile_selection; + self + } + + pub fn with_flow_selection(mut self, flow_selection: Option) -> Self { + self.flow_selection = flow_selection; + self + } + + pub fn build(self) -> proc_macro2::TokenStream { + let Self { + lifetimes, + trait_name, + app_error, + app_error_constraint_enabled, + output, + output_constraint_enabled, + workspace_params_k_maybe, + workspace_params_k, + profile_params_k_maybe, + profile_params_k, + flow_params_k_maybe, + flow_params_k, + workspace_params_selection, + profile_params_selection, + flow_params_selection, + profile_selection, + flow_selection, + builder_type, + } = self; + + let mut where_predicates = Punctuated::::new(); + if let Some(app_error) = app_error.as_ref() { + if app_error_constraint_enabled { + where_predicates.push(parse_quote!( + #app_error: peace_value_traits::AppError + From + )); + } + }; + if let Some((output, app_error)) = output.as_ref().zip(app_error.as_ref()) { + if output_constraint_enabled { + where_predicates.push(parse_quote!( + #output: peace_rt_model::output::OutputWrite<#app_error> + )); + } + }; + if let Some(workspace_params_k_maybe) = workspace_params_k_maybe.as_ref() { + where_predicates.push(parse_quote!( + #workspace_params_k_maybe: peace_rt_model::params::KeyMaybe + )); + }; + if let Some(workspace_params_k) = workspace_params_k.as_ref() { + where_predicates.push(parse_quote!( + #workspace_params_k: Clone + std::fmt::Debug + Eq + std::hash::Hash + serde::de::DeserializeOwned + serde::Serialize + Send + Sync + Unpin + 'static + )); + } + if let Some(profile_params_k_maybe) = profile_params_k_maybe.as_ref() { + where_predicates.push(parse_quote!( + #profile_params_k_maybe: peace_rt_model::params::KeyMaybe + )); + }; + if let Some(profile_params_k) = profile_params_k.as_ref() { + where_predicates.push(parse_quote!( + #profile_params_k: Clone + std::fmt::Debug + Eq + std::hash::Hash + serde::de::DeserializeOwned + serde::Serialize + Send + Sync + Unpin + 'static + )); + } + if let Some(flow_params_k_maybe) = flow_params_k_maybe.as_ref() { + where_predicates.push(parse_quote!( + #flow_params_k_maybe: peace_rt_model::params::KeyMaybe + )); + }; + if let Some(flow_params_k) = flow_params_k.as_ref() { + where_predicates.push(parse_quote!( + #flow_params_k: Clone + std::fmt::Debug + Eq + std::hash::Hash + serde::de::DeserializeOwned + serde::Serialize + Send + Sync + Unpin + 'static + )); + } + + let trait_name_for = trait_name.map(|trait_name| quote!(#trait_name for)); + let app_error = app_error.map(|app_error| quote!(#app_error,)); + let output = output.map(|output| quote!(#output,)); + let workspace_params_k_maybe = workspace_params_k_maybe + .map(|workspace_params_k_maybe| quote!(#workspace_params_k_maybe,)); + let workspace_params_k = + workspace_params_k.map(|workspace_params_k| quote!(#workspace_params_k,)); + let profile_params_k_maybe = + profile_params_k_maybe.map(|profile_params_k_maybe| quote!(#profile_params_k_maybe,)); + let profile_params_k = profile_params_k.map(|profile_params_k| quote!(#profile_params_k,)); + let flow_params_k_maybe = + flow_params_k_maybe.map(|flow_params_k_maybe| quote!(#flow_params_k_maybe,)); + let flow_params_k = flow_params_k.map(|flow_params_k| quote!(#flow_params_k,)); + let workspace_params_selection = workspace_params_selection + .map(|workspace_params_selection| quote!(#workspace_params_selection,)); + let profile_params_selection = profile_params_selection + .map(|profile_params_selection| quote!(#profile_params_selection,)); + let flow_params_selection = + flow_params_selection.map(|flow_params_selection| quote!(#flow_params_selection,)); + let profile_selection = + profile_selection.map(|profile_selection| quote!(#profile_selection,)); + let flow_selection = flow_selection.map(|flow_selection| quote!(#flow_selection,)); + + let where_ = if where_predicates.is_empty() { + None + } else { + Some(quote!(where)) + }; + + quote! { + impl< + #lifetimes, + #app_error + #output + #workspace_params_k_maybe + #workspace_params_k + #profile_params_k_maybe + #profile_params_k + #flow_params_k_maybe + #flow_params_k + #workspace_params_selection + #profile_params_selection + #flow_params_selection + #profile_selection + #flow_selection + > + #trait_name_for + #builder_type + #where_ + #where_predicates + } + } +} diff --git a/crate/code_gen/src/cmd/impl_params_deserialize.rs b/crate/code_gen/src/cmd/impl_params_deserialize.rs index a0b483019..09e17cfc9 100644 --- a/crate/code_gen/src/cmd/impl_params_deserialize.rs +++ b/crate/code_gen/src/cmd/impl_params_deserialize.rs @@ -1,12 +1,8 @@ use quote::quote; -use syn::{parse_quote, punctuated::Punctuated, GenericArgument, Path, Token}; +use syn::parse_quote; use crate::cmd::{ - type_parameters_impl, - type_params_selection::{ - FlowParamsSelection, ProfileParamsSelection, WorkspaceParamsSelection, - }, - ParamsScope, ScopeStruct, + with_params::cmd_ctx_builder_with_params_selected, ImplHeaderBuilder, ParamsScope, ScopeStruct, }; /// Generates the `CmdCtxBuilder::*_params_deserialize` methods for each params @@ -37,79 +33,8 @@ fn impl_params_deserialize_for( scope_struct: &ScopeStruct, params_scope: ParamsScope, ) -> proc_macro2::TokenStream { - let scope = scope_struct.scope(); let scope_builder_name = &scope_struct.item_struct().ident; - let params_module: Path = parse_quote!(peace_rt_model::params); - let (workspace_params_selection, profile_params_selection, flow_params_selection) = - match params_scope { - ParamsScope::Workspace => ( - WorkspaceParamsSelection::Some.type_param(), - parse_quote!(ProfileParamsSelection), - parse_quote!(FlowParamsSelection), - ), - ParamsScope::Profile => ( - parse_quote!(WorkspaceParamsSelection), - ProfileParamsSelection::Some.type_param(), - parse_quote!(FlowParamsSelection), - ), - ParamsScope::Flow => ( - parse_quote!(WorkspaceParamsSelection), - parse_quote!(ProfileParamsSelection), - FlowParamsSelection::Some.type_param(), - ), - }; - - let impl_type_params = { - let mut type_params = Punctuated::::new(); - type_parameters_impl::profile_and_flow_selection_push(&mut type_params, scope); - - type_params.push(parse_quote!(PKeys)); - - match params_scope { - ParamsScope::Workspace => { - if scope.profile_params_supported() { - type_params.push(profile_params_selection.clone()); - } - - if scope.flow_params_supported() { - type_params.push(flow_params_selection.clone()); - } - } - ParamsScope::Profile => { - type_params.push(workspace_params_selection.clone()); - - if scope.flow_params_supported() { - type_params.push(flow_params_selection.clone()); - } - } - ParamsScope::Flow => { - type_params.push(workspace_params_selection.clone()); - - if scope.profile_params_supported() { - type_params.push(profile_params_selection.clone()); - } - } - } - - type_params - }; - let scope_builder_type_params = { - let mut type_params = Punctuated::::new(); - type_parameters_impl::profile_and_flow_selection_push(&mut type_params, scope); - - type_params.push(parse_quote!(PKeys)); - - type_params.push(workspace_params_selection); - if scope.profile_params_supported() { - type_params.push(profile_params_selection); - } - if scope.flow_params_supported() { - type_params.push(flow_params_selection); - } - - type_params - }; let params_deserialize_method_name = params_scope.params_deserialize_method_name(); let params_map_type = params_scope.params_map_type(); let p_keys_key_maybe_key = params_scope.p_keys_key_maybe_key(); @@ -124,47 +49,63 @@ fn impl_params_deserialize_for( ) }; + let builder_type = + cmd_ctx_builder_with_params_selected(scope_builder_name, scope_struct, params_scope); + let impl_header = { + let impl_header_builder = ImplHeaderBuilder::new(builder_type); + match params_scope { + ParamsScope::Workspace => impl_header_builder + .with_workspace_params_k_maybe(None) + .with_workspace_params_k(parse_quote!(WorkspaceParamsK)) + .with_workspace_params_selection(None), + ParamsScope::Profile => impl_header_builder + .with_profile_params_k_maybe(None) + .with_profile_params_k(parse_quote!(ProfileParamsK)) + .with_profile_params_selection(None), + ParamsScope::Flow => impl_header_builder + .with_flow_params_k_maybe(None) + .with_flow_params_k(parse_quote!(FlowParamsK)) + .with_flow_params_selection(None), + } + .build() + }; + + let params_keys_impl_type_params = match params_scope { + ParamsScope::Workspace => quote!( + peace_rt_model::params::KeyKnown, + ProfileParamsKMaybe, + FlowParamsKMaybe, + ), + ParamsScope::Profile => quote!( + WorkspaceParamsKMaybe, + peace_rt_model::params::KeyKnown, + FlowParamsKMaybe, + ), + ParamsScope::Flow => quote!( + WorkspaceParamsKMaybe, + ProfileParamsKMaybe, + peace_rt_model::params::KeyKnown, + ), + }; + quote! { - impl< - 'ctx, - 'key, - E, - O, - // ProfileSelection, - // FlowSelection, - // PKeys, - // ProfileParamsSelection, - // FlowParamsSelection, - #impl_type_params - > - crate::ctx::CmdCtxBuilder< - 'ctx, - O, - #scope_builder_name< - E, - // ProfileSelection, - // FlowSelection, - // PKeys, - // WorkspaceParamsSome<::Key>, - // ProfileParamsSelection, - // FlowParamsSelection, - #scope_builder_type_params - >, - > - where - PKeys: #params_module::ParamsKeys + 'static, + #impl_header { #[doc = #doc_summary] // async fn workspace_params_deserialize async fn #params_deserialize_method_name( storage: &peace_rt_model::Storage, - params_type_regs_builder: &#params_module::ParamsTypeRegsBuilder, + params_type_regs_builder: &peace_rt_model::params::ParamsTypeRegsBuilder< + peace_rt_model::params::ParamsKeysImpl< + #params_keys_impl_type_params + >, + >, // workspace_params_file: &peace_resources::internal::WorkspaceParamsFile, #params_file_name: &peace_resources::internal::#params_file_type, // ) -> Result, peace_rt_model::Error> { - ) -> Result>, peace_rt_model::Error> { + ) -> Result>, peace_rt_model::Error> { let params_deserialized = peace_rt_model::WorkspaceInitializer::#params_deserialize_method_name::< - // ::Key, + // ::Key, #p_keys_key_maybe_key >( storage, diff --git a/crate/code_gen/src/cmd/impl_params_merge.rs b/crate/code_gen/src/cmd/impl_params_merge.rs index 345107e35..3cbbc22d2 100644 --- a/crate/code_gen/src/cmd/impl_params_merge.rs +++ b/crate/code_gen/src/cmd/impl_params_merge.rs @@ -1,12 +1,9 @@ use quote::quote; -use syn::{parse_quote, punctuated::Punctuated, GenericArgument, Path, Token}; +use syn::parse_quote; use crate::cmd::{ - type_parameters_impl, - type_params_selection::{ - FlowParamsSelection, ProfileParamsSelection, WorkspaceParamsSelection, - }, - ParamsScope, ScopeStruct, + with_params::cmd_ctx_builder_with_params_selected, ImplHeaderBuilder, ParamsScope, + ProfileCount, ScopeStruct, }; /// Generates the `CmdCtxBuilder::*_params_merge` methods for each params type. @@ -17,8 +14,10 @@ pub fn impl_params_merge(scope_struct: &ScopeStruct) -> proc_macro2::TokenStream ParamsScope::iter().fold( proc_macro2::TokenStream::new(), |mut impl_tokens, params_scope| { - if (!scope_struct.scope().profile_params_supported() - && params_scope == ParamsScope::Profile) + let scope = scope_struct.scope(); + if ((scope.profile_count() == ProfileCount::Multiple + && matches!(params_scope, ParamsScope::Profile | ParamsScope::Flow)) + || !scope.profile_params_supported() && params_scope == ParamsScope::Profile) || (!scope_struct.scope().flow_params_supported() && params_scope == ParamsScope::Flow) { @@ -37,79 +36,8 @@ fn impl_params_merge_for( scope_struct: &ScopeStruct, params_scope: ParamsScope, ) -> proc_macro2::TokenStream { - let scope = scope_struct.scope(); let scope_builder_name = &scope_struct.item_struct().ident; - let params_module: Path = parse_quote!(peace_rt_model::params); - let (workspace_params_selection, profile_params_selection, flow_params_selection) = - match params_scope { - ParamsScope::Workspace => ( - WorkspaceParamsSelection::Some.type_param(), - parse_quote!(ProfileParamsSelection), - parse_quote!(FlowParamsSelection), - ), - ParamsScope::Profile => ( - parse_quote!(WorkspaceParamsSelection), - ProfileParamsSelection::Some.type_param(), - parse_quote!(FlowParamsSelection), - ), - ParamsScope::Flow => ( - parse_quote!(WorkspaceParamsSelection), - parse_quote!(ProfileParamsSelection), - FlowParamsSelection::Some.type_param(), - ), - }; - - let impl_type_params = { - let mut type_params = Punctuated::::new(); - type_parameters_impl::profile_and_flow_selection_push(&mut type_params, scope); - - type_params.push(parse_quote!(PKeys)); - - match params_scope { - ParamsScope::Workspace => { - if scope.profile_params_supported() { - type_params.push(profile_params_selection.clone()); - } - - if scope.flow_params_supported() { - type_params.push(flow_params_selection.clone()); - } - } - ParamsScope::Profile => { - type_params.push(workspace_params_selection.clone()); - - if scope.flow_params_supported() { - type_params.push(flow_params_selection.clone()); - } - } - ParamsScope::Flow => { - type_params.push(workspace_params_selection.clone()); - - if scope.profile_params_supported() { - type_params.push(profile_params_selection.clone()); - } - } - } - - type_params - }; - let scope_builder_type_params = { - let mut type_params = Punctuated::::new(); - type_parameters_impl::profile_and_flow_selection_push(&mut type_params, scope); - - type_params.push(parse_quote!(PKeys)); - - type_params.push(workspace_params_selection); - if scope.profile_params_supported() { - type_params.push(profile_params_selection); - } - if scope.flow_params_supported() { - type_params.push(flow_params_selection); - } - - type_params - }; let params_merge_method_name = params_scope.params_merge_method_name(); let params_deserialize_method_name = params_scope.params_deserialize_method_name(); let p_keys_key_maybe_key = params_scope.p_keys_key_maybe_key(); @@ -125,35 +53,29 @@ fn impl_params_merge_for( ) }; + let builder_type = + cmd_ctx_builder_with_params_selected(scope_builder_name, scope_struct, params_scope); + let impl_header = { + let impl_header_builder = ImplHeaderBuilder::new(builder_type); + match params_scope { + ParamsScope::Workspace => impl_header_builder + .with_workspace_params_k_maybe(None) + .with_workspace_params_k(parse_quote!(WorkspaceParamsK)) + .with_workspace_params_selection(None), + ParamsScope::Profile => impl_header_builder + .with_profile_params_k_maybe(None) + .with_profile_params_k(parse_quote!(ProfileParamsK)) + .with_profile_params_selection(None), + ParamsScope::Flow => impl_header_builder + .with_flow_params_k_maybe(None) + .with_flow_params_k(parse_quote!(FlowParamsK)) + .with_flow_params_selection(None), + } + .build() + }; + quote! { - impl< - 'ctx, - 'key, - E, - O, - // ProfileSelection, - // FlowSelection, - // PKeys, - // ProfileParamsSelection, - // FlowParamsSelection, - #impl_type_params - > - crate::ctx::CmdCtxBuilder< - 'ctx, - O, - #scope_builder_name< - E, - // ProfileSelection, - // FlowSelection, - // PKeys, - // WorkspaceParamsSome<::Key>, - // ProfileParamsSelection, - // FlowParamsSelection, - #scope_builder_type_params - >, - > - where - PKeys: #params_module::ParamsKeys + 'static, + #impl_header { #[doc = #doc_summary] // async fn workspace_params_merge @@ -164,7 +86,7 @@ fn impl_params_merge_for( ) -> Result<(), peace_rt_model::Error> { let storage = self.workspace.storage(); let params_deserialized = peace_rt_model::WorkspaceInitializer::#params_deserialize_method_name::< - // ::Key, + // WorkspaceParamsK, #p_keys_key_maybe_key >( storage, diff --git a/crate/code_gen/src/cmd/impl_with_flow.rs b/crate/code_gen/src/cmd/impl_with_flow.rs index c28a40161..3eaf0056c 100644 --- a/crate/code_gen/src/cmd/impl_with_flow.rs +++ b/crate/code_gen/src/cmd/impl_with_flow.rs @@ -1,114 +1,83 @@ use quote::quote; -use syn::{ - parse_quote, punctuated::Punctuated, token::Comma, FieldValue, GenericArgument, Path, Token, -}; +use syn::{parse_quote, punctuated::Punctuated, token::Comma, FieldValue, Token}; -use crate::cmd::{type_parameters_impl, FlowCount, ProfileCount, Scope, ScopeStruct}; +use crate::cmd::{ + CmdCtxBuilderTypeBuilder, FlowCount, ImplHeaderBuilder, ProfileCount, Scope, ScopeStruct, +}; /// Generates the `with_flow` method for the command context builder. pub fn impl_with_flow(scope_struct: &ScopeStruct) -> proc_macro2::TokenStream { let scope = scope_struct.scope(); let scope_builder_name = &scope_struct.item_struct().ident; - let params_module: Path = parse_quote!(peace_rt_model::params); if scope.profile_count() == ProfileCount::None || scope.flow_count() == FlowCount::None { // `with_flow` is not supported. return proc_macro2::TokenStream::new(); }; - let impl_type_params = { - let mut type_params = Punctuated::::new(); - match scope.profile_count() { - ProfileCount::None => { - unreachable!("Flow is not specifiable when there are no profiles.") - } - ProfileCount::One | ProfileCount::Multiple => { - type_params.push(parse_quote!(ProfileSelection)); - } - } - type_parameters_impl::params_selection_push(&mut type_params, scope); - type_params - }; - let scope_builder_type_params_flow_not_selected = { - let mut type_params = Punctuated::::new(); - match scope.profile_count() { - ProfileCount::None => { - unreachable!("Flow is not specifiable when there are no profiles.") - } - ProfileCount::One | ProfileCount::Multiple => { - type_params.push(parse_quote!(ProfileSelection)); - } - } - type_params.push(parse_quote!(crate::scopes::type_params::FlowNotSelected)); - type_parameters_impl::params_selection_push(&mut type_params, scope); - type_params - }; - let scope_builder_type_params_flow_selected = { - let mut type_params = Punctuated::::new(); - match scope.profile_count() { - ProfileCount::None => { - unreachable!("Flow is not specifiable when there are no profiles.") - } - ProfileCount::One | ProfileCount::Multiple => { - type_params.push(parse_quote!(ProfileSelection)); - } - } - type_params.push(parse_quote!( - crate::scopes::type_params::FlowSelected<'ctx, E> - )); - type_parameters_impl::params_selection_push(&mut type_params, scope); - type_params - }; - let scope_builder_fields_flow_not_selected = scope_builder_fields_flow_not_selected(scope); let scope_builder_fields_flow_selected = scope_builder_fields_flow_selected(scope); + // ```rust,ignore + // crate::ctx::CmdCtxBuilder< + // 'ctx, + // crate::ctx::CmdCtxBuilderTypesCollector< + // Output, + // AppError, + // peace_rt_model::params::ParamsKeysImpl< + // WorkspaceParamsKMaybe, + // ProfileParamsKMaybe, + // FlowParamsKMaybe, + // >, + // WorkspaceParamsSelection, + // ProfileParamsSelection, + // FlowParamsSelection, + // ProfileSelection, + // crate::scopes::type_params::FlowNotSelected, + // >, + // > + // ``` + + let builder_type = CmdCtxBuilderTypeBuilder::new(scope_builder_name.clone()) + .with_flow_selection(parse_quote!(crate::scopes::type_params::FlowNotSelected)) + .build(); + let impl_header = ImplHeaderBuilder::new(builder_type) + .with_flow_selection(None) + .build(); + let return_type = CmdCtxBuilderTypeBuilder::new(scope_builder_name.clone()) + .with_flow_selection(parse_quote!( + crate::scopes::type_params::FlowSelected<'ctx, AppError> + )) + .build(); + quote! { - impl< - 'ctx, - E, - O, - // ProfileSelection, - // PKeys, - // WorkspaceParamsSelection, - // ProfileParamsSelection, - // FlowParamsSelection, - #impl_type_params - > - crate::ctx::CmdCtxBuilder< - 'ctx, - O, - #scope_builder_name< - E, - // ProfileSelection, - // FlowNotSelected, - // PKeys, - // WorkspaceParamsSelection, - // ProfileParamsSelection, - // FlowParamsSelection, - #scope_builder_type_params_flow_not_selected - >, - > - where - PKeys: #params_module::ParamsKeys + 'static, + #impl_header { pub fn with_flow( self, - flow: &'ctx peace_rt_model::Flow, - ) -> crate::ctx::CmdCtxBuilder< - 'ctx, - O, - #scope_builder_name< - E, - // ProfileSelection, - // FlowSelected<'ctx, E>, - // PKeys, - // WorkspaceParamsSelection, - // ProfileParamsSelection, - // FlowParamsSelection, - #scope_builder_type_params_flow_selected - >, - > { + flow: &'ctx peace_rt_model::Flow, + ) -> + // ```rust,ignore + // crate::ctx::CmdCtxBuilder< + // 'ctx, + // crate::ctx::CmdCtxBuilderTypesCollector< + // Output, + // AppError, + // peace_rt_model::params::ParamsKeysImpl< + // WorkspaceParamsKMaybe, + // ProfileParamsKMaybe, + // FlowParamsKMaybe, + // >, + // WorkspaceParamsSelection, + // ProfileParamsSelection, + // FlowParamsSelection, + // ProfileSelection, + // crate::scopes::type_params::FlowSelected<'ctx, AppError>, + // >, + // > + // ``` + #return_type + { let Self { output, interruptibility, @@ -122,7 +91,6 @@ pub fn impl_with_flow(scope_struct: &ScopeStruct) -> proc_macro2::TokenStream { // profile_params_selection, // flow_params_selection, // params_specs_provided, - // marker: std::marker::PhantomData, #scope_builder_fields_flow_not_selected }, } = self; @@ -135,7 +103,6 @@ pub fn impl_with_flow(scope_struct: &ScopeStruct) -> proc_macro2::TokenStream { // profile_params_selection, // flow_params_selection, // params_specs_provided, - // marker: std::marker::PhantomData, #scope_builder_fields_flow_selected }; @@ -167,7 +134,6 @@ fn scope_builder_fields_flow_not_selected(scope: Scope) -> Punctuated Punctuated::new(); - type_parameters_impl::profile_and_flow_selection_push(&mut type_params, scope); - type_params - }; - - let impl_type_params = { - let mut type_params = selection_type_params.clone(); - type_parameters_impl::params_selection_maybe_push( - &mut type_params, - scope, - params_scope, - false, - ); - type_params - }; - - let impl_scope_builder_type_params_none = { - let mut type_params = selection_type_params.clone(); - type_parameters_impl::params_selection_none_push(&mut type_params, scope, params_scope); - type_params - }; - - let impl_scope_builder_type_params_some = { - let mut type_params = selection_type_params; - type_parameters_impl::params_selection_some_push(&mut type_params, scope, params_scope); - type_params - }; - - let param_key_impl_unknown_predicates = param_key_impl::unknown_predicates(scope, params_scope); - let params_scope_str = params_scope.to_str(); let with_param_value_method_name = params_scope.with_param_value_method_name(); let params_map_type = params_scope.params_map_type(); @@ -113,42 +82,67 @@ fn impl_with_param_key_unknown( let doc_summary = format!("Adds a {params_scope_str} parameter."); let doc_param = format!("* `{param_name_str}`: The {params_scope_str} parameter to register."); - quote! { - impl< - 'ctx, - E, - O, - // ProfileSelection, - // FlowSelection, - // ProfileParamsSelection, - // ProfileParamsKMaybe, - // FlowParamsKMaybe, - - #impl_type_params - > - crate::ctx::CmdCtxBuilder< - 'ctx, - O, - #scope_builder_name< - E, - // ProfileSelection, - // FlowSelection, - - // peace_rt_model::params::ParamsKeysImpl< - // KeyUnknown, ProfileParamsKMaybe, FlowParamsKMaybe - // >, - - // WorkspaceParamsNone, - // ProfileParamsSelection, - // FlowParamsSelection, + // ```rust,ignore + // crate::ctx::CmdCtxBuilder< + // 'ctx, + // crate::ctx::CmdCtxBuilderTypesCollector< + // Output, + // AppError, + // peace_rt_model::params::ParamsKeysImpl< + // WorkspaceParamsKMaybe = peace_rt_model::params::KeyUnknown, + // ProfileParamsKMaybe, + // FlowParamsKMaybe, + // >, + // WorkspaceParamsSelection, + // ProfileParamsSelection, + // FlowParamsSelection, + // ProfileSelection, + // FlowSelection, + // >, + // > + // ``` + + let builder_type = { + let builder_type_builder = CmdCtxBuilderTypeBuilder::new(scope_builder_name.clone()); + match params_scope { + ParamsScope::Workspace => builder_type_builder + .with_workspace_params_k_maybe(parse_quote!(peace_rt_model::params::KeyUnknown)) + .with_workspace_params_selection(parse_quote!( + crate::scopes::type_params::WorkspaceParamsNone + )), + ParamsScope::Profile => builder_type_builder + .with_profile_params_k_maybe(parse_quote!(peace_rt_model::params::KeyUnknown)) + .with_profile_params_selection(parse_quote!( + crate::scopes::type_params::ProfileParamsNone + )), + ParamsScope::Flow => builder_type_builder + .with_flow_params_k_maybe(parse_quote!(peace_rt_model::params::KeyUnknown)) + .with_flow_params_selection(parse_quote!( + crate::scopes::type_params::FlowParamsNone + )), + } + .build() + }; + let impl_header = { + let impl_header_builder = ImplHeaderBuilder::new(builder_type); + match params_scope { + ParamsScope::Workspace => impl_header_builder + .with_workspace_params_k_maybe(None) + .with_workspace_params_selection(None), + ParamsScope::Profile => impl_header_builder + .with_profile_params_k_maybe(None) + .with_profile_params_selection(None), + ParamsScope::Flow => impl_header_builder + .with_flow_params_k_maybe(None) + .with_flow_params_selection(None), + } + .build() + }; + let return_type = + cmd_ctx_builder_with_params_selected(scope_builder_name, scope_struct, params_scope); - #impl_scope_builder_type_params_none - >, - > - where - // ProfileParamsKMaybe: KeyMaybe, - // FlowParamsKMaybe: KeyMaybe, - #param_key_impl_unknown_predicates + quote! { + #impl_header { #[doc = #doc_summary] /// @@ -166,25 +160,25 @@ fn impl_with_param_key_unknown( self, k: #params_k_type_param, #param_name: Option<#param_type_param>, - ) -> crate::ctx::CmdCtxBuilder< - 'ctx, - O, - #scope_builder_name< - E, - // ProfileSelection, - // FlowSelection, - - // peace_rt_model::params::ParamsKeysImpl< - // KeyKnown, ProfileParamsKMaybe, FlowParamsKMaybe - // >, - - // WorkspaceParamsSome<#params_k_type_param>, - // ProfileParamsSelection, - // FlowParamsSelection, - - #impl_scope_builder_type_params_some - >, - > + ) -> + // crate::ctx::CmdCtxBuilder< + // 'ctx, + // crate::ctx::CmdCtxBuilderTypesCollector< + // CmdCtxBuilderTypesT::Output, + // CmdCtxBuilderTypesT::AppError, + // peace_rt_model::params::ParamsKeysImpl< + // peace_rt_model::params::KeyKnown, + // ::ProfileParamsKMaybe, + // ::FlowParamsKMaybe, + // >, + // crate::scopes::type_params::WorkspaceParamsSome, + // CmdCtxBuilderTypesT::ProfileParamsSelection, + // CmdCtxBuilderTypesT::FlowParamsSelection, + // CmdCtxBuilderTypesT::ProfileSelection, + // CmdCtxBuilderTypesT::FlowSelection, + // >, + // > + #return_type where #params_k_type_param: Clone + std::fmt::Debug + Eq + std::hash::Hash + serde::de::DeserializeOwned + serde::Serialize + Send + Sync + Unpin + 'static, @@ -203,7 +197,6 @@ fn impl_with_param_key_unknown( // profile_params_selection, // flow_params_selection, // params_specs_provided, - // marker, #scope_builder_fields_params_none }, @@ -230,7 +223,6 @@ fn impl_with_param_key_unknown( // profile_params_selection, // flow_params_selection, // params_specs_provided, - // marker, #scope_builder_fields_params_some_new }; @@ -253,35 +245,6 @@ fn impl_with_param_key_known( let scope = scope_struct.scope(); let scope_builder_name = &scope_struct.item_struct().ident; - // ProfileSelection, FlowSelection - let selection_type_params = { - let mut type_params = Punctuated::::new(); - type_parameters_impl::profile_and_flow_selection_push(&mut type_params, scope); - type_params - }; - - let impl_type_params = { - let mut type_params = Punctuated::::new(); - - type_parameters_impl::profile_and_flow_selection_push(&mut type_params, scope); - type_parameters_impl::params_selection_maybe_push( - &mut type_params, - scope, - params_scope, - true, - ); - - type_params - }; - - let impl_scope_builder_type_params_some = { - let mut type_params = selection_type_params; - type_parameters_impl::params_selection_some_push(&mut type_params, scope, params_scope); - type_params - }; - - let param_key_impl_known_predicates = param_key_impl::known_predicates(scope, params_scope); - let params_scope_str = params_scope.to_str(); let with_param_value_method_name = params_scope.with_param_value_method_name(); let param_type_param = params_scope.param_type_param(); @@ -296,46 +259,50 @@ fn impl_with_param_key_known( let doc_summary = format!("Adds a {params_scope_str} parameter."); let doc_param = format!("* `{param_name_str}`: The {params_scope_str} parameter to register."); - quote! { - impl< - 'ctx, - E, - O, - // ProfileSelection, - // FlowSelection, - // ProfileParamsSelection, - // WorkspaceParamsK, - // ProfileParamsKMaybe, - // FlowParamsKMaybe, - - #impl_type_params - > - crate::ctx::CmdCtxBuilder< - 'ctx, - O, - #scope_builder_name< - E, - // ProfileSelection, - // FlowSelection, - - // peace_rt_model::params::ParamsKeysImpl< - // KeyKnown, ProfileParamsKMaybe, FlowParamsKMaybe - // >, - - // WorkspaceParamsSome, - // ProfileParamsSelection, - // FlowParamsSelection, - - #impl_scope_builder_type_params_some - >, - > - where - // WorkspaceParamsK: - // Clone + std::fmt::Debug + Eq + std::hash::Hash + serde::de::DeserializeOwned + serde::Serialize + Send + Sync + Unpin + 'static, - // ProfileParamsKMaybe: KeyMaybe, - // FlowParamsKMaybe: KeyMaybe, + // ```rust,ignore + // crate::ctx::CmdCtxBuilder< + // 'ctx, + // crate::ctx::CmdCtxBuilderTypesCollector< + // Output, + // AppError, + // peace_rt_model::params::ParamsKeysImpl< + // WorkspaceParamsKMaybe, + // ProfileParamsKMaybe, + // FlowParamsKMaybe, + // >, + // WorkspaceParamsSelection, + // ProfileParamsSelection, + // FlowParamsSelection, + // ProfileSelection, + // FlowSelection, + // >, + // > + // ``` + + let builder_type = + cmd_ctx_builder_with_params_selected(scope_builder_name, scope_struct, params_scope); + let return_type = builder_type.clone(); + let impl_header = { + let impl_header_builder = ImplHeaderBuilder::new(builder_type); + match params_scope { + ParamsScope::Workspace => impl_header_builder + .with_workspace_params_k_maybe(None) + .with_workspace_params_k(Some(parse_quote!(WorkspaceParamsK))) + .with_workspace_params_selection(None), + ParamsScope::Profile => impl_header_builder + .with_profile_params_k_maybe(None) + .with_profile_params_k(Some(parse_quote!(ProfileParamsK))) + .with_profile_params_selection(None), + ParamsScope::Flow => impl_header_builder + .with_flow_params_k_maybe(None) + .with_flow_params_k(Some(parse_quote!(FlowParamsK))) + .with_flow_params_selection(None), + } + .build() + }; - #param_key_impl_known_predicates + quote! { + #impl_header { #[doc = #doc_summary] /// @@ -353,25 +320,25 @@ fn impl_with_param_key_known( self, k: #params_k_type_param, #param_name: Option<#param_type_param>, - ) -> crate::ctx::CmdCtxBuilder< - 'ctx, - O, - #scope_builder_name< - E, - // ProfileSelection, - // FlowSelection, - - // peace_rt_model::params::ParamsKeysImpl< - // KeyKnown, ProfileParamsKMaybe, FlowParamsKMaybe - // >, - - // WorkspaceParamsSome, - // ProfileParamsSelection, - // FlowParamsSelection, - - #impl_scope_builder_type_params_some - >, - > + ) -> + // crate::ctx::CmdCtxBuilder< + // 'ctx, + // crate::ctx::CmdCtxBuilderTypesCollector< + // CmdCtxBuilderTypesT::Output, + // CmdCtxBuilderTypesT::AppError, + // peace_rt_model::params::ParamsKeysImpl< + // peace_rt_model::params::KeyKnown, + // ::ProfileParamsKMaybe, + // ::FlowParamsKMaybe, + // >, + // crate::scopes::type_params::WorkspaceParamsSome, + // CmdCtxBuilderTypesT::ProfileParamsSelection, + // CmdCtxBuilderTypesT::FlowParamsSelection, + // CmdCtxBuilderTypesT::ProfileSelection, + // CmdCtxBuilderTypesT::FlowSelection, + // >, + // > + #return_type where #param_type_param: Clone + std::fmt::Debug + serde::de::DeserializeOwned + serde::Serialize + Send + Sync + 'static, { @@ -388,7 +355,6 @@ fn impl_with_param_key_known( // profile_params_selection, // flow_params_selection, // params_specs_provided, - // marker, #scope_builder_fields_params_some }, @@ -411,7 +377,6 @@ fn impl_with_param_key_known( // profile_params_selection, // flow_params_selection, // params_specs_provided, - // marker, #scope_builder_fields_passthrough }; diff --git a/crate/code_gen/src/cmd/impl_with_params_k.rs b/crate/code_gen/src/cmd/impl_with_params_k.rs index 6c60b2e84..b27f83fcc 100644 --- a/crate/code_gen/src/cmd/impl_with_params_k.rs +++ b/crate/code_gen/src/cmd/impl_with_params_k.rs @@ -1,8 +1,9 @@ use quote::quote; -use syn::{parse_quote, punctuated::Punctuated, GenericArgument, Path, Token}; +use syn::parse_quote; use crate::cmd::{ - param_key_impl, scope_builder_fields, type_parameters_impl, ParamsScope, Scope, ScopeStruct, + scope_builder_fields, with_params::cmd_ctx_builder_with_params_selected, + CmdCtxBuilderTypeBuilder, ImplHeaderBuilder, ParamsScope, Scope, ScopeStruct, }; /// Generates the `with_workspace_params_k` / `with_profile_params_k` / @@ -64,44 +65,11 @@ fn impl_with_params_k_key_unknown( ) -> proc_macro2::TokenStream { let scope = scope_struct.scope(); let scope_builder_name = &scope_struct.item_struct().ident; - let params_module: Path = parse_quote!(peace_rt_model::params); - - // ProfileSelection, FlowSelection - let selection_type_params = { - let mut type_params = Punctuated::::new(); - type_parameters_impl::profile_and_flow_selection_push(&mut type_params, scope); - type_params - }; - - let impl_type_params = { - let mut type_params = selection_type_params.clone(); - type_parameters_impl::params_selection_maybe_push( - &mut type_params, - scope, - params_scope, - false, - ); - type_params - }; - - let impl_scope_builder_type_params_none = { - let mut type_params = selection_type_params.clone(); - type_parameters_impl::params_selection_none_push(&mut type_params, scope, params_scope); - type_params - }; - - let impl_scope_builder_type_params_some = { - let mut type_params = selection_type_params; - type_parameters_impl::params_selection_some_push(&mut type_params, scope, params_scope); - type_params - }; - - let param_key_impl_unknown_predicates = param_key_impl::unknown_predicates(scope, params_scope); let params_scope_str = params_scope.to_str(); let with_params_k_method_name = params_scope.params_k_method_name(); - let params_map_type = params_scope.params_map_type(); let params_k_method_name = params_scope.params_k_method_name(); + let params_map_type = params_scope.params_map_type(); let params_k_type_param = params_scope.params_k_type_param(); let scope_builder_fields_params_none = scope_builder_fields::params_none(scope, params_scope); let scope_builder_fields_params_some_new = @@ -109,42 +77,67 @@ fn impl_with_params_k_key_unknown( let doc_summary = format!("Registers a {params_scope_str} parameter type."); - quote! { - impl< - 'ctx, - E, - O, - // ProfileSelection, - // FlowSelection, - // ProfileParamsSelection, - // ProfileParamsKMaybe, - // FlowParamsKMaybe, - - #impl_type_params - > - crate::ctx::CmdCtxBuilder< - 'ctx, - O, - #scope_builder_name< - E, - // ProfileSelection, - // FlowSelection, - - // peace_rt_model::params::ParamsKeysImpl< - // KeyUnknown, ProfileParamsKMaybe, FlowParamsKMaybe - // >, - - // WorkspaceParamsNone, - // ProfileParamsSelection, - // FlowParamsSelection, + // ```rust,ignore + // crate::ctx::CmdCtxBuilder< + // 'ctx, + // crate::ctx::CmdCtxBuilderTypesCollector< + // Output, + // AppError, + // peace_rt_model::params::ParamsKeysImpl< + // WorkspaceParamsKMaybe = peace_rt_model::params::KeyUnknown, + // ProfileParamsKMaybe, + // FlowParamsKMaybe, + // >, + // WorkspaceParamsSelection, + // ProfileParamsSelection, + // FlowParamsSelection, + // ProfileSelection, + // FlowSelection, + // >, + // > + // ``` + + let builder_type = { + let builder_type_builder = CmdCtxBuilderTypeBuilder::new(scope_builder_name.clone()); + match params_scope { + ParamsScope::Workspace => builder_type_builder + .with_workspace_params_k_maybe(parse_quote!(peace_rt_model::params::KeyUnknown)) + .with_workspace_params_selection(parse_quote!( + crate::scopes::type_params::WorkspaceParamsNone + )), + ParamsScope::Profile => builder_type_builder + .with_profile_params_k_maybe(parse_quote!(peace_rt_model::params::KeyUnknown)) + .with_profile_params_selection(parse_quote!( + crate::scopes::type_params::ProfileParamsNone + )), + ParamsScope::Flow => builder_type_builder + .with_flow_params_k_maybe(parse_quote!(peace_rt_model::params::KeyUnknown)) + .with_flow_params_selection(parse_quote!( + crate::scopes::type_params::FlowParamsNone + )), + } + .build() + }; + let impl_header = { + let impl_header_builder = ImplHeaderBuilder::new(builder_type); + match params_scope { + ParamsScope::Workspace => impl_header_builder + .with_workspace_params_k_maybe(None) + .with_workspace_params_selection(None), + ParamsScope::Profile => impl_header_builder + .with_profile_params_k_maybe(None) + .with_profile_params_selection(None), + ParamsScope::Flow => impl_header_builder + .with_flow_params_k_maybe(None) + .with_flow_params_selection(None), + } + .build() + }; + let return_type = + cmd_ctx_builder_with_params_selected(scope_builder_name, scope_struct, params_scope); - #impl_scope_builder_type_params_none - >, - > - where - // ProfileParamsKMaybe: KeyMaybe, - // FlowParamsKMaybe: KeyMaybe, - #param_key_impl_unknown_predicates + quote! { + #impl_header { #[doc = #doc_summary] /// @@ -153,25 +146,25 @@ fn impl_with_params_k_key_unknown( // pub fn with_workspace_params_k pub fn #with_params_k_method_name<#params_k_type_param>( self, - ) -> crate::ctx::CmdCtxBuilder< - 'ctx, - O, - #scope_builder_name< - E, - // ProfileSelection, - // FlowSelection, - - // peace_rt_model::params::ParamsKeysImpl< - // KeyKnown, ProfileParamsKMaybe, FlowParamsKMaybe - // >, - - // WorkspaceParamsSome<#params_k_type_param>, - // ProfileParamsSelection, - // FlowParamsSelection, - - #impl_scope_builder_type_params_some - >, - > + ) -> + // crate::ctx::CmdCtxBuilder< + // 'ctx, + // crate::ctx::CmdCtxBuilderTypesCollector< + // CmdCtxBuilderTypesT::Output, + // CmdCtxBuilderTypesT::AppError, + // peace_rt_model::params::ParamsKeysImpl< + // peace_rt_model::params::KeyKnown, + // ProfileParamsKMaybe, + // FlowParamsKMaybe, + // >, + // crate::scopes::type_params::WorkspaceParamsSome, + // CmdCtxBuilderTypesT::ProfileParamsSelection, + // CmdCtxBuilderTypesT::FlowParamsSelection, + // CmdCtxBuilderTypesT::ProfileSelection, + // CmdCtxBuilderTypesT::FlowSelection, + // >, + // > + #return_type where #params_k_type_param: Clone + std::fmt::Debug + Eq + std::hash::Hash + serde::de::DeserializeOwned + serde::Serialize + Send + Sync + Unpin + 'static, @@ -188,7 +181,6 @@ fn impl_with_params_k_key_unknown( // workspace_params_selection: WorkspaceParamsNone, // profile_params_selection, // flow_params_selection, - // marker, #scope_builder_fields_params_none }, @@ -200,7 +192,7 @@ fn impl_with_params_k_key_unknown( params_type_regs_builder.#params_k_method_name::<#params_k_type_param>(); // let mut workspace_params = WorkspaceParams::::new(); - let params_map = #params_module::#params_map_type::<#params_k_type_param>::new(); + let params_map = peace_rt_model::params::#params_map_type::<#params_k_type_param>::new(); let scope_builder = #scope_builder_name { // profile_selection, @@ -209,7 +201,6 @@ fn impl_with_params_k_key_unknown( // workspace_params_selection: WorkspaceParamsSome(params_map), // profile_params_selection, // flow_params_selection, - // marker, #scope_builder_fields_params_some_new }; @@ -232,35 +223,6 @@ fn impl_with_param_key_known( let scope = scope_struct.scope(); let scope_builder_name = &scope_struct.item_struct().ident; - // ProfileSelection, FlowSelection - let selection_type_params = { - let mut type_params = Punctuated::::new(); - type_parameters_impl::profile_and_flow_selection_push(&mut type_params, scope); - type_params - }; - - let impl_type_params = { - let mut type_params = Punctuated::::new(); - - type_parameters_impl::profile_and_flow_selection_push(&mut type_params, scope); - type_parameters_impl::params_selection_maybe_push( - &mut type_params, - scope, - params_scope, - true, - ); - - type_params - }; - - let impl_scope_builder_type_params_some = { - let mut type_params = selection_type_params; - type_parameters_impl::params_selection_some_push(&mut type_params, scope, params_scope); - type_params - }; - - let param_key_impl_known_predicates = param_key_impl::known_predicates(scope, params_scope); - let params_scope_str = params_scope.to_str(); let with_param_method_name = params_scope.with_param_method_name(); let with_param_value_method_name = params_scope.with_param_value_method_name(); @@ -274,46 +236,29 @@ fn impl_with_param_key_known( let doc_body = format!("See the `{with_param_value_method_name}` method if you want to specify a value."); - quote! { - impl< - 'ctx, - E, - O, - // ProfileSelection, - // FlowSelection, - // ProfileParamsSelection, - // WorkspaceParamsK, - // ProfileParamsKMaybe, - // FlowParamsKMaybe, - - #impl_type_params - > - crate::ctx::CmdCtxBuilder< - 'ctx, - O, - #scope_builder_name< - E, - // ProfileSelection, - // FlowSelection, - - // peace_rt_model::params::ParamsKeysImpl< - // KeyKnown, ProfileParamsKMaybe, FlowParamsKMaybe - // >, - - // WorkspaceParamsSome, - // ProfileParamsSelection, - // FlowParamsSelection, - - #impl_scope_builder_type_params_some - >, - > - where - // WorkspaceParamsK: - // Clone + std::fmt::Debug + Eq + std::hash::Hash + serde::de::DeserializeOwned + serde::Serialize + Send + Sync + Unpin + 'static, - // ProfileParamsKMaybe: KeyMaybe, - // FlowParamsKMaybe: KeyMaybe, + let builder_type = + cmd_ctx_builder_with_params_selected(scope_builder_name, scope_struct, params_scope); + let impl_header = { + let impl_header_builder = ImplHeaderBuilder::new(builder_type); + match params_scope { + ParamsScope::Workspace => impl_header_builder + .with_workspace_params_k_maybe(None) + .with_workspace_params_k(Some(parse_quote!(WorkspaceParamsK))) + .with_workspace_params_selection(None), + ParamsScope::Profile => impl_header_builder + .with_profile_params_k_maybe(None) + .with_profile_params_k(Some(parse_quote!(ProfileParamsK))) + .with_profile_params_selection(None), + ParamsScope::Flow => impl_header_builder + .with_flow_params_k_maybe(None) + .with_flow_params_k(Some(parse_quote!(FlowParamsK))) + .with_flow_params_selection(None), + } + .build() + }; - #param_key_impl_known_predicates + quote! { + #impl_header { #[doc = #doc_summary] /// @@ -323,28 +268,14 @@ fn impl_with_param_key_known( /// /// * `k`: Key to store the parameter with. // pub fn with_workspace_params + /// + /// # Type Parameters + /// + /// * `#param_type_param` The type that is stored against `#params_k_type_param`. pub fn #with_param_method_name<#param_type_param>( self, k: #params_k_type_param, - ) -> crate::ctx::CmdCtxBuilder< - 'ctx, - O, - #scope_builder_name< - E, - // ProfileSelection, - // FlowSelection, - - // peace_rt_model::params::ParamsKeysImpl< - // KeyKnown, ProfileParamsKMaybe, FlowParamsKMaybe - // >, - - // WorkspaceParamsSome, - // ProfileParamsSelection, - // FlowParamsSelection, - - #impl_scope_builder_type_params_some - >, - > + ) -> Self where #param_type_param: Clone + std::fmt::Debug + serde::de::DeserializeOwned + serde::Serialize + Send + Sync + Unpin + 'static, { @@ -360,7 +291,6 @@ fn impl_with_param_key_known( // mut workspace_params_selection, // profile_params_selection, // flow_params_selection, - // marker, #scope_builder_fields_params_some }, @@ -377,7 +307,6 @@ fn impl_with_param_key_known( // workspace_params_selection, // profile_params_selection, // flow_params_selection, - // marker, #scope_builder_fields_passthrough }; diff --git a/crate/code_gen/src/cmd/impl_with_profile.rs b/crate/code_gen/src/cmd/impl_with_profile.rs index 43de23c31..99db11ba7 100644 --- a/crate/code_gen/src/cmd/impl_with_profile.rs +++ b/crate/code_gen/src/cmd/impl_with_profile.rs @@ -1,82 +1,80 @@ use quote::quote; -use syn::{ - parse_quote, punctuated::Punctuated, token::Comma, FieldValue, GenericArgument, Path, Token, -}; +use syn::{parse_quote, punctuated::Punctuated, token::Comma, FieldValue, Token}; use crate::cmd::{ - param_key_impl, type_parameters_impl, FlowCount, ParamsScope, ProfileCount, Scope, ScopeStruct, + CmdCtxBuilderTypeBuilder, FlowCount, ImplHeaderBuilder, ProfileCount, Scope, ScopeStruct, }; /// Generates the `with_profile` method for the command context builder. pub fn impl_with_profile(scope_struct: &ScopeStruct) -> proc_macro2::TokenStream { let scope = scope_struct.scope(); let scope_builder_name = &scope_struct.item_struct().ident; - let params_module: Path = parse_quote!(peace_rt_model::params); if scope_struct.scope().profile_count() != ProfileCount::One { // `with_profile` is not supported. return proc_macro2::TokenStream::new(); }; - let scope_params = { - let mut type_params = Punctuated::::new(); - if scope.flow_count() == FlowCount::One { - type_params.push(parse_quote!(FlowSelection)); - } - type_parameters_impl::params_selection_push(&mut type_params, scope); - type_params - }; - let scope_builder_fields_profile_not_selected = scope_builder_fields_profile_not_selected(scope); let scope_builder_fields_profile_selected = scope_builder_fields_profile_selected(scope); + // ```rust,ignore + // crate::ctx::CmdCtxBuilder< + // 'ctx, + // crate::ctx::CmdCtxBuilderTypesCollector< + // Output, + // AppError, + // peace_rt_model::params::ParamsKeysImpl< + // WorkspaceParamsKMaybe, + // ProfileParamsKMaybe, + // FlowParamsKMaybe, + // >, + // WorkspaceParamsSelection, + // ProfileParamsSelection, + // FlowParamsSelection, + // crate::scopes::type_params::ProfileNotSelected, + // FlowSelection, + // >, + // > + // ``` + + let builder_type = CmdCtxBuilderTypeBuilder::new(scope_builder_name.clone()) + .with_profile_selection(parse_quote!(crate::scopes::type_params::ProfileNotSelected)) + .build(); + let impl_header = ImplHeaderBuilder::new(builder_type) + .with_profile_selection(None) + .build(); + let return_type = CmdCtxBuilderTypeBuilder::new(scope_builder_name.clone()) + .with_profile_selection(parse_quote!(crate::scopes::type_params::ProfileSelected)) + .build(); + let mut tokens = quote! { - impl< - 'ctx, - E, - O, - // FlowSelection, - // PKeys, - // WorkspaceParamsSelection, - // ProfileParamsSelection, - // FlowParamsSelection, - #scope_params, - > - crate::ctx::CmdCtxBuilder< - 'ctx, - O, - #scope_builder_name< - E, - crate::scopes::type_params::ProfileNotSelected, - // FlowSelection, - // PKeys, - // WorkspaceParamsSelection, - // ProfileParamsSelection, - // FlowParamsSelection, - #scope_params - >, - > - where - PKeys: #params_module::ParamsKeys + 'static, + #impl_header { pub fn with_profile( self, profile: peace_core::Profile, - ) -> crate::ctx::CmdCtxBuilder< - 'ctx, - O, - #scope_builder_name< - E, - crate::scopes::type_params::ProfileSelected, - // FlowSelection, - // PKeys, - // WorkspaceParamsSelection, - // ProfileParamsSelection, - // FlowParamsSelection, - #scope_params - >, - > { + ) -> + // crate::ctx::CmdCtxBuilder< + // 'ctx, + // crate::ctx::CmdCtxBuilderTypesCollector< + // Output, + // AppError, + // peace_rt_model::params::ParamsKeysImpl< + // WorkspaceParamsKMaybe, + // ProfileParamsKMaybe, + // FlowParamsKMaybe, + // >, + // WorkspaceParamsSelection, + // ProfileParamsSelection, + // FlowParamsSelection, + // crate::scopes::type_params::ProfileSelected, + // FlowSelection, + // >, + // > + #return_type + { let Self { output, interruptibility, @@ -90,7 +88,6 @@ pub fn impl_with_profile(scope_struct: &ScopeStruct) -> proc_macro2::TokenStream // profile_params_selection, // flow_params_selection, // params_specs_provided, - // marker: std::marker::PhantomData, #scope_builder_fields_profile_not_selected }, } = self; @@ -103,7 +100,6 @@ pub fn impl_with_profile(scope_struct: &ScopeStruct) -> proc_macro2::TokenStream // profile_params_selection, // flow_params_selection, // params_specs_provided, - // marker: std::marker::PhantomData, #scope_builder_fields_profile_selected }; @@ -129,130 +125,84 @@ pub fn impl_with_profile_from_workspace_param( let scope = scope_struct.scope(); let scope_builder_name = &scope_struct.item_struct().ident; - let impl_params_with_workspace_params_k = { - let mut type_params = Punctuated::::new(); - if scope.flow_count() == FlowCount::One { - type_params.push(parse_quote!(FlowSelection)); - } - if scope.profile_params_supported() { - type_params.push(parse_quote!(ProfileParamsSelection)); - } - if scope.flow_params_supported() { - type_params.push(parse_quote!(FlowParamsSelection)); - } - - type_params.push(parse_quote!(WorkspaceParamsK)); - - if scope.profile_params_supported() { - type_params.push(parse_quote!(ProfileParamsKMaybe)); - } - if scope.flow_params_supported() { - type_params.push(parse_quote!(FlowParamsKMaybe)); - } - type_params - }; - - let scope_params_with_workspace_params_k = { - let mut type_params = Punctuated::::new(); - if scope.flow_count() == FlowCount::One { - type_params.push(parse_quote!(FlowSelection)); - } - - let impl_params_key_known_params = { - let mut type_params = Punctuated::::new(); - type_parameters_impl::params_key_known_push( - &mut type_params, - scope, - ParamsScope::Workspace, - ); - type_params - }; - type_params.push(parse_quote! { - peace_rt_model::params::ParamsKeysImpl< - // KeyKnown, ProfileParamsKMaybe, FlowParamsKMaybe - #impl_params_key_known_params - > - }); - - type_params.push(parse_quote! { - crate::scopes::type_params::WorkspaceParamsSome - }); - if scope.profile_params_supported() { - type_params.push(parse_quote!(ProfileParamsSelection)); - } - if scope.flow_params_supported() { - type_params.push(parse_quote!(FlowParamsSelection)); - } - type_params - }; - - let param_key_impl_known_predicates = - param_key_impl::known_predicates(scope, ParamsScope::Workspace); - let scope_builder_fields_profile_not_selected = scope_builder_fields_profile_not_selected(scope); let scope_builder_fields_profile_from_workspace = scope_builder_fields_profile_from_workspace(scope); - quote! { - impl< - 'ctx, - E, - O, - // FlowSelection, - // ProfileParamsSelection, - // FlowParamsSelection, - // WorkspaceParamsK, - // ProfileParamsKMaybe, - // FlowParamsKMaybe, - #impl_params_with_workspace_params_k - > - crate::ctx::CmdCtxBuilder< - 'ctx, - O, - #scope_builder_name< - E, - crate::scopes::type_params::ProfileNotSelected, - // FlowSelection, - - // peace_rt_model::params::ParamsKeysImpl< - // KeyKnown, ProfileParamsKMaybe, FlowParamsKMaybe - // >, + // ```rust,ignore + // crate::ctx::CmdCtxBuilder< + // 'ctx, + // crate::ctx::CmdCtxBuilderTypesCollector< + // Output, + // AppError, + // peace_rt_model::params::ParamsKeysImpl< + // WorkspaceParamsKMaybe, + // ProfileParamsKMaybe, + // FlowParamsKMaybe, + // >, + // crate::scopes::type_params::WorkspaceParamsSome, + // ProfileParamsSelection, + // FlowParamsSelection, + // crate::scopes::type_params::ProfileNotSelected, + // FlowSelection, + // >, + // > + // ``` + + let builder_type = CmdCtxBuilderTypeBuilder::new(scope_builder_name.clone()) + .with_workspace_params_k_maybe(parse_quote!( + peace_rt_model::params::KeyKnown + )) + .with_workspace_params_selection(parse_quote!( + crate::scopes::type_params::WorkspaceParamsSome + )) + .with_profile_selection(parse_quote!(crate::scopes::type_params::ProfileNotSelected)) + .build(); + let impl_header = ImplHeaderBuilder::new(builder_type) + .with_workspace_params_k_maybe(None) + .with_workspace_params_k(Some(parse_quote!(WorkspaceParamsK))) + .with_workspace_params_selection(None) + .with_profile_selection(None) + .build(); + let return_type = CmdCtxBuilderTypeBuilder::new(scope_builder_name.clone()) + .with_workspace_params_k_maybe(parse_quote!( + peace_rt_model::params::KeyKnown + )) + .with_workspace_params_selection(parse_quote!( + crate::scopes::type_params::WorkspaceParamsSome + )) + .with_profile_selection(parse_quote!( + crate::scopes::type_params::ProfileFromWorkspaceParam<'key, WorkspaceParamsK> + )) + .build(); - // WorkspaceParamsSome, - // ProfileParamsSelection, - // FlowParamsSelection, - #scope_params_with_workspace_params_k - >, - > - where - // WorkspaceParamsK: - // Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + 'static, - // ProfileParamsKMaybe: KeyMaybe, - // FlowParamsKMaybe: KeyMaybe, - #param_key_impl_known_predicates + quote! { + #impl_header { pub fn with_profile_from_workspace_param<'key>( self, workspace_param_k: &'key WorkspaceParamsK, - ) -> crate::ctx::CmdCtxBuilder< - 'ctx, - O, - #scope_builder_name< - E, - crate::scopes::type_params::ProfileFromWorkspaceParam<'key, WorkspaceParamsK>, - // FlowSelection, - - // peace_rt_model::params::ParamsKeysImpl< - // KeyKnown, ProfileParamsKMaybe, FlowParamsKMaybe - // >, - - // WorkspaceParamsSome, - // ProfileParamsSelection, - // FlowParamsSelection, - #scope_params_with_workspace_params_k - >, - > { + ) -> + // crate::ctx::CmdCtxBuilder< + // 'ctx, + // crate::ctx::CmdCtxBuilderTypesCollector< + // Output, + // AppError, + // peace_rt_model::params::ParamsKeysImpl< + // WorkspaceParamsKMaybe = peace_rt_model::params::KeyKnown, + // ProfileParamsKMaybe, + // FlowParamsKMaybe, + // >, + // crate::scopes::type_params::WorkspaceParamsSome, + // ProfileParamsSelection, + // FlowParamsSelection, + // crate::scopes::type_params::ProfileFromWorkspaceParam<'key, WorkspaceParamsK>, + // FlowSelection, + // >, + // > + #return_type + { let Self { output, interruptibility, @@ -266,7 +216,6 @@ pub fn impl_with_profile_from_workspace_param( // profile_params_selection, // flow_params_selection, // params_specs_provided, - // marker: std::marker::PhantomData, #scope_builder_fields_profile_not_selected }, } = self; @@ -279,7 +228,6 @@ pub fn impl_with_profile_from_workspace_param( // profile_params_selection, // flow_params_selection, // params_specs_provided, - // marker: std::marker::PhantomData, #scope_builder_fields_profile_from_workspace }; @@ -342,5 +290,4 @@ fn scope_builder_fields_remainder_push( if scope.flow_count() == FlowCount::One { field_values.push(parse_quote!(params_specs_provided)); } - field_values.push(parse_quote!(marker: std::marker::PhantomData)); } diff --git a/crate/code_gen/src/cmd/impl_with_profile_filter.rs b/crate/code_gen/src/cmd/impl_with_profile_filter.rs index 814c9c2e5..43330c05f 100644 --- a/crate/code_gen/src/cmd/impl_with_profile_filter.rs +++ b/crate/code_gen/src/cmd/impl_with_profile_filter.rs @@ -1,80 +1,81 @@ use quote::quote; -use syn::{ - parse_quote, punctuated::Punctuated, token::Comma, FieldValue, GenericArgument, Path, Token, -}; +use syn::{parse_quote, punctuated::Punctuated, token::Comma, FieldValue, Token}; -use crate::cmd::{type_parameters_impl, FlowCount, ProfileCount, Scope, ScopeStruct}; +use crate::cmd::{ + CmdCtxBuilderTypeBuilder, FlowCount, ImplHeaderBuilder, ProfileCount, Scope, ScopeStruct, +}; /// Generates the `with_profile_filter` method for the command context builder. pub fn impl_with_profile_filter(scope_struct: &ScopeStruct) -> proc_macro2::TokenStream { let scope = scope_struct.scope(); let scope_builder_name = &scope_struct.item_struct().ident; - let params_module: Path = parse_quote!(peace_rt_model::params); if scope_struct.scope().profile_count() != ProfileCount::Multiple { // `with_profile_filter` is not supported. return proc_macro2::TokenStream::new(); }; - let scope_params = { - let mut type_params = Punctuated::::new(); - if scope.flow_count() == FlowCount::One { - type_params.push(parse_quote!(FlowSelection)); - } - type_parameters_impl::params_selection_push(&mut type_params, scope); - type_params - }; - let scope_builder_fields_profile_not_selected = scope_builder_fields_profile_not_selected(scope); let scope_builder_fields_profile_filter_fn = scope_builder_fields_profile_filter_fn(scope); + // ```rust,ignore + // crate::ctx::CmdCtxBuilder< + // 'ctx, + // crate::ctx::CmdCtxBuilderTypesCollector< + // Output, + // AppError, + // peace_rt_model::params::ParamsKeysImpl< + // WorkspaceParamsKMaybe, + // ProfileParamsKMaybe, + // FlowParamsKMaybe, + // >, + // WorkspaceParamsSelection, + // ProfileParamsSelection, + // FlowParamsSelection, + // crate::scopes::type_params::ProfileNotSelected, + // FlowSelection, + // >, + // > + // ``` + + let builder_type = CmdCtxBuilderTypeBuilder::new(scope_builder_name.clone()) + .with_profile_selection(parse_quote!(crate::scopes::type_params::ProfileNotSelected)) + .build(); + let impl_header = ImplHeaderBuilder::new(builder_type) + .with_profile_selection(None) + .build(); + let return_type = CmdCtxBuilderTypeBuilder::new(scope_builder_name.clone()) + .with_profile_selection(parse_quote!( + crate::scopes::type_params::ProfileFilterFn<'ctx> + )) + .build(); + quote! { - impl< - 'ctx, - E, - O, - // FlowSelection, - // PKeys, - // WorkspaceParamsSelection, - // ProfileParamsSelection, - // FlowParamsSelection, - #scope_params, - > - crate::ctx::CmdCtxBuilder< - 'ctx, - O, - #scope_builder_name< - E, - crate::scopes::type_params::ProfileNotSelected, - // FlowSelection, - // PKeys, - // WorkspaceParamsSelection, - // ProfileParamsSelection, - // FlowParamsSelection, - #scope_params - >, - > - where - PKeys: #params_module::ParamsKeys + 'static, + #impl_header { pub fn with_profile_filter( self, profile_filter_fn: F, - ) -> crate::ctx::CmdCtxBuilder< - 'ctx, - O, - #scope_builder_name< - E, - crate::scopes::type_params::ProfileFilterFn<'ctx>, - // FlowSelection, - // PKeys, - // WorkspaceParamsSelection, - // ProfileParamsSelection, - // FlowParamsSelection, - #scope_params - >, - > + ) -> + // crate::ctx::CmdCtxBuilder< + // 'ctx, + // crate::ctx::CmdCtxBuilderTypesCollector< + // Output, + // AppError, + // peace_rt_model::params::ParamsKeysImpl< + // WorkspaceParamsKMaybe, + // ProfileParamsKMaybe, + // FlowParamsKMaybe, + // >, + // WorkspaceParamsSelection, + // ProfileParamsSelection, + // FlowParamsSelection, + // crate::scopes::type_params::ProfileFilterFn<'ctx>, + // FlowSelection, + // >, + // > + #return_type where F: (Fn(&peace_core::Profile) -> bool) + 'ctx { @@ -91,7 +92,6 @@ pub fn impl_with_profile_filter(scope_struct: &ScopeStruct) -> proc_macro2::Toke // profile_params_selection, // flow_params_selection, // params_specs_provided, - // marker: std::marker::PhantomData, #scope_builder_fields_profile_not_selected }, } = self; @@ -104,7 +104,6 @@ pub fn impl_with_profile_filter(scope_struct: &ScopeStruct) -> proc_macro2::Toke // profile_params_selection, // flow_params_selection, // params_specs_provided, - // marker: std::marker::PhantomData, #scope_builder_fields_profile_filter_fn }; @@ -157,5 +156,4 @@ fn scope_builder_fields_remainder_push( if scope.flow_count() == FlowCount::One { field_values.push(parse_quote!(params_specs_provided)); } - field_values.push(parse_quote!(marker: std::marker::PhantomData)); } diff --git a/crate/code_gen/src/cmd/param_key_impl.rs b/crate/code_gen/src/cmd/param_key_impl.rs deleted file mode 100644 index a0f78ee5f..000000000 --- a/crate/code_gen/src/cmd/param_key_impl.rs +++ /dev/null @@ -1,122 +0,0 @@ -use syn::{parse_quote, punctuated::Punctuated, token::Comma, Path, Token, WherePredicate}; - -use crate::cmd::{ParamsScope, Scope}; - -pub fn unknown_predicates( - scope: Scope, - params_scope: ParamsScope, -) -> Punctuated { - let mut predicates = Punctuated::::new(); - let params_module: Path = parse_quote!(peace_rt_model::params); - - match params_scope { - ParamsScope::Workspace => { - if scope.profile_params_supported() { - predicates.push(parse_quote! { - ProfileParamsKMaybe: #params_module::KeyMaybe - }); - } - - if scope.flow_params_supported() { - predicates.push(parse_quote! { - FlowParamsKMaybe: #params_module::KeyMaybe - }); - } - } - ParamsScope::Profile => { - // Workspace params are supported by all scopes. - predicates.push(parse_quote! { - WorkspaceParamsKMaybe: #params_module::KeyMaybe - }); - - if scope.flow_params_supported() { - predicates.push(parse_quote! { - FlowParamsKMaybe: #params_module::KeyMaybe - }); - } - } - ParamsScope::Flow => { - // Workspace params are supported by all scopes. - predicates.push(parse_quote! { - WorkspaceParamsKMaybe: #params_module::KeyMaybe - }); - - if scope.profile_params_supported() { - predicates.push(parse_quote! { - ProfileParamsKMaybe: #params_module::KeyMaybe - }); - } - } - } - - predicates -} - -pub fn known_predicates( - scope: Scope, - params_scope: ParamsScope, -) -> Punctuated { - let mut predicates = Punctuated::::new(); - let params_module: Path = parse_quote!(peace_rt_model::params); - - match params_scope { - ParamsScope::Workspace => { - predicates.push(parse_quote! { - WorkspaceParamsK: - Clone + std::fmt::Debug + Eq + std::hash::Hash + serde::de::DeserializeOwned + serde::Serialize + Send + Sync + Unpin + 'static - }); - - if scope.profile_params_supported() { - predicates.push(parse_quote! { - ProfileParamsKMaybe: #params_module::KeyMaybe - }); - } - - if scope.flow_params_supported() { - predicates.push(parse_quote! { - FlowParamsKMaybe: #params_module::KeyMaybe - }); - } - } - ParamsScope::Profile => { - // Workspace params are supported by all scopes. - predicates.push(parse_quote! { - WorkspaceParamsKMaybe: #params_module::KeyMaybe - }); - - if scope.profile_params_supported() { - predicates.push(parse_quote! { - ProfileParamsK: - Clone + std::fmt::Debug + Eq + std::hash::Hash + serde::de::DeserializeOwned + serde::Serialize + Send + Sync + Unpin + 'static - }); - } - - if scope.flow_params_supported() { - predicates.push(parse_quote! { - FlowParamsKMaybe: #params_module::KeyMaybe - }); - } - } - ParamsScope::Flow => { - // Workspace params are supported by all scopes. - predicates.push(parse_quote! { - WorkspaceParamsKMaybe: #params_module::KeyMaybe - }); - - if scope.profile_params_supported() { - predicates.push(parse_quote! { - ProfileParamsKMaybe: #params_module::KeyMaybe - }); - } - - if scope.flow_params_supported() { - predicates.push(parse_quote! { - FlowParamsK: - Clone + std::fmt::Debug + Eq + std::hash::Hash + serde::de::DeserializeOwned + serde::Serialize + Send + Sync + Unpin + 'static - }); - } - } - } - - predicates -} diff --git a/crate/code_gen/src/cmd/params_scope.rs b/crate/code_gen/src/cmd/params_scope.rs index 1116b6d53..bfc10288b 100644 --- a/crate/code_gen/src/cmd/params_scope.rs +++ b/crate/code_gen/src/cmd/params_scope.rs @@ -143,18 +143,12 @@ impl ParamsScope { } } - /// Returns the `::Key` associated type. + /// Returns the `*ParamsK` associated type. pub fn p_keys_key_maybe_key(self) -> TypePath { match self { - Self::Workspace => parse_quote!( - ::Key - ), - Self::Profile => { - parse_quote!(::Key) - } - Self::Flow => { - parse_quote!(::Key) - } + Self::Workspace => parse_quote!(WorkspaceParamsK), + Self::Profile => parse_quote!(ProfileParamsK), + Self::Flow => parse_quote!(FlowParamsK), } } diff --git a/crate/code_gen/src/cmd/scope_builder_fields.rs b/crate/code_gen/src/cmd/scope_builder_fields.rs index 96c8bbcc2..bd96a6b41 100644 --- a/crate/code_gen/src/cmd/scope_builder_fields.rs +++ b/crate/code_gen/src/cmd/scope_builder_fields.rs @@ -53,8 +53,6 @@ pub(crate) fn passthrough( field_values.push(parse_quote!(params_specs_provided)); } - field_values.push(parse_quote!(marker)); - field_values } @@ -115,8 +113,6 @@ pub(crate) fn params_none( field_values.push(parse_quote!(params_specs_provided)); } - field_values.push(parse_quote!(marker)); - field_values } @@ -168,8 +164,6 @@ pub(crate) fn params_some(scope: Scope, params_scope: ParamsScope) -> Punctuated field_values.push(parse_quote!(params_specs_provided)); } - field_values.push(parse_quote!(marker)); - field_values } @@ -206,10 +200,21 @@ pub(crate) fn params_some_new( ParamsScope::Profile => { field_values.push(parse_quote!(workspace_params_selection)); if scope.profile_params_supported() { - field_values.push(parse_quote! { - profile_params_selection: - crate::scopes::type_params::ProfileParamsSome(params_map) - }); + match scope.profile_count() { + ProfileCount::None => {} + ProfileCount::One => { + field_values.push(parse_quote! { + profile_params_selection: + crate::scopes::type_params::ProfileParamsSome(params_map) + }); + } + ProfileCount::Multiple => { + field_values.push(parse_quote! { + profile_params_selection: + crate::scopes::type_params::ProfileParamsSomeMulti(Default::default()) + }); + } + } } if scope.flow_params_supported() { field_values.push(parse_quote!(flow_params_selection)); @@ -221,10 +226,21 @@ pub(crate) fn params_some_new( field_values.push(parse_quote!(profile_params_selection)); } if scope.flow_params_supported() { - field_values.push(parse_quote! { - flow_params_selection: - crate::scopes::type_params::FlowParamsSome(params_map) - }); + match scope.profile_count() { + ProfileCount::None => {} + ProfileCount::One => { + field_values.push(parse_quote! { + flow_params_selection: + crate::scopes::type_params::FlowParamsSome(params_map) + }); + } + ProfileCount::Multiple => { + field_values.push(parse_quote! { + flow_params_selection: + crate::scopes::type_params::FlowParamsSomeMulti(Default::default()) + }); + } + } } } } @@ -233,7 +249,5 @@ pub(crate) fn params_some_new( field_values.push(parse_quote!(params_specs_provided)); } - field_values.push(parse_quote!(marker)); - field_values } diff --git a/crate/code_gen/src/cmd/scope_struct.rs b/crate/code_gen/src/cmd/scope_struct.rs index f8f87dabc..7be1b5832 100644 --- a/crate/code_gen/src/cmd/scope_struct.rs +++ b/crate/code_gen/src/cmd/scope_struct.rs @@ -47,12 +47,6 @@ impl Parse for ScopeStruct { return Err(input.error(format!("expected `{struct_ident}` to be a unit struct."))); } - if item_struct.generics.lt_token.is_some() { - return Err(input.error(format!( - "expected `{struct_ident}` to not have any generics." - ))); - } - let scope = if struct_ident == "MultiProfileNoFlowBuilder" { Scope::MultiProfileNoFlow } else if struct_ident == "MultiProfileSingleFlowBuilder" { diff --git a/crate/code_gen/src/cmd/struct_definition.rs b/crate/code_gen/src/cmd/struct_definition.rs index a34f19d5a..f4b2c53c6 100644 --- a/crate/code_gen/src/cmd/struct_definition.rs +++ b/crate/code_gen/src/cmd/struct_definition.rs @@ -1,7 +1,7 @@ use quote::ToTokens; -use syn::{parse_quote, punctuated::Punctuated, Fields, FieldsNamed, GenericArgument, Token}; +use syn::{parse_quote, Fields, FieldsNamed}; -use crate::cmd::{scope_struct::ScopeStruct, type_parameters_impl}; +use crate::cmd::scope_struct::ScopeStruct; /// Generates the struct definition for a scope struct builder. /// @@ -15,75 +15,41 @@ use crate::cmd::{scope_struct::ScopeStruct, type_parameters_impl}; /// following: /// /// ```rust,ignore -/// pub struct SingleProfileSingleFlowBuilder< -/// ProfileSelection, -/// FlowSelection, -/// WorkspaceParamsSelection, -/// ProfileParamsSelection, -/// FlowParamsSelection, -/// > { +/// pub struct SingleProfileSingleFlowBuilder +/// where +/// CmdCtxBuilderTypesT: CmdCtxBuilderTypes +/// { /// /// The profile this command operates on. -/// pub(crate) profile_selection: ProfileSelection, +/// pub(crate) profile_selection: CmdCtxBuilderTypesT::ProfileSelection, /// /// Identifier or name of the chosen process flow. -/// pub(crate) flow_selection: FlowSelection, +/// pub(crate) flow_selection: CmdCtxBuilderTypesT::FlowSelection, /// /// Type registries for [`WorkspaceParams`], [`ProfileParams`], and /// /// [`FlowParams`] deserialization. /// /// /// /// [`WorkspaceParams`]: peace_rt_model::params::WorkspaceParams /// /// [`ProfileParams`]: peace_rt_model::params::ProfileParams /// /// [`FlowParams`]: peace_rt_model::params::FlowParams -/// pub(crate) params_type_regs_builder: ParamsTypeRegsBuilder, +/// pub(crate) params_type_regs_builder: +/// peace_rt_model::params::ParamsTypeRegsBuilder, /// /// Workspace parameters. -/// pub(crate) workspace_params_selection: WorkspaceParamsSelection, +/// pub(crate) workspace_params_selection: CmdCtxBuilderTypesT::WorkspaceParamsSelection, /// /// Profile parameters. -/// pub(crate) profile_params_selection: ProfileParamsSelection, +/// pub(crate) profile_params_selection: CmdCtxBuilderTypesT::ProfileParamsSelection, /// /// Flow parameters. -/// pub(crate) flow_params_selection: FlowParamsSelection, +/// pub(crate) flow_params_selection: CmdCtxBuilderTypesT::FlowParamsSelection, /// /// Map of item ID to its parameters. `TypeMap` newtype. -/// pub(crate) item_params: peace_rt_model::ItemParams, -/// /// Marker. -/// pub(crate) marker: std::marker::PhantomData, +/// pub(crate) params_specs_provided: peace_params::ParamsSpecs, /// } /// ``` pub fn struct_definition(scope_struct: &mut ScopeStruct) -> proc_macro2::TokenStream { let scope = scope_struct.scope(); - scope_struct.item_struct_mut().generics = { - let mut type_params = Punctuated::::new(); - - type_params.push(parse_quote!(E)); - type_parameters_impl::profile_and_flow_selection_push(&mut type_params, scope); - type_parameters_impl::params_selection_push(&mut type_params, scope); - - // < - // E, - // - // // SingleProfile / MultiProfile - // ProfileSelection, - // // SingleFlow - // FlowSelection, - // - // PKeys, - // WorkspaceParamsSelection, - // // SingleProfile / MultiProfile - // ProfileParamsSelection, - // // SingleFlow - // FlowParamsSelection, - // > - parse_quote!(<#type_params>) - }; - scope_struct.item_struct_mut().generics.where_clause = Some(parse_quote! { - where - PKeys: peace_rt_model::params::ParamsKeys + 'static, - }); - scope_struct.item_struct_mut().fields = { let mut fields: FieldsNamed = parse_quote!({}); fields::profile_and_flow_selection_push(&mut fields, scope); fields::params_selection_push(&mut fields, scope); fields::params_specs_push(&mut fields, scope); - fields::marker_push(&mut fields); Fields::from(fields) }; @@ -104,7 +70,7 @@ mod fields { ProfileCount::One | ProfileCount::Multiple => { let fields: FieldsNamed = parse_quote!({ /// The profile this command operates on. - pub(crate) profile_selection: ProfileSelection + pub(crate) profile_selection: CmdCtxBuilderTypesT::ProfileSelection }); fields_named.named.extend(fields.named); } @@ -112,7 +78,7 @@ mod fields { if scope.flow_count() == FlowCount::One { let fields: FieldsNamed = parse_quote!({ /// Identifier or name of the chosen process flow. - pub(crate) flow_selection: FlowSelection + pub(crate) flow_selection: CmdCtxBuilderTypesT::FlowSelection }); fields_named.named.extend(fields.named); } @@ -130,21 +96,21 @@ mod fields { /// [`ProfileParams`]: peace_rt_model::params::ProfileParams /// [`FlowParams`]: peace_rt_model::params::FlowParams pub(crate) params_type_regs_builder: - peace_rt_model::params::ParamsTypeRegsBuilder + peace_rt_model::params::ParamsTypeRegsBuilder }); fields_named.named.extend(fields.named); // Workspace params are supported by all scopes. let fields: FieldsNamed = parse_quote!({ /// Workspace parameters. - pub(crate) workspace_params_selection: WorkspaceParamsSelection + pub(crate) workspace_params_selection: CmdCtxBuilderTypesT::WorkspaceParamsSelection }); fields_named.named.extend(fields.named); if scope.profile_params_supported() { let fields: FieldsNamed = parse_quote!({ /// Profile parameters. - pub(crate) profile_params_selection: ProfileParamsSelection + pub(crate) profile_params_selection: CmdCtxBuilderTypesT::ProfileParamsSelection }); fields_named.named.extend(fields.named); } @@ -152,7 +118,7 @@ mod fields { if scope.flow_params_supported() { let fields: FieldsNamed = parse_quote!({ /// Flow parameters. - pub(crate) flow_params_selection: FlowParamsSelection + pub(crate) flow_params_selection: CmdCtxBuilderTypesT::FlowParamsSelection }); fields_named.named.extend(fields.named); } @@ -162,20 +128,11 @@ mod fields { /// fields. pub fn params_specs_push(fields_named: &mut FieldsNamed, scope: Scope) { if scope.flow_count() == FlowCount::One { - let fields_marker: FieldsNamed = parse_quote!({ + let fields_params_specs: FieldsNamed = parse_quote!({ /// Map of item ID to its parameters. `TypeMap` newtype. pub(crate) params_specs_provided: peace_params::ParamsSpecs }); - fields_named.named.extend(fields_marker.named); + fields_named.named.extend(fields_params_specs.named); } } - - /// Appends a `marker: PhantomData` field to the given fields. - pub fn marker_push(fields_named: &mut FieldsNamed) { - let fields_marker: FieldsNamed = parse_quote!({ - /// Marker. - pub(crate) marker: std::marker::PhantomData - }); - fields_named.named.extend(fields_marker.named); - } } diff --git a/crate/code_gen/src/cmd/type_parameters_impl.rs b/crate/code_gen/src/cmd/type_parameters_impl.rs deleted file mode 100644 index c2ea4464d..000000000 --- a/crate/code_gen/src/cmd/type_parameters_impl.rs +++ /dev/null @@ -1,375 +0,0 @@ -use syn::{parse_quote, punctuated::Punctuated, GenericArgument, Token}; - -use crate::cmd::{FlowCount, ProfileCount, Scope}; - -use super::ParamsScope; - -/// Appends profile / flow ID selection type parameters if applicable to the -/// given scope. -pub fn profile_and_flow_selection_push( - type_params: &mut Punctuated, - scope: Scope, -) { - match scope.profile_count() { - ProfileCount::None => {} - ProfileCount::One | ProfileCount::Multiple => { - type_params.push(parse_quote!(ProfileSelection)); - } - } - if scope.flow_count() == FlowCount::One { - type_params.push(parse_quote!(FlowSelection)); - } -} - -/// Appends workspace / profile / flow params selection type parameters if -/// applicable to the given scope. -pub fn params_selection_push( - type_params: &mut Punctuated, - scope: Scope, -) { - // Always collect PKeys. - type_params.push(parse_quote!(PKeys)); - - // Workspace params are supported by all scopes. - type_params.push(parse_quote!(WorkspaceParamsSelection)); - - if scope.profile_params_supported() { - type_params.push(parse_quote!(ProfileParamsSelection)); - } - - if scope.flow_params_supported() { - type_params.push(parse_quote!(FlowParamsSelection)); - } -} - -/// Appends the type parameters for params selection for the `impl`. -/// -/// For the `Workspace` params scope, the following are generated, if -/// applicable to the current command context builder scope: -/// -/// * `ProfileParamsSelection`: To retain any existing profile params selection. -/// * `FlowParamsSelection`: To retain any existing flow params selection. -/// * `ProfileParamsKMaybe`: To retain the key for existing profile params -/// selection. -/// * `FlowParamsKMaybe`: To retain the key for existing flow params selection. -pub fn params_selection_maybe_push( - type_params: &mut Punctuated, - scope: Scope, - params_scope: ParamsScope, - params_key_known: bool, -) { - match params_scope { - ParamsScope::Workspace => { - if params_key_known { - type_params.push(parse_quote!(WorkspaceParamsK)); - } - - if scope.profile_params_supported() { - type_params.push(parse_quote!(ProfileParamsSelection)); - type_params.push(parse_quote!(ProfileParamsKMaybe)); - } - - if scope.flow_params_supported() { - type_params.push(parse_quote!(FlowParamsSelection)); - type_params.push(parse_quote!(FlowParamsKMaybe)); - } - } - ParamsScope::Profile => { - // Workspace params are supported by all scopes. - type_params.push(parse_quote!(WorkspaceParamsSelection)); - type_params.push(parse_quote!(WorkspaceParamsKMaybe)); - - if scope.profile_params_supported() && params_key_known { - type_params.push(parse_quote!(ProfileParamsK)); - } - - if scope.flow_params_supported() { - type_params.push(parse_quote!(FlowParamsSelection)); - type_params.push(parse_quote!(FlowParamsKMaybe)); - } - } - ParamsScope::Flow => { - // Workspace params are supported by all scopes. - type_params.push(parse_quote!(WorkspaceParamsSelection)); - type_params.push(parse_quote!(WorkspaceParamsKMaybe)); - - if scope.profile_params_supported() { - type_params.push(parse_quote!(ProfileParamsSelection)); - type_params.push(parse_quote!(ProfileParamsKMaybe)); - } - - if scope.flow_params_supported() && params_key_known { - type_params.push(parse_quote!(FlowParamsK)); - } - } - } -} - -/// Appends the type parameters for params selection for the `ScopeBuilder` in -/// the `impl`. -/// -/// For the `Workspace` params scope, the following are generated, if -/// applicable to the current command context builder scope: -/// -/// * `WorkspaceParamsNone`: Indicates that the incoming that params selection -/// is none. -/// * `ProfileParamsSelection`: To retain any existing profile params selection. -/// * `FlowParamsSelection`: To retain any existing flow params selection. -pub fn params_selection_none_push( - type_params: &mut Punctuated, - scope: Scope, - params_scope: ParamsScope, -) { - let impl_params_key_unknown_params = { - let mut type_params = Punctuated::::new(); - params_key_unknown_push(&mut type_params, scope, params_scope); - type_params - }; - - type_params.push(parse_quote! { - peace_rt_model::params::ParamsKeysImpl< - // KeyUnknown, ProfileParamsKMaybe, FlowParamsKMaybe - #impl_params_key_unknown_params - > - }); - - match params_scope { - ParamsScope::Workspace => { - type_params.push(parse_quote!( - crate::scopes::type_params::WorkspaceParamsNone - )); - - if scope.profile_params_supported() { - type_params.push(parse_quote!(ProfileParamsSelection)); - } - - if scope.flow_params_supported() { - type_params.push(parse_quote!(FlowParamsSelection)); - } - } - ParamsScope::Profile => { - // Workspace params are supported by all scopes. - type_params.push(parse_quote!(WorkspaceParamsSelection)); - - if scope.profile_params_supported() { - type_params.push(parse_quote!(crate::scopes::type_params::ProfileParamsNone)); - } - - if scope.flow_params_supported() { - type_params.push(parse_quote!(FlowParamsSelection)); - } - } - ParamsScope::Flow => { - // Workspace params are supported by all scopes. - type_params.push(parse_quote!(WorkspaceParamsSelection)); - - if scope.profile_params_supported() { - type_params.push(parse_quote!(ProfileParamsSelection)); - } - - if scope.flow_params_supported() { - type_params.push(parse_quote!(crate::scopes::type_params::FlowParamsNone)); - } - } - } -} - -/// Appends the type parameters for params selection for the `ScopeBuilder` in -/// the `impl`. -/// -/// For the `Workspace` params scope, the following are generated, if -/// applicable to the current command context builder scope: -/// -/// * `WorkspaceParamsSome`: Indicates that the incoming -/// params selection is none. -/// * `ProfileParamsSelection`: To retain any existing profile params selection. -/// * `FlowParamsSelection`: To retain any existing flow params selection. -pub fn params_selection_some_push( - type_params: &mut Punctuated, - scope: Scope, - params_scope: ParamsScope, -) { - let impl_params_key_known_params = { - let mut type_params = Punctuated::::new(); - params_key_known_push(&mut type_params, scope, params_scope); - type_params - }; - - type_params.push(parse_quote! { - peace_rt_model::params::ParamsKeysImpl< - // KeyKnown, ProfileParamsKMaybe, FlowParamsKMaybe - #impl_params_key_known_params - > - }); - - match params_scope { - ParamsScope::Workspace => { - type_params.push(parse_quote!( - crate::scopes::type_params::WorkspaceParamsSome - )); - - if scope.profile_params_supported() { - type_params.push(parse_quote!(ProfileParamsSelection)); - } - - if scope.flow_params_supported() { - type_params.push(parse_quote!(FlowParamsSelection)); - } - } - ParamsScope::Profile => { - // Workspace params are supported by all scopes. - type_params.push(parse_quote!(WorkspaceParamsSelection)); - - if scope.profile_params_supported() { - type_params.push(parse_quote!( - crate::scopes::type_params::ProfileParamsSome - )); - } - - if scope.flow_params_supported() { - type_params.push(parse_quote!(FlowParamsSelection)); - } - } - ParamsScope::Flow => { - // Workspace params are supported by all scopes. - type_params.push(parse_quote!(WorkspaceParamsSelection)); - - if scope.profile_params_supported() { - type_params.push(parse_quote!(ProfileParamsSelection)); - } - - if scope.flow_params_supported() { - type_params.push(parse_quote!( - crate::scopes::type_params::FlowParamsSome - )); - } - } - } -} - -/// Appends the type parameters for params selection for the `ScopeBuilder` in -/// the `impl`. -/// -/// For the `Workspace` params scope, the following are generated, if -/// applicable to the current command context builder scope: -/// -/// * `KeyUnknown`: Indicates that the incoming params key is known. -/// * `ProfileParamsKMaybe`: To retain any existing profile params key. -/// * `FlowParamsKMaybe`: To retain any existing flow params key. -pub fn params_key_unknown_push( - type_params: &mut Punctuated, - scope: Scope, - params_scope: ParamsScope, -) { - match params_scope { - ParamsScope::Workspace => { - type_params.push(parse_quote!(peace_rt_model::params::KeyUnknown)); - - if scope.profile_params_supported() { - type_params.push(parse_quote!(ProfileParamsKMaybe)); - } else { - type_params.push(parse_quote!(peace_rt_model::params::KeyUnknown)); - } - - if scope.flow_params_supported() { - type_params.push(parse_quote!(FlowParamsKMaybe)); - } else { - type_params.push(parse_quote!(peace_rt_model::params::KeyUnknown)); - } - } - ParamsScope::Profile => { - // Workspace params are supported by all scopes. - type_params.push(parse_quote!(WorkspaceParamsKMaybe)); - - type_params.push(parse_quote!(peace_rt_model::params::KeyUnknown)); - - if scope.flow_params_supported() { - type_params.push(parse_quote!(FlowParamsKMaybe)); - } else { - type_params.push(parse_quote!(peace_rt_model::params::KeyUnknown)); - } - } - ParamsScope::Flow => { - // Workspace params are supported by all scopes. - type_params.push(parse_quote!(WorkspaceParamsKMaybe)); - - if scope.profile_params_supported() { - type_params.push(parse_quote!(ProfileParamsKMaybe)); - } else { - type_params.push(parse_quote!(peace_rt_model::params::KeyUnknown)); - } - - type_params.push(parse_quote!(peace_rt_model::params::KeyUnknown)); - } - } -} - -/// Appends the type parameters for params selection for the `ScopeBuilder` in -/// the `impl`. -/// -/// For the `Workspace` params scope, the following are generated, if -/// applicable to the current command context builder scope: -/// -/// * `KeyKnown`: Indicates that the outgoing params key is -/// known. -/// * `ProfileParamsKMaybe`: To retain any existing profile params key. -/// * `FlowParamsKMaybe`: To retain any existing flow params key. -pub fn params_key_known_push( - type_params: &mut Punctuated, - scope: Scope, - params_scope: ParamsScope, -) { - match params_scope { - ParamsScope::Workspace => { - type_params.push(parse_quote!( - peace_rt_model::params::KeyKnown - )); - - if scope.profile_params_supported() { - type_params.push(parse_quote!(ProfileParamsKMaybe)); - } else { - type_params.push(parse_quote!(peace_rt_model::params::KeyUnknown)); - } - - if scope.flow_params_supported() { - type_params.push(parse_quote!(FlowParamsKMaybe)); - } else { - type_params.push(parse_quote!(peace_rt_model::params::KeyUnknown)); - } - } - ParamsScope::Profile => { - // Workspace params are supported by all scopes. - type_params.push(parse_quote!(WorkspaceParamsKMaybe)); - - if scope.profile_params_supported() { - type_params.push(parse_quote!( - peace_rt_model::params::KeyKnown - )); - } else { - type_params.push(parse_quote!(peace_rt_model::params::KeyUnknown)); - } - - if scope.flow_params_supported() { - type_params.push(parse_quote!(FlowParamsKMaybe)); - } else { - type_params.push(parse_quote!(peace_rt_model::params::KeyUnknown)); - } - } - ParamsScope::Flow => { - // Workspace params are supported by all scopes. - type_params.push(parse_quote!(WorkspaceParamsKMaybe)); - - if scope.profile_params_supported() { - type_params.push(parse_quote!(ProfileParamsKMaybe)); - } else { - type_params.push(parse_quote!(peace_rt_model::params::KeyUnknown)); - } - - if scope.flow_params_supported() { - type_params.push(parse_quote!(peace_rt_model::params::KeyKnown)); - } else { - type_params.push(parse_quote!(peace_rt_model::params::KeyUnknown)); - } - } - } -} diff --git a/crate/code_gen/src/cmd/type_params_selection.rs b/crate/code_gen/src/cmd/type_params_selection.rs index 6784a0814..931c5911c 100644 --- a/crate/code_gen/src/cmd/type_params_selection.rs +++ b/crate/code_gen/src/cmd/type_params_selection.rs @@ -1,4 +1,6 @@ -use syn::{parse_quote, FieldValue, GenericArgument}; +use syn::{parse_quote, FieldValue, TypePath}; + +use crate::cmd::ProfileCount; #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub(crate) enum ProfileSelection { @@ -20,15 +22,12 @@ impl ProfileSelection { .into_iter() } - pub(crate) fn type_param(self) -> GenericArgument { + pub(crate) fn type_param(self) -> TypePath { match self { Self::NotSelected => parse_quote!(crate::scopes::type_params::ProfileNotSelected), Self::Selected => parse_quote!(crate::scopes::type_params::ProfileSelected), Self::FromWorkspaceParam => parse_quote!( - crate::scopes::type_params::ProfileFromWorkspaceParam< - 'key, - ::Key, - > + crate::scopes::type_params::ProfileFromWorkspaceParam<'key, WorkspaceParamsK> ), Self::FilterFunction => { parse_quote!(crate::scopes::type_params::ProfileFilterFn<'ctx>) @@ -39,17 +38,23 @@ impl ProfileSelection { #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub(crate) enum FlowSelection { + NotSelected, Selected, } impl FlowSelection { - pub(crate) fn iter() -> std::array::IntoIter { - [Self::Selected].into_iter() + pub(crate) fn iter() -> std::array::IntoIter { + [Self::NotSelected, Self::Selected].into_iter() } - pub(crate) fn type_param(&self) -> GenericArgument { + pub(crate) fn type_param(&self) -> TypePath { match self { - Self::Selected => parse_quote!(crate::scopes::type_params::FlowSelected<'ctx, E>), + Self::NotSelected => { + parse_quote!(crate::scopes::type_params::FlowNotSelected) + } + Self::Selected => { + parse_quote!(crate::scopes::type_params::FlowSelected<'ctx, AppError>) + } } } } @@ -65,20 +70,22 @@ impl WorkspaceParamsSelection { [Self::None, Self::Some].into_iter() } - pub(crate) fn type_param(&self) -> GenericArgument { + pub(crate) fn type_param(&self) -> TypePath { match self { Self::None => parse_quote!(crate::scopes::type_params::WorkspaceParamsNone), Self::Some => parse_quote! { - crate::scopes::type_params::WorkspaceParamsSome< - < - PKeys::WorkspaceParamsKMaybe - as peace_rt_model::params::KeyMaybe - >::Key - > + crate::scopes::type_params::WorkspaceParamsSome }, } } + pub(crate) fn k_maybe_type_param(&self) -> TypePath { + match self { + Self::None => parse_quote!(peace_rt_model::params::KeyUnknown), + Self::Some => parse_quote!(peace_rt_model::params::KeyKnown), + } + } + pub(crate) fn deconstruct(self) -> FieldValue { match self { Self::None => parse_quote!( @@ -103,30 +110,55 @@ impl ProfileParamsSelection { [Self::None, Self::Some].into_iter() } - pub(crate) fn type_param(&self) -> GenericArgument { + pub(crate) fn type_param(&self, profile_count: ProfileCount) -> TypePath { match self { - Self::None => parse_quote!(crate::scopes::type_params::ProfileParamsNone), - Self::Some => parse_quote! { - crate::scopes::type_params::ProfileParamsSome< - < - PKeys::ProfileParamsKMaybe - as peace_rt_model::params::KeyMaybe - >::Key - > + Self::None => { + parse_quote!(crate::scopes::type_params::ProfileParamsNone) + } + Self::Some => match profile_count { + ProfileCount::None => parse_quote!(crate::scopes::type_params::ProfileParamsNone), + ProfileCount::One => parse_quote! { + crate::scopes::type_params::ProfileParamsSome + }, + ProfileCount::Multiple => parse_quote! { + crate::scopes::type_params::ProfileParamsSomeMulti + }, }, } } - pub(crate) fn deconstruct(self) -> FieldValue { + pub(crate) fn k_maybe_type_param(&self) -> TypePath { + match self { + Self::None => parse_quote!(peace_rt_model::params::KeyUnknown), + Self::Some => parse_quote!(peace_rt_model::params::KeyKnown), + } + } + + pub(crate) fn deconstruct(self, profile_count: ProfileCount) -> FieldValue { match self { Self::None => { parse_quote!( profile_params_selection: crate::scopes::type_params::ProfileParamsNone ) } - Self::Some => parse_quote! { - profile_params_selection: - crate::scopes::type_params::ProfileParamsSome(profile_params) + Self::Some => match profile_count { + ProfileCount::None => parse_quote! { + profile_params_selection: crate::scopes::type_params::ProfileParamsNone + }, + ProfileCount::One => parse_quote! { + profile_params_selection: + crate::scopes::type_params::ProfileParamsSome(profile_params) + }, + ProfileCount::Multiple => { + // The `profile_to_profile_params` in `ProfileParamsSomeMulti` is not used. + // On build, profile params are deserialized from disk. + parse_quote! { + profile_params_selection: + crate::scopes::type_params::ProfileParamsSomeMulti( + _profile_to_profile_params + ) + } + } }, } } @@ -143,30 +175,52 @@ impl FlowParamsSelection { [Self::None, Self::Some].into_iter() } - pub(crate) fn type_param(&self) -> GenericArgument { + pub(crate) fn type_param(&self, profile_count: ProfileCount) -> TypePath { match self { Self::None => { parse_quote!(crate::scopes::type_params::FlowParamsNone) } - Self::Some => parse_quote! { - crate::scopes::type_params::FlowParamsSome< - < - PKeys::FlowParamsKMaybe - as peace_rt_model::params::KeyMaybe - >::Key - > + Self::Some => match profile_count { + ProfileCount::None => parse_quote!(crate::scopes::type_params::FlowParamsNone), + ProfileCount::One => parse_quote! { + crate::scopes::type_params::FlowParamsSome + }, + ProfileCount::Multiple => parse_quote! { + crate::scopes::type_params::FlowParamsSomeMulti + }, }, } } - pub(crate) fn deconstruct(self) -> FieldValue { + pub(crate) fn k_maybe_type_param(&self) -> TypePath { + match self { + Self::None => parse_quote!(peace_rt_model::params::KeyUnknown), + Self::Some => parse_quote!(peace_rt_model::params::KeyKnown), + } + } + + pub(crate) fn deconstruct(self, profile_count: ProfileCount) -> FieldValue { match self { Self::None => { parse_quote!(flow_params_selection: crate::scopes::type_params::FlowParamsNone) } - Self::Some => parse_quote! { - flow_params_selection: - crate::scopes::type_params::FlowParamsSome(flow_params) + Self::Some => match profile_count { + ProfileCount::None => parse_quote! { + flow_params_selection: crate::scopes::type_params::FlowParamsNone + }, + ProfileCount::One => parse_quote! { + flow_params_selection: crate::scopes::type_params::FlowParamsSome(flow_params) + }, + ProfileCount::Multiple => { + // The `profile_to_flow_params` in `FlowParamsSomeMulti` is not used. + // On build, profile params are deserialized from disk. + parse_quote! { + flow_params_selection: + crate::scopes::type_params::FlowParamsSomeMulti( + _profile_to_flow_params + ) + } + } }, } } diff --git a/crate/code_gen/src/cmd/with_params.rs b/crate/code_gen/src/cmd/with_params.rs new file mode 100644 index 000000000..a42562947 --- /dev/null +++ b/crate/code_gen/src/cmd/with_params.rs @@ -0,0 +1,37 @@ +use syn::{parse_quote, Ident, Path}; + +use crate::cmd::{ + type_params_selection::{FlowParamsSelection, ProfileParamsSelection}, + CmdCtxBuilderTypeBuilder, ParamsScope, ScopeStruct, +}; + +pub(crate) fn cmd_ctx_builder_with_params_selected( + scope_builder_name: &Ident, + scope_struct: &ScopeStruct, + params_scope: ParamsScope, +) -> Path { + let builder_type_builder = CmdCtxBuilderTypeBuilder::new(scope_builder_name.clone()); + let profile_count = scope_struct.scope().profile_count(); + match params_scope { + ParamsScope::Workspace => builder_type_builder + .with_workspace_params_k_maybe(parse_quote!( + peace_rt_model::params::KeyKnown + )) + .with_workspace_params_selection(parse_quote!( + crate::scopes::type_params::WorkspaceParamsSome + )), + ParamsScope::Profile => { + let profile_params_selection = ProfileParamsSelection::Some; + builder_type_builder + .with_profile_params_k_maybe(profile_params_selection.k_maybe_type_param()) + .with_profile_params_selection(profile_params_selection.type_param(profile_count)) + } + ParamsScope::Flow => { + let flow_params_selection = FlowParamsSelection::Some; + builder_type_builder + .with_flow_params_k_maybe(flow_params_selection.k_maybe_type_param()) + .with_flow_params_selection(flow_params_selection.type_param(profile_count)) + } + } + .build() +} diff --git a/crate/rt/Cargo.toml b/crate/rt/Cargo.toml index 59a5d3480..fed3c3d84 100644 --- a/crate/rt/Cargo.toml +++ b/crate/rt/Cargo.toml @@ -30,6 +30,7 @@ peace_params = { workspace = true } peace_resources = { workspace = true } peace_rt_model = { workspace = true } peace_rt_model_core = { workspace = true } +peace_value_traits = { workspace = true } serde = { workspace = true } serde_yaml = { workspace = true } tokio = { workspace = true, features = ["sync"] } diff --git a/crate/rt/src/cmd_blocks/apply_exec_cmd_block.rs b/crate/rt/src/cmd_blocks/apply_exec_cmd_block.rs index f791a1653..59015ea64 100644 --- a/crate/rt/src/cmd_blocks/apply_exec_cmd_block.rs +++ b/crate/rt/src/cmd_blocks/apply_exec_cmd_block.rs @@ -3,7 +3,7 @@ use std::{fmt::Debug, marker::PhantomData}; use fn_graph::{StreamOpts, StreamOutcome}; use futures::join; use peace_cfg::{ApplyCheck, FnCtx, ItemId}; -use peace_cmd::scopes::SingleProfileSingleFlowView; +use peace_cmd::{ctx::CmdCtxTypesConstrained, scopes::SingleProfileSingleFlowView}; use peace_cmd_model::CmdBlockOutcome; use peace_cmd_rt::{async_trait, CmdBlock}; use peace_params::ParamsSpecs; @@ -18,8 +18,7 @@ use peace_resources::{ }; use peace_rt_model::{ outcomes::{ItemApplyBoxed, ItemApplyPartialBoxed}, - params::ParamsKeys, - Error, ItemBoxed, ItemRt, + ItemBoxed, ItemRt, }; use tokio::sync::mpsc::{self, Receiver}; @@ -30,6 +29,8 @@ use crate::BUFFERED_FUTURES_MAX; cfg_if::cfg_if! { if #[cfg(feature = "output_progress")] { + use std::error::Error; + use peace_cfg::{ progress::{ CmdProgressUpdate, @@ -45,15 +46,15 @@ cfg_if::cfg_if! { /// Stops a `CmdExecution` if stored states and discovered states are not in /// sync. -pub struct ApplyExecCmdBlock(PhantomData<(E, PKeys, StatesTs)>); +pub struct ApplyExecCmdBlock(PhantomData<(CmdCtxTypesT, StatesTs)>); -impl Debug for ApplyExecCmdBlock { +impl Debug for ApplyExecCmdBlock { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_tuple("ApplyExecCmdBlock").field(&self.0).finish() } } -impl ApplyExecCmdBlock { +impl ApplyExecCmdBlock { /// Returns an `ApplyExecCmdBlock`. /// /// This is a generic constructor where `StatesTs` determines whether the @@ -63,16 +64,15 @@ impl ApplyExecCmdBlock { } } -impl Default for ApplyExecCmdBlock { +impl Default for ApplyExecCmdBlock { fn default() -> Self { Self(PhantomData) } } -impl ApplyExecCmdBlock +impl ApplyExecCmdBlock where - E: std::error::Error + From + Send + 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { /// Returns an `ApplyExecCmdBlock` with the goal state as the target state. pub fn ensure() -> Self { @@ -80,10 +80,9 @@ where } } -impl ApplyExecCmdBlock +impl ApplyExecCmdBlock where - E: std::error::Error + From + Send + 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { /// Returns an `ApplyExecCmdBlock` with the goal state as the target state. pub fn ensure_dry() -> Self { @@ -91,10 +90,9 @@ where } } -impl ApplyExecCmdBlock +impl ApplyExecCmdBlock where - E: std::error::Error + From + Send + 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { /// Returns an `ApplyExecCmdBlock` with the clean state as the target state. pub fn clean() -> Self { @@ -102,10 +100,9 @@ where } } -impl ApplyExecCmdBlock +impl ApplyExecCmdBlock where - E: std::error::Error + From + Send + 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { /// Returns an `ApplyExecCmdBlock` with the clean state as the target state. pub fn clean_dry() -> Self { @@ -113,11 +110,10 @@ where } } -impl ApplyExecCmdBlock +impl ApplyExecCmdBlock where - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, StatesTs: StatesTsApplyExt + Debug + Send, - E: std::error::Error + 'static, { /// /// # Implementation Note @@ -129,17 +125,20 @@ where /// ```rust,ignore /// async fn item_apply_exec( /// resources: &Resources, - /// outcomes_tx: &Sender>, - /// item: FnRef<'_, ItemBoxed>, + /// outcomes_tx: &Sender::AppError>>, + /// item: FnRef<'_, ItemBoxed<::AppError>>, /// f: F, /// ) -> bool /// where - /// F: (Fn(&dyn ItemRt, fn_ctx: OpCtx<'_>, &Resources, &mut ItemApplyBoxed) -> Fut) + Copy, - /// Fut: Future>, + /// F: (Fn(&dyn ItemRt<::AppError>, fn_ctx: OpCtx<'_>, &Resources, &mut ItemApplyBoxed) -> Fut) + Copy, + /// Fut: Future::AppError>>, /// ``` async fn item_apply_exec( - item_apply_exec_ctx: ItemApplyExecCtx<'_, E>, - item: &ItemBoxed, + item_apply_exec_ctx: ItemApplyExecCtx< + '_, + ::AppError, + >, + item: &ItemBoxed<::AppError>, ) -> Result<(), ()> { let ItemApplyExecCtx { params_specs, @@ -318,16 +317,18 @@ where } async fn outcome_collate_task( - mut outcomes_rx: Receiver>, + mut outcomes_rx: Receiver< + ItemApplyOutcome<::AppError>, + >, mut states_applied_mut: StatesMut, mut states_target_mut: StatesMut, ) -> Result< ( States, States, - IndexMap, + IndexMap::AppError>, ), - E, + ::AppError, > { let mut errors = IndexMap::new(); while let Some(item_outcome) = outcomes_rx.recv().await { @@ -348,9 +349,9 @@ where fn outcome_collate( states_applied_mut: &mut StatesMut, states_target_mut: &mut StatesMut, - errors: &mut IndexMap, - outcome_partial: ItemApplyOutcome, - ) -> Result<(), E> { + errors: &mut IndexMap::AppError>, + outcome_partial: ItemApplyOutcome<::AppError>, + ) -> Result<(), ::AppError> { let apply_for = StatesTs::apply_for(); match outcome_partial { @@ -420,16 +421,14 @@ where } #[async_trait(?Send)] -impl CmdBlock for ApplyExecCmdBlock +impl CmdBlock for ApplyExecCmdBlock where - E: std::error::Error + From + Send + 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, StatesTs: StatesTsApplyExt + Debug + Send + Sync + 'static, { - type Error = E; + type CmdCtxTypes = CmdCtxTypesT; type InputT = (StatesCurrent, States); type Outcome = (StatesPrevious, States, States); - type PKeys = PKeys; fn input_fetch( &self, @@ -467,9 +466,12 @@ where async fn exec( &self, input: Self::InputT, - cmd_view: &mut SingleProfileSingleFlowView<'_, Self::Error, Self::PKeys, SetUp>, + cmd_view: &mut SingleProfileSingleFlowView<'_, Self::CmdCtxTypes, SetUp>, #[cfg(feature = "output_progress")] progress_tx: &Sender, - ) -> Result, Self::Error> { + ) -> Result< + CmdBlockOutcome::AppError>, + ::AppError, + > { let (states_current, states_target) = input; let (states_previous, states_applied_mut, states_target_mut) = { let states_previous = StatesPrevious::from(states_current.clone()); @@ -499,8 +501,9 @@ where ApplyFor::Clean => ApplyForInternal::Clean { states_current }, }; - let (outcomes_tx, outcomes_rx) = - mpsc::channel::>(item_graph.node_count()); + let (outcomes_tx, outcomes_rx) = mpsc::channel::< + ItemApplyOutcome<::AppError>, + >(item_graph.node_count()); let stream_opts = { let stream_opts = StreamOpts::new() diff --git a/crate/rt/src/cmd_blocks/apply_state_sync_check_cmd_block.rs b/crate/rt/src/cmd_blocks/apply_state_sync_check_cmd_block.rs index cef6fa7da..be7587995 100644 --- a/crate/rt/src/cmd_blocks/apply_state_sync_check_cmd_block.rs +++ b/crate/rt/src/cmd_blocks/apply_state_sync_check_cmd_block.rs @@ -1,6 +1,6 @@ use std::{fmt::Debug, marker::PhantomData}; -use peace_cmd::scopes::SingleProfileSingleFlowView; +use peace_cmd::{ctx::CmdCtxTypesConstrained, scopes::SingleProfileSingleFlowView}; use peace_cmd_model::CmdBlockOutcome; use peace_cmd_rt::{async_trait, CmdBlock}; use peace_resources::{ @@ -8,7 +8,7 @@ use peace_resources::{ states::{States, StatesCurrent, StatesCurrentStored, StatesGoal, StatesGoalStored}, ResourceFetchError, Resources, }; -use peace_rt_model::{params::ParamsKeys, Error}; +use peace_rt_model::Error; use peace_rt_model_core::{ApplyCmdError, ItemsStateStoredStale, StateStoredAndDiscovered}; cfg_if::cfg_if! { @@ -63,12 +63,12 @@ pub struct ApplyStoreStateSyncCurrentAndGoal; /// Stops a `CmdExecution` if stored states and discovered states are not in /// sync. -pub struct ApplyStateSyncCheckCmdBlock( - PhantomData<(E, PKeys, ApplyStoreStateSync)>, +pub struct ApplyStateSyncCheckCmdBlock( + PhantomData<(CmdCtxTypesT, ApplyStoreStateSync)>, ); -impl Debug - for ApplyStateSyncCheckCmdBlock +impl Debug + for ApplyStateSyncCheckCmdBlock { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_tuple("ApplyStateSyncCheckCmdBlock") @@ -77,10 +77,9 @@ impl Debug } } -impl ApplyStateSyncCheckCmdBlock +impl ApplyStateSyncCheckCmdBlock where - E: std::error::Error + From + Send + 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { /// Returns a block that discovers current states. pub fn none() -> Self { @@ -88,10 +87,9 @@ where } } -impl ApplyStateSyncCheckCmdBlock +impl ApplyStateSyncCheckCmdBlock where - E: std::error::Error + From + Send + 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { /// Returns a block that discovers current states. pub fn current() -> Self { @@ -99,10 +97,9 @@ where } } -impl ApplyStateSyncCheckCmdBlock +impl ApplyStateSyncCheckCmdBlock where - E: std::error::Error + From + Send + 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { /// Returns a block that discovers goal states. pub fn goal() -> Self { @@ -110,10 +107,9 @@ where } } -impl ApplyStateSyncCheckCmdBlock +impl ApplyStateSyncCheckCmdBlock where - E: std::error::Error + From + Send + 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { /// Returns a block that discovers both current and goal states. pub fn current_and_goal() -> Self { @@ -121,19 +117,17 @@ where } } -impl ApplyStateSyncCheckCmdBlock +impl + ApplyStateSyncCheckCmdBlock where - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { fn items_state_stored_stale( - cmd_view: &SingleProfileSingleFlowView<'_, E, PKeys, SetUp>, + cmd_view: &SingleProfileSingleFlowView<'_, CmdCtxTypesT, SetUp>, states_stored: &States, states_discovered: &States, #[cfg(feature = "output_progress")] progress_tx: &Sender, - ) -> Result - where - E: std::error::Error + From + Send + 'static, - { + ) -> Result::AppError> { let items_state_stored_stale = cmd_view.flow.graph().iter_insertion().try_fold( ItemsStateStoredStale::new(), |mut items_state_stored_stale, item_rt| { @@ -226,15 +220,13 @@ where } #[async_trait(?Send)] -impl CmdBlock for ApplyStateSyncCheckCmdBlock +impl CmdBlock for ApplyStateSyncCheckCmdBlock where - E: std::error::Error + From + Send + 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { - type Error = E; + type CmdCtxTypes = CmdCtxTypesT; type InputT = (); type Outcome = Self::InputT; - type PKeys = PKeys; fn input_fetch(&self, _resources: &mut Resources) -> Result<(), ResourceFetchError> { Ok(()) @@ -253,23 +245,25 @@ where async fn exec( &self, input: Self::InputT, - _cmd_view: &mut SingleProfileSingleFlowView<'_, Self::Error, Self::PKeys, SetUp>, + _cmd_view: &mut SingleProfileSingleFlowView<'_, Self::CmdCtxTypes, SetUp>, #[cfg(feature = "output_progress")] _progress_tx: &Sender, - ) -> Result, Self::Error> { + ) -> Result< + CmdBlockOutcome::AppError>, + ::AppError, + > { outcome_collate(input, OutcomeResult::Ok) } } #[async_trait(?Send)] -impl CmdBlock for ApplyStateSyncCheckCmdBlock +impl CmdBlock + for ApplyStateSyncCheckCmdBlock where - E: std::error::Error + From + Send + 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { - type Error = E; + type CmdCtxTypes = CmdCtxTypesT; type InputT = (StatesCurrentStored, StatesCurrent); type Outcome = Self::InputT; - type PKeys = PKeys; fn input_fetch( &self, @@ -301,9 +295,12 @@ where async fn exec( &self, mut input: Self::InputT, - cmd_view: &mut SingleProfileSingleFlowView<'_, Self::Error, Self::PKeys, SetUp>, + cmd_view: &mut SingleProfileSingleFlowView<'_, Self::CmdCtxTypes, SetUp>, #[cfg(feature = "output_progress")] progress_tx: &Sender, - ) -> Result, Self::Error> { + ) -> Result< + CmdBlockOutcome::AppError>, + ::AppError, + > { let (states_current_stored, states_current) = &mut input; let state_current_stale_result = Self::items_state_stored_stale( @@ -334,15 +331,13 @@ where } #[async_trait(?Send)] -impl CmdBlock for ApplyStateSyncCheckCmdBlock +impl CmdBlock for ApplyStateSyncCheckCmdBlock where - E: std::error::Error + From + Send + 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { - type Error = E; + type CmdCtxTypes = CmdCtxTypesT; type InputT = (StatesGoalStored, StatesGoal); type Outcome = Self::InputT; - type PKeys = PKeys; fn input_fetch( &self, @@ -374,9 +369,12 @@ where async fn exec( &self, mut input: Self::InputT, - cmd_view: &mut SingleProfileSingleFlowView<'_, Self::Error, Self::PKeys, SetUp>, + cmd_view: &mut SingleProfileSingleFlowView<'_, Self::CmdCtxTypes, SetUp>, #[cfg(feature = "output_progress")] progress_tx: &Sender, - ) -> Result, Self::Error> { + ) -> Result< + CmdBlockOutcome::AppError>, + ::AppError, + > { let (states_goal_stored, states_goal) = &mut input; let state_goal_stale_result = Self::items_state_stored_stale( @@ -407,12 +405,12 @@ where } #[async_trait(?Send)] -impl CmdBlock for ApplyStateSyncCheckCmdBlock +impl CmdBlock + for ApplyStateSyncCheckCmdBlock where - E: std::error::Error + From + Send + 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { - type Error = E; + type CmdCtxTypes = CmdCtxTypesT; type InputT = ( StatesCurrentStored, StatesCurrent, @@ -420,7 +418,6 @@ where StatesGoal, ); type Outcome = Self::InputT; - type PKeys = PKeys; fn input_fetch( &self, @@ -466,9 +463,12 @@ where async fn exec( &self, mut input: Self::InputT, - cmd_view: &mut SingleProfileSingleFlowView<'_, Self::Error, Self::PKeys, SetUp>, + cmd_view: &mut SingleProfileSingleFlowView<'_, Self::CmdCtxTypes, SetUp>, #[cfg(feature = "output_progress")] progress_tx: &Sender, - ) -> Result, Self::Error> { + ) -> Result< + CmdBlockOutcome::AppError>, + ::AppError, + > { let (states_current_stored, states_current, states_goal_stored, states_goal) = &mut input; let state_current_stale_result = Self::items_state_stored_stale( @@ -564,25 +564,25 @@ fn input_fetch_goal( Ok((states_goal_stored, states_goal)) } -fn outcome_collate( +fn outcome_collate( states_stored_and_discovered: InputT, - outcome_result: OutcomeResult, -) -> Result, E> + outcome_result: OutcomeResult, +) -> Result, AppErrorT> where - E: std::error::Error + From + Send + 'static, + AppErrorT: peace_value_traits::AppError + From, { match outcome_result { OutcomeResult::Ok => Ok(CmdBlockOutcome::Single(states_stored_and_discovered)), OutcomeResult::StatesCurrentOutOfSync { items_state_stored_stale, - } => Err(E::from(Error::ApplyCmdError( + } => Err(AppErrorT::from(Error::ApplyCmdError( ApplyCmdError::StatesCurrentOutOfSync { items_state_stored_stale, }, ))), OutcomeResult::StatesGoalOutOfSync { items_state_stored_stale, - } => Err(E::from(Error::ApplyCmdError( + } => Err(AppErrorT::from(Error::ApplyCmdError( ApplyCmdError::StatesGoalOutOfSync { items_state_stored_stale, }, diff --git a/crate/rt/src/cmd_blocks/diff_cmd_block.rs b/crate/rt/src/cmd_blocks/diff_cmd_block.rs index c9f2e687e..35a944bb7 100644 --- a/crate/rt/src/cmd_blocks/diff_cmd_block.rs +++ b/crate/rt/src/cmd_blocks/diff_cmd_block.rs @@ -3,7 +3,10 @@ use std::{fmt::Debug, marker::PhantomData}; use fn_graph::{StreamOpts, StreamOutcome}; use futures::FutureExt; use peace_cfg::ItemId; -use peace_cmd::{interruptible::InterruptibilityState, scopes::SingleProfileSingleFlowView}; +use peace_cmd::{ + ctx::CmdCtxTypesConstrained, interruptible::InterruptibilityState, + scopes::SingleProfileSingleFlowView, +}; use peace_cmd_model::CmdBlockOutcome; use peace_cmd_rt::{async_trait, CmdBlock}; use peace_params::ParamsSpecs; @@ -17,7 +20,7 @@ use peace_resources::{ type_reg::untagged::{BoxDtDisplay, TypeMap}, ResourceFetchError, Resources, }; -use peace_rt_model::{params::ParamsKeys, Error, Flow}; +use peace_rt_model::Flow; use crate::cmds::DiffStateSpec; @@ -28,27 +31,28 @@ cfg_if::cfg_if! { } } -pub struct DiffCmdBlock( - PhantomData<(E, PKeys, StatesTs0, StatesTs1)>, +pub struct DiffCmdBlock( + PhantomData<(CmdCtxTypesT, StatesTs0, StatesTs1)>, ); -impl Debug for DiffCmdBlock { +impl Debug + for DiffCmdBlock +{ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_tuple("DiffCmdBlock").field(&self.0).finish() } } -impl DiffCmdBlock { +impl DiffCmdBlock { /// Returns a new `DiffCmdBlock`. pub fn new() -> Self { Self(PhantomData) } } -impl DiffCmdBlock +impl DiffCmdBlock where - E: std::error::Error + From + Send + 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { /// Returns the [`state_diff`]` for each [`Item`]. /// @@ -60,12 +64,12 @@ where /// [`state_diff`]: peace_cfg::Item::state_diff pub async fn diff_any( interruptibility_state: InterruptibilityState<'_, '_>, - flow: &Flow, + flow: &Flow<::AppError>, params_specs: &ParamsSpecs, resources: &Resources, states_a: &TypeMap, states_b: &TypeMap, - ) -> Result, E> { + ) -> Result, ::AppError> { let stream_outcome_result = flow .graph() .try_fold_async_with( @@ -85,7 +89,9 @@ where state_diffs_mut.insert_raw(item.id().clone(), state_diff); } - Result::<_, E>::Ok(state_diffs_mut) + Result::<_, ::AppError>::Ok( + state_diffs_mut, + ) } .boxed_local() }, @@ -96,24 +102,25 @@ where } } -impl Default for DiffCmdBlock { +impl Default + for DiffCmdBlock +{ fn default() -> Self { Self(PhantomData) } } #[async_trait(?Send)] -impl CmdBlock for DiffCmdBlock +impl CmdBlock + for DiffCmdBlock where - E: std::error::Error + From + Send + 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, StatesTs0: Debug + Send + Sync + 'static, StatesTs1: Debug + Send + Sync + 'static, { - type Error = E; + type CmdCtxTypes = CmdCtxTypesT; type InputT = (States, States); type Outcome = (StateDiffs, Self::InputT); - type PKeys = PKeys; fn input_fetch( &self, @@ -150,9 +157,12 @@ where async fn exec( &self, input: Self::InputT, - cmd_view: &mut SingleProfileSingleFlowView<'_, Self::Error, Self::PKeys, SetUp>, + cmd_view: &mut SingleProfileSingleFlowView<'_, Self::CmdCtxTypes, SetUp>, #[cfg(feature = "output_progress")] _progress_tx: &Sender, - ) -> Result, Self::Error> { + ) -> Result< + CmdBlockOutcome::AppError>, + ::AppError, + > { let SingleProfileSingleFlowView { interruptibility_state, flow, diff --git a/crate/rt/src/cmd_blocks/states_clean_insertion_cmd_block.rs b/crate/rt/src/cmd_blocks/states_clean_insertion_cmd_block.rs index d291a8ee7..f1c12bf15 100644 --- a/crate/rt/src/cmd_blocks/states_clean_insertion_cmd_block.rs +++ b/crate/rt/src/cmd_blocks/states_clean_insertion_cmd_block.rs @@ -1,7 +1,7 @@ use std::{fmt::Debug, marker::PhantomData}; use futures::FutureExt; -use peace_cmd::scopes::SingleProfileSingleFlowView; +use peace_cmd::{ctx::CmdCtxTypesConstrained, scopes::SingleProfileSingleFlowView}; use peace_cmd_model::CmdBlockOutcome; use peace_cmd_rt::{async_trait, CmdBlock}; use peace_resources::{ @@ -10,7 +10,7 @@ use peace_resources::{ states::{ts::Clean, StatesClean}, ResourceFetchError, Resources, }; -use peace_rt_model::{fn_graph::StreamOpts, params::ParamsKeys, Error}; +use peace_rt_model::fn_graph::StreamOpts; use peace_rt_model_core::IndexMap; cfg_if::cfg_if! { @@ -25,12 +25,11 @@ cfg_if::cfg_if! { /// This calls [`Item::state_clean`] for each item, and groups them together /// into `StatesClean`. #[derive(Debug)] -pub struct StatesCleanInsertionCmdBlock(PhantomData<(E, PKeys)>); +pub struct StatesCleanInsertionCmdBlock(PhantomData); -impl StatesCleanInsertionCmdBlock +impl StatesCleanInsertionCmdBlock where - E: std::error::Error + From + Send + 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { /// Returns a new `StatesCleanInsertionCmdBlock`. pub fn new() -> Self { @@ -38,22 +37,20 @@ where } } -impl Default for StatesCleanInsertionCmdBlock { +impl Default for StatesCleanInsertionCmdBlock { fn default() -> Self { Self(PhantomData) } } #[async_trait(?Send)] -impl CmdBlock for StatesCleanInsertionCmdBlock +impl CmdBlock for StatesCleanInsertionCmdBlock where - E: std::error::Error + From + Send + 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { - type Error = E; + type CmdCtxTypes = CmdCtxTypesT; type InputT = (); type Outcome = StatesClean; - type PKeys = PKeys; fn input_fetch(&self, _resources: &mut Resources) -> Result<(), ResourceFetchError> { Ok(()) @@ -66,9 +63,12 @@ where async fn exec( &self, _input: Self::InputT, - cmd_view: &mut SingleProfileSingleFlowView<'_, Self::Error, Self::PKeys, SetUp>, + cmd_view: &mut SingleProfileSingleFlowView<'_, Self::CmdCtxTypes, SetUp>, #[cfg(feature = "output_progress")] _progress_tx: &Sender, - ) -> Result, Self::Error> { + ) -> Result< + CmdBlockOutcome::AppError>, + ::AppError, + > { let SingleProfileSingleFlowView { interruptibility_state, flow, diff --git a/crate/rt/src/cmd_blocks/states_current_read_cmd_block.rs b/crate/rt/src/cmd_blocks/states_current_read_cmd_block.rs index d2fd108c7..c247099eb 100644 --- a/crate/rt/src/cmd_blocks/states_current_read_cmd_block.rs +++ b/crate/rt/src/cmd_blocks/states_current_read_cmd_block.rs @@ -1,7 +1,7 @@ use std::{fmt::Debug, marker::PhantomData}; use peace_cfg::{FlowId, ItemId}; -use peace_cmd::scopes::SingleProfileSingleFlowView; +use peace_cmd::{ctx::CmdCtxTypesConstrained, scopes::SingleProfileSingleFlowView}; use peace_cmd_model::CmdBlockOutcome; use peace_cmd_rt::{async_trait, CmdBlock}; use peace_resources::{ @@ -11,7 +11,7 @@ use peace_resources::{ type_reg::untagged::{BoxDtDisplay, TypeReg}, ResourceFetchError, Resources, }; -use peace_rt_model::{params::ParamsKeys, Error, StatesSerializer, Storage}; +use peace_rt_model::{StatesSerializer, Storage}; cfg_if::cfg_if! { if #[cfg(feature = "output_progress")] { @@ -28,12 +28,11 @@ cfg_if::cfg_if! { /// /// [`StatesDiscoverCmd`]: crate::StatesDiscoverCmd #[derive(Debug)] -pub struct StatesCurrentReadCmdBlock(PhantomData<(E, PKeys)>); +pub struct StatesCurrentReadCmdBlock(PhantomData); -impl StatesCurrentReadCmdBlock +impl StatesCurrentReadCmdBlock where - E: std::error::Error + From + Send + 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { /// Returns a new `StatesCurrentReadCmdBlock`. pub fn new() -> Self { @@ -43,7 +42,7 @@ where pub(crate) async fn deserialize_internal( resources: &mut Resources, states_type_reg: &TypeReg, - ) -> Result { + ) -> Result::AppError> { let flow_id = resources.borrow::(); let flow_dir = resources.borrow::(); let storage = resources.borrow::(); @@ -67,22 +66,20 @@ where } } -impl Default for StatesCurrentReadCmdBlock { +impl Default for StatesCurrentReadCmdBlock { fn default() -> Self { Self(PhantomData) } } #[async_trait(?Send)] -impl CmdBlock for StatesCurrentReadCmdBlock +impl CmdBlock for StatesCurrentReadCmdBlock where - E: std::error::Error + From + Send + 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { - type Error = E; + type CmdCtxTypes = CmdCtxTypesT; type InputT = (); type Outcome = StatesCurrentStored; - type PKeys = PKeys; fn input_fetch(&self, _resources: &mut Resources) -> Result<(), ResourceFetchError> { Ok(()) @@ -95,9 +92,12 @@ where async fn exec( &self, _input: Self::InputT, - cmd_view: &mut SingleProfileSingleFlowView<'_, Self::Error, Self::PKeys, SetUp>, + cmd_view: &mut SingleProfileSingleFlowView<'_, Self::CmdCtxTypes, SetUp>, #[cfg(feature = "output_progress")] _progress_tx: &Sender, - ) -> Result, Self::Error> { + ) -> Result< + CmdBlockOutcome::AppError>, + ::AppError, + > { let SingleProfileSingleFlowView { states_type_reg, resources, diff --git a/crate/rt/src/cmd_blocks/states_discover_cmd_block.rs b/crate/rt/src/cmd_blocks/states_discover_cmd_block.rs index decd6e269..d31dfe48d 100644 --- a/crate/rt/src/cmd_blocks/states_discover_cmd_block.rs +++ b/crate/rt/src/cmd_blocks/states_discover_cmd_block.rs @@ -2,7 +2,7 @@ use std::{fmt::Debug, marker::PhantomData}; use futures::join; use peace_cfg::{FnCtx, ItemId}; -use peace_cmd::scopes::SingleProfileSingleFlowView; +use peace_cmd::{ctx::CmdCtxTypesConstrained, scopes::SingleProfileSingleFlowView}; use peace_cmd_model::CmdBlockOutcome; use peace_cmd_rt::{async_trait, CmdBlock}; use peace_resources::{ @@ -15,7 +15,7 @@ use peace_resources::{ type_reg::untagged::BoxDtDisplay, ResourceFetchError, Resources, }; -use peace_rt_model::{fn_graph::StreamOpts, params::ParamsKeys, Error, ItemBoxed}; +use peace_rt_model::{fn_graph::StreamOpts, ItemBoxed}; use peace_rt_model_core::IndexMap; use tokio::sync::mpsc::{self, Receiver}; @@ -51,15 +51,15 @@ pub struct DiscoverForGoal; pub struct DiscoverForCurrentAndGoal; /// Discovers [`StatesCurrent`] and/or [`StatesGoal`]. -pub struct StatesDiscoverCmdBlock { +pub struct StatesDiscoverCmdBlock { /// Whether or not to mark progress bars complete on success. #[cfg(feature = "output_progress")] progress_complete_on_success: bool, /// Marker. - marker: PhantomData<(E, PKeys, DiscoverFor)>, + marker: PhantomData<(CmdCtxTypesT, DiscoverFor)>, } -impl Debug for StatesDiscoverCmdBlock { +impl Debug for StatesDiscoverCmdBlock { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let mut debug_struct = f.debug_struct("StatesDiscoverCmdBlock"); #[cfg(feature = "output_progress")] @@ -72,10 +72,9 @@ impl Debug for StatesDiscoverCmdBlock StatesDiscoverCmdBlock +impl StatesDiscoverCmdBlock where - E: std::error::Error + From + Send + 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { /// Returns a block that discovers current states. pub fn current() -> Self { @@ -87,10 +86,9 @@ where } } -impl StatesDiscoverCmdBlock +impl StatesDiscoverCmdBlock where - E: std::error::Error + From + Send + 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { /// Returns a block that discovers goal states. pub fn goal() -> Self { @@ -102,10 +100,9 @@ where } } -impl StatesDiscoverCmdBlock +impl StatesDiscoverCmdBlock where - E: std::error::Error + From + Send + 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { /// Returns a block that discovers both current and goal states. pub fn current_and_goal() -> Self { @@ -117,10 +114,9 @@ where } } -impl StatesDiscoverCmdBlock +impl StatesDiscoverCmdBlock where - E: std::error::Error + From + Send + 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, DiscoverFor: Discover, { /// Indicate that the progress tracker should be marked complete on success. @@ -138,8 +134,10 @@ where #[cfg(feature = "output_progress")] progress_complete_on_success: bool, params_specs: &peace_params::ParamsSpecs, resources: &Resources, - outcomes_tx: &tokio::sync::mpsc::Sender>, - item: &ItemBoxed, + outcomes_tx: &tokio::sync::mpsc::Sender< + ItemDiscoverOutcome<::AppError>, + >, + item: &ItemBoxed<::AppError>, ) { let item_id = item.id(); let fn_ctx = FnCtx::new( @@ -216,8 +214,12 @@ where #[cfg(feature = "output_progress")] fn discover_progress_update( progress_complete_on_success: bool, - states_current_result: Option<&Result, E>>, - states_goal_result: Option<&Result, E>>, + states_current_result: Option< + &Result, ::AppError>, + >, + states_goal_result: Option< + &Result, ::AppError>, + >, progress_tx: &Sender, item_id: &ItemId, ) { @@ -239,7 +241,7 @@ where } #[derive(Debug)] -pub enum ItemDiscoverOutcome { +pub enum ItemDiscoverOutcome { /// Discover succeeded. Success { item_id: ItemId, @@ -251,20 +253,18 @@ pub enum ItemDiscoverOutcome { item_id: ItemId, state_current: Option, state_goal: Option, - error: E, + error: AppErrorT, }, } #[async_trait(?Send)] -impl CmdBlock for StatesDiscoverCmdBlock +impl CmdBlock for StatesDiscoverCmdBlock where - E: std::error::Error + From + Send + 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { - type Error = E; + type CmdCtxTypes = CmdCtxTypesT; type InputT = (); type Outcome = States; - type PKeys = PKeys; fn input_fetch(&self, _resources: &mut Resources) -> Result<(), ResourceFetchError> { Ok(()) @@ -277,9 +277,12 @@ where async fn exec( &self, _input: Self::InputT, - cmd_view: &mut SingleProfileSingleFlowView<'_, Self::Error, Self::PKeys, SetUp>, + cmd_view: &mut SingleProfileSingleFlowView<'_, Self::CmdCtxTypes, SetUp>, #[cfg(feature = "output_progress")] progress_tx: &Sender, - ) -> Result, Self::Error> { + ) -> Result< + CmdBlockOutcome::AppError>, + ::AppError, + > { let SingleProfileSingleFlowView { interruptibility_state, flow, @@ -288,8 +291,9 @@ where .. } = cmd_view; - let (outcomes_tx, outcomes_rx) = - mpsc::channel::>(flow.graph().node_count()); + let (outcomes_tx, outcomes_rx) = mpsc::channel::< + ItemDiscoverOutcome<::AppError>, + >(flow.graph().node_count()); let (stream_outcome, outcome_collate) = { let states_current_mut = StatesMut::::with_capacity(flow.graph().node_count()); @@ -337,15 +341,22 @@ where } } -impl StatesDiscoverCmdBlock +impl StatesDiscoverCmdBlock where - E: std::error::Error + From + Send + 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { async fn outcome_collate_task( - mut outcomes_rx: Receiver>, + mut outcomes_rx: Receiver< + ItemDiscoverOutcome<::AppError>, + >, mut states_current_mut: StatesMut, - ) -> Result<(States, IndexMap), E> { + ) -> Result< + ( + States, + IndexMap::AppError>, + ), + ::AppError, + > { let mut errors = IndexMap::new(); while let Some(item_outcome) = outcomes_rx.recv().await { Self::outcome_collate(&mut states_current_mut, &mut errors, item_outcome)?; @@ -358,9 +369,9 @@ where fn outcome_collate( states_current_mut: &mut StatesMut, - errors: &mut IndexMap, - outcome_partial: ItemDiscoverOutcome, - ) -> Result<(), E> { + errors: &mut IndexMap::AppError>, + outcome_partial: ItemDiscoverOutcome<::AppError>, + ) -> Result<(), ::AppError> { match outcome_partial { ItemDiscoverOutcome::Success { item_id, @@ -390,15 +401,13 @@ where } #[async_trait(?Send)] -impl CmdBlock for StatesDiscoverCmdBlock +impl CmdBlock for StatesDiscoverCmdBlock where - E: std::error::Error + From + Send + 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { - type Error = E; + type CmdCtxTypes = CmdCtxTypesT; type InputT = (); type Outcome = States; - type PKeys = PKeys; fn input_fetch(&self, _resources: &mut Resources) -> Result<(), ResourceFetchError> { Ok(()) @@ -411,9 +420,12 @@ where async fn exec( &self, _input: Self::InputT, - cmd_view: &mut SingleProfileSingleFlowView<'_, Self::Error, Self::PKeys, SetUp>, + cmd_view: &mut SingleProfileSingleFlowView<'_, Self::CmdCtxTypes, SetUp>, #[cfg(feature = "output_progress")] progress_tx: &Sender, - ) -> Result, Self::Error> { + ) -> Result< + CmdBlockOutcome::AppError>, + ::AppError, + > { let SingleProfileSingleFlowView { interruptibility_state, flow, @@ -422,8 +434,9 @@ where .. } = cmd_view; - let (outcomes_tx, outcomes_rx) = - mpsc::channel::>(flow.graph().node_count()); + let (outcomes_tx, outcomes_rx) = mpsc::channel::< + ItemDiscoverOutcome<::AppError>, + >(flow.graph().node_count()); let (stream_outcome, outcome_collate) = { let states_goal_mut = StatesMut::::with_capacity(flow.graph().node_count()); @@ -471,15 +484,22 @@ where } } -impl StatesDiscoverCmdBlock +impl StatesDiscoverCmdBlock where - E: std::error::Error + From + Send + 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { async fn outcome_collate_task( - mut outcomes_rx: Receiver>, + mut outcomes_rx: Receiver< + ItemDiscoverOutcome<::AppError>, + >, mut states_goal_mut: StatesMut, - ) -> Result<(States, IndexMap), E> { + ) -> Result< + ( + States, + IndexMap::AppError>, + ), + ::AppError, + > { let mut errors = IndexMap::new(); while let Some(item_outcome) = outcomes_rx.recv().await { Self::outcome_collate(&mut states_goal_mut, &mut errors, item_outcome)?; @@ -492,9 +512,9 @@ where fn outcome_collate( states_goal_mut: &mut StatesMut, - errors: &mut IndexMap, - outcome_partial: ItemDiscoverOutcome, - ) -> Result<(), E> { + errors: &mut IndexMap::AppError>, + outcome_partial: ItemDiscoverOutcome<::AppError>, + ) -> Result<(), ::AppError> { match outcome_partial { ItemDiscoverOutcome::Success { item_id, @@ -524,15 +544,13 @@ where } #[async_trait(?Send)] -impl CmdBlock for StatesDiscoverCmdBlock +impl CmdBlock for StatesDiscoverCmdBlock where - E: std::error::Error + From + Send + 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { - type Error = E; + type CmdCtxTypes = CmdCtxTypesT; type InputT = (); type Outcome = (States, States); - type PKeys = PKeys; fn input_fetch(&self, _resources: &mut Resources) -> Result<(), ResourceFetchError> { Ok(()) @@ -558,9 +576,12 @@ where async fn exec( &self, _input: Self::InputT, - cmd_view: &mut SingleProfileSingleFlowView<'_, Self::Error, Self::PKeys, SetUp>, + cmd_view: &mut SingleProfileSingleFlowView<'_, Self::CmdCtxTypes, SetUp>, #[cfg(feature = "output_progress")] progress_tx: &Sender, - ) -> Result, Self::Error> { + ) -> Result< + CmdBlockOutcome::AppError>, + ::AppError, + > { let SingleProfileSingleFlowView { interruptibility_state, flow, @@ -569,8 +590,9 @@ where .. } = cmd_view; - let (outcomes_tx, outcomes_rx) = - mpsc::channel::>(flow.graph().node_count()); + let (outcomes_tx, outcomes_rx) = mpsc::channel::< + ItemDiscoverOutcome<::AppError>, + >(flow.graph().node_count()); let (stream_outcome, outcome_collate) = { let states_current_mut = StatesMut::::with_capacity(flow.graph().node_count()); @@ -620,16 +642,24 @@ where } } -impl StatesDiscoverCmdBlock +impl StatesDiscoverCmdBlock where - E: std::error::Error + From + Send + 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { async fn outcome_collate_task( - mut outcomes_rx: Receiver>, + mut outcomes_rx: Receiver< + ItemDiscoverOutcome<::AppError>, + >, mut states_current_mut: StatesMut, mut states_goal_mut: StatesMut, - ) -> Result<(States, States, IndexMap), E> { + ) -> Result< + ( + States, + States, + IndexMap::AppError>, + ), + ::AppError, + > { let mut errors = IndexMap::new(); while let Some(item_outcome) = outcomes_rx.recv().await { Self::outcome_collate( @@ -649,9 +679,9 @@ where fn outcome_collate( states_current_mut: &mut StatesMut, states_goal_mut: &mut StatesMut, - errors: &mut IndexMap, - outcome_partial: ItemDiscoverOutcome, - ) -> Result<(), E> { + errors: &mut IndexMap::AppError>, + outcome_partial: ItemDiscoverOutcome<::AppError>, + ) -> Result<(), ::AppError> { match outcome_partial { ItemDiscoverOutcome::Success { item_id, @@ -689,41 +719,41 @@ where /// Behaviour for each discover variant. #[async_trait::async_trait(?Send)] pub trait Discover { - async fn discover( - item: &ItemBoxed, + async fn discover( + item: &ItemBoxed, params_specs: &peace_params::ParamsSpecs, resources: &Resources, fn_ctx: FnCtx<'_>, ) -> ( - Option, E>>, - Option, E>>, + Option, AppErrorT>>, + Option, AppErrorT>>, ) where - E: std::error::Error + From + Send + 'static; + AppErrorT: peace_value_traits::AppError + From; #[cfg(feature = "output_progress")] - fn progress_update( + fn progress_update( progress_complete_on_success: bool, - states_current_result: Option<&Result, E>>, - states_goal_result: Option<&Result, E>>, + states_current_result: Option<&Result, AppErrorT>>, + states_goal_result: Option<&Result, AppErrorT>>, ) -> Option<(ProgressUpdate, ProgressMsgUpdate)> where - E: std::error::Error + From + Send + 'static; + AppErrorT: peace_value_traits::AppError + From; } #[async_trait::async_trait(?Send)] impl Discover for DiscoverForCurrent { - async fn discover( - item: &ItemBoxed, + async fn discover( + item: &ItemBoxed, params_specs: &peace_params::ParamsSpecs, resources: &Resources, fn_ctx: FnCtx<'_>, ) -> ( - Option, E>>, - Option, E>>, + Option, AppErrorT>>, + Option, AppErrorT>>, ) where - E: std::error::Error + From + Send + 'static, + AppErrorT: peace_value_traits::AppError + From, { let states_current_result = item .state_current_try_exec(params_specs, resources, fn_ctx) @@ -733,13 +763,13 @@ impl Discover for DiscoverForCurrent { } #[cfg(feature = "output_progress")] - fn progress_update( + fn progress_update( progress_complete_on_success: bool, - states_current_result: Option<&Result, E>>, - _states_goal_result: Option<&Result, E>>, + states_current_result: Option<&Result, AppErrorT>>, + _states_goal_result: Option<&Result, AppErrorT>>, ) -> Option<(ProgressUpdate, ProgressMsgUpdate)> where - E: std::error::Error + From + Send + 'static, + AppErrorT: peace_value_traits::AppError + From, { states_current_result.map(|states_current_result| match states_current_result { Ok(_) => { @@ -761,17 +791,17 @@ impl Discover for DiscoverForCurrent { #[async_trait::async_trait(?Send)] impl Discover for DiscoverForGoal { - async fn discover( - item: &ItemBoxed, + async fn discover( + item: &ItemBoxed, params_specs: &peace_params::ParamsSpecs, resources: &Resources, fn_ctx: FnCtx<'_>, ) -> ( - Option, E>>, - Option, E>>, + Option, AppErrorT>>, + Option, AppErrorT>>, ) where - E: std::error::Error + From + Send + 'static, + AppErrorT: peace_value_traits::AppError + From, { let states_goal_result = item .state_goal_try_exec(params_specs, resources, fn_ctx) @@ -781,13 +811,13 @@ impl Discover for DiscoverForGoal { } #[cfg(feature = "output_progress")] - fn progress_update( + fn progress_update( progress_complete_on_success: bool, - _states_current_result: Option<&Result, E>>, - states_goal_result: Option<&Result, E>>, + _states_current_result: Option<&Result, AppErrorT>>, + states_goal_result: Option<&Result, AppErrorT>>, ) -> Option<(ProgressUpdate, ProgressMsgUpdate)> where - E: std::error::Error + From + Send + 'static, + AppErrorT: peace_value_traits::AppError + From, { states_goal_result.map(|states_goal_result| match states_goal_result { Ok(_) => { @@ -809,17 +839,17 @@ impl Discover for DiscoverForGoal { #[async_trait::async_trait(?Send)] impl Discover for DiscoverForCurrentAndGoal { - async fn discover( - item: &ItemBoxed, + async fn discover( + item: &ItemBoxed, params_specs: &peace_params::ParamsSpecs, resources: &Resources, fn_ctx: FnCtx<'_>, ) -> ( - Option, E>>, - Option, E>>, + Option, AppErrorT>>, + Option, AppErrorT>>, ) where - E: std::error::Error + From + Send + 'static, + AppErrorT: peace_value_traits::AppError + From, { let states_current_result = item .state_current_try_exec(params_specs, resources, fn_ctx) @@ -832,13 +862,13 @@ impl Discover for DiscoverForCurrentAndGoal { } #[cfg(feature = "output_progress")] - fn progress_update( + fn progress_update( progress_complete_on_success: bool, - states_current_result: Option<&Result, E>>, - states_goal_result: Option<&Result, E>>, + states_current_result: Option<&Result, AppErrorT>>, + states_goal_result: Option<&Result, AppErrorT>>, ) -> Option<(ProgressUpdate, ProgressMsgUpdate)> where - E: std::error::Error + From + Send + 'static, + AppErrorT: peace_value_traits::AppError + From, { states_current_result .zip(states_goal_result) diff --git a/crate/rt/src/cmd_blocks/states_goal_read_cmd_block.rs b/crate/rt/src/cmd_blocks/states_goal_read_cmd_block.rs index 9d6d0cafa..e5e447f92 100644 --- a/crate/rt/src/cmd_blocks/states_goal_read_cmd_block.rs +++ b/crate/rt/src/cmd_blocks/states_goal_read_cmd_block.rs @@ -1,7 +1,7 @@ use std::{fmt::Debug, marker::PhantomData}; use peace_cfg::{FlowId, ItemId}; -use peace_cmd::scopes::SingleProfileSingleFlowView; +use peace_cmd::{ctx::CmdCtxTypesConstrained, scopes::SingleProfileSingleFlowView}; use peace_cmd_model::CmdBlockOutcome; use peace_cmd_rt::{async_trait, CmdBlock}; use peace_resources::{ @@ -11,7 +11,7 @@ use peace_resources::{ type_reg::untagged::{BoxDtDisplay, TypeReg}, ResourceFetchError, Resources, }; -use peace_rt_model::{params::ParamsKeys, Error, StatesSerializer, Storage}; +use peace_rt_model::{StatesSerializer, Storage}; cfg_if::cfg_if! { if #[cfg(feature = "output_progress")] { @@ -28,12 +28,11 @@ cfg_if::cfg_if! { /// /// [`StatesDiscoverCmd`]: crate::StatesDiscoverCmd #[derive(Debug)] -pub struct StatesGoalReadCmdBlock(PhantomData<(E, PKeys)>); +pub struct StatesGoalReadCmdBlock(PhantomData); -impl StatesGoalReadCmdBlock +impl StatesGoalReadCmdBlock where - E: std::error::Error + From + Send + 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { /// Returns a new `StatesGoalReadCmdBlock`. pub fn new() -> Self { @@ -43,7 +42,7 @@ where pub(crate) async fn deserialize_internal( resources: &mut Resources, states_type_reg: &TypeReg, - ) -> Result { + ) -> Result::AppError> { let flow_id = resources.borrow::(); let flow_dir = resources.borrow::(); let storage = resources.borrow::(); @@ -67,22 +66,20 @@ where } } -impl Default for StatesGoalReadCmdBlock { +impl Default for StatesGoalReadCmdBlock { fn default() -> Self { Self(PhantomData) } } #[async_trait(?Send)] -impl CmdBlock for StatesGoalReadCmdBlock +impl CmdBlock for StatesGoalReadCmdBlock where - E: std::error::Error + From + Send + 'static, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { - type Error = E; + type CmdCtxTypes = CmdCtxTypesT; type InputT = (); type Outcome = StatesGoalStored; - type PKeys = PKeys; fn input_fetch(&self, _resources: &mut Resources) -> Result<(), ResourceFetchError> { Ok(()) @@ -95,9 +92,12 @@ where async fn exec( &self, _input: Self::InputT, - cmd_view: &mut SingleProfileSingleFlowView<'_, Self::Error, Self::PKeys, SetUp>, + cmd_view: &mut SingleProfileSingleFlowView<'_, Self::CmdCtxTypes, SetUp>, #[cfg(feature = "output_progress")] _progress_tx: &Sender, - ) -> Result, Self::Error> { + ) -> Result< + CmdBlockOutcome::AppError>, + ::AppError, + > { let SingleProfileSingleFlowView { states_type_reg, resources, diff --git a/crate/rt/src/cmds/clean_cmd.rs b/crate/rt/src/cmds/clean_cmd.rs index 92188e61a..1689f9286 100644 --- a/crate/rt/src/cmds/clean_cmd.rs +++ b/crate/rt/src/cmds/clean_cmd.rs @@ -1,7 +1,7 @@ use std::{fmt::Debug, marker::PhantomData}; use peace_cmd::{ - ctx::CmdCtx, + ctx::{CmdCtx, CmdCtxTypesConstrained}, scopes::{SingleProfileSingleFlow, SingleProfileSingleFlowView}, }; use peace_cmd_model::CmdOutcome; @@ -12,7 +12,7 @@ use peace_resources::{ states::{States, StatesCleaned, StatesCleanedDry, StatesPrevious}, Resources, }; -use peace_rt_model::{output::OutputWrite, params::ParamsKeys, Error, ItemGraph, Storage}; +use peace_rt_model::{ItemGraph, Storage}; use crate::{ cmd_blocks::{ @@ -23,13 +23,11 @@ use crate::{ }; #[derive(Debug)] -pub struct CleanCmd(PhantomData<(E, O, PKeys)>); +pub struct CleanCmd(PhantomData); -impl CleanCmd +impl CleanCmd where - E: std::error::Error + From + Send + Sync + Unpin + 'static, - PKeys: ParamsKeys + 'static, - O: OutputWrite, + CmdCtxTypesT: CmdCtxTypesConstrained, { /// Conditionally runs [`Item::apply_exec_dry`] for each [`Item`]. /// @@ -63,8 +61,14 @@ where /// [`Item::apply_exec_dry`]: peace_cfg::ItemRt::apply_exec_dry /// [`Item`]: peace_cfg::Item pub async fn exec_dry<'ctx>( - cmd_ctx: &mut CmdCtx>, - ) -> Result, E> { + cmd_ctx: &mut CmdCtx>, + ) -> Result< + CmdOutcome::AppError>, + ::AppError, + > + where + CmdCtxTypesT: 'ctx, + { Self::exec_dry_with(cmd_ctx, ApplyStoredStateSync::Both).await } @@ -75,9 +79,15 @@ where /// This function exists so that this command can be executed as sub /// functionality of another command. pub async fn exec_dry_with<'ctx>( - cmd_ctx: &mut CmdCtx>, + cmd_ctx: &mut CmdCtx>, apply_stored_state_sync: ApplyStoredStateSync, - ) -> Result, E> { + ) -> Result< + CmdOutcome::AppError>, + ::AppError, + > + where + CmdCtxTypesT: 'ctx, + { let cmd_outcome = Self::exec_internal(cmd_ctx, apply_stored_state_sync).await?; let cmd_outcome = cmd_outcome.map(|clean_exec_change| match clean_exec_change { @@ -128,8 +138,14 @@ where /// [`Item::apply_exec`]: peace_cfg::ItemRt::apply_exec /// [`Item`]: peace_cfg::Item pub async fn exec<'ctx>( - cmd_ctx: &mut CmdCtx>, - ) -> Result, E> { + cmd_ctx: &mut CmdCtx>, + ) -> Result< + CmdOutcome::AppError>, + ::AppError, + > + where + CmdCtxTypesT: 'ctx, + { Self::exec_with(cmd_ctx, ApplyStoredStateSync::Both).await } @@ -140,9 +156,15 @@ where /// This function exists so that this command can be executed as sub /// functionality of another command. pub async fn exec_with<'ctx, 'ctx_ref>( - cmd_ctx: &'ctx_ref mut CmdCtx>, + cmd_ctx: &'ctx_ref mut CmdCtx>, apply_stored_state_sync: ApplyStoredStateSync, - ) -> Result, E> { + ) -> Result< + CmdOutcome::AppError>, + ::AppError, + > + where + CmdCtxTypesT: 'ctx, + { let cmd_outcome = Self::exec_internal(cmd_ctx, apply_stored_state_sync).await?; let SingleProfileSingleFlowView { @@ -180,28 +202,31 @@ where /// [`Item`]: peace_cfg::Item /// [`ApplyFns`]: peace_cfg::Item::ApplyFns async fn exec_internal<'ctx, 'ctx_ref, StatesTs>( - cmd_ctx: &'ctx_ref mut CmdCtx>, + cmd_ctx: &'ctx_ref mut CmdCtx>, apply_stored_state_sync: ApplyStoredStateSync, - ) -> Result, E>, E> + ) -> Result< + CmdOutcome, ::AppError>, + ::AppError, + > where + CmdCtxTypesT: 'ctx, StatesTs: StatesTsApplyExt + Debug + Send + Sync + Unpin + 'static, { let mut cmd_execution = { - let mut cmd_execution_builder = - CmdExecution::, _, _>::builder() - .with_cmd_block(CmdBlockWrapper::new( - StatesCurrentReadCmdBlock::new(), - |_states_current_stored| CleanExecChange::None, - )) - // Always discover current states, as we need them to be able to clean up. - .with_cmd_block(CmdBlockWrapper::new( - StatesDiscoverCmdBlock::current(), - |_states_current_mut| CleanExecChange::None, - )) - .with_cmd_block(CmdBlockWrapper::new( - StatesCleanInsertionCmdBlock::new(), - |_states_clean| CleanExecChange::None, - )); + let mut cmd_execution_builder = CmdExecution::, _>::builder() + .with_cmd_block(CmdBlockWrapper::new( + StatesCurrentReadCmdBlock::new(), + |_states_current_stored| CleanExecChange::None, + )) + // Always discover current states, as we need them to be able to clean up. + .with_cmd_block(CmdBlockWrapper::new( + StatesDiscoverCmdBlock::current(), + |_states_current_mut| CleanExecChange::None, + )) + .with_cmd_block(CmdBlockWrapper::new( + StatesCleanInsertionCmdBlock::new(), + |_states_clean| CleanExecChange::None, + )); cmd_execution_builder = match apply_stored_state_sync { // Data modelling doesn't work well here -- for `CleanCmd` we don't check if the @@ -219,7 +244,7 @@ where cmd_execution_builder .with_cmd_block(CmdBlockWrapper::new( - ApplyExecCmdBlock::::new(), + ApplyExecCmdBlock::::new(), |(states_previous, states_applied_mut, _states_target_mut)| { CleanExecChange::Some(Box::new((states_previous, states_applied_mut))) }, @@ -255,10 +280,10 @@ where // TODO: This duplicates a bit of code with `StatesDiscoverCmd`, async fn serialize_current( - item_graph: &ItemGraph, + item_graph: &ItemGraph<::AppError>, resources: &Resources, states_cleaned: &StatesCleaned, - ) -> Result<(), E> { + ) -> Result<(), ::AppError> { use peace_rt_model::StatesSerializer; let flow_dir = resources.borrow::(); @@ -275,7 +300,7 @@ where } } -impl Default for CleanCmd { +impl Default for CleanCmd { fn default() -> Self { Self(PhantomData) } diff --git a/crate/rt/src/cmds/diff_cmd.rs b/crate/rt/src/cmds/diff_cmd.rs index 27276abf9..bbb333c5d 100644 --- a/crate/rt/src/cmds/diff_cmd.rs +++ b/crate/rt/src/cmds/diff_cmd.rs @@ -3,7 +3,7 @@ use std::{fmt::Debug, marker::PhantomData}; use futures::{StreamExt, TryStreamExt}; use peace_cfg::{ItemId, Profile}; use peace_cmd::{ - ctx::CmdCtx, + ctx::{CmdCtx, CmdCtxTypesConstrained}, scopes::{MultiProfileSingleFlow, MultiProfileSingleFlowView, SingleProfileSingleFlow}, }; use peace_cmd_model::CmdOutcome; @@ -19,7 +19,7 @@ use peace_resources::{ type_reg::untagged::{BoxDtDisplay, TypeMap}, Resources, }; -use peace_rt_model::{output::OutputWrite, params::ParamsKeys, Error, Flow}; +use peace_rt_model::{Error, Flow}; use crate::cmd_blocks::{ DiffCmdBlock, DiffCmdBlockStatesTsExt, StatesCurrentReadCmdBlock, StatesDiscoverCmdBlock, @@ -31,20 +31,17 @@ pub use self::{diff_info_spec::DiffInfoSpec, diff_state_spec::DiffStateSpec}; mod diff_info_spec; mod diff_state_spec; -pub struct DiffCmd<'cmd, E, O, PKeys, Scope>(PhantomData<(E, &'cmd O, PKeys, Scope)>); +pub struct DiffCmd(PhantomData<(CmdCtxTypesT, Scope)>); -impl<'cmd, E, O, PKeys, Scope> Debug for DiffCmd<'cmd, E, O, PKeys, Scope> { +impl Debug for DiffCmd { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_tuple("DiffCmd").field(&self.0).finish() } } -impl<'cmd, E, O, PKeys> - DiffCmd<'cmd, E, O, PKeys, SingleProfileSingleFlow<'cmd, E, O, PKeys, SetUp>> +impl<'ctx, CmdCtxTypesT> DiffCmd> where - E: std::error::Error + From + Send + Sync + Unpin + 'static, - O: OutputWrite + 'cmd, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained + 'ctx, { /// Returns the [`state_diff`]`s between the stored current and goal /// states. @@ -60,9 +57,12 @@ where /// /// [`state_diff`]: peace_cfg::Item::state_diff /// [`StatesDiscoverCmd::current_and_goal`]: crate::cmds::StatesDiscoverCmd::current_and_goal - pub async fn diff_stored<'ctx>( - cmd_ctx: &mut CmdCtx>, - ) -> Result, E> { + pub async fn diff_stored( + cmd_ctx: &mut CmdCtx>, + ) -> Result< + CmdOutcome::AppError>, + ::AppError, + > { Self::diff::(cmd_ctx).await } @@ -76,14 +76,17 @@ where /// /// [`state_diff`]: peace_cfg::Item::state_diff /// [`StatesDiscoverCmd::current_and_goal`]: crate::cmds::StatesDiscoverCmd::current_and_goal - pub async fn diff<'ctx, StatesTs0, StatesTs1>( - cmd_ctx: &mut CmdCtx>, - ) -> Result, E> + pub async fn diff( + cmd_ctx: &mut CmdCtx>, + ) -> Result< + CmdOutcome::AppError>, + ::AppError, + > where StatesTs0: Debug + DiffCmdBlockStatesTsExt + Send + Sync + Unpin + 'static, StatesTs1: Debug + DiffCmdBlockStatesTsExt + Send + Sync + Unpin + 'static, { - let mut cmd_execution_builder = CmdExecution::::builder(); + let mut cmd_execution_builder = CmdExecution::::builder(); cmd_execution_builder = Self::states_fetch_cmd_block_append( cmd_execution_builder, StatesTs0::diff_state_spec(), @@ -94,7 +97,7 @@ where ); cmd_execution_builder = cmd_execution_builder.with_cmd_block(CmdBlockWrapper::new( - DiffCmdBlock::<_, _, StatesTs0, StatesTs1>::new(), + DiffCmdBlock::<_, StatesTs0, StatesTs1>::new(), |_state_diffs_ts0_and_ts1| StateDiffs::new(), )); @@ -105,9 +108,9 @@ where } fn states_fetch_cmd_block_append( - cmd_execution_builder: CmdExecutionBuilder, + cmd_execution_builder: CmdExecutionBuilder<'ctx, StateDiffs, CmdCtxTypesT>, diff_state_spec: DiffStateSpec, - ) -> CmdExecutionBuilder { + ) -> CmdExecutionBuilder<'ctx, StateDiffs, CmdCtxTypesT> { match diff_state_spec { DiffStateSpec::Current => cmd_execution_builder.with_cmd_block(CmdBlockWrapper::new( StatesDiscoverCmdBlock::current(), @@ -130,11 +133,9 @@ where } } -impl<'cmd, E, O, PKeys> DiffCmd<'cmd, E, O, PKeys, MultiProfileSingleFlow<'cmd, E, O, PKeys, SetUp>> +impl<'ctx, CmdCtxTypesT> DiffCmd> where - E: std::error::Error + From + Send + 'static, - O: OutputWrite + 'cmd, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { /// Returns the [`state_diff`]`s between the stored current states of two /// profiles. @@ -144,11 +145,11 @@ where /// /// [`state_diff`]: peace_cfg::Item::state_diff /// [`StatesDiscoverCmd::current`]: crate::cmds::StatesDiscoverCmd::current - pub async fn diff_current_stored<'ctx>( - cmd_ctx: &mut CmdCtx>, + pub async fn diff_current_stored( + cmd_ctx: &mut CmdCtx>, profile_a: &Profile, profile_b: &Profile, - ) -> Result { + ) -> Result::AppError> { let MultiProfileSingleFlowView { flow, profiles, @@ -204,11 +205,9 @@ where } } -impl<'cmd, E, O, PKeys, Scope> DiffCmd<'cmd, E, O, PKeys, Scope> +impl DiffCmd where - E: std::error::Error + From + Send + 'static, - O: OutputWrite + 'cmd, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { /// Returns the [`state_diff`]` for each [`Item`]. /// @@ -219,17 +218,17 @@ where /// [`Item`]: peace_cfg::Item /// [`state_diff`]: peace_cfg::Item::state_diff pub async fn diff_any( - flow: &Flow, + flow: &Flow<::AppError>, params_specs: &ParamsSpecs, resources: &Resources, states_a: &TypeMap, states_b: &TypeMap, - ) -> Result { + ) -> Result::AppError> { let state_diffs = { let state_diffs_mut = flow .graph() .stream() - .map(Result::<_, E>::Ok) + .map(Result::<_, ::AppError>::Ok) .try_filter_map(|item| async move { let state_diff_opt = item .state_diff_exec(params_specs, resources, states_a, states_b) @@ -247,7 +246,7 @@ where } } -impl<'cmd, E, O, PKeys, Scope> Default for DiffCmd<'cmd, E, O, PKeys, Scope> { +impl Default for DiffCmd { fn default() -> Self { Self(PhantomData) } diff --git a/crate/rt/src/cmds/ensure_cmd.rs b/crate/rt/src/cmds/ensure_cmd.rs index 29aff8ce8..36f266388 100644 --- a/crate/rt/src/cmds/ensure_cmd.rs +++ b/crate/rt/src/cmds/ensure_cmd.rs @@ -1,7 +1,7 @@ use std::{fmt::Debug, marker::PhantomData}; use peace_cmd::{ - ctx::CmdCtx, + ctx::{CmdCtx, CmdCtxTypesConstrained}, scopes::{SingleProfileSingleFlow, SingleProfileSingleFlowView}, }; use peace_cmd_model::CmdOutcome; @@ -12,7 +12,7 @@ use peace_resources::{ states::{States, StatesEnsured, StatesEnsuredDry, StatesGoal, StatesPrevious}, Resources, }; -use peace_rt_model::{output::OutputWrite, params::ParamsKeys, Error, ItemGraph, Storage}; +use peace_rt_model::{ItemGraph, Storage}; use crate::{ cmd_blocks::{ @@ -23,13 +23,11 @@ use crate::{ }; #[derive(Debug)] -pub struct EnsureCmd(PhantomData<(E, O, PKeys)>); +pub struct EnsureCmd(PhantomData); -impl EnsureCmd +impl EnsureCmd where - E: std::error::Error + From + Send + Sync + Unpin + 'static, - PKeys: ParamsKeys + 'static, - O: OutputWrite, + CmdCtxTypesT: CmdCtxTypesConstrained, { /// Conditionally runs [`Item::apply_exec_dry`] for each [`Item`]. /// @@ -55,8 +53,14 @@ where /// [`Item::apply_exec_dry`]: peace_cfg::ItemRt::apply_exec_dry /// [`Item`]: peace_cfg::Item pub async fn exec_dry<'ctx>( - cmd_ctx: &mut CmdCtx>, - ) -> Result, E> { + cmd_ctx: &mut CmdCtx>, + ) -> Result< + CmdOutcome::AppError>, + ::AppError, + > + where + CmdCtxTypesT: 'ctx, + { Self::exec_dry_with(cmd_ctx, ApplyStoredStateSync::Both).await } @@ -67,9 +71,15 @@ where /// This function exists so that this command can be executed as sub /// functionality of another command. pub async fn exec_dry_with<'ctx>( - cmd_ctx: &mut CmdCtx>, + cmd_ctx: &mut CmdCtx>, apply_stored_state_sync: ApplyStoredStateSync, - ) -> Result, E> { + ) -> Result< + CmdOutcome::AppError>, + ::AppError, + > + where + CmdCtxTypesT: 'ctx, + { let cmd_outcome = Self::exec_internal(cmd_ctx, apply_stored_state_sync).await?; let cmd_outcome = cmd_outcome.map(|ensure_exec_change| match ensure_exec_change { @@ -112,8 +122,14 @@ where /// [`Item::apply_exec`]: peace_cfg::ItemRt::apply_exec /// [`Item`]: peace_cfg::Item pub async fn exec<'ctx>( - cmd_ctx: &mut CmdCtx>, - ) -> Result, E> { + cmd_ctx: &mut CmdCtx>, + ) -> Result< + CmdOutcome::AppError>, + ::AppError, + > + where + CmdCtxTypesT: 'ctx, + { Self::exec_with(cmd_ctx, ApplyStoredStateSync::Both).await } @@ -124,9 +140,15 @@ where /// This function exists so that this command can be executed as sub /// functionality of another command. pub async fn exec_with<'ctx>( - cmd_ctx: &mut CmdCtx>, + cmd_ctx: &mut CmdCtx>, apply_stored_state_sync: ApplyStoredStateSync, - ) -> Result, E> { + ) -> Result< + CmdOutcome::AppError>, + ::AppError, + > + where + CmdCtxTypesT: 'ctx, + { let cmd_outcome = Self::exec_internal(cmd_ctx, apply_stored_state_sync).await?; let SingleProfileSingleFlowView { @@ -165,15 +187,19 @@ where /// [`Item`]: peace_cfg::Item /// [`ApplyFns`]: peace_cfg::Item::ApplyFns async fn exec_internal<'ctx, StatesTs>( - cmd_ctx: &mut CmdCtx>, + cmd_ctx: &mut CmdCtx>, apply_stored_state_sync: ApplyStoredStateSync, - ) -> Result, E>, E> + ) -> Result< + CmdOutcome, ::AppError>, + ::AppError, + > where + CmdCtxTypesT: 'ctx, StatesTs: StatesTsApplyExt + Debug + Send + Sync + Unpin + 'static, { let mut cmd_execution = { let mut cmd_execution_builder = - CmdExecution::, _, _>::builder() + CmdExecution::, _>::builder() .with_cmd_block(CmdBlockWrapper::new( StatesCurrentReadCmdBlock::new(), |_states_current_stored| EnsureExecChange::None, @@ -213,7 +239,7 @@ where cmd_execution_builder .with_cmd_block(CmdBlockWrapper::new( - ApplyExecCmdBlock::::new(), + ApplyExecCmdBlock::::new(), |(states_previous, states_applied, states_target): ( StatesPrevious, States, @@ -266,10 +292,10 @@ where // TODO: This duplicates a bit of code with `StatesDiscoverCmd`, async fn serialize_current( - item_graph: &ItemGraph, + item_graph: &ItemGraph<::AppError>, resources: &Resources, states_applied: &StatesEnsured, - ) -> Result<(), E> { + ) -> Result<(), ::AppError> { use peace_rt_model::StatesSerializer; let flow_dir = resources.borrow::(); @@ -286,10 +312,10 @@ where } async fn serialize_goal( - item_graph: &ItemGraph, + item_graph: &ItemGraph<::AppError>, resources: &Resources, states_goal: &StatesGoal, - ) -> Result<(), E> { + ) -> Result<(), ::AppError> { use peace_rt_model::StatesSerializer; let flow_dir = resources.borrow::(); @@ -305,7 +331,7 @@ where } } -impl Default for EnsureCmd { +impl Default for EnsureCmd { fn default() -> Self { Self(PhantomData) } diff --git a/crate/rt/src/cmds/states_current_read_cmd.rs b/crate/rt/src/cmds/states_current_read_cmd.rs index c1316490d..56bd7ef7d 100644 --- a/crate/rt/src/cmds/states_current_read_cmd.rs +++ b/crate/rt/src/cmds/states_current_read_cmd.rs @@ -1,23 +1,22 @@ use std::{fmt::Debug, marker::PhantomData}; -use peace_cmd::{ctx::CmdCtx, scopes::SingleProfileSingleFlow}; +use peace_cmd::{ + ctx::{CmdCtx, CmdCtxTypesConstrained}, + scopes::SingleProfileSingleFlow, +}; use peace_cmd_model::CmdOutcome; use peace_cmd_rt::{CmdBlockWrapper, CmdExecution}; use peace_resources::{resources::ts::SetUp, states::StatesCurrentStored}; -use peace_rt_model::{params::ParamsKeys, Error}; -use peace_rt_model_core::output::OutputWrite; use crate::cmd_blocks::StatesCurrentReadCmdBlock; /// Reads [`StatesCurrentStored`]s from storage. #[derive(Debug)] -pub struct StatesCurrentReadCmd(PhantomData<(E, O, PKeys)>); +pub struct StatesCurrentReadCmd(PhantomData); -impl StatesCurrentReadCmd +impl StatesCurrentReadCmd where - E: std::error::Error + From + Send + Sync + Unpin + 'static, - O: OutputWrite, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { /// Reads [`StatesCurrentStored`]s from storage. /// @@ -27,12 +26,19 @@ where /// [`StatesCurrentStoredDiscoverCmd`]: crate::StatesCurrentStoredDiscoverCmd /// [`StatesDiscoverCmd`]: crate::StatesDiscoverCmd pub async fn exec<'ctx>( - cmd_ctx: &mut CmdCtx>, - ) -> Result, E> { - let cmd_execution_builder = - CmdExecution::::builder().with_cmd_block( - CmdBlockWrapper::new(StatesCurrentReadCmdBlock::new(), std::convert::identity), - ); + cmd_ctx: &mut CmdCtx>, + ) -> Result< + CmdOutcome::AppError>, + ::AppError, + > + where + CmdCtxTypesT: 'ctx, + { + let cmd_execution_builder = CmdExecution::::builder() + .with_cmd_block(CmdBlockWrapper::new( + StatesCurrentReadCmdBlock::new(), + std::convert::identity, + )); #[cfg(feature = "output_progress")] let cmd_execution_builder = cmd_execution_builder.with_progress_render_enabled(false); @@ -41,7 +47,7 @@ where } } -impl Default for StatesCurrentReadCmd { +impl Default for StatesCurrentReadCmd { fn default() -> Self { Self(PhantomData) } diff --git a/crate/rt/src/cmds/states_current_stored_display_cmd.rs b/crate/rt/src/cmds/states_current_stored_display_cmd.rs index 31a55f484..c1e5eb705 100644 --- a/crate/rt/src/cmds/states_current_stored_display_cmd.rs +++ b/crate/rt/src/cmds/states_current_stored_display_cmd.rs @@ -1,22 +1,22 @@ use std::{fmt::Debug, marker::PhantomData}; -use peace_cmd::{ctx::CmdCtx, scopes::SingleProfileSingleFlow}; +use peace_cmd::{ + ctx::{CmdCtx, CmdCtxTypesConstrained}, + scopes::SingleProfileSingleFlow, +}; use peace_cmd_model::CmdOutcome; use peace_resources::{resources::ts::SetUp, states::StatesCurrentStored}; -use peace_rt_model::{params::ParamsKeys, Error}; use peace_rt_model_core::output::OutputWrite; use crate::cmds::StatesCurrentReadCmd; /// Displays [`StatesCurrent`]s from storage. #[derive(Debug)] -pub struct StatesCurrentStoredDisplayCmd(PhantomData<(E, O, PKeys)>); +pub struct StatesCurrentStoredDisplayCmd(PhantomData); -impl StatesCurrentStoredDisplayCmd +impl StatesCurrentStoredDisplayCmd where - E: std::error::Error + From + Send + Sync + Unpin + 'static, - PKeys: ParamsKeys + 'static, - O: OutputWrite, + CmdCtxTypesT: CmdCtxTypesConstrained, { /// Displays [`StatesCurrentStored`]s from storage. /// @@ -25,8 +25,14 @@ where /// /// [`StatesDiscoverCmd`]: crate::StatesDiscoverCmd pub async fn exec<'ctx>( - cmd_ctx: &mut CmdCtx>, - ) -> Result, E> { + cmd_ctx: &mut CmdCtx>, + ) -> Result< + CmdOutcome::AppError>, + ::AppError, + > + where + CmdCtxTypesT: 'ctx, + { let states_current_stored_result = StatesCurrentReadCmd::exec(cmd_ctx).await; let output = cmd_ctx.output_mut(); @@ -45,7 +51,7 @@ where } } -impl Default for StatesCurrentStoredDisplayCmd { +impl Default for StatesCurrentStoredDisplayCmd { fn default() -> Self { Self(PhantomData) } diff --git a/crate/rt/src/cmds/states_discover_cmd.rs b/crate/rt/src/cmds/states_discover_cmd.rs index 81d549d5d..8e2853d61 100644 --- a/crate/rt/src/cmds/states_discover_cmd.rs +++ b/crate/rt/src/cmds/states_discover_cmd.rs @@ -1,7 +1,7 @@ use std::{fmt::Debug, marker::PhantomData}; use peace_cmd::{ - ctx::CmdCtx, + ctx::{CmdCtx, CmdCtxTypesConstrained}, scopes::{SingleProfileSingleFlow, SingleProfileSingleFlowView}, }; use peace_cmd_model::CmdOutcome; @@ -12,23 +12,21 @@ use peace_resources::{ states::{StatesCurrent, StatesGoal}, Resources, }; -use peace_rt_model::{output::OutputWrite, params::ParamsKeys, Error, ItemGraph, Storage}; +use peace_rt_model::{ItemGraph, Storage}; use crate::cmd_blocks::StatesDiscoverCmdBlock; -pub struct StatesDiscoverCmd(PhantomData<(E, O, PKeys)>); +pub struct StatesDiscoverCmd(PhantomData); -impl Debug for StatesDiscoverCmd { +impl Debug for StatesDiscoverCmd { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_tuple("StatesDiscoverCmd").field(&self.0).finish() } } -impl StatesDiscoverCmd +impl StatesDiscoverCmd where - E: std::error::Error + From + Send + Sync + Unpin + 'static, - O: OutputWrite, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { /// Runs [`try_state_current`] for each [`Item`]. /// @@ -49,8 +47,14 @@ where /// [`Item`]: peace_cfg::Item /// [`try_state_current`]: peace_cfg::Item::try_state_current pub async fn current<'ctx>( - cmd_ctx: &mut CmdCtx>, - ) -> Result, E> { + cmd_ctx: &mut CmdCtx>, + ) -> Result< + CmdOutcome::AppError>, + ::AppError, + > + where + CmdCtxTypesT: 'ctx, + { Self::current_with(cmd_ctx, true).await } @@ -69,10 +73,16 @@ where /// /// [`try_state_current`]: peace_cfg::Item::try_state_current pub async fn current_with<'ctx>( - cmd_ctx: &mut CmdCtx>, + cmd_ctx: &mut CmdCtx>, serialize_to_storage: bool, - ) -> Result, E> { - let mut cmd_execution = CmdExecution::::builder() + ) -> Result< + CmdOutcome::AppError>, + ::AppError, + > + where + CmdCtxTypesT: 'ctx, + { + let mut cmd_execution = CmdExecution::::builder() .with_cmd_block(CmdBlockWrapper::new( #[cfg(not(feature = "output_progress"))] StatesDiscoverCmdBlock::current(), @@ -117,8 +127,14 @@ where /// [`Item`]: peace_cfg::Item /// [`try_state_goal`]: peace_cfg::Item::try_state_goal pub async fn goal<'ctx>( - cmd_ctx: &mut CmdCtx>, - ) -> Result, E> { + cmd_ctx: &mut CmdCtx>, + ) -> Result< + CmdOutcome::AppError>, + ::AppError, + > + where + CmdCtxTypesT: 'ctx, + { Self::goal_with(cmd_ctx, true).await } @@ -137,10 +153,16 @@ where /// /// [`try_state_goal`]: peace_cfg::Item::try_state_goal pub async fn goal_with<'ctx>( - cmd_ctx: &mut CmdCtx>, + cmd_ctx: &mut CmdCtx>, serialize_to_storage: bool, - ) -> Result, E> { - let mut cmd_execution = CmdExecution::::builder() + ) -> Result< + CmdOutcome::AppError>, + ::AppError, + > + where + CmdCtxTypesT: 'ctx, + { + let mut cmd_execution = CmdExecution::::builder() .with_cmd_block(CmdBlockWrapper::new( #[cfg(not(feature = "output_progress"))] StatesDiscoverCmdBlock::goal(), @@ -194,8 +216,14 @@ where /// [`try_state_current`]: peace_cfg::Item::try_state_current /// [`try_state_goal`]: peace_cfg::Item::try_state_goal pub async fn current_and_goal<'ctx>( - cmd_ctx: &mut CmdCtx>, - ) -> Result, E> { + cmd_ctx: &mut CmdCtx>, + ) -> Result< + CmdOutcome<(StatesCurrent, StatesGoal), ::AppError>, + ::AppError, + > + where + CmdCtxTypesT: 'ctx, + { Self::current_and_goal_with(cmd_ctx, true).await } @@ -216,10 +244,16 @@ where /// [`try_state_current`]: peace_cfg::Item::try_state_current /// [`try_state_goal`]: peace_cfg::Item::try_state_goal pub async fn current_and_goal_with<'ctx>( - cmd_ctx: &mut CmdCtx>, + cmd_ctx: &mut CmdCtx>, serialize_to_storage: bool, - ) -> Result, E> { - let mut cmd_execution = CmdExecution::<(StatesCurrent, StatesGoal), _, _>::builder() + ) -> Result< + CmdOutcome<(StatesCurrent, StatesGoal), ::AppError>, + ::AppError, + > + where + CmdCtxTypesT: 'ctx, + { + let mut cmd_execution = CmdExecution::<(StatesCurrent, StatesGoal), _>::builder() .with_cmd_block(CmdBlockWrapper::new( #[cfg(not(feature = "output_progress"))] StatesDiscoverCmdBlock::current_and_goal(), @@ -261,10 +295,10 @@ where // TODO: This duplicates a bit of code with `EnsureCmd` and `CleanCmd`. async fn serialize_current( - item_graph: &ItemGraph, + item_graph: &ItemGraph<::AppError>, resources: &mut Resources, states_current: &StatesCurrent, - ) -> Result<(), E> { + ) -> Result<(), ::AppError> { use peace_rt_model::StatesSerializer; let flow_dir = resources.borrow::(); @@ -283,10 +317,10 @@ where } async fn serialize_goal( - item_graph: &ItemGraph, + item_graph: &ItemGraph<::AppError>, resources: &mut Resources, states_goal: &StatesGoal, - ) -> Result<(), E> { + ) -> Result<(), ::AppError> { use peace_rt_model::StatesSerializer; let flow_dir = resources.borrow::(); @@ -304,7 +338,7 @@ where } } -impl Default for StatesDiscoverCmd { +impl Default for StatesDiscoverCmd { fn default() -> Self { Self(PhantomData) } diff --git a/crate/rt/src/cmds/states_goal_display_cmd.rs b/crate/rt/src/cmds/states_goal_display_cmd.rs index ae0b4f9c5..25063eeaf 100644 --- a/crate/rt/src/cmds/states_goal_display_cmd.rs +++ b/crate/rt/src/cmds/states_goal_display_cmd.rs @@ -1,22 +1,23 @@ use std::{fmt::Debug, marker::PhantomData}; -use peace_cmd::{ctx::CmdCtx, scopes::SingleProfileSingleFlow}; +use peace_cmd::{ + ctx::{CmdCtx, CmdCtxTypesConstrained}, + scopes::SingleProfileSingleFlow, +}; use peace_cmd_model::CmdOutcome; use peace_resources::{resources::ts::SetUp, states::StatesGoalStored}; -use peace_rt_model::{params::ParamsKeys, Error}; + use peace_rt_model_core::output::OutputWrite; use crate::cmds::StatesGoalReadCmd; /// Displays [`StatesGoal`]s from storage. #[derive(Debug)] -pub struct StatesGoalDisplayCmd(PhantomData<(E, O, PKeys)>); +pub struct StatesGoalDisplayCmd(PhantomData); -impl StatesGoalDisplayCmd +impl StatesGoalDisplayCmd where - E: std::error::Error + From + Send + Sync + Unpin + 'static, - PKeys: ParamsKeys + 'static, - O: OutputWrite, + CmdCtxTypesT: CmdCtxTypesConstrained, { /// Displays [`StatesGoal`]s from storage. /// @@ -25,8 +26,14 @@ where /// /// [`StatesDiscoverCmd`]: crate::StatesDiscoverCmd pub async fn exec<'ctx>( - cmd_ctx: &mut CmdCtx>, - ) -> Result, E> { + cmd_ctx: &mut CmdCtx>, + ) -> Result< + CmdOutcome::AppError>, + ::AppError, + > + where + CmdCtxTypesT: 'ctx, + { let states_goal_stored_result = StatesGoalReadCmd::exec(cmd_ctx).await; let output = cmd_ctx.output_mut(); @@ -46,7 +53,7 @@ where } } -impl Default for StatesGoalDisplayCmd { +impl Default for StatesGoalDisplayCmd { fn default() -> Self { Self(PhantomData) } diff --git a/crate/rt/src/cmds/states_goal_read_cmd.rs b/crate/rt/src/cmds/states_goal_read_cmd.rs index f031e3fc0..90fe8ca84 100644 --- a/crate/rt/src/cmds/states_goal_read_cmd.rs +++ b/crate/rt/src/cmds/states_goal_read_cmd.rs @@ -1,23 +1,22 @@ use std::{fmt::Debug, marker::PhantomData}; -use peace_cmd::{ctx::CmdCtx, scopes::SingleProfileSingleFlow}; +use peace_cmd::{ + ctx::{CmdCtx, CmdCtxTypesConstrained}, + scopes::SingleProfileSingleFlow, +}; use peace_cmd_model::CmdOutcome; use peace_cmd_rt::{CmdBlockWrapper, CmdExecution}; use peace_resources::{resources::ts::SetUp, states::StatesGoalStored}; -use peace_rt_model::{params::ParamsKeys, Error}; -use peace_rt_model_core::output::OutputWrite; use crate::cmd_blocks::StatesGoalReadCmdBlock; /// Reads [`StatesGoalStored`]s from storage. #[derive(Debug)] -pub struct StatesGoalReadCmd(PhantomData<(E, O, PKeys)>); +pub struct StatesGoalReadCmd(PhantomData); -impl StatesGoalReadCmd +impl StatesGoalReadCmd where - E: std::error::Error + From + Send + Sync + Unpin + 'static, - O: OutputWrite, - PKeys: ParamsKeys + 'static, + CmdCtxTypesT: CmdCtxTypesConstrained, { /// Reads [`StatesGoalStored`]s from storage. /// @@ -26,13 +25,17 @@ where /// /// [`StatesDiscoverCmd`]: crate::StatesDiscoverCmd pub async fn exec<'ctx>( - cmd_ctx: &mut CmdCtx>, - ) -> Result, E> { - let cmd_execution_builder = CmdExecution::::builder() - .with_cmd_block(CmdBlockWrapper::new( - StatesGoalReadCmdBlock::new(), - std::convert::identity, - )); + cmd_ctx: &mut CmdCtx>, + ) -> Result< + CmdOutcome::AppError>, + ::AppError, + > + where + CmdCtxTypesT: 'ctx, + { + let cmd_execution_builder = CmdExecution::::builder().with_cmd_block( + CmdBlockWrapper::new(StatesGoalReadCmdBlock::new(), std::convert::identity), + ); #[cfg(feature = "output_progress")] let cmd_execution_builder = cmd_execution_builder.with_progress_render_enabled(false); @@ -41,7 +44,7 @@ where } } -impl Default for StatesGoalReadCmd { +impl Default for StatesGoalReadCmd { fn default() -> Self { Self(PhantomData) } diff --git a/crate/rt_model_core/src/output/output_write.rs b/crate/rt_model_core/src/output/output_write.rs index 5cb888466..33c1100ca 100644 --- a/crate/rt_model_core/src/output/output_write.rs +++ b/crate/rt_model_core/src/output/output_write.rs @@ -1,3 +1,5 @@ +use std::fmt::Debug; + use async_trait::async_trait; use peace_fmt::Presentable; @@ -25,7 +27,7 @@ cfg_if::cfg_if! { /// /// Progress updates sent during `ApplyFns::exec` and `CleanOpSpec::exec`. #[async_trait(?Send)] -pub trait OutputWrite { +pub trait OutputWrite: Debug + Unpin { /// Prepares this `OutputWrite` implementation for rendering progress. /// /// # Implementors diff --git a/crate/rt_model_core/src/params/params_keys.rs b/crate/rt_model_core/src/params/params_keys.rs index 9eed841d2..8f5fae8fb 100644 --- a/crate/rt_model_core/src/params/params_keys.rs +++ b/crate/rt_model_core/src/params/params_keys.rs @@ -13,7 +13,7 @@ use serde::{de::DeserializeOwned, Deserialize, Serialize}; /// * The code for those types is more understandable. /// * We reduce the ripple effect of needing each of these associated types /// propagated to callers who use those types in type / method signatures. -pub trait ParamsKeys: Debug + Unpin { +pub trait ParamsKeys: Debug + Unpin + 'static { type WorkspaceParamsKMaybe: KeyMaybe; type ProfileParamsKMaybe: KeyMaybe; type FlowParamsKMaybe: KeyMaybe; @@ -67,7 +67,7 @@ pub struct KeyUnknown; #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)] pub struct KeyKnown(PhantomData); -pub trait KeyMaybe: Debug + Unpin { +pub trait KeyMaybe: Debug + Unpin + 'static { type Key: Clone + Debug + Eq + Hash + DeserializeOwned + Serialize + Send + Sync + 'static; } diff --git a/crate/rt_model_native/src/output/cli_output.rs b/crate/rt_model_native/src/output/cli_output.rs index c0144164e..ad3135ac4 100644 --- a/crate/rt_model_native/src/output/cli_output.rs +++ b/crate/rt_model_native/src/output/cli_output.rs @@ -505,7 +505,7 @@ impl Default for CliOutput { impl OutputWrite for CliOutput where E: std::error::Error + From, - W: AsyncWrite + std::marker::Unpin, + W: AsyncWrite + Debug + Unpin, { #[cfg(feature = "output_progress")] async fn progress_begin(&mut self, cmd_progress_tracker: &CmdProgressTracker) { diff --git a/crate/value_traits/Cargo.toml b/crate/value_traits/Cargo.toml new file mode 100644 index 000000000..3d5f4bb06 --- /dev/null +++ b/crate/value_traits/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "peace_value_traits" +description = "Trait bounds for value types for the Peace framework." +documentation = "https://docs.rs/peace_value_traits/" +version.workspace = true +authors.workspace = true +edition.workspace = true +homepage.workspace = true +repository.workspace = true +readme.workspace = true +categories.workspace = true +keywords.workspace = true +license.workspace = true + +[lib] +doctest = false +test = false + +[dependencies] + diff --git a/crate/value_traits/src/app_error.rs b/crate/value_traits/src/app_error.rs new file mode 100644 index 000000000..a10650da3 --- /dev/null +++ b/crate/value_traits/src/app_error.rs @@ -0,0 +1,6 @@ +use std::fmt::Debug; + +/// Bounds that the application error type must satisfy. +pub trait AppError: Debug + std::error::Error + Send + Sync + Unpin + 'static {} + +impl AppError for T where T: Debug + std::error::Error + Send + Sync + Unpin + 'static {} diff --git a/crate/value_traits/src/lib.rs b/crate/value_traits/src/lib.rs new file mode 100644 index 000000000..93ec94668 --- /dev/null +++ b/crate/value_traits/src/lib.rs @@ -0,0 +1,5 @@ +//! Trait bounds for value types for the Peace framework. + +pub use crate::app_error::AppError; + +mod app_error; diff --git a/examples/download/Cargo.toml b/examples/download/Cargo.toml index 95c13ad76..c71cc440f 100644 --- a/examples/download/Cargo.toml +++ b/examples/download/Cargo.toml @@ -24,17 +24,17 @@ thiserror = "1.0.56" url = { version = "2.5.0", features = ["serde"] } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] -clap = { version = "4.4.12", features = ["derive"] } +clap = { version = "4.4.18", features = ["derive"] } tokio = { version = "1.35.1", features = ["net", "time", "rt"] } [target.'cfg(target_arch = "wasm32")'.dependencies] console_error_panic_hook = "0.1.7" serde-wasm-bindgen = "0.6.3" tokio = "1.35.1" -wasm-bindgen = "0.2.89" -wasm-bindgen-futures = "0.4.39" -js-sys = "0.3.66" -web-sys = "0.3.66" +wasm-bindgen = "0.2.90" +wasm-bindgen-futures = "0.4.40" +js-sys = "0.3.67" +web-sys = "0.3.67" [features] default = [] diff --git a/examples/download/src/download_cmd_ctx_types.rs b/examples/download/src/download_cmd_ctx_types.rs new file mode 100644 index 000000000..86a6381f4 --- /dev/null +++ b/examples/download/src/download_cmd_ctx_types.rs @@ -0,0 +1,6 @@ +use peace::{cmd::ctx::CmdCtxTypesCollector, rt_model::params::ParamsKeysUnknown}; + +use crate::DownloadError; + +pub type DownloadCmdCtxTypes = + CmdCtxTypesCollector; diff --git a/examples/download/src/lib.rs b/examples/download/src/lib.rs index 24050e642..63c567d02 100644 --- a/examples/download/src/lib.rs +++ b/examples/download/src/lib.rs @@ -7,20 +7,19 @@ use peace::{ CleanCmd, DiffCmd, EnsureCmd, StatesCurrentStoredDisplayCmd, StatesDiscoverCmd, StatesGoalDisplayCmd, }, - rt_model::{ - output::OutputWrite, - params::{KeyUnknown, ParamsKeysImpl}, - Flow, ItemGraphBuilder, Workspace, WorkspaceSpec, - }, + rt_model::{output::OutputWrite, Flow, ItemGraphBuilder, Workspace, WorkspaceSpec}, }; use peace_items::file_download::{FileDownloadItem, FileDownloadParams}; #[cfg(not(target_arch = "wasm32"))] pub use crate::download_args::{DownloadArgs, DownloadCommand}; -pub use crate::{download_error::DownloadError, file_id::FileId}; +pub use crate::{ + download_cmd_ctx_types::DownloadCmdCtxTypes, download_error::DownloadError, file_id::FileId, +}; #[cfg(not(target_arch = "wasm32"))] mod download_args; +mod download_cmd_ctx_types; mod download_error; mod file_id; @@ -72,15 +71,8 @@ pub async fn workspace_and_flow_setup( Ok(workspace_and_flow) } -pub type DownloadCmdCtx<'ctx, O> = CmdCtx< - SingleProfileSingleFlow< - 'ctx, - DownloadError, - O, - ParamsKeysImpl, - SetUp, - >, ->; +pub type DownloadCmdCtx<'ctx, O> = + CmdCtx, SetUp>>; /// Returns a `CmdCtx` initialized from the workspace and item graph pub async fn cmd_ctx<'ctx, O>( diff --git a/examples/envman/Cargo.toml b/examples/envman/Cargo.toml index be289e54e..65b4f3787 100644 --- a/examples/envman/Cargo.toml +++ b/examples/envman/Cargo.toml @@ -18,20 +18,20 @@ test = false crate-type = ["cdylib", "rlib"] [dependencies] -aws-config = { version = "1.1.1", optional = true } -aws-sdk-iam = { version = "1.9.1", optional = true } -aws-sdk-s3 = { version = "1.11.0", optional = true } -aws-smithy-types = { version = "1.1.1", optional = true } # used to reference error type, otherwise not recommended for direct usage -base64 = { version = "0.21.5", optional = true } +aws-config = { version = "1.1.4", optional = true } +aws-sdk-iam = { version = "1.12.0", optional = true } +aws-sdk-s3 = { version = "1.14.0", optional = true } +aws-smithy-types = { version = "1.1.4", optional = true } # used to reference error type, otherwise not recommended for direct usage +base64 = { version = "0.21.7", optional = true } cfg-if = "1.0.0" -chrono = { version = "0.4.31", default-features = false, features = ["clock", "serde"], optional = true } +chrono = { version = "0.4.33", default-features = false, features = ["clock", "serde"], optional = true } derivative = { version = "2.2.0", optional = true } futures = { version = "0.3.30", optional = true } md5-rs = { version = "0.1.5", optional = true } # WASM compatible, and reads bytes as stream peace = { path = "../..", default-features = false } peace_items = { path = "../../items", features = ["file_download", "tar_x"] } semver = { version = "1.0.21", optional = true } -serde = { version = "1.0.194", features = ["derive"] } +serde = { version = "1.0.196", features = ["derive"] } thiserror = { version = "1.0.56", optional = true } url = { version = "2.5.0", features = ["serde"] } urlencoding = { version = "2.1.3", optional = true } @@ -39,19 +39,19 @@ whoami = { version = "1.4.1", optional = true } # web_server # ssr -axum = { version = "0.7.3", optional = true } +axum = { version = "0.7.4", optional = true } hyper = { version = "1.1.0", optional = true } -leptos = { version = "0.5.4", default-features = false, features = ["serde"] } -leptos_axum = { version = "0.6.0-alpha", optional = true } -leptos_meta = { version = "0.5.4", default-features = false } -leptos_router = { version = "0.5.4", default-features = false } +leptos = { version = "0.6.3", default-features = false, features = ["serde"] } +leptos_axum = { version = "0.6.3", optional = true } +leptos_meta = { version = "0.6.3", default-features = false } +leptos_router = { version = "0.6.3", default-features = false } tower = { version = "0.4.13", optional = true } -tower-http = { version = "0.5.0", optional = true, features = ["fs"] } +tower-http = { version = "0.5.1", optional = true, features = ["fs"] } tracing = { version = "0.1.40", optional = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] -clap = { version = "4.4.12", features = ["derive"], optional = true } -tokio = { version = "1.35.1", features = ["rt", "rt-multi-thread"], optional = true } +clap = { version = "4.4.18", features = ["derive"], optional = true } +tokio = { version = "1.35.1", features = ["rt", "rt-multi-thread", "signal"], optional = true } [target.'cfg(target_arch = "wasm32")'.dependencies] console_error_panic_hook = "0.1.7" @@ -59,10 +59,10 @@ console_log = { version = "1.0.0", features = ["color"] } log = "0.4.20" serde-wasm-bindgen = "0.6.3" tokio = "1.35.1" -wasm-bindgen = "0.2.89" -wasm-bindgen-futures = "0.4.39" -js-sys = "0.3.66" -web-sys = "0.3.66" +wasm-bindgen = "0.2.90" +wasm-bindgen-futures = "0.4.40" +js-sys = "0.3.67" +web-sys = "0.3.67" [features] default = [] diff --git a/examples/envman/src/cmds/app_upload_cmd.rs b/examples/envman/src/cmds/app_upload_cmd.rs index 1b657388a..29f7c6437 100644 --- a/examples/envman/src/cmds/app_upload_cmd.rs +++ b/examples/envman/src/cmds/app_upload_cmd.rs @@ -11,11 +11,7 @@ use peace::{ fmt::presentln, params::Params, resources::resources::ts::SetUp, - rt_model::{ - output::OutputWrite, - params::{KeyKnown, KeyUnknown, ParamsKeysImpl}, - Workspace, WorkspaceSpec, - }, + rt_model::{output::OutputWrite, Workspace, WorkspaceSpec}, }; use crate::{ @@ -26,7 +22,7 @@ use crate::{ peace_aws_s3_object::{S3ObjectItem, S3ObjectParams}, }, model::{EnvManError, EnvType, ProfileParamsKey, WebApp, WorkspaceParamsKey}, - rt_model::EnvManCmdCtx, + rt_model::{EnvManCmdCtx, EnvmanCmdCtxTypes}, }; /// Runs a `*Cmd` that interacts with the application upload. @@ -104,19 +100,7 @@ impl AppUploadCmd { where O: OutputWrite, for<'fn_once> F: FnOnce( - &'fn_once mut CmdCtx< - MultiProfileSingleFlow< - '_, - EnvManError, - O, - ParamsKeysImpl< - KeyKnown, - KeyKnown, - KeyUnknown, - >, - SetUp, - >, - >, + &'fn_once mut CmdCtx, SetUp>>, ) -> LocalBoxFuture<'fn_once, Result>, { let workspace = Workspace::new( diff --git a/examples/envman/src/cmds/env_cmd.rs b/examples/envman/src/cmds/env_cmd.rs index 19adb5219..e3024268a 100644 --- a/examples/envman/src/cmds/env_cmd.rs +++ b/examples/envman/src/cmds/env_cmd.rs @@ -11,11 +11,7 @@ use peace::{ fmt::presentln, params::Params, resources::resources::ts::SetUp, - rt_model::{ - output::OutputWrite, - params::{KeyKnown, KeyUnknown, ParamsKeysImpl}, - Workspace, WorkspaceSpec, - }, + rt_model::{output::OutputWrite, Workspace, WorkspaceSpec}, }; use crate::{ @@ -26,7 +22,7 @@ use crate::{ peace_aws_iam_role::{IamRoleItem, IamRoleParams}, }, model::{EnvManError, EnvType, ProfileParamsKey, WebApp, WorkspaceParamsKey}, - rt_model::EnvManCmdCtx, + rt_model::{EnvManCmdCtx, EnvmanCmdCtxTypes}, }; /// Runs a `*Cmd` that accesses the environment. @@ -108,19 +104,7 @@ impl EnvCmd { where O: OutputWrite, for<'fn_once> F: FnOnce( - &'fn_once mut CmdCtx< - MultiProfileSingleFlow< - '_, - EnvManError, - O, - ParamsKeysImpl< - KeyKnown, - KeyKnown, - KeyUnknown, - >, - SetUp, - >, - >, + &'fn_once mut CmdCtx, SetUp>>, ) -> LocalBoxFuture<'fn_once, Result>, { let workspace = Workspace::new( diff --git a/examples/envman/src/cmds/profile_init_cmd.rs b/examples/envman/src/cmds/profile_init_cmd.rs index c1e7081fc..96f9688bd 100644 --- a/examples/envman/src/cmds/profile_init_cmd.rs +++ b/examples/envman/src/cmds/profile_init_cmd.rs @@ -10,11 +10,7 @@ use peace::{ fmt::{presentable::CodeInline, presentln}, resources::resources::ts::SetUp, rt::cmds::StatesDiscoverCmd, - rt_model::{ - output::OutputWrite, - params::{KeyKnown, KeyUnknown, ParamsKeysImpl}, - Flow, Workspace, WorkspaceSpec, - }, + rt_model::{output::OutputWrite, Flow, Workspace, WorkspaceSpec}, }; use peace_items::{file_download::FileDownloadItem, tar_x::TarXItem}; use semver::Version; @@ -30,6 +26,7 @@ use crate::{ model::{ EnvManError, EnvManFlow, EnvType, ProfileParamsKey, RepoSlug, WebApp, WorkspaceParamsKey, }, + rt_model::EnvmanCmdCtxTypes, }; /// Flow to initialize and set the default profile. @@ -202,18 +199,7 @@ async fn app_upload_flow_init<'f, O>( url: Option, output: &'f mut O, workspace: &'f Workspace, -) -> Result< - CmdCtx< - SingleProfileSingleFlow< - 'f, - EnvManError, - O, - ParamsKeysImpl, KeyKnown, KeyUnknown>, - SetUp, - >, - >, - EnvManError, -> +) -> Result, SetUp>>, EnvManError> where O: OutputWrite, { @@ -251,18 +237,7 @@ async fn env_deploy_flow_init<'f, O>( url: Option, output: &'f mut O, workspace: &'f Workspace, -) -> Result< - CmdCtx< - SingleProfileSingleFlow< - 'f, - EnvManError, - O, - ParamsKeysImpl, KeyKnown, KeyUnknown>, - SetUp, - >, - >, - EnvManError, -> +) -> Result, SetUp>>, EnvManError> where O: OutputWrite, { diff --git a/examples/envman/src/rt_model.rs b/examples/envman/src/rt_model.rs index 587698d93..04d4f38bc 100644 --- a/examples/envman/src/rt_model.rs +++ b/examples/envman/src/rt_model.rs @@ -1,5 +1,6 @@ //! Runtime data types for the EnvMan example -pub use self::envman_cmd_ctx::EnvManCmdCtx; +pub use self::{envman_cmd_ctx::EnvManCmdCtx, envman_cmd_ctx_types::EnvmanCmdCtxTypes}; mod envman_cmd_ctx; +mod envman_cmd_ctx_types; diff --git a/examples/envman/src/rt_model/envman_cmd_ctx.rs b/examples/envman/src/rt_model/envman_cmd_ctx.rs index ac9826813..fa2a14e5b 100644 --- a/examples/envman/src/rt_model/envman_cmd_ctx.rs +++ b/examples/envman/src/rt_model/envman_cmd_ctx.rs @@ -1,17 +1,7 @@ -use peace::{ - cmd::scopes::SingleProfileSingleFlow, - rt_model::params::{KeyKnown, KeyUnknown, ParamsKeysImpl}, -}; +use peace::cmd::scopes::SingleProfileSingleFlow; -use crate::model::{EnvManError, ProfileParamsKey, WorkspaceParamsKey}; +use crate::rt_model::EnvmanCmdCtxTypes; /// Alias to simplify naming the `CmdCtx` type. -pub type EnvManCmdCtx<'ctx, O, TS> = peace::cmd::ctx::CmdCtx< - SingleProfileSingleFlow< - 'ctx, - EnvManError, - O, - ParamsKeysImpl, KeyKnown, KeyUnknown>, - TS, - >, ->; +pub type EnvManCmdCtx<'ctx, Output, TS> = + peace::cmd::ctx::CmdCtx, TS>>; diff --git a/examples/envman/src/rt_model/envman_cmd_ctx_types.rs b/examples/envman/src/rt_model/envman_cmd_ctx_types.rs new file mode 100644 index 000000000..0d5f04765 --- /dev/null +++ b/examples/envman/src/rt_model/envman_cmd_ctx_types.rs @@ -0,0 +1,12 @@ +use peace::{ + cmd::ctx::CmdCtxTypesCollector, + rt_model::params::{KeyKnown, KeyUnknown, ParamsKeysImpl}, +}; + +use crate::model::{EnvManError, ProfileParamsKey, WorkspaceParamsKey}; + +pub type EnvmanCmdCtxTypes = CmdCtxTypesCollector< + EnvManError, + Output, + ParamsKeysImpl, KeyKnown, KeyUnknown>, +>; diff --git a/examples/envman/src/web/components/flow_graph.rs b/examples/envman/src/web/components/flow_graph.rs index cfbffa920..8268ac5df 100644 --- a/examples/envman/src/web/components/flow_graph.rs +++ b/examples/envman/src/web/components/flow_graph.rs @@ -1,5 +1,6 @@ use leptos::{ - component, create_signal, view, IntoView, ServerFnError, SignalGet, SignalUpdate, Transition, + component, create_signal, server_fn::error::NoCustomError, view, IntoView, ServerFnError, + SignalGet, SignalUpdate, Transition, }; /// Renders the flow graph. @@ -77,11 +78,11 @@ pub fn FlowGraph() -> impl IntoView { } #[leptos::server(FlowGraphSrc, "/flow_graph")] -pub async fn flow_graph_src() -> Result { +pub async fn flow_graph_src() -> Result> { use crate::{flows::AppUploadFlow, web::FlowDotRenderer}; - let flow = AppUploadFlow::flow() - .await - .map_err(|envman_error| ServerFnError::ServerError(format!("{}", envman_error)))?; + let flow = AppUploadFlow::flow().await.map_err(|envman_error| { + ServerFnError::::ServerError(format!("{}", envman_error)) + })?; // use peace::rt_model::fn_graph::daggy::petgraph::dot::{Config, Dot}; // let dot_source = Dot::with_config(cx.props.flow.graph().graph(), diff --git a/workspace_tests/src/cmd_rt/cmd_execution.rs b/workspace_tests/src/cmd_rt/cmd_execution.rs index cd08563bb..375b82d67 100644 --- a/workspace_tests/src/cmd_rt/cmd_execution.rs +++ b/workspace_tests/src/cmd_rt/cmd_execution.rs @@ -75,7 +75,7 @@ async fn runs_one_cmd_block() -> Result<(), PeaceTestError> { #[tokio::test] async fn chains_multiple_cmd_blocks() -> Result<(), PeaceTestError> { - let mut cmd_execution = CmdExecution::::builder() + let mut cmd_execution = CmdExecution::::builder() .with_cmd_block(CmdBlockWrapper::new( StatesDiscoverCmdBlock::current_and_goal(), // Should we support diffing the accumulated states? @@ -83,7 +83,7 @@ async fn chains_multiple_cmd_blocks() -> Result<(), PeaceTestError> { |_states_current_and_goal_mut| StateDiffs::new(), )) .with_cmd_block(CmdBlockWrapper::new( - DiffCmdBlock::<_, _, Current, Goal>::new(), + DiffCmdBlock::<_, Current, Goal>::new(), |_state_diffs_ts0_and_ts1| StateDiffs::new(), )) .build(); diff --git a/workspace_tests/src/cmd_rt/cmd_execution/cmd_execution_error_builder.rs b/workspace_tests/src/cmd_rt/cmd_execution/cmd_execution_error_builder.rs index 7a2c4e379..123ad3114 100644 --- a/workspace_tests/src/cmd_rt/cmd_execution/cmd_execution_error_builder.rs +++ b/workspace_tests/src/cmd_rt/cmd_execution/cmd_execution_error_builder.rs @@ -21,7 +21,7 @@ use crate::{ #[tokio::test] async fn builds_error_for_missing_input_tuple_first_parameter() -> Result<(), PeaceTestError> { - let mut cmd_execution = CmdExecution::::builder() + let mut cmd_execution = CmdExecution::::builder() .with_cmd_block(CmdBlockWrapper::new( // Note: deliberately don't discover `Current`, so error will occur in `DiffCmdBlock`. StatesDiscoverCmdBlock::goal(), @@ -30,7 +30,7 @@ async fn builds_error_for_missing_input_tuple_first_parameter() -> Result<(), Pe |_states_current_and_goal_mut| StateDiffs::new(), )) .with_cmd_block(CmdBlockWrapper::new( - DiffCmdBlock::<_, _, Current, Goal>::new(), + DiffCmdBlock::<_, Current, Goal>::new(), |_state_diffs_ts0_and_ts1| StateDiffs::new(), )) .build(); @@ -110,7 +110,7 @@ CmdBlocks: #[tokio::test] async fn builds_error_for_missing_input_tuple_second_parameter() -> Result<(), PeaceTestError> { - let mut cmd_execution = CmdExecution::::builder() + let mut cmd_execution = CmdExecution::::builder() .with_cmd_block(CmdBlockWrapper::new( // Note: deliberately don't discover `Goal`, so error will occur in `DiffCmdBlock`. StatesDiscoverCmdBlock::current(), @@ -119,7 +119,7 @@ async fn builds_error_for_missing_input_tuple_second_parameter() -> Result<(), P |_states_current_and_goal_mut| StateDiffs::new(), )) .with_cmd_block(CmdBlockWrapper::new( - DiffCmdBlock::<_, _, Current, Goal>::new(), + DiffCmdBlock::<_, Current, Goal>::new(), |_state_diffs_ts0_and_ts1| StateDiffs::new(), )) .build(); diff --git a/workspace_tests/src/lib.rs b/workspace_tests/src/lib.rs index 00e967c16..d1fded7e3 100644 --- a/workspace_tests/src/lib.rs +++ b/workspace_tests/src/lib.rs @@ -38,6 +38,7 @@ mod fn_name; mod fn_tracker_output; mod fn_tracker_presenter; mod no_op_output; +mod peace_cmd_ctx_types; mod peace_test_error; mod test_support; mod vec_copy_item; diff --git a/workspace_tests/src/peace_cmd_ctx_types.rs b/workspace_tests/src/peace_cmd_ctx_types.rs new file mode 100644 index 000000000..cd7838b85 --- /dev/null +++ b/workspace_tests/src/peace_cmd_ctx_types.rs @@ -0,0 +1,12 @@ +use peace::{cmd::ctx::CmdCtxTypes, rt_model::params::ParamsKeysUnknown}; + +use crate::{NoOpOutput, PeaceTestError}; + +#[derive(Debug)] +pub(crate) struct PeaceCmdCtxTypes; + +impl CmdCtxTypes for PeaceCmdCtxTypes { + type AppError = PeaceTestError; + type Output = NoOpOutput; + type ParamsKeys = ParamsKeysUnknown; +} diff --git a/workspace_tests/src/rt/cmd_blocks/apply_exec_cmd_block.rs b/workspace_tests/src/rt/cmd_blocks/apply_exec_cmd_block.rs index f1c7990bb..a96cefc96 100644 --- a/workspace_tests/src/rt/cmd_blocks/apply_exec_cmd_block.rs +++ b/workspace_tests/src/rt/cmd_blocks/apply_exec_cmd_block.rs @@ -2,17 +2,15 @@ use peace::{ cmd_rt::CmdBlock, resources::states::ts::{Cleaned, CleanedDry, Ensured, EnsuredDry}, rt::cmd_blocks::ApplyExecCmdBlock, - rt_model::params::ParamsKeysUnknown, }; -use crate::peace_test_error::PeaceTestError; +use crate::peace_cmd_ctx_types::PeaceCmdCtxTypes; #[test] fn input_type_names_includes_states_current_and_states_target() { macro_rules! assert_input_type_names { ($states_ts:ident, $expected:expr) => { - let cmd_block = - ApplyExecCmdBlock::::new(); + let cmd_block = ApplyExecCmdBlock::::new(); let input_type_names = cmd_block.input_type_names(); @@ -30,8 +28,7 @@ fn input_type_names_includes_states_current_and_states_target() { fn outcome_type_names_includes_states_previous_states_target() { macro_rules! assert_outcome_type_names { ($states_ts:ident, $expected:expr) => { - let cmd_block = - ApplyExecCmdBlock::::new(); + let cmd_block = ApplyExecCmdBlock::::new(); let outcome_type_names = cmd_block.outcome_type_names(); diff --git a/workspace_tests/src/rt/cmd_blocks/apply_state_sync_check_cmd_block.rs b/workspace_tests/src/rt/cmd_blocks/apply_state_sync_check_cmd_block.rs index bf545d9e4..454ff82dd 100644 --- a/workspace_tests/src/rt/cmd_blocks/apply_state_sync_check_cmd_block.rs +++ b/workspace_tests/src/rt/cmd_blocks/apply_state_sync_check_cmd_block.rs @@ -1,16 +1,12 @@ -use peace::{ - cmd_rt::CmdBlock, rt::cmd_blocks::ApplyStateSyncCheckCmdBlock, - rt_model::params::ParamsKeysUnknown, -}; +use peace::{cmd_rt::CmdBlock, rt::cmd_blocks::ApplyStateSyncCheckCmdBlock}; -use crate::peace_test_error::PeaceTestError; +use crate::peace_cmd_ctx_types::PeaceCmdCtxTypes; #[test] fn input_type_names_includes_states_compared() { macro_rules! assert_input_type_names { ($constructor:ident, $expected:expr) => { - let cmd_block = - ApplyStateSyncCheckCmdBlock::::$constructor(); + let cmd_block = ApplyStateSyncCheckCmdBlock::::$constructor(); let input_type_names: Vec = cmd_block.input_type_names(); @@ -36,8 +32,7 @@ fn input_type_names_includes_states_compared() { fn outcome_type_names_includes_states_compared() { macro_rules! assert_outcome_type_names { ($constructor:ident, $expected:expr) => { - let cmd_block = - ApplyStateSyncCheckCmdBlock::::$constructor(); + let cmd_block = ApplyStateSyncCheckCmdBlock::::$constructor(); let outcome_type_names = cmd_block.outcome_type_names(); diff --git a/workspace_tests/src/rt/cmd_blocks/diff_cmd_block.rs b/workspace_tests/src/rt/cmd_blocks/diff_cmd_block.rs index 6c3032c80..0be3226cb 100644 --- a/workspace_tests/src/rt/cmd_blocks/diff_cmd_block.rs +++ b/workspace_tests/src/rt/cmd_blocks/diff_cmd_block.rs @@ -2,17 +2,15 @@ use peace::{ cmd_rt::CmdBlock, resources::states::ts::{Current, CurrentStored, Goal, GoalStored}, rt::cmd_blocks::DiffCmdBlock, - rt_model::params::ParamsKeysUnknown, }; -use crate::peace_test_error::PeaceTestError; +use crate::peace_cmd_ctx_types::PeaceCmdCtxTypes; #[test] fn input_type_names_includes_states_ts0_and_states_ts1() { macro_rules! assert_input_type_names { ($states_ts0:ident, $states_ts1:ident, $expected:expr) => { - let cmd_block = - DiffCmdBlock::::new(); + let cmd_block = DiffCmdBlock::::new(); let input_type_names: Vec = cmd_block.input_type_names(); @@ -32,8 +30,7 @@ fn input_type_names_includes_states_ts0_and_states_ts1() { fn outcome_type_names_includes_state_diffs_states_ts0_and_states_ts1() { macro_rules! assert_outcome_type_names { ($states_ts0:ident, $states_ts1:ident, $expected:expr) => { - let cmd_block = - DiffCmdBlock::::new(); + let cmd_block = DiffCmdBlock::::new(); let outcome_type_names = cmd_block.outcome_type_names(); diff --git a/workspace_tests/src/rt/cmd_blocks/states_clean_insertion_cmd_block.rs b/workspace_tests/src/rt/cmd_blocks/states_clean_insertion_cmd_block.rs index 0951fedbf..127a0de7a 100644 --- a/workspace_tests/src/rt/cmd_blocks/states_clean_insertion_cmd_block.rs +++ b/workspace_tests/src/rt/cmd_blocks/states_clean_insertion_cmd_block.rs @@ -1,13 +1,10 @@ -use peace::{ - cmd_rt::CmdBlock, rt::cmd_blocks::StatesCleanInsertionCmdBlock, - rt_model::params::ParamsKeysUnknown, -}; +use peace::{cmd_rt::CmdBlock, rt::cmd_blocks::StatesCleanInsertionCmdBlock}; -use crate::peace_test_error::PeaceTestError; +use crate::peace_cmd_ctx_types::PeaceCmdCtxTypes; #[test] fn input_type_names_is_empty() { - let cmd_block = StatesCleanInsertionCmdBlock::::new(); + let cmd_block = StatesCleanInsertionCmdBlock::::new(); let input_type_names: Vec = cmd_block.input_type_names(); @@ -16,7 +13,7 @@ fn input_type_names_is_empty() { #[test] fn outcome_type_names_includes_states_clean() { - let cmd_block = StatesCleanInsertionCmdBlock::::new(); + let cmd_block = StatesCleanInsertionCmdBlock::::new(); let outcome_type_names: Vec = cmd_block.outcome_type_names(); diff --git a/workspace_tests/src/rt/cmd_blocks/states_current_read_cmd_block.rs b/workspace_tests/src/rt/cmd_blocks/states_current_read_cmd_block.rs index 772b02baa..bfc44b178 100644 --- a/workspace_tests/src/rt/cmd_blocks/states_current_read_cmd_block.rs +++ b/workspace_tests/src/rt/cmd_blocks/states_current_read_cmd_block.rs @@ -1,13 +1,10 @@ -use peace::{ - cmd_rt::CmdBlock, rt::cmd_blocks::StatesCurrentReadCmdBlock, - rt_model::params::ParamsKeysUnknown, -}; +use peace::{cmd_rt::CmdBlock, rt::cmd_blocks::StatesCurrentReadCmdBlock}; -use crate::peace_test_error::PeaceTestError; +use crate::peace_cmd_ctx_types::PeaceCmdCtxTypes; #[test] fn input_type_names_is_empty() { - let cmd_block = StatesCurrentReadCmdBlock::::new(); + let cmd_block = StatesCurrentReadCmdBlock::::new(); let input_type_names: Vec = cmd_block.input_type_names(); @@ -16,7 +13,7 @@ fn input_type_names_is_empty() { #[test] fn outcome_type_names_includes_states_current_stored() { - let cmd_block = StatesCurrentReadCmdBlock::::new(); + let cmd_block = StatesCurrentReadCmdBlock::::new(); let outcome_type_names: Vec = cmd_block.outcome_type_names(); diff --git a/workspace_tests/src/rt/cmd_blocks/states_discover_cmd_block.rs b/workspace_tests/src/rt/cmd_blocks/states_discover_cmd_block.rs index 686f5db5b..2300c3825 100644 --- a/workspace_tests/src/rt/cmd_blocks/states_discover_cmd_block.rs +++ b/workspace_tests/src/rt/cmd_blocks/states_discover_cmd_block.rs @@ -1,15 +1,12 @@ -use peace::{ - cmd_rt::CmdBlock, rt::cmd_blocks::StatesDiscoverCmdBlock, rt_model::params::ParamsKeysUnknown, -}; +use peace::{cmd_rt::CmdBlock, rt::cmd_blocks::StatesDiscoverCmdBlock}; -use crate::peace_test_error::PeaceTestError; +use crate::peace_cmd_ctx_types::PeaceCmdCtxTypes; #[test] fn input_type_names_includes_states_compared() { macro_rules! assert_input_type_names { ($constructor:ident) => { - let cmd_block = - StatesDiscoverCmdBlock::::$constructor(); + let cmd_block = StatesDiscoverCmdBlock::::$constructor(); let input_type_names: Vec = cmd_block.input_type_names(); @@ -26,8 +23,7 @@ fn input_type_names_includes_states_compared() { fn outcome_type_names_includes_states_compared() { macro_rules! assert_outcome_type_names { ($constructor:ident, $expected:expr) => { - let cmd_block = - StatesDiscoverCmdBlock::::$constructor(); + let cmd_block = StatesDiscoverCmdBlock::::$constructor(); let outcome_type_names = cmd_block.outcome_type_names(); diff --git a/workspace_tests/src/rt/cmd_blocks/states_goal_read_cmd_block.rs b/workspace_tests/src/rt/cmd_blocks/states_goal_read_cmd_block.rs index bcf73501b..4a2ade018 100644 --- a/workspace_tests/src/rt/cmd_blocks/states_goal_read_cmd_block.rs +++ b/workspace_tests/src/rt/cmd_blocks/states_goal_read_cmd_block.rs @@ -1,12 +1,10 @@ -use peace::{ - cmd_rt::CmdBlock, rt::cmd_blocks::StatesGoalReadCmdBlock, rt_model::params::ParamsKeysUnknown, -}; +use peace::{cmd_rt::CmdBlock, rt::cmd_blocks::StatesGoalReadCmdBlock}; -use crate::peace_test_error::PeaceTestError; +use crate::peace_cmd_ctx_types::PeaceCmdCtxTypes; #[test] fn input_type_names_is_empty() { - let cmd_block = StatesGoalReadCmdBlock::::new(); + let cmd_block = StatesGoalReadCmdBlock::::new(); let input_type_names: Vec = cmd_block.input_type_names(); @@ -15,7 +13,7 @@ fn input_type_names_is_empty() { #[test] fn outcome_type_names_includes_states_goal_stored() { - let cmd_block = StatesGoalReadCmdBlock::::new(); + let cmd_block = StatesGoalReadCmdBlock::::new(); let outcome_type_names: Vec = cmd_block.outcome_type_names(); diff --git a/workspace_tests/src/rt/cmds/clean_cmd.rs b/workspace_tests/src/rt/cmds/clean_cmd.rs index 56b3ff46c..a658d4fd3 100644 --- a/workspace_tests/src/rt/cmds/clean_cmd.rs +++ b/workspace_tests/src/rt/cmds/clean_cmd.rs @@ -15,8 +15,9 @@ use peace::{ use crate::{ mock_item::{MockItem, MockItemError, MockSrc, MockState}, + peace_cmd_ctx_types::PeaceCmdCtxTypes, vec_copy_item::VecB, - NoOpOutput, PeaceTestError, VecA, VecCopyError, VecCopyItem, VecCopyState, + NoOpOutput, PeaceTestError, VecA, VecCopyItem, VecCopyState, }; #[tokio::test] @@ -978,9 +979,9 @@ async fn states_current_not_serialized_on_states_discover_cmd_block_fail() #[test] fn debug() { - let debug_str = format!("{:?}", CleanCmd::::default()); + let debug_str = format!("{:?}", CleanCmd::::default()); assert_eq!( - r#"CleanCmd(PhantomData<(workspace_tests::vec_copy_item::VecCopyError, workspace_tests::no_op_output::NoOpOutput, ())>)"#, + r#"CleanCmd(PhantomData)"#, debug_str, ); } diff --git a/workspace_tests/src/rt/cmds/diff_cmd.rs b/workspace_tests/src/rt/cmds/diff_cmd.rs index 4f1ff52e0..12b55487c 100644 --- a/workspace_tests/src/rt/cmds/diff_cmd.rs +++ b/workspace_tests/src/rt/cmds/diff_cmd.rs @@ -17,7 +17,8 @@ use peace::{ use crate::{ mock_item::{MockDest, MockDiff, MockItem, MockSrc, MockState}, - NoOpOutput, PeaceTestError, VecA, VecB, VecCopyDiff, VecCopyError, VecCopyItem, VecCopyState, + peace_cmd_ctx_types::PeaceCmdCtxTypes, + NoOpOutput, PeaceTestError, VecA, VecB, VecCopyDiff, VecCopyItem, VecCopyState, }; mod diff_info_spec; @@ -718,9 +719,9 @@ async fn diff_with_multiple_changes() -> Result<(), Box> #[test] fn debug() { - let debug_str = format!("{:?}", DiffCmd::::default()); + let debug_str = format!("{:?}", DiffCmd::::default()); assert_eq!( - r#"DiffCmd(PhantomData<(workspace_tests::vec_copy_item::VecCopyError, &(), (), ())>)"#, + r#"DiffCmd(PhantomData<(workspace_tests::peace_cmd_ctx_types::PeaceCmdCtxTypes, ())>)"#, debug_str, ); } diff --git a/workspace_tests/src/rt/cmds/ensure_cmd.rs b/workspace_tests/src/rt/cmds/ensure_cmd.rs index f0ef99dda..45f81fc5b 100644 --- a/workspace_tests/src/rt/cmds/ensure_cmd.rs +++ b/workspace_tests/src/rt/cmds/ensure_cmd.rs @@ -19,8 +19,9 @@ use tokio::sync::mpsc; use crate::{ mock_item::{MockItem, MockItemError, MockSrc, MockState}, + peace_cmd_ctx_types::PeaceCmdCtxTypes, vec_copy_item::VecB, - NoOpOutput, PeaceTestError, VecA, VecCopyError, VecCopyItem, VecCopyState, + NoOpOutput, PeaceTestError, VecA, VecCopyItem, VecCopyState, }; #[tokio::test] @@ -1830,9 +1831,9 @@ mock: 1 #[test] fn debug() { - let debug_str = format!("{:?}", EnsureCmd::::default()); + let debug_str = format!("{:?}", EnsureCmd::::default()); assert_eq!( - r#"EnsureCmd(PhantomData<(workspace_tests::vec_copy_item::VecCopyError, workspace_tests::no_op_output::NoOpOutput, ())>)"#, + r#"EnsureCmd(PhantomData)"#, debug_str, ); } diff --git a/workspace_tests/src/rt/cmds/states_current_read_cmd.rs b/workspace_tests/src/rt/cmds/states_current_read_cmd.rs index 4bd06f6b8..89e7dbfb0 100644 --- a/workspace_tests/src/rt/cmds/states_current_read_cmd.rs +++ b/workspace_tests/src/rt/cmds/states_current_read_cmd.rs @@ -6,7 +6,10 @@ use peace::{ rt_model::{Error, Flow, ItemGraphBuilder, Workspace, WorkspaceSpec}, }; -use crate::{NoOpOutput, PeaceTestError, VecA, VecCopyError, VecCopyItem, VecCopyState}; +use crate::{ + peace_cmd_ctx_types::PeaceCmdCtxTypes, NoOpOutput, PeaceTestError, VecA, VecCopyItem, + VecCopyState, +}; #[tokio::test] async fn reads_states_current_stored_from_disk_when_present() @@ -104,12 +107,9 @@ async fn returns_error_when_states_not_on_disk() -> Result<(), Box::default() - ); + let debug_str = format!("{:?}", StatesCurrentReadCmd::::default()); assert_eq!( - r#"StatesCurrentReadCmd(PhantomData<(workspace_tests::vec_copy_item::VecCopyError, workspace_tests::no_op_output::NoOpOutput, ())>)"#, + r#"StatesCurrentReadCmd(PhantomData)"#, debug_str, ); } diff --git a/workspace_tests/src/rt/cmds/states_current_stored_display_cmd.rs b/workspace_tests/src/rt/cmds/states_current_stored_display_cmd.rs index ba9390198..75dea4843 100644 --- a/workspace_tests/src/rt/cmds/states_current_stored_display_cmd.rs +++ b/workspace_tests/src/rt/cmds/states_current_stored_display_cmd.rs @@ -7,8 +7,8 @@ use peace::{ }; use crate::{ - FnInvocation, FnTrackerOutput, NoOpOutput, PeaceTestError, VecA, VecCopyError, VecCopyItem, - VecCopyState, + peace_cmd_ctx_types::PeaceCmdCtxTypes, FnInvocation, FnTrackerOutput, NoOpOutput, + PeaceTestError, VecA, VecCopyItem, VecCopyState, }; #[tokio::test] @@ -130,10 +130,10 @@ async fn returns_error_when_states_not_on_disk() -> Result<(), Box::default() + StatesCurrentStoredDisplayCmd::::default() ); assert_eq!( - r#"StatesCurrentStoredDisplayCmd(PhantomData<(workspace_tests::vec_copy_item::VecCopyError, workspace_tests::no_op_output::NoOpOutput, ())>)"#, + r#"StatesCurrentStoredDisplayCmd(PhantomData)"#, debug_str, ); } diff --git a/workspace_tests/src/rt/cmds/states_discover_cmd.rs b/workspace_tests/src/rt/cmds/states_discover_cmd.rs index f27d3adf7..e04fe7c06 100644 --- a/workspace_tests/src/rt/cmds/states_discover_cmd.rs +++ b/workspace_tests/src/rt/cmds/states_discover_cmd.rs @@ -13,8 +13,9 @@ use peace::{ use crate::{ mock_item::{MockItem, MockItemError, MockSrc, MockState}, + peace_cmd_ctx_types::PeaceCmdCtxTypes, vec_copy_item::VecB, - NoOpOutput, PeaceTestError, VecA, VecCopyError, VecCopyItem, VecCopyState, + NoOpOutput, PeaceTestError, VecA, VecCopyItem, VecCopyState, }; #[cfg(feature = "output_progress")] @@ -926,8 +927,7 @@ async fn current_with_sets_progress_complete_for_successful_items() ) .await?; - let _cmd_outcome = - StatesDiscoverCmd::<_, NoOpOutput, _>::current_with(&mut cmd_ctx, false).await; + let _cmd_outcome = StatesDiscoverCmd::<_>::current_with(&mut cmd_ctx, false).await; let cmd_progress_tracker = cmd_ctx.cmd_progress_tracker(); let vec_copy_progress_tracker = cmd_progress_tracker @@ -984,8 +984,7 @@ async fn goal_with_sets_progress_complete_for_successful_items() ) .await?; - let _cmd_outcome = - StatesDiscoverCmd::<_, NoOpOutput, _>::goal_with(&mut cmd_ctx, false).await?; + let _cmd_outcome = StatesDiscoverCmd::<_>::goal_with(&mut cmd_ctx, false).await?; let cmd_progress_tracker = cmd_ctx.cmd_progress_tracker(); let vec_copy_progress_tracker = cmd_progress_tracker @@ -1042,8 +1041,7 @@ async fn current_and_goal_with_sets_progress_complete_for_successful_items() ) .await?; - let _cmd_outcome = - StatesDiscoverCmd::<_, NoOpOutput, _>::current_and_goal_with(&mut cmd_ctx, false).await?; + let _cmd_outcome = StatesDiscoverCmd::<_>::current_and_goal_with(&mut cmd_ctx, false).await?; let cmd_progress_tracker = cmd_ctx.cmd_progress_tracker(); let vec_copy_progress_tracker = cmd_progress_tracker @@ -1077,12 +1075,9 @@ async fn current_and_goal_with_sets_progress_complete_for_successful_items() #[test] fn debug() { - let debug_str = format!( - "{:?}", - StatesDiscoverCmd::::default() - ); + let debug_str = format!("{:?}", StatesDiscoverCmd::::default()); assert_eq!( - r#"StatesDiscoverCmd(PhantomData<(workspace_tests::vec_copy_item::VecCopyError, workspace_tests::no_op_output::NoOpOutput, ())>)"#, + r#"StatesDiscoverCmd(PhantomData)"#, debug_str ); } diff --git a/workspace_tests/src/rt/cmds/states_goal_display_cmd.rs b/workspace_tests/src/rt/cmds/states_goal_display_cmd.rs index a6f99b85b..b0eace210 100644 --- a/workspace_tests/src/rt/cmds/states_goal_display_cmd.rs +++ b/workspace_tests/src/rt/cmds/states_goal_display_cmd.rs @@ -7,8 +7,8 @@ use peace::{ }; use crate::{ - FnInvocation, FnTrackerOutput, NoOpOutput, PeaceTestError, VecA, VecCopyError, VecCopyItem, - VecCopyState, + peace_cmd_ctx_types::PeaceCmdCtxTypes, FnInvocation, FnTrackerOutput, NoOpOutput, + PeaceTestError, VecA, VecCopyItem, VecCopyState, }; #[tokio::test] @@ -123,12 +123,9 @@ async fn returns_error_when_states_not_on_disk() -> Result<(), Box::default() - ); + let debug_str = format!("{:?}", StatesGoalDisplayCmd::::default()); assert_eq!( - r#"StatesGoalDisplayCmd(PhantomData<(workspace_tests::vec_copy_item::VecCopyError, workspace_tests::no_op_output::NoOpOutput, ())>)"#, + r#"StatesGoalDisplayCmd(PhantomData)"#, debug_str, ); } diff --git a/workspace_tests/src/rt/cmds/states_goal_read_cmd.rs b/workspace_tests/src/rt/cmds/states_goal_read_cmd.rs index f3cb1ab5e..95b8b54d2 100644 --- a/workspace_tests/src/rt/cmds/states_goal_read_cmd.rs +++ b/workspace_tests/src/rt/cmds/states_goal_read_cmd.rs @@ -6,7 +6,10 @@ use peace::{ rt_model::{Error, Flow, ItemGraphBuilder, Workspace, WorkspaceSpec}, }; -use crate::{NoOpOutput, PeaceTestError, VecA, VecCopyError, VecCopyItem, VecCopyState}; +use crate::{ + peace_cmd_ctx_types::PeaceCmdCtxTypes, NoOpOutput, PeaceTestError, VecA, VecCopyItem, + VecCopyState, +}; #[tokio::test] async fn reads_states_goal_from_disk_when_present() -> Result<(), Box> { @@ -101,12 +104,9 @@ async fn returns_error_when_states_not_on_disk() -> Result<(), Box::default() - ); + let debug_str = format!("{:?}", StatesGoalReadCmd::::default()); assert_eq!( - r#"StatesGoalReadCmd(PhantomData<(workspace_tests::vec_copy_item::VecCopyError, workspace_tests::no_op_output::NoOpOutput, ())>)"#, + r#"StatesGoalReadCmd(PhantomData)"#, debug_str, ); }