Nested params

This commit is contained in:
bluepython508
2023-12-09 22:27:53 +00:00
parent 342a364aed
commit 8482b7fea0
3 changed files with 50 additions and 11 deletions

View File

@@ -1 +1 @@
abc 123 {{ name }}
abc 123 {{ name }} {{ nested.param }}

View File

@@ -61,8 +61,7 @@ fn run(
"Expected {} to be empty or not exist",
destination.display()
);
// let destination = destination.canonicalize()?;
let params = Params(params.into_iter().collect());
let params = Params::from_kv(params)?;
context::Context::load(template, params)?.generate(destination)?;

View File

@@ -1,7 +1,7 @@
use eyre::Result;
use eyre::{bail, Result};
use serde::{Deserialize, Serialize};
use tracing::instrument;
use std::{collections::HashMap, convert::Infallible, path::PathBuf, str::FromStr};
use tracing::instrument;
#[derive(Debug, Clone, PartialEq, Deserialize)]
pub struct Manifest {
@@ -34,7 +34,7 @@ impl Source {
Self::Path(relative) if relative.is_relative() => match self {
Self::Path(root) => Self::Path(root.join(relative)),
},
other => other.clone()
other => other.clone(),
}
}
@@ -48,7 +48,7 @@ impl Source {
#[instrument]
pub fn load(&self) -> Result<Vec<u8>> {
match self {
Self::Path(path) => Ok(std::fs::read(path)?)
Self::Path(path) => Ok(std::fs::read(path)?),
}
}
}
@@ -89,7 +89,8 @@ impl Transform {
}
#[derive(Debug, Serialize, Deserialize, Default, Clone, PartialEq)]
pub struct Params(pub HashMap<String, String>);
#[serde(transparent)]
pub struct Params(toml::Table);
impl Params {
pub fn load_user() -> Result<Self> {
@@ -98,8 +99,47 @@ impl Params {
)?))
}
pub fn merge(mut self, other: Self) -> Self {
self.0.extend(other.0);
self
pub fn from_kv(it: impl IntoIterator<Item = (String, String)>) -> Result<Self> {
it.into_iter()
.map(|(k, v)| {
let toml::Value::Table(val) = k
.split('.')
.rev()
.fold(toml::Value::String(v), |v, k| {
toml::Value::Table(toml::Table::from_iter([(k.to_owned(), v)]))
})
else {
bail!("Key must not be empty")
};
Ok(Self(val))
})
.try_fold(Self::default(), |acc, param| Ok(acc.merge(param?)))
}
pub fn merge(self, other: Self) -> Self {
fn merge(v1: &mut toml::Value, v2: toml::Value) {
use toml::Value::*;
match (v1, v2) {
(Table(t1), Table(t2)) => {
for (k, v) in t2 {
match t1.entry(k) {
toml::map::Entry::Vacant(e) => {
e.insert(v);
}
toml::map::Entry::Occupied(e) => {
merge(e.into_mut(), v);
}
}
}
}
(v1, v2) => {
*v1 = v2;
}
}
}
let mut lhs = toml::Value::Table(self.0);
merge(&mut lhs, toml::Value::Table(other.0));
let toml::Value::Table(table) = lhs else { unreachable!() };
Self(table)
}
}