2025-10-11 14:35:29 -07:00
|
|
|
use crate::context::SproutContext;
|
2025-10-14 12:47:33 -07:00
|
|
|
use crate::entries::EntryDeclaration;
|
2025-10-11 14:35:29 -07:00
|
|
|
use anyhow::Result;
|
2025-10-11 14:11:31 -07:00
|
|
|
use serde::{Deserialize, Serialize};
|
2025-10-04 23:12:01 -07:00
|
|
|
use std::collections::BTreeMap;
|
|
|
|
|
use std::rc::Rc;
|
|
|
|
|
|
2025-10-11 14:11:31 -07:00
|
|
|
#[derive(Serialize, Deserialize, Default, Clone)]
|
|
|
|
|
pub struct MatrixConfiguration {
|
|
|
|
|
#[serde(default)]
|
|
|
|
|
pub entry: EntryDeclaration,
|
|
|
|
|
#[serde(default)]
|
|
|
|
|
pub values: BTreeMap<String, Vec<String>>,
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-04 23:12:01 -07:00
|
|
|
fn build_matrix(input: &BTreeMap<String, Vec<String>>) -> Vec<BTreeMap<String, String>> {
|
|
|
|
|
let items: Vec<(String, Vec<String>)> = input.clone().into_iter().collect();
|
|
|
|
|
let mut result: Vec<BTreeMap<String, String>> = vec![BTreeMap::new()];
|
|
|
|
|
|
|
|
|
|
for (key, values) in items {
|
|
|
|
|
let mut new_result = Vec::new();
|
|
|
|
|
|
|
|
|
|
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()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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-11 14:35:29 -07:00
|
|
|
) -> Result<Vec<(Rc<SproutContext>, EntryDeclaration)>> {
|
2025-10-04 23:12:01 -07:00
|
|
|
let combinations = build_matrix(&matrix.values);
|
|
|
|
|
let mut entries = Vec::new();
|
|
|
|
|
|
|
|
|
|
for combination in combinations {
|
|
|
|
|
let mut context = context.fork();
|
|
|
|
|
context.insert(&combination);
|
|
|
|
|
let context = context.freeze();
|
|
|
|
|
|
|
|
|
|
let mut entry = matrix.entry.clone();
|
|
|
|
|
entry.title = context.stamp(&entry.title);
|
|
|
|
|
entry.actions = entry
|
|
|
|
|
.actions
|
|
|
|
|
.into_iter()
|
|
|
|
|
.map(|action| context.stamp(action))
|
|
|
|
|
.collect();
|
|
|
|
|
entries.push((context, entry));
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-11 14:35:29 -07:00
|
|
|
Ok(entries)
|
2025-10-04 23:12:01 -07:00
|
|
|
}
|