|
|
|
@ -2,15 +2,19 @@ use anyhow::{Context, Result}; |
|
|
|
use config::{Config, Environment, File}; |
|
|
|
use config::{Config, Environment, File}; |
|
|
|
use serde::Deserialize; |
|
|
|
use serde::Deserialize; |
|
|
|
|
|
|
|
|
|
|
|
use applib::cli::{Command, GlobalArgs, defaults::set_defaults}; |
|
|
|
use applib::cli::{Command, GlobalArgs, defaults::set_command_defaults}; |
|
|
|
use applib::config::*; |
|
|
|
use applib::config::*; |
|
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Deserialize, Clone)] |
|
|
|
#[derive(Debug, Deserialize, Clone)] |
|
|
|
pub struct AppConfig { |
|
|
|
pub struct AppConfig { |
|
|
|
pub server: ServerConfig, |
|
|
|
#[serde(default)] |
|
|
|
pub decoder: DecoderConfig, |
|
|
|
pub server: Option<ServerConfig>, |
|
|
|
pub encoder: EncoderConfig, |
|
|
|
#[serde(default)] |
|
|
|
pub import_dict: ImportDictConfig, |
|
|
|
pub decoder: Option<DecoderConfig>, |
|
|
|
|
|
|
|
#[serde(default)] |
|
|
|
|
|
|
|
pub encoder: Option<EncoderConfig>, |
|
|
|
|
|
|
|
#[serde(default)] |
|
|
|
|
|
|
|
pub import_dict: Option<ImportDictConfig>, |
|
|
|
pub log_level: String, |
|
|
|
pub log_level: String, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -18,8 +22,8 @@ impl AppConfig { |
|
|
|
pub fn build(args: &GlobalArgs, command: &Command) -> Result<Self> { |
|
|
|
pub fn build(args: &GlobalArgs, command: &Command) -> Result<Self> { |
|
|
|
let mut builder = Config::builder(); |
|
|
|
let mut builder = Config::builder(); |
|
|
|
|
|
|
|
|
|
|
|
// Defaults
|
|
|
|
// Command-specific defaults
|
|
|
|
builder = set_defaults(builder)?; |
|
|
|
builder = set_command_defaults(builder, command)?; |
|
|
|
|
|
|
|
|
|
|
|
// File Layer
|
|
|
|
// File Layer
|
|
|
|
let config_path = &args.config; |
|
|
|
let config_path = &args.config; |
|
|
|
@ -31,33 +35,7 @@ impl AppConfig { |
|
|
|
builder = builder.add_source(Environment::with_prefix("APP").separator("_")); |
|
|
|
builder = builder.add_source(Environment::with_prefix("APP").separator("_")); |
|
|
|
|
|
|
|
|
|
|
|
// CLI Overrides Layer
|
|
|
|
// CLI Overrides Layer
|
|
|
|
if let Some(ref level) = args.log_level { |
|
|
|
builder = apply_cli_overrides(builder, args, command)?; |
|
|
|
builder = builder.set_override("log_level", level.clone())?; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
match command { |
|
|
|
|
|
|
|
Command::Server(cmd_args) => { |
|
|
|
|
|
|
|
if let Some(port) = cmd_args.port { |
|
|
|
|
|
|
|
builder = builder.set_override("server.port", port)?; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
Command::Decode(cmd_args) => { |
|
|
|
|
|
|
|
if let Some(name) = &cmd_args.system { |
|
|
|
|
|
|
|
builder = builder.set_override("decoder.system", name.as_str())?; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
builder = builder.set_override("decoder.input", cmd_args.input.clone())?; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
Command::Encode(cmd_args) => { |
|
|
|
|
|
|
|
if let Some(name) = &cmd_args.system { |
|
|
|
|
|
|
|
builder = builder.set_override("encoder.system", name.as_str())?; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
builder = builder.set_override("encoder.input", cmd_args.input.clone())?; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
Command::ImportDict(cmd_args) => { |
|
|
|
|
|
|
|
builder = builder.set_override("import_dict.name", cmd_args.name.clone())?; |
|
|
|
|
|
|
|
builder = builder.set_override("import_dict.path", cmd_args.path.clone())?; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
builder |
|
|
|
builder |
|
|
|
.build() |
|
|
|
.build() |
|
|
|
@ -66,3 +44,43 @@ impl AppConfig { |
|
|
|
.context("Failed to deserialize Config") |
|
|
|
.context("Failed to deserialize Config") |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn apply_cli_overrides( |
|
|
|
|
|
|
|
builder: config::ConfigBuilder<config::builder::DefaultState>, |
|
|
|
|
|
|
|
args: &GlobalArgs, |
|
|
|
|
|
|
|
command: &Command, |
|
|
|
|
|
|
|
) -> Result<config::ConfigBuilder<config::builder::DefaultState>> { |
|
|
|
|
|
|
|
let mut builder = builder; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Global log level override
|
|
|
|
|
|
|
|
if let Some(ref level) = args.log_level { |
|
|
|
|
|
|
|
builder = builder.set_override("log_level", level.clone())?; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Command-specific overrides
|
|
|
|
|
|
|
|
match command { |
|
|
|
|
|
|
|
Command::Server(cmd_args) => { |
|
|
|
|
|
|
|
if let Some(port) = cmd_args.port { |
|
|
|
|
|
|
|
builder = builder.set_override("server.port", port)?; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
Command::Decode(cmd_args) => { |
|
|
|
|
|
|
|
if let Some(name) = &cmd_args.system { |
|
|
|
|
|
|
|
builder = builder.set_override("decoder.system", name.as_str())?; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
builder = builder.set_override("decoder.input", cmd_args.input.clone())?; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
Command::Encode(cmd_args) => { |
|
|
|
|
|
|
|
if let Some(name) = &cmd_args.system { |
|
|
|
|
|
|
|
builder = builder.set_override("encoder.system", name.as_str())?; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
builder = builder.set_override("encoder.input", cmd_args.input.clone())?; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
Command::ImportDict(cmd_args) => { |
|
|
|
|
|
|
|
builder = builder.set_override("import_dict.name", cmd_args.name.clone())?; |
|
|
|
|
|
|
|
builder = builder.set_override("import_dict.path", cmd_args.path.clone())?; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Ok(builder) |
|
|
|
|
|
|
|
} |
|
|
|
|