]> git.huck.website - metaforge.git/commitdiff
better benchmarks
authorHuck Boles <huck@huck.website>
Sun, 14 May 2023 19:43:08 +0000 (14:43 -0500)
committerHuck Boles <huck@huck.website>
Sun, 14 May 2023 19:43:08 +0000 (14:43 -0500)
12 files changed:
benches/build_site.rs
benches/map_dir.rs [new file with mode: 0644]
files/site/pattern/body/bench.meta [new file with mode: 0644]
files/site/pattern/footer/bench.meta [new file with mode: 0644]
files/site/pattern/header/bench.meta [new file with mode: 0644]
files/site/pattern/list/item/bench.meta [new file with mode: 0644]
files/site/source/benchmark.meta [new file with mode: 0644]
src/builder.rs
src/lib.rs
src/main.rs
src/metafile.rs
src/parser.rs

index 07e4ca13a028972260bee2bbc55752f4b49e1cc4..96304d25f843562e596fc8857cb76957b906e41c 100644 (file)
@@ -1,23 +1,31 @@
 use criterion::{black_box, criterion_group, criterion_main, Criterion};
-use metaforge::Options;
 
-pub fn build_site_benchmark(c: &mut Criterion) {
+pub fn build_file_benchmark(c: &mut Criterion) {
     let dir = std::path::PathBuf::from("files/site")
         .canonicalize()
         .unwrap();
 
-    let mut opts = Options::new();
+    let mut opts = metaforge::Options::new();
     opts.root = dir.clone();
     opts.source = dir.join("source");
     opts.build = dir.join("build");
     opts.pattern = dir.join("pattern");
     opts.clean = true;
 
-    todo!("implement with DirNode")
-    // c.bench_function("build test site", |b| {
-    //     b.iter(|| build_site(black_box(&opts)))
-    // });
+    let source = opts.source.join("benchmark.meta");
+
+    c.bench_function("build benchmark file", |b| {
+        b.iter(|| {
+            let string = std::fs::read_to_string(black_box(&source)).unwrap();
+            let file = metaforge::parse_file(string, black_box(&opts)).unwrap();
+            let mut path = opts
+                .build
+                .join(source.strip_prefix(black_box(&opts.source)).unwrap());
+            path.set_extension("html");
+            std::fs::write(path, metaforge::build_metafile(&file).unwrap()).unwrap();
+        })
+    });
 }
 
-criterion_group!(benches, build_site_benchmark);
+criterion_group!(benches, build_file_benchmark);
 criterion_main!(benches);
diff --git a/benches/map_dir.rs b/benches/map_dir.rs
new file mode 100644 (file)
index 0000000..c1434f7
--- /dev/null
@@ -0,0 +1,27 @@
+use criterion::{black_box, criterion_group, criterion_main, Criterion};
+
+pub fn map_dir_benchmark(c: &mut Criterion) {
+    let dir = std::path::PathBuf::from("files/site")
+        .canonicalize()
+        .unwrap();
+
+    let mut opts = metaforge::Options::new();
+    opts.root = dir.clone();
+    opts.source = dir.join("source");
+    opts.build = dir.join("build");
+    opts.pattern = dir.join("pattern");
+    opts.clean = true;
+
+    c.bench_function("build benchmark file", |b| {
+        b.iter(|| {
+            let mut dir =
+                metaforge::DirNode::build(black_box(opts.source.clone()), black_box(&opts))
+                    .unwrap();
+            let tmp = metaforge::MetaFile::new(black_box(&opts));
+            dir.map(&tmp).unwrap();
+        })
+    });
+}
+
+criterion_group!(benches, map_dir_benchmark);
+criterion_main!(benches);
diff --git a/files/site/pattern/body/bench.meta b/files/site/pattern/body/bench.meta
new file mode 100644 (file)
index 0000000..8c1e1fa
--- /dev/null
@@ -0,0 +1,6 @@
+<body>
+    &{header}
+    ${bench_variable}
+    &{SOURCE}
+    &{footer}
+<body>
diff --git a/files/site/pattern/footer/bench.meta b/files/site/pattern/footer/bench.meta
new file mode 100644 (file)
index 0000000..c8f73d7
--- /dev/null
@@ -0,0 +1 @@
+@{array}
diff --git a/files/site/pattern/header/bench.meta b/files/site/pattern/header/bench.meta
new file mode 100644 (file)
index 0000000..80351bf
--- /dev/null
@@ -0,0 +1,11 @@
+@{
+    link.url = ['a.com','a.com','a.com','a.com','a.com','a.com','a.com','a.com','a.com','a.com'] 
+    link.title = ['a','a','a','a','a','a','a','a','a','a']
+}
+
+&{
+    list.item = 'bench'
+}
+
+&{list}
+
diff --git a/files/site/pattern/list/item/bench.meta b/files/site/pattern/list/item/bench.meta
new file mode 100644 (file)
index 0000000..b4259e0
--- /dev/null
@@ -0,0 +1 @@
+<li>&{link}</li>
diff --git a/files/site/source/benchmark.meta b/files/site/source/benchmark.meta
new file mode 100644 (file)
index 0000000..68eec32
--- /dev/null
@@ -0,0 +1,43 @@
+#{ filetype = 'html' }
+
+${
+    var = 'variables'
+    inline = 'inline variables'
+    bench_variable = 'this is a really long variable that contains multiple lines
+    and other interesting features to test how well metaforge deals long variables
+    \t this is a list:
+        - to
+        - see
+        - how
+        - flexible
+        - variables
+        - are
+    pretty cool!'
+
+}
+
+@{
+    single = ['single value arrays']
+    footer.array = ['1','2','3','4','5','6','7','8','9','10']
+}
+
+&{
+    body = 'bench'
+    header = 'bench'
+    footer = 'bench'
+}
+
+# THIS IS THE BENCHMARK FILE FOR METAFORGE
+
+*it has __${var}* and @{single}__
+
+<p>Some inline html with ${inline}</p>
+
+-{comments before a line} ### Other Tests 
+
+a bunch of symbols !@#$%^&*())_
+
+code blocks:
+```
+let f = "foo"
+```
index b1b757ad630b04b29a79c74189a81bcf3753d4a6..08deae6e74593e52bce0e5e62af0f4a6f1354fb5 100644 (file)
@@ -10,10 +10,10 @@ use std::{
 pub fn build_metafile(file: &MetaFile) -> Result<String> {
     let html = get_source_html(file, file.opts)?;
 
-    let pattern = get_pattern("base", &file)?;
+    let pattern = get_pattern("base", file)?;
     let mut base = parse_file(pattern, file.opts)?;
 
-    base.merge(&file);
+    base.merge(file);
     base.patterns.insert("SOURCE".to_string(), html);
 
     let output = metafile_to_string(&base)?;
@@ -24,7 +24,7 @@ pub fn build_metafile(file: &MetaFile) -> Result<String> {
 pub fn write_file(path: &Path, html: String, opts: &Options) -> Result<()> {
     let dest = find_dest(path, opts)?;
     // want newline to end file
-    fs::write(&dest, html + "\n")?;
+    fs::write(dest, html + "\n")?;
     Ok(())
 }
 
@@ -135,21 +135,19 @@ fn get_pattern(key: &str, file: &MetaFile) -> Result<String> {
     let mut pattern = MetaFile::build(path, file.opts)?;
 
     // copy over maps for expanding contained variables
-    pattern.merge(&file);
+    pattern.merge(file);
 
     metafile_to_string(&pattern)
 }
 
-fn get_variable(key: &str, file: &MetaFile) -> Result<String> {
+fn get_variable(_key: &str, _file: &MetaFile) -> Result<String> {
     todo!()
 }
 
 fn find_dest(path: &Path, opts: &Options) -> Result<PathBuf> {
     let path = path.canonicalize()?;
 
-    let path = opts.build.join(path.strip_prefix(&opts.source)?);
-    let mut path = PathBuf::from(path);
-
+    let mut path = opts.build.join(path.strip_prefix(&opts.source)?);
     path.set_extension("html");
 
     Ok(path)
@@ -169,7 +167,6 @@ fn expand_arrays(input: String, file: &MetaFile) -> Result<String> {
         })
         // make a hash map of [keys in source] -> [defined arrays]
         .map(|key| {
-            let y: String;
             // concat array to pattern name to get key in HashMap
             let name = file.name().unwrap();
             let long_key = name + "." + key;
index 3bb3fa38de0f0d7d5151de7a926f657f75bc50fa..9a9a080674cd7db6028ad8724857de3a78836d6f 100644 (file)
@@ -11,3 +11,35 @@ pub use builder::*;
 pub use metafile::*;
 pub use options::*;
 pub use parser::*;
+
+use clap::Parser;
+use color_eyre::Result;
+
+pub fn get_opts() -> Result<Options> {
+    let opts = Options::try_from(Opts::parse())?;
+
+    log!(
+        opts,
+        format!("cleaning build directory: {}", opts.build.display()),
+        1
+    );
+    if opts.clean && opts.build.exists() {
+        std::fs::remove_dir_all(&opts.build)?;
+    }
+
+    if !opts.build.exists() {
+        std::fs::create_dir(&opts.build)?;
+    }
+
+    Ok(opts)
+}
+
+pub fn build_dir(opts: &Options) -> Result<()> {
+    let mut source = DirNode::build(opts.source.clone(), opts)?;
+
+    let global_init = MetaFile::new(&opts);
+
+    source.map(&global_init)?;
+
+    Ok(())
+}
index a23cfdfa76404003abdb62ba00e1a35260c78877..63046405cfe6ed0236cdf642ef193984fef19f71 100644 (file)
@@ -1,24 +1,7 @@
-use clap::Parser;
-use color_eyre::Result;
-use metaforge::{log, Options, Opts};
-
-fn main() -> Result<()> {
+fn main() -> color_eyre::Result<()> {
     color_eyre::install()?;
 
-    let opts = Options::try_from(Opts::parse())?;
-
-    log!(
-        opts,
-        format!("cleaning build directory: {}", opts.build.display()),
-        1
-    );
-    if opts.clean && opts.build.exists() {
-        std::fs::remove_dir_all(&opts.build)?;
-    }
-
-    if !opts.build.exists() {
-        std::fs::create_dir(&opts.build)?;
-    }
+    let opts = metaforge::get_opts()?;
 
-    todo!("implement DirNode chain")
+    metaforge::build_dir(&opts)
 }
index 8a76317d0209615214c6dc8c2c7cd256424a7886..01ef06f00ca75db0defafc830619938a5ca56a0b 100644 (file)
@@ -18,7 +18,7 @@ impl<'a> MetaFile<'a> {
     pub fn build(path: PathBuf, opts: &'a Options) -> Result<Self> {
         let str = fs::read_to_string(&path)?;
         let mut metafile = parse_file(str, opts)?;
-        metafile.path = path.to_path_buf();
+        metafile.path = path;
         metafile.opts = opts;
         Ok(metafile)
     }
@@ -37,12 +37,19 @@ impl<'a> MetaFile<'a> {
 
     pub fn name(&self) -> Result<String> {
         if self.path.starts_with(&self.opts.source) {
+            // in source dir, we want the file name
             let name = self.path.strip_prefix(&self.opts.source)?;
             let name = name.to_string_lossy().to_string().replace('/', ".");
             Ok(name)
         } else {
+            // in pattern dir, we want the parent dir
             let name = self.path.strip_prefix(&self.opts.pattern)?;
-            let name = name.to_string_lossy().to_string().replace('/', ".");
+            let name = name
+                .parent()
+                .unwrap()
+                .to_string_lossy()
+                .to_string()
+                .replace('/', ".");
             Ok(name)
         }
     }
@@ -121,7 +128,7 @@ impl<'a> DirNode<'a> {
         let global = MetaFile::new(opts);
 
         Ok(Self {
-            path: path.to_path_buf(),
+            path,
             opts,
             global,
             files,
@@ -132,7 +139,7 @@ impl<'a> DirNode<'a> {
     // parses all contained files and directories and pushes
     // parsed structures into the files and directories vectors
     pub fn map(&mut self, global: &'a MetaFile) -> Result<()> {
-        for f in fs::read_dir(&self.path)?.into_iter() {
+        for f in fs::read_dir(&self.path)? {
             let file = f?.path();
 
             if file.is_dir() {
index 1eab21919413d660be0604ce1c55aeca0ad39b9d..65e11d3e2c97f2b740ef058577f084ba825b22b2 100644 (file)
@@ -10,7 +10,7 @@ use std::collections::HashMap;
 #[grammar = "meta.pest"]
 pub struct MetaParser;
 
-pub fn parse_file<'a>(file: String, opts: &'a Options) -> Result<MetaFile<'a>> {
+pub fn parse_file(file: String, opts: &Options) -> Result<MetaFile> {
     let meta_source = MetaParser::parse(Rule::file, &file)
         .wrap_err("parser error")?
         .next()
@@ -226,4 +226,10 @@ mod tests {
     fn map_source_map() {
         test_str!(r#"${var='v'} Some text @{array = ['a']}"#);
     }
+
+    #[test]
+    #[should_panic]
+    fn header_not_first() {
+        test_str!(r#"${v='v'} #{ type = 'html'} @{a=['a']}"#);
+    }
 }