finally fix context :neofox_googly_shocked:

This commit is contained in:
KitsuneCafe 2024-02-13 09:34:07 -05:00
parent 09ffd82157
commit 26f74906c1
3 changed files with 34 additions and 70 deletions

View file

@ -1,53 +1,16 @@
use std::path::Path;
use std::{path::Path, borrow::BorrowMut};
use tera::{Map, Value};
// FIXME: first processed entry in a map gets pushed to parent. see note below
fn inner_merge<'a>(a: &mut Map<String, Value>, b: &'a Value) -> Option<Value> {
match b {
Value::Object(o) => {
let mut map = Map::new();
for (key, entry) in o.iter() {
println!("{key} {entry:?}");
let mut child_map = if a.contains_key(key) {
// FIXME: this is probably the culprit. it doesn't pick up changes made during
// this iteration
a[key]
.as_object()
.map(|m| m.to_owned())
.unwrap_or(Map::new())
} else {
Map::new()
};
println!("map {child_map:?}");
if let Some(value) = inner_merge(&mut child_map, entry) {
child_map.insert(key.into(), value);
}
map.extend(child_map);
}
println!("final map {map:?}");
Some(map.into())
fn merge(a: &mut Value, b: Value) {
match (a, b) {
(&mut Value::Object(ref mut a), Value::Object(b)) => {
b.into_iter().for_each(|(k, v)| {
merge(a.entry(k).or_insert(Value::Null), v);
});
}
value => Some(value.to_owned()),
}
}
trait Merge {
fn merge(&mut self, other: Self);
}
impl Merge for tera::Context {
fn merge(&mut self, other: Self) {
let mut json = self.clone().into_json();
let map = json.as_object_mut().unwrap();
if let Some(value) = inner_merge(map, &other.into_json()) {
if let Ok(new_map) = tera::Context::from_value(value) {
self.extend(new_map);
}
(a, b) => {
*a = b;
}
}
}
@ -109,22 +72,26 @@ impl<I: Iterator> MapFoldExt for I {
type Item = I::Item;
}
#[derive(Debug)]
#[derive(Clone, Debug)]
pub(crate) struct Context {
inner: tera::Context,
inner: tera::Value,
}
impl Context {
pub fn new() -> Self {
Self {
inner: tera::Context::new(),
inner: tera::Value::Null
}
}
pub fn to_inner(&mut self) -> &mut tera::Context {
&mut self.inner
pub fn merge(&mut self, other: tera::Context) {
merge(
self.inner.borrow_mut(),
other.into_json()
)
}
fn path_to_string<P: AsRef<Path>>(path: &P) -> String {
path.as_ref().to_string_lossy().to_string()
}
@ -160,7 +127,7 @@ impl Context {
if let Some(v) = Self::create_path(&path.unwrap(), value) {
if let Ok(ctx) = tera::Context::from_value(v) {
self.inner.merge(ctx)
self.merge(ctx);
}
}
}
@ -170,18 +137,17 @@ impl Context {
}
}
#[cfg(test)]
mod tests {
use std::path::Path;
use super::Context;
#[test]
fn whatever() {
let path = "this/is/a/test.html";
let mut context = Context::new();
println!("{context:?}");
context.insert(&Path::new(&path), &":3".into());
println!("{context:?}");
impl Into<tera::Value> for Context {
fn into(self) -> tera::Value {
self.inner
}
}
impl TryInto<tera::Context> for Context {
type Error = tera::Error;
fn try_into(self) -> Result<tera::Context, Self::Error> {
tera::Context::from_value(self.inner)
}
}

View file

@ -2,7 +2,6 @@ use std::collections::HashMap;
use tera::{to_value, try_get_value, Map, Result, Tera, Value};
pub fn values(value: &Value, _args: &HashMap<String, Value>) -> Result<Value> {
println!("value {value:?}");
let arr = try_get_value!("values", "value", Map<String, Value>, value)
.into_iter()
.map(|(_, x)| x)

View file

@ -82,7 +82,6 @@ fn context_from_meta_files<'a, T: AsRef<Path>>(
let mut str = String::from_utf8(buf).map_err(handle_err)?;
let toml: Table = toml::from_str(&mut str).map_err(handle_err)?;
println!("{:?}", &file_path.strip_root(path)?);
context.insert(
&file_path.strip_root(path)?,
&tera::to_value(toml).map_err(handle_err)?,
@ -125,8 +124,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
CONTENT_EXT.contains(&ext)
});
let mut context = context_from_meta_files(&meta, &file_path)?;
println!(":3 {context:?}\n");
let mut context: Context = context_from_meta_files(&meta, &file_path)?;
let theme = config.syntect.theme.unwrap_or(DEFAULT_THEME.to_string());
let syntax_set = SyntaxSet::load_defaults_newlines();
@ -162,7 +160,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut tera = tera::Tera::default();
register_functions(&mut tera);
let mut html = TeraParser::new(&mut tera, TeraParserOptions::default());
html.add_context(context.to_inner());
let ctx: tera::Context = context.clone().try_into().unwrap();
html.add_context(&ctx);
parser.push(&mut html);
Roxy::process_file(&file, &output_path, &mut parser).unwrap();