actiondb/utils/
common_prefix.rs

1use std::cmp;
2
3pub trait CommonPrefix {
4    fn has_common_prefix(&self, other: &Self) -> Option<usize> {
5        let cpl = self.common_prefix_len(other);
6
7        if cpl > 0 {
8            Some(cpl)
9        } else {
10            None
11        }
12    }
13
14    fn common_prefix_len(&self, other: &Self) -> usize;
15    fn ltrunc(&self, len: usize) -> &Self;
16    fn rtrunc(&self, len: usize) -> &Self;
17}
18
19impl CommonPrefix for str {
20    fn common_prefix_len(&self, other: &Self) -> usize {
21        let min_len = cmp::min(self.len(), other.len());
22        let mut a_i = self.chars();
23        let mut b_i = other.chars();
24
25        for i in 0..min_len {
26            let x = a_i.next();
27            let y = b_i.next();
28
29            if x != y {
30                return i;
31            }
32        }
33        min_len
34    }
35
36    fn ltrunc(&self, len: usize) -> &Self {
37        &self[len..]
38    }
39    fn rtrunc(&self, len: usize) -> &Self {
40        let new_len = self.len() - len;
41        &self[..new_len]
42    }
43}
44
45#[cfg(test)]
46mod test {
47    use utils::common_prefix::CommonPrefix;
48
49    #[test]
50    fn given_a_string_when_longest_common_prefix_is_calulated_then_the_result_is_right() {
51        let alpha = "alpha";
52        let aleph = "aleph";
53        let beta = "beta";
54
55        assert_eq!(alpha.has_common_prefix(aleph).unwrap(), 2);
56        assert_eq!(alpha.has_common_prefix(beta), None);
57        assert_eq!(alpha.common_prefix_len(aleph), 2);
58    }
59
60    #[test]
61    fn test_given_a_string_when_truncated_by_left_then_the_result_is_the_expected() {
62        assert_eq!("alpha".rtrunc(0), "alpha");
63        assert_eq!("alpha".rtrunc(2), "alp");
64    }
65
66    #[test]
67    fn test_given_a_string_when_truncated_by_right_then_the_result_is_the_expected() {
68        assert_eq!("alpha".rtrunc(0), "alpha");
69        assert_eq!("alpha".rtrunc(2), "alp");
70    }
71}