Skip to content

Commit

Permalink
Make 'nest()' consider array indices.
Browse files Browse the repository at this point in the history
  • Loading branch information
thorio committed Aug 31, 2024
1 parent 4655e48 commit b6f8d3d
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 2 deletions.
15 changes: 13 additions & 2 deletions src/providers/env.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::fmt;

use crate::{Profile, Provider, Metadata};
use crate::coalesce::Coalescible;
use crate::coalesce::{Coalescible, Order};
use crate::value::{Map, Dict};
use crate::error::Error;
use crate::util::nest;
Expand Down Expand Up @@ -375,31 +375,42 @@ impl Env {
/// struct Config {
/// foo: Foo,
/// map: Dict,
/// array: Vec<usize>,
/// }
///
/// Jail::expect_with(|jail| {
/// // Without splitting: using structured data.
/// jail.set_env("APP_FOO", "{key=10}");
/// jail.set_env("APP_MAP", "{one=1,two=2.0}");
/// jail.set_env("APP_ARRAY", "[1,2,3]");
///
/// let config: Config = Figment::from(Env::prefixed("APP_")).extract()?;
/// assert_eq!(config, Config {
/// foo: Foo { key: 10 },
/// map: map!["one".into() => 1u8.into(), "two".into() => 2.0.into()],
/// array: vec![1, 2, 3],
/// });
///
/// jail.clear_env();
///
/// // With splitting.
/// jail.set_env("APP_FOO_KEY", 20);
/// jail.set_env("APP_MAP_ONE", "1.0");
/// jail.set_env("APP_MAP_TWO", "dos");
///
/// // Note that array order currently depends on definition order
/// jail.set_env("APP_ARRAY_0", "4");
/// jail.set_env("APP_ARRAY_2", "5");
/// jail.set_env("APP_ARRAY_1", "6");
///
/// let config: Config = Figment::new()
/// .merge(Env::prefixed("APP_").split("_"))
/// .extract()?;
///
/// assert_eq!(config, Config {
/// foo: Foo { key: 20 },
/// map: map!["one".into() => 1.0.into(), "two".into() => "dos".into()],
/// array: vec![4, 5, 6],
/// });
///
/// Ok(())
Expand Down Expand Up @@ -617,7 +628,7 @@ impl Provider for Env {
.into_dict()
.expect("key is non-empty: must have dict");

dict = dict.merge(nested_dict);
dict = dict.coalesce(nested_dict, Order::Admerge);
}

Ok(self.profile.collect(dict))
Expand Down
7 changes: 7 additions & 0 deletions src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,13 @@ use crate::value::{Value, Dict};
pub fn nest(key: &str, value: Value) -> Value {
fn value_from(mut keys: std::str::Split<'_, char>, value: Value) -> Value {
match keys.next() {
Some(k) if k.parse::<usize>().is_ok() => {
// TODO
// even if we do honor the index, it will get lost when coalescing.
// seems to me that nesting arrays will only be truly useful when
// coalescing two array items by their index is possible.
Value::from(vec![value_from(keys, value)])
}
Some(k) if !k.is_empty() => {
let mut dict = Dict::new();
dict.insert(k.into(), value_from(keys, value));
Expand Down

0 comments on commit b6f8d3d

Please sign in to comment.