From a1d5d6977a34b923c10a5e6e06112ddc20dcbb33 Mon Sep 17 00:00:00 2001 From: chodak166 Date: Sun, 11 Jan 2026 19:36:47 +0100 Subject: [PATCH] WIP: refactor --- app/src/app.rs | 14 +++++----- app/src/commands.rs | 46 +++++++++++++++++++++++---------- app/src/commands/decode.rs | 8 +++--- app/src/commands/encode.rs | 8 +++--- app/src/commands/import_dict.rs | 8 +++--- app/src/config.rs | 4 +-- 6 files changed, 52 insertions(+), 36 deletions(-) diff --git a/app/src/app.rs b/app/src/app.rs index 8ad7839..a5accbf 100644 --- a/app/src/app.rs +++ b/app/src/app.rs @@ -1,4 +1,4 @@ -use crate::commands::{CliArgs, Command, resolve_command}; +use crate::commands::{AppCommand, CliArgs}; use crate::config::AppConfig; use crate::container::Container; use anyhow::Result; @@ -8,17 +8,16 @@ use tracing::debug; pub struct Application { config: AppConfig, container: Container, - command: Command, + command: Box, } impl Application { pub async fn build() -> Result { let args = CliArgs::parse(); - // Resolve the command once to get the trait object for configuration - let handler = resolve_command(&args.command); + let app_cmd = args.command.into_app_command(); - let config = AppConfig::build(&args.global, handler)?; + let config = AppConfig::build(&args.global, app_cmd.as_ref())?; tracing_subscriber::fmt() .compact() @@ -33,12 +32,11 @@ impl Application { Ok(Self { config, container, - command: args.command, + command: app_cmd, }) } pub async fn run(self) -> Result<()> { - let handler = resolve_command(&self.command); - handler.execute(&self.config, &self.container).await + self.command.execute(&self.config, &self.container).await } } diff --git a/app/src/commands.rs b/app/src/commands.rs index 54d4a8b..673edba 100644 --- a/app/src/commands.rs +++ b/app/src/commands.rs @@ -15,23 +15,41 @@ use std::path::PathBuf; #[derive(Subcommand, Debug, Clone)] pub enum Command { /// Decode a word using given system - Decode(decode::DecodeArgs), + Decode(decode::DecodeCmd), /// Encode a number using given system - Encode(encode::EncodeArgs), + Encode(encode::EncodeCmd), /// Import dictionary - ImportDict(import_dict::ImportDictArgs), + ImportDict(import_dict::ImportDictCmd), } -pub fn resolve_command(command: &Command) -> &dyn AppCommand { - match command { - Command::Decode(args) => args, - Command::Encode(args) => args, - Command::ImportDict(args) => args, +impl Command { + pub fn into_app_command(self) -> Box { + match self { + Command::Decode(cmd) => Box::new(cmd), + Command::Encode(cmd) => Box::new(cmd), + Command::ImportDict(cmd) => Box::new(cmd), + } } } +// pub fn resolve_command(command: &Command) -> &dyn AppCommand { +// match command { +// Command::Decode(app_cmd) => app_cmd, +// Command::Encode(app_cmd) => app_cmd, +// Command::ImportDict(app_cmd) => app_cmd, +// } +// } + +// pub fn resolve_command_box(command: Command) -> Box { +// match command { +// Command::Decode(cmd) => Box::new(cmd), +// Command::Encode(cmd) => Box::new(cmd), +// Command::ImportDict(cmd) => Box::new(cmd), +// } +// } + #[derive(Parser, Debug)] #[command(author, version, about)] pub struct CliArgs { @@ -52,7 +70,7 @@ pub struct GlobalArgs { pub log_level: Option, } -pub trait ConfigurableCommand { +pub trait Configurable { fn apply_defaults( &self, builder: ConfigBuilder, @@ -64,15 +82,15 @@ pub trait ConfigurableCommand { } #[async_trait] -pub trait CommandExecutor { +pub trait Executable { async fn execute(&self, config: &AppConfig, container: &Container) -> Result<()>; } -// AppCommand must be dyn-compatible. ConfigurableCommand is already dyn-compatible. -// CommandExecutor is dyn-compatible because of #[async_trait]. -pub trait AppCommand: ConfigurableCommand + CommandExecutor {} +// AppCommand must be dyn-compatible. Configurable is already dyn-compatible. +// Executable is dyn-compatible because of #[async_trait]. +pub trait AppCommand: Configurable + Executable {} -impl AppCommand for T {} +impl AppCommand for T {} mod defaults { use const_format::formatcp; diff --git a/app/src/commands/decode.rs b/app/src/commands/decode.rs index acdfa32..95c53f1 100644 --- a/app/src/commands/decode.rs +++ b/app/src/commands/decode.rs @@ -1,4 +1,4 @@ -use crate::commands::{ClapArgs, CommandExecutor, ConfigurableCommand}; +use crate::commands::{ClapArgs, Configurable, Executable}; use crate::config::AppConfig; use crate::config::System; use crate::container::Container; @@ -16,7 +16,7 @@ pub struct Config { } #[derive(ClapArgs, Debug, Clone)] -pub struct DecodeArgs { +pub struct DecodeCmd { #[arg(short, long, help = defaults::HELP_DEC_SYSTEM)] pub system: Option, @@ -24,7 +24,7 @@ pub struct DecodeArgs { pub input: String, } -impl ConfigurableCommand for DecodeArgs { +impl Configurable for DecodeCmd { fn apply_defaults( &self, builder: ConfigBuilder, @@ -50,7 +50,7 @@ impl ConfigurableCommand for DecodeArgs { } #[async_trait] -impl CommandExecutor for DecodeArgs { +impl Executable for DecodeCmd { async fn execute(&self, config: &AppConfig, container: &Container) -> Result<()> { let config = config .decode diff --git a/app/src/commands/encode.rs b/app/src/commands/encode.rs index 6e7e22f..c4e288a 100644 --- a/app/src/commands/encode.rs +++ b/app/src/commands/encode.rs @@ -1,6 +1,6 @@ use serde::Deserialize; -use crate::commands::{ClapArgs, CommandExecutor, ConfigurableCommand}; +use crate::commands::{ClapArgs, Configurable, Executable}; use crate::config::{AppConfig, System}; use crate::container::Container; @@ -17,7 +17,7 @@ pub struct Config { } #[derive(ClapArgs, Debug, Clone)] -pub struct EncodeArgs { +pub struct EncodeCmd { #[arg(short, long, help = defaults::HELP_ENC_SYSTEM)] pub system: Option, @@ -28,7 +28,7 @@ pub struct EncodeArgs { pub input: String, } -impl ConfigurableCommand for EncodeArgs { +impl Configurable for EncodeCmd { fn apply_defaults( &self, builder: ConfigBuilder, @@ -58,7 +58,7 @@ impl ConfigurableCommand for EncodeArgs { } #[async_trait] -impl CommandExecutor for EncodeArgs { +impl Executable for EncodeCmd { async fn execute(&self, config: &AppConfig, container: &Container) -> Result<()> { let config = config .encode diff --git a/app/src/commands/import_dict.rs b/app/src/commands/import_dict.rs index 6d9041d..b989f8e 100644 --- a/app/src/commands/import_dict.rs +++ b/app/src/commands/import_dict.rs @@ -1,4 +1,4 @@ -use crate::commands::{ClapArgs, CommandExecutor, ConfigurableCommand}; +use crate::commands::{ClapArgs, Configurable, Executable}; use crate::config::AppConfig; use crate::container::Container; use anyhow::Result; @@ -14,7 +14,7 @@ pub struct Config { } #[derive(ClapArgs, Debug, Clone)] -pub struct ImportDictArgs { +pub struct ImportDictCmd { #[arg(long, help = defaults::HELP_IMPORT_DICT_NAME)] pub name: String, @@ -22,7 +22,7 @@ pub struct ImportDictArgs { pub path: String, } -impl ConfigurableCommand for ImportDictArgs { +impl Configurable for ImportDictCmd { fn apply_defaults( &self, builder: ConfigBuilder, @@ -45,7 +45,7 @@ impl ConfigurableCommand for ImportDictArgs { } #[async_trait] -impl CommandExecutor for ImportDictArgs { +impl Executable for ImportDictCmd { async fn execute(&self, config: &AppConfig, container: &Container) -> Result<()> { let config = config .import_dict diff --git a/app/src/config.rs b/app/src/config.rs index 8635dd1..463462e 100644 --- a/app/src/config.rs +++ b/app/src/config.rs @@ -1,5 +1,5 @@ use crate::commands::*; -// use crate::commands::{ConfigurableCommand, GlobalArgs}; +// use crate::commands::{Configurable, GlobalArgs}; use anyhow::{Context, Result}; use config::{Config, Environment, File}; use serde::Deserialize; @@ -16,7 +16,7 @@ pub struct AppConfig { } impl AppConfig { - pub fn build(args: &GlobalArgs, handler: &dyn ConfigurableCommand) -> Result { + pub fn build(args: &GlobalArgs, handler: &dyn Configurable) -> Result { let mut builder = Config::builder(); // Command-specific defaults via Trait