use color_eyre::Result;
use std::{
collections::HashMap,
+ fs,
path::{Path, PathBuf},
};
for section in file.source.iter() {
match section {
// concatenate any char sequences
- Source::Str(str) => output.push_str(str),
+ Source::Str(str) => {
+ output.push_str(str);
+ }
// expand all variables and recursively expand patterns
Source::Sub(sub) => {
let expanded = match sub {
// so we use them to mark keys for array substitution
Substitution::Array(key) => format!("-{{{key}}}"),
};
- output.push_str(&expanded);
+ output.push_str(&format!("\n{}\n", expanded));
}
}
}
// deal with arrays
- Ok(expand_arrays(output, file, name)?)
+ expand_arrays(output, file, name)
}
fn get_pattern(key: &str, file: &MetaFile, dirs: &RootDirs) -> Result<String> {
- let filename = match file.get_pat(key) {
- Some(file) => file,
- None => "default",
- };
+ let filename = file.get_pat(key).unwrap_or("default");
let pattern_path = key.replace('.', "/") + "/" + filename;
- let mut path = dirs.pattern.join(pattern_path).canonicalize()?;
- path.set_extension(".meta");
- let pattern = parse_file(path.to_str().unwrap_or_default())?;
+ let mut path = dirs.pattern.join(pattern_path);
+ path.set_extension("meta");
+ let pattern = &fs::read_to_string(path.to_str().unwrap_or_default())?;
+ let pattern = parse_file(pattern)?;
metafile_to_string(&pattern, dirs, Some(key))
}
})
// make a hash map of keys in the source to previously defined arrays
.map(|array| {
- let key = name.unwrap_or_default().to_owned() + "." + array;
+ let key: String;
+ if let Some(name) = name {
+ key = name.to_owned() + "." + array;
+ } else {
+ key = array.to_string();
+ }
+ // let key = dbg!(name.unwrap_or_default().to_owned() + "." + array);
let value = file.get_arr(&key).unwrap_or_default();
(*array, value)
})
let mut expanded = String::new();
// loop to duplicate the output template for each array member
- for i in 0.. {
+ for i in 0..get_max_size(&map) {
// get a fresh copy of the file
let mut str = output.clone();
// replace each key in the file
for (key, val) in map.iter() {
- str = str.replace(&format!("-{{{key}}}"), val[i]);
+ str = str.replace(&format!("-{{{key}}}"), val.get(i).unwrap_or(&""));
}
// concatenate to final file
expanded.push_str(&str);
Ok(expanded)
}
+
+fn get_max_size(map: &HashMap<&str, &[&str]>) -> usize {
+ let mut max = 0;
+ for val in map.values() {
+ if max < val.len() {
+ max = val.len();
+ }
+ }
+ max
+}
Pattern(&'a str),
}
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, Default)]
pub struct RootDirs {
pub source: PathBuf,
pub build: PathBuf,
extern crate pest;
extern crate pest_derive;
-fn main() {
- println!("Hello, world!");
+use color_eyre::Result;
+
+fn main() -> Result<()> {
+ Ok(())
}
+++ /dev/null
-TESTS:
-
-var1 [VALUE]: GOOD
-var2 [BLANK]:
-var3 [VAL WITH SPACES]: GOOD GOOD
-
-arr1 [VALUE]: GOOD
-arr3 [BLANK]:
-
-Pattern subs:
-
-test [WITH ARRAY]: <p>GOOD</p><p>GOOD GOOD</p>
-test.sub_pat: <h1>SUBPATTERN</h1>
-test.default: <h1>DEFAULT</h1>
-test.blank:
-
-This comment should not be rendered:
use crate::{metafile_to_string, parse_file, source, RootDirs, Source, Substitution};
use color_eyre::Result;
use pretty_assertions::assert_eq;
-use std::fs;
+use std::{fs, path::PathBuf};
-static SOURCE: &str = include_str!("test_files/test_site/source/test_source.meta");
-static PATTERN: &str = include_str!("test_files/test_site/pattern/test/pattern.meta");
-static PRE_EXPAND: &str = include_str!("test_files/test_site/source/expand.meta");
-static POST_EXPAND: &str = include_str!("test_files/expanded");
+static SOURCE: &str = include_str!("../../tests/files/test_site/source/test_source.meta");
+static PATTERN: &str = include_str!("../../tests/files//test_site/pattern/test/pattern.meta");
#[test]
fn test_metafile_gets() -> Result<()> {
Ok(())
}
-
-#[ignore = "Need to setup tmp dir first"]
-#[test]
-fn builder_tests() -> Result<()> {
- // vector of tests to perform on tmp_dir
- let mut tests: Vec<fn(dirs: &RootDirs) -> Result<()>> = Vec::default();
- tests.push(test_metafile_to_str);
-
- // run tests on tmp dir
- test_on_tmp_dir(tests)?;
- Ok(())
-}
-
-// builds a tmp_dir
-// runs multiple tests on it,
-// sanitizes build_dir between tests
-// deletes the tmpdir
-// so we don't have to rebuild entire tmpdir every test
-fn test_on_tmp_dir(tests: Vec<fn(dirs: &RootDirs) -> Result<()>>) -> Result<()> {
- let tmp_dir = std::env::temp_dir();
-
- let dirs = RootDirs {
- source: tmp_dir.join("source"),
- build: tmp_dir.join("site"),
- pattern: tmp_dir.join("pattern"),
- };
-
- for test in tests.iter() {
- // delete and remake build dir
- fs::remove_dir_all(&dirs.build)?;
- fs::create_dir(&dirs.build)?;
- // run test
- test(&dirs)?;
- }
-
- fs::remove_dir_all(tmp_dir)?;
- Ok(())
-}
-
-fn test_metafile_to_str(dirs: &RootDirs) -> Result<()> {
- let metafile = parse_file(PRE_EXPAND)?;
-
- let file = metafile_to_string(&metafile, dirs, None)?;
-
- assert_eq!(file, POST_EXPAND);
-
- Ok(())
-}
--- /dev/null
+TESTS:
+
+var1 [VALUE]:
+GOOD
+var2 [BLANK]:
+
+var3 [VAL WITH SPACES]:
+GOOD GOOD
+
+arr1 [VALUE]:
+GOOD
+arr2 [BLANK]:
+
+Pattern subs:
+
+test [WITH ARRAY]:
+<p>GOOD</p>
+<p>GOOD GOOD</p>
+test.sub_pat:
+<h1>SUBPATTERN</h1>
+test.default:
+<h1>DEFAULT</h1>
+test.blank:
+
+This comment should not be rendered:
--- /dev/null
+<p>@{arr}</p>
--- /dev/null
+<h1>DEFAULT</h1>
--- /dev/null
+<h1>SUBPATTERN</h1>
@{
arr1 = ['GOOD']
arr2 = []
- test.array = ["GOOD", "GOOD GOOD"]
+ test.arr = ["GOOD", "GOOD GOOD"]
}
&{
--- /dev/null
+use color_eyre::Result;
+use metaforge::*;
+use pretty_assertions::assert_eq;
+use std::{fs, path::PathBuf};
+
+static PRE_EXPAND: &str = include_str!("./files/test_site/source/expand.meta");
+static POST_EXPAND: &str = include_str!("./files/expanded");
+
+#[test]
+fn test_metafile_to_str() -> Result<()> {
+ let metafile = parse_file(PRE_EXPAND)?;
+ let dirs = build_rootdir()?;
+
+ let file = metafile_to_string(&metafile, &dirs, None)?;
+
+ assert_eq!(file, POST_EXPAND);
+
+ Ok(())
+}
+
+fn build_rootdir() -> Result<RootDirs> {
+ let dir = PathBuf::from("./tests/files/test_site");
+
+ let dirs = RootDirs {
+ source: dir.join("source"),
+ build: dir.join("site"),
+ pattern: dir.join("pattern"),
+ };
+
+ if dirs.build.exists() {
+ fs::remove_dir(&dirs.build)?;
+ }
+
+ fs::create_dir(&dirs.build)?;
+
+ Ok(dirs)
+}