tikz-gallery-generator

Custum build of stapix for tikz.pablopie.xyz

Commit
fbd97db8a741b7e8161b77d11d901ae86ddc6ffd
Parent
373f7524b7969d8ef245d003918444f8b0699c02
Author
Pablo <pablo-pie@riseup.net>
Date

Added an option for configuring the number of threads used for rendering

Renamed the "--full-build" option to "-B"

Also removed the usageln! macro

Diffstats

3 files changed, 69 insertions, 63 deletions

Status Name Changes Insertions Deletions
Deleted TODO.md 1 file changed 0 4
Modified src/log.rs 2 files changed 11 19
Modified src/main.rs 2 files changed 58 40
diff --git a/TODO.md /dev/null
@@ -1,4 +0,0 @@
-# TODO
-
-* add a flag to configure the size of the thread pool
-* introduce a static configuration file?
diff --git a/src/log.rs b/src/log.rs
@@ -22,7 +22,6 @@ pub(crate) enum Level {
   Error,
   Info,
   Warn,
-  Usage,
 }
 
 pub struct JobListLogger {
@@ -64,23 +63,10 @@ macro_rules! warnln {
   });
 }
 
-#[macro_export]
-macro_rules! usageln {
-  // usageln!("a {} event", "log");
-  ($($arg:tt)+) => ({
-    $crate::log::log(
-      $crate::log::Level::Usage,
-      &std::format_args!($($arg)+),
-    );
-  });
-}
-
 pub fn finished(duration: Duration) {
-  let duration = duration.as_millis() / 100;
-  let secs  = duration / 10;
-  let dsecs = duration % 10;
+  let millis = duration.as_millis();
 
-  println!("  {BOLD_GREEN}Finished{RESET} Rendering took {secs}.{dsecs}s");
+  println!("  {BOLD_GREEN}Finished{RESET} Rendering took {millis}ms");
 }
 
 #[cfg(target_arch = "x86_64")]
@@ -97,6 +83,15 @@ pub fn version(program_name: &str) {
   infoln!("Running {BOLD_WHITE}{program_name} {PROGRAM_VERSION}{RESET}");
 }
 
+pub fn usage(program: &str) {
+  use crate::{FULL_BUILD_OPT, N_THREADS_OPT};
+  println!("     {BOLD_YELLOW}Usage{RESET} {program} [{FULL_BUILD_OPT}] [{N_THREADS_OPT} <jobs>] <config.yml>");
+}
+
+pub fn usage_config() {
+  println!("     {BOLD_YELLOW}Usage{RESET} See `examples/config.yaml` for an example of configuration file");
+}
+
 impl JobListLogger {
   pub fn new(total_jobs: usize) -> Self {
     Self {
@@ -171,8 +166,5 @@ pub(crate) fn log(level: Level, args: &Arguments<'_>) {
     Level::Warn => {
       println!("   {BOLD_YELLOW}Warning{RESET} {args}");
     }
-    Level::Usage => {
-      println!("     {BOLD_YELLOW}Usage{RESET} {args}");
-    }
   }
 }
diff --git a/src/main.rs b/src/main.rs
@@ -24,10 +24,9 @@ mod gallery_entry;
 /// A wrapper for displaying the path for the thumbnail of a given path
 pub struct ThumbPath<'a>(pub &'a GalleryEntry);
 
-/// A wrapper to display lists of command line arguments
-struct ArgList<'a>(pub &'a [String]);
-
-const FULL_BUILD_OPT: &str = "--full-build";
+const FULL_BUILD_OPT: &str = "-B";
+const N_THREADS_OPT:  &str = "-j";
+const BOTH_OPTS:      &str = "-Bj";
 
 const TARGET_PATH:  &str = "./site";
 const PAGES_PATH:   &str = "figures";
@@ -42,40 +41,75 @@ fn main() -> ExitCode {
   let program = args
     .next()
     .expect("args always contains at least the input program");
-  let args: Vec<String> = args.collect();
+  // let args: Vec<String> = args.collect();
 
   log::version(&program);
 
-  let (config, full_build) = match &args[..] {
-    [config] => (config, false),
-    [config, opt] if opt == FULL_BUILD_OPT => {
-      (config, true)
-    }
-    [_config, ..] => {
-      errorln!("Unknown arguments: {}", ArgList(&args[1..]));
-      usageln!("{program} [{FULL_BUILD_OPT}] <config.yml>");
-      return ExitCode::FAILURE;
-    }
-    [] => {
+  let config = match args.next() {
+    Some(config) => config,
+    None         => {
       errorln!("Expected 1 command line argument, found none");
-      usageln!("{program} [{FULL_BUILD_OPT}] <config.yml>");
+      log::usage(&program);
       return ExitCode::FAILURE;
     }
   };
 
-  let f = File::open(config);
+  let mut full_build = false;
+  let mut num_threads = num_cpus::get() - 1;
+  while let Some(arg) = args.next() {
+    let mut is_valid_arg = false;
+
+    if arg == FULL_BUILD_OPT || arg == BOTH_OPTS {
+      full_build = true;
+      is_valid_arg = true;
+    }
+
+    if arg == N_THREADS_OPT || arg == BOTH_OPTS {
+      is_valid_arg = true;
+
+      let val = match args.next() {
+        Some(val) => val,
+        None      => {
+          errorln!("Expected one more argument, got none");
+          log::usage(&program);
+          return ExitCode::FAILURE;
+        }
+      };
+
+      match val.parse() {
+        Ok(val) => num_threads = val,
+        Err(_)  => {
+          errorln!("Expected a number, got {val:?}");
+          log::usage(&program);
+          return ExitCode::FAILURE;
+        }
+      }
+    }
+    
+    if !is_valid_arg {
+      if arg.starts_with("-") {
+        errorln!("Unknown option: {arg:?}");
+      } else {
+        errorln!("Unknown argument: {arg:?}");
+      }
+      log::usage(&program);
+      return ExitCode::FAILURE;
+    }
+  }
+
+  let f = File::open(&config);
   match f.map(serde_yaml::from_reader::<_, Vec<GalleryEntry>>) {
     Err(err) => {
       errorln!("Couldn't open {config:?}: {err}");
-      usageln!("{program} [{FULL_BUILD_OPT}] <config.yml>");
+      log::usage(&program);
       return ExitCode::FAILURE;
     }
     Ok(Err(err)) => {
       errorln!("Couldn't parse {config:?}: {err}");
-      usageln!("See `examples/config.yaml` for an example of configuration file");
+      log::usage_config();
       return ExitCode::FAILURE;
     }
-    Ok(Ok(pics)) => if render_gallery(pics, full_build).is_err() {
+    Ok(Ok(pics)) => if render_gallery(pics, full_build, num_threads).is_err() {
       return ExitCode::FAILURE;
     },
   }
@@ -86,7 +120,8 @@ fn main() -> ExitCode {
 /// Coordinates the rendering of all the pages and file conversions
 fn render_gallery(
   pics: Vec<GalleryEntry>,
-  full_build: bool
+  full_build: bool,
+  num_threads: usize,
 ) -> Result<(), ()> {
   let start = Instant::now();
 
@@ -112,7 +147,7 @@ fn render_gallery(
   }
 
   // ========================================================================
-  let num_threads = cmp::min(num_cpus::get() - 1, pics.len());
+  let num_threads = cmp::min(num_threads, pics.len());
   let rendering_pool = ThreadPool::with_name(
     String::from("thumbnails renderer"),
     num_threads
@@ -522,20 +557,3 @@ impl From> for PathBuf {
     result
   }
 }
-
-impl Display for ArgList<'_> {
-  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
-    let mut first = true;
-
-    for arg in self.0 {
-      if first {
-        first = false;
-        write!(f, "{:?}", arg)?;
-      } else {
-        write!(f, " {:?}", arg)?;
-      }
-    }
-
-    Ok(())
-  }
-}