rrc_lib/
util.rs

1use trash::TrashItem;
2
3//The following 3 functions are all designed to work together in the same context (being a mutable reference to a vector which should be changed in place)
4pub fn remove_from_vec<T>(vec: &mut Vec<T>, needle: &T)
5where
6    T: PartialEq,
7{
8    vec.retain(|v| v != needle);
9}
10
11pub fn remove_first_from_vec<T>(vec: &mut Vec<T>, needle: &T)
12where
13    T: PartialEq,
14{
15    if let Some(pos) = vec.iter().position(|x| x == needle) {
16        vec.remove(pos);
17    }
18}
19
20pub fn count_occurences<'a, U, T>(iter: &'a T, needle: U) -> usize
21where
22    &'a T: IntoIterator<Item = U>,
23    U: PartialEq,
24{
25    iter.into_iter().filter(|v| *v == needle).count()
26}
27
28///Handles a restore collision by
29pub fn handle_collision_string(
30    error: trash::Error,
31    files: &mut Vec<String>,
32    path: &String,
33) -> Result<String, trash::Error> {
34    match error {
35        trash::Error::RestoreCollision {
36            path: path_buf,
37            remaining_items: _,
38        } => {
39            //This is a little dumb, but it lets me reuse existing code
40            while count_occurences(files, &path) > 1 {
41                remove_first_from_vec(files, path);
42            }
43
44            Ok(crate::files::path_to_string(path_buf))
45        }
46        _ => Err(error),
47    }
48}
49
50pub fn handle_collision_item(
51    error: trash::Error,
52    files: &mut Vec<TrashItem>,
53    item: &TrashItem,
54) -> Result<(), trash::Error> {
55    match error {
56        trash::Error::RestoreCollision {
57            path: _,
58            remaining_items: _,
59        } => {
60            //This is a little dumb, but it lets me reuse existing code
61            while count_occurences(files, item) > 1 {
62                remove_first_from_vec(files, item);
63            }
64
65            Ok(())
66        }
67        _ => Err(error),
68    }
69}
70
71#[cfg(test)]
72mod tests {
73    use super::*;
74
75    #[test]
76    fn test_remove_from_vec() {
77        let mut vec = vec!["Hello".to_string(), "Hi".to_string()];
78        remove_from_vec(&mut vec, &"Hi".to_string());
79
80        assert_eq!(vec, vec!["Hello".to_string()]);
81
82        let mut vec = vec!["Hello", "Hi"];
83        remove_from_vec(&mut vec, &"Hi");
84
85        assert_eq!(vec, vec!["Hello"]);
86    }
87
88    #[test]
89    fn test_remove_first_from_vec() {
90        let mut vec = vec!["Hello".to_string(), "Hi".to_string(), "Hi".to_string()];
91        remove_first_from_vec(&mut vec, &"Hi".to_string());
92
93        assert_eq!(vec, vec!["Hello".to_string(), "Hi".to_string()]);
94
95        let mut vec = vec!["Hello", "Hi", "Hi"];
96        remove_first_from_vec(&mut vec, &"Hi");
97
98        assert_eq!(vec, vec!["Hello", "Hi"]);
99    }
100
101    #[test]
102    fn test_count_occurences() {
103        let mut vec = vec!["Hi", "Hello", "How are you", "Hi", "Hi"];
104        assert_eq!(count_occurences(&vec, &"Hi"), 3);
105
106        remove_first_from_vec(&mut vec, &"Hi");
107
108        assert_eq!(count_occurences(&vec, &"Hi"), 2);
109    }
110}