Skip to content

Commit

Permalink
implement sha generator (#46)
Browse files Browse the repository at this point in the history
* implement sha generator

* satisfy clippy

* fix tests
  • Loading branch information
igaray authored Jan 12, 2025
1 parent 07c81bb commit 43f17e4
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 43 deletions.
21 changes: 21 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ kamadak-exif = "*"
# string wrangling
heck = "*"
chrono-tz = "0.10.0"
strum = "0.26.3"
strum_macros = "0.26.4"
#unicode-segmentation = "*"

# output
Expand Down
3 changes: 3 additions & 0 deletions src/ocd/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,9 @@ impl Plan {
}

fn present_long(&self) {
println!(
"--------------------------------------------------------------------------------"
);
println!("Result:");
for (src, action) in &self.actions {
match action {
Expand Down
38 changes: 12 additions & 26 deletions src/ocd/mrn/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ use crate::ocd::Plan;
use crate::ocd::Speaker;
use crate::ocd::Verbosity;
use clap::Args;
use clap::ValueEnum;
use heck::ToKebabCase;
use heck::ToSnakeCase;
use heck::ToTitleCase;
use heck::ToUpperCamelCase;
use regex::Regex;
use std::error::Error;
use std::fs;
use std::path::Path;
use std::path::PathBuf;
use std::sync::LazyLock;
use walkdir::WalkDir;
Expand Down Expand Up @@ -72,11 +72,6 @@ Default is low, one medium, two high, three or more debug."#)]
#[arg(long)]
mode: Mode,

#[arg(default_value = "lalrpop")]
#[arg(help = "Specifies with parser to use.")]
#[arg(long)]
parser: crate::ocd::mrn::MassRenameParser,

#[arg(help = "Recurse directories.")]
#[arg(long)]
#[arg(short = 'r')]
Expand Down Expand Up @@ -135,24 +130,15 @@ impl Speaker for MassRenameArgs {
}
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, ValueEnum)]
enum MassRenameParser {
Handwritten,
Lalrpop,
}

pub(crate) fn run(config: &MassRenameArgs) -> Result<(), Box<dyn Error + '_>> {
if config.verbosity() >= Verbosity::Silent {
println!("Verbosity: {:?}", config.verbosity())
}

// Parse instructions
let program = match config.parser {
MassRenameParser::Handwritten => parse_with_handwritten(config)?,
MassRenameParser::Lalrpop => parse_with_lalrpop(config)?,
};
let program = parse_with_lalrpop(config)?;
if config.verbosity() >= Verbosity::Debug {
println!("Program: \n{:#?}", &program);
println!("{:#?}", &program);
}

// Initialize plan
Expand All @@ -179,10 +165,6 @@ pub(crate) fn run(config: &MassRenameArgs) -> Result<(), Box<dyn Error + '_>> {
Ok(())
}

fn parse_with_handwritten(_config: &MassRenameArgs) -> Result<Program, Box<dyn Error + '_>> {
todo!("Parsing with the handwritten parser is not implemented yet!")
}

fn parse_with_lalrpop(config: &MassRenameArgs) -> Result<Program, Box<dyn Error + '_>> {
let lexer = crate::ocd::mrn::lalrpop::mrn_lexer::Lexer::new(&config.input);
let parser = crate::ocd::mrn::lalrpop::mrn_parser::ProgramParser::new();
Expand Down Expand Up @@ -340,13 +322,16 @@ fn apply_program(
for instruction in program.instructions() {
for (index, (src, action)) in plan.actions.iter_mut().enumerate() {
if config.verbosity() == Verbosity::Debug {
println!(
"--------------------------------------------------------------------------------"
);
println!("Applying");
println!(" instruction: {:?}", instruction);
println!(" index: {:?}", index);
println!(" index: {}", index);
println!(" src: {:?}", src);
println!(" action: {:?}", action);
println!(" action: {}", action);
println!(" instruction: {}", instruction);
}
apply_instruction(config, index, instruction, action);
apply_instruction(config, index, src.as_path(), instruction, action);
}
}
plan.clean();
Expand All @@ -356,6 +341,7 @@ fn apply_program(
fn apply_instruction(
config: &MassRenameArgs,
index: usize,
src: &Path,
instruction: &Instruction,
action: &mut Action,
) {
Expand Down Expand Up @@ -423,7 +409,7 @@ fn apply_instruction(
match_pattern: pattern,
replace_pattern: replace,
} => {
let filename = pattern_match::apply(config, index, filename, pattern, replace);
let filename = pattern_match::apply(config, index, src, filename, pattern, replace);
crate::ocd::rename_file(path, filename);
}
Instruction::ExtensionAdd(extension) => {
Expand Down
46 changes: 33 additions & 13 deletions src/ocd/mrn/pattern_match/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ use crate::ocd::Verbosity;
use rand::distributions::Distribution;
use rand::distributions::Uniform;
use regex::Regex;
use std::path::Path;
use std::process::Command;

pub mod replace_pattern_lexer;
pub mod replace_pattern_tokens;
Expand Down Expand Up @@ -55,32 +57,42 @@ pub fn process_replace(
pub fn apply(
config: &MassRenameArgs,
index: usize,
src: &Path,
filename: &str,
match_pattern: &str,
replace_pattern: &ReplacePattern,
) -> String {
let florb_matches = extract_florb_matches(filename, match_pattern);
if config.verbosity() == Verbosity::Debug {
println!("Pattern match instruction");
println!(" index: {index:?}");
println!(" filename: {filename:?}");
println!(" input match pattern: {match_pattern:?}");
println!(" input replace pattern: {replace_pattern:?}");
println!(" florb matches: {florb_matches:?}");
println!(" Pattern match instruction debug information:");
println!(" filename: {filename:?}");
println!(" match_pattern: {match_pattern:?}");
println!(" replace_pattern: {replace_pattern:?}");
println!(" florb matches: {florb_matches:?}");
}

let mut filename = String::new();
let mut new_filename = String::new();
for rpc in &replace_pattern.components {
match rpc {
ReplacePatternComponent::Florb(ref index) => {
// TODO error/warning message if the else happens, and in general check florb indexes
// if a florb index was not there, perhaps it should cancel the entire apply and just return the input
if let Some(florb_match) = florb_matches.get(*index - 1) {
filename.push_str(florb_match.as_str())
new_filename.push_str(florb_match.as_str())
}
}
ReplacePatternComponent::Literal(literal) => {
filename.push_str(literal.as_str());
new_filename.push_str(literal.as_str());
}
ReplacePatternComponent::ShaGenerator => {
let output = Command::new("sha256sum")
.args([src.as_os_str()])
.output()
.expect("Error invoking sha256sum.");
if output.status.success() {
let sha = String::from_utf8(output.stdout[0..64].to_vec()).unwrap();
new_filename.push_str(&sha);
}
}
ReplacePatternComponent::RandomNumberGenerator {
start,
Expand All @@ -91,19 +103,19 @@ pub fn apply(
let mut rng = rand::thread_rng();
let n: usize = between.sample(&mut rng);
let num = format!("{:0padding$}", n);
filename.push_str(num.as_str());
new_filename.push_str(num.as_str());
}
ReplacePatternComponent::SequentialNumberGenerator {
start,
step,
padding,
} => {
let num = format!("{:0padding$}", start + (index * step));
filename.push_str(num.as_str());
new_filename.push_str(num.as_str());
}
}
}
filename
new_filename
}

/// Extract data from filename using the match pattern
Expand Down Expand Up @@ -150,6 +162,7 @@ mod test {
use crate::ocd::mrn::program::ReplacePatternComponent;
use crate::ocd::Cli;
use crate::ocd::OcdCommand;
use std::path::Path;

fn test_pattern(
index: usize,
Expand All @@ -163,7 +176,14 @@ mod test {
let match_pattern = super::process_match(String::from(match_pattern_str));
let replace_pattern =
super::process_replace(String::from(replace_pattern_str)).unwrap();
let result = super::apply(&config, index, filename, &match_pattern, &replace_pattern);
let result = super::apply(
&config,
index,
Path::new(filename),
filename,
&match_pattern,
&replace_pattern,
);
assert_eq!(expected, result);
} else {
panic!()
Expand Down
3 changes: 2 additions & 1 deletion src/ocd/mrn/pattern_match/replace_pattern_parser.lalrpop
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ extern {
"dash" => Token::Dash,
"obrace" => Token::OpeningBrace,
"cbrace" => Token::ClosingBrace,
"date" => Token::DateGenerator,
"sha" => Token::ShaGenerator,
"sng" => Token::SequentialNumberGenerator,
"rng" => Token::RandomNumberGenerator,
"florb" => Token::Florb(<usize>),
Expand All @@ -40,6 +40,7 @@ RPC: ReplacePatternComponent = {
"dash" => ReplacePatternComponent::Literal(String::from("-")),
"obrace" => ReplacePatternComponent::Literal(String::from("{")),
"cbrace" => ReplacePatternComponent::Literal(String::from("}")),
"sha" => ReplacePatternComponent::ShaGenerator,
"sng" <sng:SNG> => sng,
"rng" <rng:RNG> => rng,
<t:"florb"> => ReplacePatternComponent::Florb(t),
Expand Down
4 changes: 2 additions & 2 deletions src/ocd/mrn/pattern_match/replace_pattern_tokens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ pub enum Token {
OpeningBrace,
#[token("}", priority = 3)]
ClosingBrace,
#[token("{date}")]
DateGenerator,
#[token("{sha}")]
ShaGenerator,
#[token("{sng")]
SequentialNumberGenerator,
#[token("{rng")]
Expand Down
3 changes: 2 additions & 1 deletion src/ocd/mrn/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ impl Program {
}
}

#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, strum_macros::Display)]
pub enum Instruction {
Sanitize,
CaseLower,
Expand Down Expand Up @@ -88,6 +88,7 @@ pub struct ReplacePattern {
pub enum ReplacePatternComponent {
Literal(String),
Florb(usize),
ShaGenerator,
RandomNumberGenerator {
start: usize,
end: usize,
Expand Down

0 comments on commit 43f17e4

Please sign in to comment.