Browse Source

WIP: refactor

develop-refactor
chodak166 4 months ago
parent
commit
fa25f6c927
  1. 4
      app/src/app.rs
  2. 5
      app/src/cli.rs
  3. 3
      app/src/cli/args.rs
  4. 0
      app/src/cli/commands.rs
  5. 22
      app/src/cli/commands/decode.rs
  6. 36
      app/src/cli/commands/encode.rs
  7. 12
      app/src/cli/commands/import_dict.rs
  8. 6
      app/src/cli/commands/server.rs
  9. 0
      app/src/cli/defaults.rs
  10. 81
      app/src/cli/handlers.rs
  11. 14
      app/src/cli/traits.rs
  12. 5
      app/src/config.rs
  13. 3
      app/src/main.rs
  14. 2
      lib/Cargo.toml
  15. 4
      lib/src/core/sys_major.rs
  16. 6
      lib/src/lib.rs
  17. 2
      lib/src/presentation.rs
  18. 10
      lib/src/presentation/cli/commands/decode.rs
  19. 13
      lib/src/presentation/cli/commands/encode.rs
  20. 27
      lib/src/presentation/cli/commands/import_dict.rs
  21. 0
      lib/src/presentation/server.rs

4
app/src/app.rs

@ -1,8 +1,8 @@
use crate::cli::args::{CliArgs, Command};
use crate::cli::handlers::resolve_command;
use crate::config::AppConfig; use crate::config::AppConfig;
use crate::container::Container; use crate::container::Container;
use crate::handlers::resolve_command;
use anyhow::Result; use anyhow::Result;
use applib::cli::{CliArgs, Command};
use clap::Parser; use clap::Parser;
use tracing::debug; use tracing::debug;

5
app/src/cli.rs

@ -0,0 +1,5 @@
pub mod args;
pub mod commands;
pub mod defaults;
pub mod handlers;
pub mod traits;

3
lib/src/presentation/cli/cli_args.rs → app/src/cli/args.rs

@ -1,4 +1,5 @@
use crate::cli::{ConfigurableCommand, defaults}; use crate::cli::defaults;
use crate::cli::traits::ConfigurableCommand;
use anyhow::Result; use anyhow::Result;
use clap::{Args as ClapArgs, Parser, Subcommand}; use clap::{Args as ClapArgs, Parser, Subcommand};
use config::ConfigBuilder; use config::ConfigBuilder;

0
lib/src/presentation/cli/commands.rs → app/src/cli/commands.rs

22
app/src/cli/commands/decode.rs

@ -0,0 +1,22 @@
use applib::application::config::DecoderConfig;
use applib::core::sys_major::decoder::Decoder;
use applib::core::sys_major::{self as major, LenValueMap};
use applib::core::traits::SystemDecoder;
use applib::system::System;
use std::sync::Arc;
pub async fn run(config: DecoderConfig) {
let decoder: Box<dyn SystemDecoder> = match config.system {
System::MajorPl => Box::new(Decoder::new(major::rules_pl::get_rules())),
System::MajorEn => Box::new(Decoder::new(major::rules_en::get_rules())),
// _ => {
// eprintln!("Unknown system: {:?}", config.system);
// return;
// }
};
match decoder.decode(&config.input) {
Ok(result) => println!("{:?}", result),
Err(e) => eprintln!("Error: {}", e),
}
}

36
app/src/cli/commands/encode.rs

@ -0,0 +1,36 @@
use applib::application::config::EncoderConfig;
use applib::core::sys_major::encoder::Encoder;
use applib::core::sys_major::{self as major, LenValueMap};
use applib::core::traits::{DictRepository, SystemEncoder};
use applib::system::System;
use tracing::debug;
pub async fn run(config: EncoderConfig, dict: &dyn DictRepository) {
debug!("Running encoder with config {:?}", config);
let system_encoder: Box<dyn SystemEncoder> = match config.system {
System::MajorPl | System::MajorEn => {
let decoder = major::Decoder::new(match config.system {
System::MajorPl => major::rules_pl::get_rules(),
System::MajorEn => major::rules_en::get_rules(),
// _ => unreachable!(),
});
let stream = dict.stream_batches(100).await.unwrap();
let lvmap = LenValueMap::from_stream(stream, &decoder).await.unwrap();
Box::new(Encoder::new(lvmap))
} // _ => {
// eprintln!("Unknown system: {:?}", config.system);
// return;
// }
};
let result = system_encoder.encode(&config.input);
match result {
Ok(res) => {
let json = serde_json::to_string_pretty(&res).expect("JSON serialization failed");
println!("{}", json);
}
Err(e) => eprintln!("Error encoding: {:?}", e),
}
}

12
app/src/cli/commands/import_dict.rs

@ -0,0 +1,12 @@
use anyhow::Result;
use applib::DictImporter;
use applib::application::config::ImportDictConfig;
pub async fn run(config: ImportDictConfig, importer: DictImporter) -> Result<()> {
// Importer expects an impl DictSource
// We need to create a DictSource from the path
use applib::infrastructure::json_file_dict_source::JsonFileDictSource;
let source = JsonFileDictSource::new(&config.path)?;
importer.import(source).await?;
Ok(())
}

6
app/src/cli/commands/server.rs

@ -0,0 +1,6 @@
use applib::application::config::ServerConfig;
use std::future::Future;
pub async fn run(config: ServerConfig, signal: impl Future<Output = ()> + Send + 'static) {
applib::presentation::server::run(config, signal).await;
}

0
lib/src/presentation/cli/defaults.rs → app/src/cli/defaults.rs

81
app/src/cli/handlers.rs

@ -0,0 +1,81 @@
use crate::cli::args::{Command, DecodeArgs, EncodeArgs, ImportDictArgs, ServerArgs};
use crate::cli::commands;
use crate::cli::traits::ConfigurableCommand;
use crate::config::AppConfig;
use crate::container::Container;
use anyhow::Result;
use async_trait::async_trait;
use tokio::signal;
use tracing::{info, warn};
#[async_trait]
pub trait CommandExecutor {
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 {}
impl<T: ConfigurableCommand + CommandExecutor> AppCommand for T {}
pub fn resolve_command(command: &Command) -> &dyn AppCommand {
match command {
Command::Server(args) => args,
Command::Decode(args) => args,
Command::Encode(args) => args,
Command::ImportDict(args) => args,
}
}
#[async_trait]
impl CommandExecutor for ServerArgs {
async fn execute(&self, config: &AppConfig, _container: &Container) -> Result<()> {
let config = config.server.as_ref().expect("Server config not set");
commands::server::run(config.clone(), wait_for_shutdown_signal()).await;
Ok(())
}
}
#[async_trait]
impl CommandExecutor for DecodeArgs {
async fn execute(&self, config: &AppConfig, _container: &Container) -> Result<()> {
let config = config.decoder.as_ref().expect("Decoder config not set");
commands::decode::run(config.clone()).await;
Ok(())
}
}
#[async_trait]
impl CommandExecutor for EncodeArgs {
async fn execute(&self, config: &AppConfig, container: &Container) -> Result<()> {
let config = config.encoder.as_ref().expect("Encoder config not set");
let repo = container.create_dict_repo("demo_pl").await?;
commands::encode::run(config.clone(), repo.as_ref()).await;
Ok(())
}
}
#[async_trait]
impl CommandExecutor for ImportDictArgs {
async fn execute(&self, config: &AppConfig, container: &Container) -> Result<()> {
let config = config
.import_dict
.as_ref()
.expect("ImportDict config not set");
let importer = container.create_dict_importer(&config.name).await?;
commands::import_dict::run(config.clone(), importer).await?;
Ok(())
}
}
async fn wait_for_shutdown_signal() {
match signal::ctrl_c().await {
Ok(()) => {
info!("Received shutdown signal (SIGINT/SIGTERM)");
}
Err(err) => {
warn!("Failed to listen for shutdown signal: {}", err);
}
}
}

14
app/src/cli/traits.rs

@ -0,0 +1,14 @@
use anyhow::Result;
pub use config::ConfigBuilder;
pub use config::builder::DefaultState;
pub trait ConfigurableCommand {
fn apply_defaults(
&self,
builder: ConfigBuilder<DefaultState>,
) -> Result<ConfigBuilder<DefaultState>>;
fn apply_overrides(
&self,
builder: ConfigBuilder<DefaultState>,
) -> Result<ConfigBuilder<DefaultState>>;
}

5
app/src/config.rs

@ -2,8 +2,9 @@ use anyhow::{Context, Result};
use config::{Config, Environment, File}; use config::{Config, Environment, File};
use serde::Deserialize; use serde::Deserialize;
use applib::cli::{ConfigurableCommand, GlobalArgs}; use crate::cli::args::GlobalArgs;
use applib::config::*; use crate::cli::traits::ConfigurableCommand;
use applib::application::config::*;
#[derive(Debug, Deserialize, Clone)] #[derive(Debug, Deserialize, Clone)]
pub struct AppConfig { pub struct AppConfig {

3
app/src/main.rs

@ -1,8 +1,7 @@
mod app; mod app;
pub mod cli;
mod config; mod config;
mod container; mod container;
mod handlers;
mod traits;
use anyhow::Result; use anyhow::Result;
use app::Application; use app::Application;

2
lib/Cargo.toml

@ -5,7 +5,7 @@ edition = "2024"
[dependencies] [dependencies]
once_cell = "1.21.3" once_cell = "1.21.3"
clap = { version = "4.5", features = ["derive", "env"] } # clap = { version = "4.5", features = ["derive", "env"] } # Removed
const_format = "0.2.35" const_format = "0.2.35"
config = "0.15.19" config = "0.15.19"
tracing = "0.1" tracing = "0.1"

4
lib/src/core/sys_major.rs

@ -1,5 +1,5 @@
mod decoder; pub mod decoder;
mod encoder; pub mod encoder;
mod lvmap; mod lvmap;
pub mod rules_en; pub mod rules_en;
pub mod rules_pl; pub mod rules_pl;

6
lib/src/lib.rs

@ -1,10 +1,10 @@
pub mod application; pub mod application;
mod core; pub mod core;
pub mod infrastructure; pub mod infrastructure;
mod presentation; pub mod presentation;
pub use self::application::config; pub use self::application::config;
pub use self::application::services::DictImporter; pub use self::application::services::DictImporter;
pub use self::core::system; pub use self::core::system;
pub use self::core::traits; pub use self::core::traits;
pub use self::presentation::cli; // pub use self::presentation::cli; // Removed as we are deleting it

2
lib/src/presentation.rs

@ -1 +1 @@
pub mod cli; pub mod server;

10
lib/src/presentation/cli/commands/decode.rs

@ -1,10 +0,0 @@
use crate::application::config::DecoderConfig;
use crate::core::system;
use tracing::debug;
pub async fn run(config: DecoderConfig) {
debug!("Running decoder with config {:?}", config);
let decoder = system::create_decoder(&config.system);
let result = decoder.decode(&config.input).unwrap();
println!("{}", result.as_str());
}

13
lib/src/presentation/cli/commands/encode.rs

@ -1,13 +0,0 @@
use crate::application::config::EncoderConfig;
use crate::core::{DictRepository, system};
use tracing::debug;
pub async fn run(config: EncoderConfig, dict: &dyn DictRepository) {
debug!("Running encoder with config {:?}", config);
let encoder = system::create_encoder(&config.system, dict).await;
let result = encoder.encode(&config.input).unwrap();
let json = serde_json::to_string_pretty(&result).expect("JSON serialization failed");
println!("{}", json);
}

27
lib/src/presentation/cli/commands/import_dict.rs

@ -1,27 +0,0 @@
use crate::application::{config::ImportDictConfig, services::DictImporter};
use crate::infrastructure::json_file_dict_source::JsonFileDictSource;
use tracing::{debug, error, info};
pub async fn run(config: ImportDictConfig, importer: DictImporter) -> Result<(), anyhow::Error> {
debug!("Importing dict with config {:?}", config);
info!(
"Starting import of dictionary '{}' from file '{}'",
config.name, config.path
);
// Create the JSON file source (will auto-generate IDs starting from 1)
let source = JsonFileDictSource::new(&config.path)?;
// Perform the import (this will call create() first)
match importer.import(source).await {
Ok(()) => {
info!("Successfully imported dictionary '{}'", config.name);
Ok(())
}
Err(e) => {
error!("Failed to import dictionary '{}': {}", config.name, e);
Err(e)
}
}
}

0
lib/src/presentation/cli/commands/server.rs → lib/src/presentation/server.rs

Loading…
Cancel
Save