2025-10-11 14:35:29 -07:00
|
|
|
use crate::context::SproutContext;
|
2025-11-02 23:28:31 -05:00
|
|
|
use crate::entries::BootableEntry;
|
2025-10-27 15:41:29 -04:00
|
|
|
use crate::generators::list;
|
2025-11-03 02:04:21 -05:00
|
|
|
use alloc::collections::BTreeMap;
|
|
|
|
|
use alloc::rc::Rc;
|
|
|
|
|
use alloc::string::String;
|
|
|
|
|
use alloc::vec;
|
|
|
|
|
use alloc::vec::Vec;
|
2025-10-11 14:35:29 -07:00
|
|
|
use anyhow::Result;
|
2025-11-02 23:28:31 -05:00
|
|
|
use edera_sprout_config::generators::list::ListConfiguration;
|
|
|
|
|
use edera_sprout_config::generators::matrix::MatrixConfiguration;
|
2025-10-04 23:12:01 -07:00
|
|
|
|
2025-10-20 00:06:46 -07:00
|
|
|
/// Builds out multiple generations of `input` based on a matrix style.
|
|
|
|
|
/// For example, if input is: {"x": ["a", "b"], "y": ["c", "d"]}
|
|
|
|
|
/// It will produce:
|
|
|
|
|
/// x: a, y: c
|
|
|
|
|
/// x: a, y: d
|
|
|
|
|
/// x: b, y: c
|
|
|
|
|
/// x: b, y: d
|
2025-10-04 23:12:01 -07:00
|
|
|
fn build_matrix(input: &BTreeMap<String, Vec<String>>) -> Vec<BTreeMap<String, String>> {
|
2025-10-20 00:06:46 -07:00
|
|
|
// Convert the input into a vector of tuples.
|
2025-10-04 23:12:01 -07:00
|
|
|
let items: Vec<(String, Vec<String>)> = input.clone().into_iter().collect();
|
2025-10-20 00:06:46 -07:00
|
|
|
|
|
|
|
|
// The result is a vector of maps.
|
2025-10-04 23:12:01 -07:00
|
|
|
let mut result: Vec<BTreeMap<String, String>> = vec![BTreeMap::new()];
|
|
|
|
|
|
|
|
|
|
for (key, values) in items {
|
|
|
|
|
let mut new_result = Vec::new();
|
|
|
|
|
|
2025-10-20 00:06:46 -07:00
|
|
|
// Produce all the combinations of the input values.
|
2025-10-04 23:12:01 -07:00
|
|
|
for combination in &result {
|
|
|
|
|
for value in &values {
|
|
|
|
|
let mut new_combination = combination.clone();
|
|
|
|
|
new_combination.insert(key.clone(), value.clone());
|
|
|
|
|
new_result.push(new_combination);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result = new_result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result.into_iter().filter(|item| !item.is_empty()).collect()
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-20 00:06:46 -07:00
|
|
|
/// Generates a set of entries using the specified `matrix` configuration in the `context`.
|
2025-10-04 23:12:01 -07:00
|
|
|
pub fn generate(
|
2025-10-11 14:35:29 -07:00
|
|
|
context: Rc<SproutContext>,
|
2025-10-04 23:12:01 -07:00
|
|
|
matrix: &MatrixConfiguration,
|
2025-10-24 16:32:48 -07:00
|
|
|
) -> Result<Vec<BootableEntry>> {
|
2025-10-20 00:06:46 -07:00
|
|
|
// Produce all the combinations of the input values.
|
2025-10-04 23:12:01 -07:00
|
|
|
let combinations = build_matrix(&matrix.values);
|
2025-10-27 15:41:29 -04:00
|
|
|
// Use the list generator to generate entries for each combination.
|
|
|
|
|
list::generate(
|
|
|
|
|
context,
|
2025-11-02 23:28:31 -05:00
|
|
|
&ListConfiguration {
|
2025-10-27 15:41:29 -04:00
|
|
|
entry: matrix.entry.clone(),
|
|
|
|
|
values: combinations,
|
|
|
|
|
},
|
|
|
|
|
)
|
2025-10-04 23:12:01 -07:00
|
|
|
}
|