X-Git-Url: https://code.octet-stream.net/hashgood/blobdiff_plain/b237f9d12de2062843975400c85dcad05bf4065c..69d73a1e6ca6798d880d79d0e5687c7a86019dd8:/src/display.rs diff --git a/src/display.rs b/src/display.rs index 2cc940a..07eb83f 100644 --- a/src/display.rs +++ b/src/display.rs @@ -21,7 +21,7 @@ fn get_stdout(no_colour: bool) -> StandardStream { } fn write_filename(mut stdout: &mut StandardStream, filename: &str) -> PrintResult { - stdout.set_color(ColorSpec::new().set_fg(Some(Color::Yellow)))?; + stdout.set_color(ColorSpec::new().set_fg(Some(Color::Yellow)).set_bold(true))?; write!(&mut stdout, "{}", filename_display(filename))?; stdout.reset()?; Ok(()) @@ -30,49 +30,70 @@ fn write_filename(mut stdout: &mut StandardStream, filename: &str) -> PrintResul fn write_algorithm(mut stdout: &mut StandardStream, alg: Algorithm) -> PrintResult { match alg { Algorithm::Md5 => { - stdout.set_color(ColorSpec::new().set_fg(Some(Color::Magenta)))?; + stdout.set_color(ColorSpec::new().set_fg(Some(Color::Magenta)).set_bold(true))?; write!(&mut stdout, "MD5")?; } Algorithm::Sha1 => { - stdout.set_color(ColorSpec::new().set_fg(Some(Color::Cyan)))?; + stdout.set_color(ColorSpec::new().set_fg(Some(Color::Cyan)).set_bold(true))?; write!(&mut stdout, "SHA-1")?; } Algorithm::Sha256 => { - stdout.set_color(ColorSpec::new().set_fg(Some(Color::Green)))?; + stdout.set_color(ColorSpec::new().set_fg(Some(Color::Green)).set_bold(true))?; write!(&mut stdout, "SHA-256")?; } + Algorithm::Sha512 => { + stdout.set_color(ColorSpec::new().set_fg(Some(Color::Blue)).set_bold(true))?; + write!(&mut stdout, "SHA-512")?; + } } stdout.reset()?; Ok(()) } -fn print_hex_compare(print: &str, against: &str, mut stdout: &mut StandardStream) -> PrintResult { - for (p, a) in print.chars().zip(against.chars()) { - if p == a { - stdout.set_color(ColorSpec::new().set_fg(Some(Color::Green)))?; +fn print_hex_compare( + print: &[u8], + matches: &[bool], + mut stdout: &mut StandardStream, +) -> PrintResult { + for (p, m) in print.iter().zip(matches.iter()) { + if *m { + stdout.set_color(ColorSpec::new().set_fg(Some(Color::Green)).set_bold(true))?; } else { - stdout.set_color(ColorSpec::new().set_fg(Some(Color::Red)))?; + stdout.set_color(ColorSpec::new().set_fg(Some(Color::Red)).set_bold(true))?; } - write!(&mut stdout, "{}", p)?; + write!(&mut stdout, "{:02x}", p)?; } stdout.reset()?; writeln!(&mut stdout)?; Ok(()) } +fn print_pointer_line( + matches: &[bool], + marker: &str, + mut stdout: &mut StandardStream, +) -> PrintResult { + for m in matches { + if *m { + write!(&mut stdout, " ")?; + } else { + write!(&mut stdout, "{}{}", marker, marker)?; + } + } + writeln!(&mut stdout)?; + Ok(()) +} + fn write_source( mut stdout: &mut StandardStream, verify_source: &VerificationSource, candidate_filename: &Option, ) -> PrintResult { - stdout.set_color(ColorSpec::new().set_fg(Some(Color::Yellow)))?; + stdout.set_color(ColorSpec::new().set_fg(Some(Color::Yellow)).set_bold(true))?; match &verify_source { VerificationSource::CommandArgument => { writeln!(&mut stdout, "command line argument")?; } - VerificationSource::Clipboard => { - writeln!(&mut stdout, "pasted from clipboard")?; - } VerificationSource::RawFile(raw_path) => match raw_path.as_str() { "-" => { writeln!(&mut stdout, "from standard input")?; @@ -103,6 +124,14 @@ fn write_source( Ok(()) } +fn calculate_match_indices(bytes1: &[u8], bytes2: &[u8]) -> Vec { + bytes1 + .iter() + .zip(bytes2.iter()) + .map(|(b1, b2)| b1 == b2) + .collect() +} + pub fn print_hash( hash: &Hash, verify_hash: Option<&CandidateHash>, @@ -117,19 +146,26 @@ pub fn print_hash( writeln!(&mut stdout)?; // Handle basic case first - nothing to compare it to - let hash_hex = hex::encode(&hash.bytes); let verify_hash = match verify_hash { None => { - write!(&mut stdout, "{}\n\n", hash_hex)?; + write!(&mut stdout, "{}\n\n", hex::encode(&hash.bytes))?; return Ok(()); } Some(verify_hash) => verify_hash, }; - let other_hex = hex::encode(&verify_hash.bytes); // Do a top-to-bottom comparison - print_hex_compare(&hash_hex, &other_hex, &mut stdout)?; - print_hex_compare(&other_hex, &hash_hex, &mut stdout)?; + let matches = calculate_match_indices(&hash.bytes, &verify_hash.bytes); + let any_wrong = matches.iter().any(|m| !*m); + + if any_wrong && no_colour { + print_pointer_line(&matches, "v", &mut stdout)?; + } + print_hex_compare(&hash.bytes, &matches, &mut stdout)?; + print_hex_compare(&verify_hash.bytes, &matches, &mut stdout)?; + if any_wrong && no_colour { + print_pointer_line(&matches, "^", &mut stdout)?; + } // Show the source of our hash if let Some(source) = verify_source { @@ -173,15 +209,15 @@ pub fn print_match_level(match_level: MatchLevel, no_colour: bool) -> PrintResul write!(&mut stdout, "Result: ")?; match match_level { MatchLevel::Ok => { - stdout.set_color(ColorSpec::new().set_fg(Some(Color::Green)))?; + stdout.set_color(ColorSpec::new().set_fg(Some(Color::Green)).set_bold(true))?; writeln!(&mut stdout, "OK")?; } MatchLevel::Maybe => { - stdout.set_color(ColorSpec::new().set_fg(Some(Color::Yellow)))?; + stdout.set_color(ColorSpec::new().set_fg(Some(Color::Yellow)).set_bold(true))?; writeln!(&mut stdout, "MAYBE")?; } MatchLevel::Fail => { - stdout.set_color(ColorSpec::new().set_fg(Some(Color::Red)))?; + stdout.set_color(ColorSpec::new().set_fg(Some(Color::Red)).set_bold(true))?; writeln!(&mut stdout, "FAIL")?; } }