Skip to content

Commit ecde75c

Browse files
committed
wip
1 parent 58ff7c4 commit ecde75c

File tree

2 files changed

+60
-34
lines changed

2 files changed

+60
-34
lines changed

rust/functora-cfg/src/lib.rs

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,43 @@ use serde::{Serialize, de::DeserializeOwned};
44
use std::path::Path;
55
use toml::Value as TomlValue;
66

7-
pub fn new<Cfg, Get, Cli>(
8-
app: &str,
9-
def: Option<&Cfg>,
10-
get_cfg_path: Get,
11-
cli: &Cli,
7+
pub struct Args<'a, Src: Serialize> {
8+
pub default: &'a Src,
9+
pub file_path: fn(&Src) -> Option<&str>,
10+
pub env_prefix: &'a str,
11+
pub command_line: &'a Src,
12+
}
13+
14+
impl<'a, Src: Serialize> Args<'a, Src> {
15+
pub fn eval<Cfg: Serialize + DeserializeOwned>(
16+
&self,
17+
) -> Result<Cfg, ConfigError> {
18+
new(self)
19+
}
20+
}
21+
22+
pub fn new<Src, Cfg>(
23+
args: &Args<Src>,
1224
) -> Result<Cfg, ConfigError>
1325
where
26+
Src: Serialize,
1427
Cfg: Serialize + DeserializeOwned,
15-
Get: Fn(&Cli) -> Option<&str>,
16-
Cli: Serialize,
1728
{
29+
//
30+
// TODO : use functional style with tierator over
31+
// trait object array and try_fold into builder,
32+
// maybe somthing else, this looks too bad:
33+
//
34+
1835
let mut builder = Config::builder();
1936

20-
// Def
21-
if let Some(cfg) = def {
22-
builder = builder.add_source(term_to_config(cfg)?);
23-
}
37+
builder =
38+
builder.add_source(term_to_config(args.default)?);
2439

25-
// Cfg
26-
if let Some(path) = get_cfg_path(cli) {
40+
let getter = args.file_path;
41+
if let Some(path) =
42+
getter(args.command_line).or(getter(args.default))
43+
{
2744
let path = Path::new(&path);
2845
if path.exists() && path.is_file() {
2946
builder = builder.add_source(File::from(path));
@@ -34,14 +51,15 @@ where
3451
}
3552
}
3653

37-
// Env
3854
builder = builder.add_source(
39-
Environment::with_prefix(&app.to_uppercase())
40-
.separator("_"),
55+
Environment::with_prefix(
56+
&args.env_prefix.to_uppercase(),
57+
)
58+
.separator("_"),
4159
);
4260

43-
// Cli
44-
builder = builder.add_source(term_to_config(cli)?);
61+
builder = builder
62+
.add_source(term_to_config(args.command_line)?);
4563

4664
builder.build()?.try_deserialize()
4765
}

rust/functora-cfg/tests/integration.rs

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,25 @@ use serde::{Deserialize, Serialize};
22
use serial_test::serial;
33
use temp_env::with_vars;
44

5-
fn new_fun_cfg(cli: &Cli) -> Cfg {
6-
let def = Cfg {
7-
host: "127.0.0.1".into(),
8-
port: 8080,
9-
debug: false,
5+
fn new_cfg(cli: &Cli) -> Cfg {
6+
let def = Cli {
7+
cfg: None,
8+
host: Some("127.0.0.1".into()),
9+
port: Some(8080),
10+
debug: Some(false),
1011
nested: Some(CfgNest {
1112
name: "foo".into(),
1213
value: 42,
1314
}),
1415
tags: None,
1516
};
16-
functora_cfg::new(
17-
"fun_app",
18-
Some(&def),
19-
|cli| cli.cfg.as_deref(),
20-
cli,
21-
)
17+
functora_cfg::Args {
18+
default: &def,
19+
file_path: |cli: &Cli| cli.cfg.as_deref(),
20+
env_prefix: "fun_app",
21+
command_line: cli,
22+
}
23+
.eval()
2224
.unwrap()
2325
}
2426

@@ -43,6 +45,7 @@ struct Cli {
4345
host: Option<String>,
4446
port: Option<u16>,
4547
debug: Option<bool>,
48+
nested: Option<CfgNest>,
4649
tags: Option<Vec<String>>,
4750
}
4851

@@ -64,9 +67,10 @@ fn defaults_only() {
6467
host: None,
6568
port: None,
6669
debug: None,
70+
nested: None,
6771
tags: None,
6872
};
69-
let cfg: Cfg = new_fun_cfg(&cli);
73+
let cfg: Cfg = new_cfg(&cli);
7074
assert_eq!(cfg, def);
7175
}
7276

@@ -86,9 +90,10 @@ fn with_file_override() {
8690
host: None,
8791
port: None,
8892
debug: None,
93+
nested: None,
8994
tags: None,
9095
};
91-
let cfg: Cfg = new_fun_cfg(&cli);
96+
let cfg: Cfg = new_cfg(&cli);
9297
assert_eq!(cfg.host, "192.168.1.100");
9398
assert_eq!(cfg.port, 9090);
9499
assert_eq!(cfg.debug, true);
@@ -103,6 +108,7 @@ fn env_override() {
103108
host: None,
104109
port: None,
105110
debug: None,
111+
nested: None,
106112
tags: None,
107113
};
108114
with_vars(
@@ -112,7 +118,7 @@ fn env_override() {
112118
("FUN_APP_DEBUG", Some("true")),
113119
],
114120
|| {
115-
let cfg: Cfg = new_fun_cfg(&cli);
121+
let cfg: Cfg = new_cfg(&cli);
116122
assert_eq!(cfg.host, "10.0.0.1");
117123
assert_eq!(cfg.port, 7070);
118124
assert_eq!(cfg.debug, true);
@@ -128,9 +134,10 @@ fn cli_override() {
128134
host: Some("cli.host".into()),
129135
port: Some(6060),
130136
debug: Some(true),
137+
nested: None,
131138
tags: Some(vec!["cli1".into(), "cli2".into()]),
132139
};
133-
let cfg: Cfg = new_fun_cfg(&cli);
140+
let cfg: Cfg = new_cfg(&cli);
134141
assert_eq!(cfg.host, "cli.host");
135142
assert_eq!(cfg.port, 6060);
136143
assert_eq!(cfg.debug, true);
@@ -145,9 +152,10 @@ fn nested_struct() {
145152
host: None,
146153
port: None,
147154
debug: None,
155+
nested: None,
148156
tags: None,
149157
};
150-
let cfg: Cfg = new_fun_cfg(&cli);
158+
let cfg: Cfg = new_cfg(&cli);
151159
assert_eq!(cfg.nested.as_ref().unwrap().name, "foo");
152160
assert_eq!(cfg.nested.as_ref().unwrap().value, 42);
153161
}

0 commit comments

Comments
 (0)