Skip to content

Commit e30debf

Browse files
author
mfirhas
committed
Add try parse ini
Parse non-string from env/ini file into the types
1 parent a383879 commit e30debf

File tree

3 files changed

+105
-8
lines changed

3 files changed

+105
-8
lines changed

src/file/format/ini.rs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,29 @@ pub fn parse(
1616
Some(sec) => {
1717
let mut sec_map: Map<String, Value> = Map::new();
1818
for (k, v) in prop.iter() {
19-
sec_map.insert(
20-
k.to_owned(),
21-
Value::new(uri, ValueKind::String(v.to_owned())),
22-
);
19+
sec_map.insert(k.to_owned(), Value::new(uri, try_parse(v)));
2320
}
2421
map.insert(sec.to_owned(), Value::new(uri, ValueKind::Table(sec_map)));
2522
}
2623
None => {
2724
for (k, v) in prop.iter() {
28-
map.insert(
29-
k.to_owned(),
30-
Value::new(uri, ValueKind::String(v.to_owned())),
31-
);
25+
map.insert(k.to_owned(), Value::new(uri, try_parse(v)));
3226
}
3327
}
3428
}
3529
}
3630
Ok(map)
3731
}
32+
33+
fn try_parse(s: &str) -> ValueKind {
34+
if let Ok(parsed) = s.parse::<bool>() {
35+
return ValueKind::Boolean(parsed);
36+
}
37+
if let Ok(parsed) = s.parse::<i64>() {
38+
return ValueKind::I64(parsed);
39+
}
40+
if let Ok(parsed) = s.parse::<f64>() {
41+
return ValueKind::Float(parsed);
42+
}
43+
ValueKind::String(s.to_string())
44+
}

tests/all.env

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
TEST__NUMBER=123
2+
TEST__STRING=this is string from file
3+
TEST__FLOAT=123.3
4+
TEST__BOOLEAN=true
5+
6+
# [SEGMENT]
7+
TEST__SEGMENT_NUMBER=234
8+
TEST__SEGMENT_STRING=segment string from file bacot
9+
TEST__SEGMENT_FLOAT=234.4
10+
TEST__SEGMENT_BOOLEAN=false
11+
12+
TEST__SEGMENT_CHILD_BOOLEAN=true
13+
TEST__SEGMENT_CHILD_FLOAT=34.23
14+
15+
TEST__SEGMENT_CHILD2_BOOLEAN=234403000
16+
TEST__SEGMENT_CHILD2_FLOAT=5.00
17+
18+
TEST__SEGMENT_CHILD2_CHILD_FLOAT=5.000

tests/file_ini_2.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
use config::{
2+
builder::DefaultState, Config, ConfigBuilder, ConfigError, Environment, File, FileFormat,
3+
};
4+
use serde::Deserialize;
5+
use std::fmt::{Debug, Display};
6+
7+
const ALL_CFG_FILE: &str = "./tests/all.env";
8+
9+
#[derive(Debug, Deserialize)]
10+
struct TestConfig {
11+
#[serde(alias = "TEST__NUMBER")]
12+
pub number: i32,
13+
#[serde(alias = "TEST__STRING")]
14+
pub string: String,
15+
#[serde(alias = "TEST__FLOAT")]
16+
pub float: f32,
17+
#[serde(alias = "TEST__BOOLEAN")]
18+
pub boolean: bool,
19+
#[serde(flatten)]
20+
pub segment: TestSegmentConfig,
21+
}
22+
23+
#[derive(Debug, Deserialize)]
24+
struct TestSegmentConfig {
25+
#[serde(alias = "TEST__SEGMENT_NUMBER")]
26+
pub segment_number: i32,
27+
#[serde(alias = "TEST__SEGMENT_STRING")]
28+
pub segment_string: String,
29+
#[serde(alias = "TEST__SEGMENT_FLOAT")]
30+
pub segment_float: f32,
31+
#[serde(alias = "TEST__SEGMENT_BOOLEAN")]
32+
pub segment_boolean: bool,
33+
#[serde(flatten)]
34+
pub segment_child: TestSegmentChildConfig,
35+
#[serde(flatten)]
36+
pub segment_child2: TestSegmentChildConfig2,
37+
}
38+
39+
#[derive(Debug, Deserialize)]
40+
struct TestSegmentChildConfig {
41+
#[serde(alias = "TEST__SEGMENT_CHILD_BOOLEAN")]
42+
pub segment_child_bool: bool,
43+
#[serde(alias = "TEST__SEGMENT_CHILD_FLOAT")]
44+
pub segment_child_float: f64,
45+
}
46+
47+
#[derive(Debug, Deserialize)]
48+
struct TestSegmentChildConfig2 {
49+
#[serde(alias = "TEST__SEGMENT_CHILD2_BOOLEAN")]
50+
pub segment_child_number: u64,
51+
#[serde(alias = "TEST__SEGMENT_CHILD2_FLOAT")]
52+
pub segment_child_float: f64,
53+
#[serde(flatten)]
54+
pub segment_child2_child: TestSegmentChildConfig2Child,
55+
}
56+
57+
#[derive(Debug, Deserialize)]
58+
struct TestSegmentChildConfig2Child {
59+
#[serde(alias = "TEST__SEGMENT_CHILD2_CHILD_FLOAT")]
60+
pub segment_child2_child: f32,
61+
}
62+
63+
#[test]
64+
fn test_file_config_success() {
65+
let cfg = Config::builder()
66+
.add_source(config::File::new(ALL_CFG_FILE, FileFormat::Ini))
67+
.build()
68+
.unwrap()
69+
.try_deserialize::<TestConfig>();
70+
dbg!(&cfg);
71+
assert!(cfg.is_ok());
72+
}

0 commit comments

Comments
 (0)