From 5cb56cf81dafba1011ccff8c24b6e4b150406f17 Mon Sep 17 00:00:00 2001 From: Qrius Date: Thu, 26 Sep 2024 00:11:05 +0200 Subject: Make ordering more forgiving, emit warnings instead of panicing --- src/skaldpress/main.rs | 65 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/skaldpress/main.rs b/src/skaldpress/main.rs index 9d68bac..425b2d7 100644 --- a/src/skaldpress/main.rs +++ b/src/skaldpress/main.rs @@ -1,6 +1,7 @@ use skaldpress::macro_processor::error::SMPError; -use skaldpress::macro_processor::macro_processor::MacroType; +use skaldpress::macro_processor::macro_processor::{MacroProcessorWarning, MacroType}; use skaldpress::skaldpress::parseopts::{parseopts, Opts}; +use std::cmp::Ordering; use std::collections::HashMap; use std::fs; use std::path::Path; @@ -34,6 +35,52 @@ struct CompiledFile { needs_recompilation: bool, } +/// Convenience function for doing cmp on a metadata key of two arbitrary indexes +/// This takes a macro_processor as input, so that it can emit warnings if the ordering failed in +/// any way. +fn order_index_by_cached_data( + smp: &mut MacroProcessor, + key: &str, + a: &usize, + b: &usize, +) -> Ordering { + let compiled_files: &Vec; + unsafe { + compiled_files = COMPILED_FILES.as_ref(); + } + if *a >= compiled_files.len() { + smp.warnings.push(MacroProcessorWarning::new(format!( + "\"a\" is not a cached file {} >= {}", + *a, + compiled_files.len() + ))); + return Ordering::Equal; + } + if *b >= compiled_files.len() { + smp.warnings.push(MacroProcessorWarning::new(format!( + "\"b\" is not a cached file {} >= {}", + *b, + compiled_files.len() + ))); + return Ordering::Equal; + } + let Some(a) = &compiled_files[*a].metadata.get(key) else { + smp.warnings.push(MacroProcessorWarning::new(format!( + "Key {:?} not found for ordering data in {:?}", + key, compiled_files[*a].source_path + ))); + return Ordering::Equal; + }; + let Some(b) = &compiled_files[*b].metadata.get(key) else { + smp.warnings.push(MacroProcessorWarning::new(format!( + "Key {:?} not found for ordering data in {:?}", + key, compiled_files[*b].source_path + ))); + return Ordering::Equal; + }; + a.cmp(b) +} + /// SMP Macro for processing input with a template /// /// This will keep state of the macro_processor from the document which invokes the macro. @@ -87,21 +134,9 @@ fn sp_all_tagged_by( let mut tagged_files = tagged_files.clone(); if args.len() > 2 { if args.len() > 3 && args[3] == "reversed" { - tagged_files.sort_by(|a, b| { - *(&compiled_files[*b] - .metadata - .get(&args[2]) - .unwrap() - .cmp(&compiled_files[*a].metadata.get(&args[2]).unwrap())) - }); + tagged_files.sort_by(|a, b| order_index_by_cached_data(smp, &args[2], b, a)); } else { - tagged_files.sort_by(|a, b| { - *(&compiled_files[*a] - .metadata - .get(&args[2]) - .unwrap() - .cmp(&compiled_files[*b].metadata.get(&args[2]).unwrap())) - }); + tagged_files.sort_by(|a, b| order_index_by_cached_data(smp, &args[2], b, a)); } } -- cgit v1.2.3