From 4c099e6f39926fc38ca5fc2bca958760784b019e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arthur=20Woimb=C3=A9e?= Date: Mon, 20 Jan 2020 18:50:42 +0100 Subject: [PATCH] Better error message for writing, better modifiers handling --- src/file_transformer.rs | 4 ++-- src/main.rs | 34 ++++++++++++++-------------------- src/modifiers.rs | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 22 deletions(-) create mode 100644 src/modifiers.rs diff --git a/src/file_transformer.rs b/src/file_transformer.rs index d79cc8c..fd5299c 100644 --- a/src/file_transformer.rs +++ b/src/file_transformer.rs @@ -74,14 +74,14 @@ impl FileTransformer { let mut file_w = match open_options { Ok(f) => f, Err(e) => { - eprintln!("Could not open file ({})", e); + eprintln!("Could not open {} for writing ({})", file_name, e); return false; } }; match file_w.write(self.contents.as_bytes()) { Ok(_size) => true, Err(e) => { - eprintln!("Could write to file ({})", e); + eprintln!("Could write to {} ({})", file_name, e); false } } diff --git a/src/main.rs b/src/main.rs index d390688..81431c5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,24 +3,18 @@ extern crate clap; mod file_finder; mod file_transformer; +mod modifiers; use file_finder::f_find; use file_transformer::FileTransformer; +use modifiers::{get_modifier, DynFnPtr}; use rayon::prelude::*; use regex::Regex; use std::error::Error; -fn to_upper(s: &str) -> String { - s.to_ascii_uppercase() -} - -fn to_lower(s: &str) -> String { - s.to_ascii_lowercase() -} - struct Match { id: usize, - transform: Option<&'static (dyn (Fn(&str) -> String) + Sync)>, + transform: Option, } enum ReplacePart<'a> { @@ -38,8 +32,9 @@ fn parse_escaped<'a>(sr: (&str, &'a str)) -> SearchReplace<'a> { let replace = vec![ReplacePart::Str(repl)]; SearchReplace { search, replace } } + fn parse<'a>(sr: (&str, &'a str)) -> SearchReplace<'a> { - let reg_match = Regex::new(r"\$\(([0-9]*)([A-Z])?\)").unwrap(); + let reg_match = Regex::new(r"\$\(([0-9]*)([A-Z]+)?\)").unwrap(); let (raw_search, raw_replace) = sr; let search = Regex::new(raw_search).unwrap(); let mut replace = Vec::new(); @@ -50,11 +45,12 @@ fn parse<'a>(sr: (&str, &'a str)) -> SearchReplace<'a> { // if is not escaped if full.start() == 0 || raw_replace.as_bytes()[full.start() - 1] != b'$' { let id = nb.as_str().parse().unwrap(); - let transform: Option<&'static (dyn (Fn(&str) -> String) + Sync)> = match m.get(2) { - Some(c) if c.as_str() == "U" => Some(&to_upper), - Some(c) if c.as_str() == "L" => Some(&to_lower), + let transform: Option = match m.get(2) { + Some(c) => match get_modifier(c.as_str()) { + Some(m) => Some(m), + None => panic!("Unrecognised modifier: {}", c.as_str()), + }, None => None, - Some(c) => panic!("Unrecognised modifier: {}", c.as_str()), }; replace.push(ReplacePart::Str(&raw_replace[read_ofset..full.start()])); replace.push(ReplacePart::Match(Match { id, transform })); @@ -121,12 +117,10 @@ fn sr_file(fname: &str, search_replace: &[SearchReplace]) { for part in &sr.replace { match part { ReplacePart::Str(stri) => new_text.push_str(stri), - ReplacePart::Match(m) => { - match m.transform { - Some(t) => new_text.push_str(&t(&cap[m.id])), - None => new_text.push_str(&cap[m.id]), - } - } + ReplacePart::Match(m) => match m.transform { + Some(t) => new_text.push_str(&t(&cap[m.id])), + None => new_text.push_str(&cap[m.id]), + }, } } ft.reader_replace(start, end, new_text); diff --git a/src/modifiers.rs b/src/modifiers.rs new file mode 100644 index 0000000..a1b0108 --- /dev/null +++ b/src/modifiers.rs @@ -0,0 +1,34 @@ +pub type DynFnPtr = &'static (dyn (Fn(&str) -> String) + Sync); + +struct Modifier { + s: &'static str, + fn_ptr: DynFnPtr, +} + +const MODIFIERS: [Modifier; 2] = [ + Modifier { + s: "U", + fn_ptr: &to_upper, + }, + Modifier { + s: "L", + fn_ptr: &to_lower, + }, +]; + +fn to_upper(s: &str) -> String { + s.to_ascii_uppercase() +} + +fn to_lower(s: &str) -> String { + s.to_ascii_lowercase() +} + +pub fn get_modifier(requested: &str) -> Option { + for m in MODIFIERS.iter() { + if requested == m.s { + return Some(m.fn_ptr); + }; + } + None +}