From 70b8ced0eb15acc3487d7e647b23311738b337fc Mon Sep 17 00:00:00 2001 From: crypto523 Date: Tue, 3 Sep 2024 00:08:12 +0700 Subject: [PATCH] Add custom error types `HammingDistanceError` (#780) ref: add custom error types `HammingDistanceError` --- src/string/hamming_distance.rs | 62 ++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 25 deletions(-) diff --git a/src/string/hamming_distance.rs b/src/string/hamming_distance.rs index 4858db2..3137d5a 100644 --- a/src/string/hamming_distance.rs +++ b/src/string/hamming_distance.rs @@ -1,13 +1,24 @@ -pub fn hamming_distance(string_a: &str, string_b: &str) -> usize { +/// Error type for Hamming distance calculation. +#[derive(Debug, PartialEq)] +pub enum HammingDistanceError { + InputStringsHaveDifferentLength, +} + +/// Calculates the Hamming distance between two strings. +/// +/// The Hamming distance is defined as the number of positions at which the corresponding characters of the two strings are different. +pub fn hamming_distance(string_a: &str, string_b: &str) -> Result { if string_a.len() != string_b.len() { - panic!("Strings must have the same length"); + return Err(HammingDistanceError::InputStringsHaveDifferentLength); } - string_a + let distance = string_a .chars() .zip(string_b.chars()) .filter(|(a, b)| a != b) - .count() + .count(); + + Ok(distance) } #[cfg(test)] @@ -16,30 +27,31 @@ mod tests { macro_rules! test_hamming_distance { ($($name:ident: $tc:expr,)*) => { - $( - #[test] - fn $name() { - let (str_a, str_b, expected) = $tc; - assert_eq!(hamming_distance(str_a, str_b), expected); - assert_eq!(hamming_distance(str_b, str_a), expected); - } - )* + $( + #[test] + fn $name() { + let (str_a, str_b, expected) = $tc; + assert_eq!(hamming_distance(str_a, str_b), expected); + assert_eq!(hamming_distance(str_b, str_a), expected); + } + )* } } test_hamming_distance! { - empty_inputs: ("", "", 0), - length_1_inputs: ("a", "a", 0), - same_strings: ("rust", "rust", 0), - regular_input_0: ("karolin", "kathrin", 3), - regular_input_1: ("kathrin", "kerstin", 4), - regular_input_2: ("00000", "11111", 5), - different_case: ("x", "X", 1), - } - - #[test] - #[should_panic] - fn panic_when_inputs_are_of_different_length() { - hamming_distance("0", ""); + empty_inputs: ("", "", Ok(0)), + different_length: ("0", "", Err(HammingDistanceError::InputStringsHaveDifferentLength)), + length_1_inputs_identical: ("a", "a", Ok(0)), + length_1_inputs_different: ("a", "b", Ok(1)), + same_strings: ("rust", "rust", Ok(0)), + regular_input_0: ("karolin", "kathrin", Ok(3)), + regular_input_1: ("kathrin", "kerstin", Ok(4)), + regular_input_2: ("00000", "11111", Ok(5)), + different_case: ("x", "X", Ok(1)), + strings_with_no_common_chars: ("abcd", "wxyz", Ok(4)), + long_strings_one_diff: (&"a".repeat(1000), &("a".repeat(999) + "b"), Ok(1)), + long_strings_many_diffs: (&("a".repeat(500) + &"b".repeat(500)), &("b".repeat(500) + &"a".repeat(500)), Ok(1000)), + strings_with_special_chars_identical: ("!@#$%^", "!@#$%^", Ok(0)), + strings_with_special_chars_diff: ("!@#$%^", "&*()_+", Ok(6)), } }