From 26f74906c1d7da47e57fcbcb2b3f6b835172aaf8 Mon Sep 17 00:00:00 2001 From: KitsuneCafe <10284516+kitsunecafe@users.noreply.github.com> Date: Tue, 13 Feb 2024 09:34:07 -0500 Subject: [PATCH] finally fix context :neofox_googly_shocked: --- src/context.rs | 96 ++++++++++++++++-------------------------------- src/functions.rs | 1 - src/main.rs | 7 ++-- 3 files changed, 34 insertions(+), 70 deletions(-) diff --git a/src/context.rs b/src/context.rs index 8d167cb..db881ab 100644 --- a/src/context.rs +++ b/src/context.rs @@ -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, b: &'a Value) -> Option { - 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 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>(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 for Context { + fn into(self) -> tera::Value { + self.inner } } + +impl TryInto for Context { + type Error = tera::Error; + + fn try_into(self) -> Result { + tera::Context::from_value(self.inner) + } +} + diff --git a/src/functions.rs b/src/functions.rs index f5534c2..e5e02b1 100644 --- a/src/functions.rs +++ b/src/functions.rs @@ -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) -> Result { - println!("value {value:?}"); let arr = try_get_value!("values", "value", Map, value) .into_iter() .map(|(_, x)| x) diff --git a/src/main.rs b/src/main.rs index b4786aa..0502c5a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -82,7 +82,6 @@ fn context_from_meta_files<'a, T: AsRef>( 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> { 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> { 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();