1use memedb_core;
2use rayon::prelude::*;
3use std::collections::HashSet;
4use std::fs;
5use std::path::{Path, PathBuf};
7
8extern crate rayon;
9
10pub fn read_file_tags(path: &Path) -> HashSet<String> {
11 memedb_core::read_tags(path).unwrap()
12}
13
14pub fn read_files_tags(files: HashSet<&Path>) -> HashSet<String> {
15 files
16 .into_par_iter()
17 .map(|path| memedb_core::read_tags(path).unwrap())
18 .flatten()
19 .collect()
20}
21
22pub fn read_dir_tags(dir_path: &Path) -> HashSet<String> {
23 fs::read_dir(dir_path)
24 .unwrap()
25 .map(|file| file.unwrap().path())
26 .collect::<HashSet<_>>()
27 .par_iter()
28 .map(|path| memedb_core::read_tags(path.as_path()).unwrap())
29 .flatten()
30 .collect()
31}
32
33pub fn write_file_tags(path: &Path, tags: HashSet<String>) -> HashSet<String> {
34 memedb_core::write_tags(path, &tags).unwrap();
35 memedb_core::read_tags(path).unwrap()
36}
37
38pub fn add_file_tags(path: &Path, tags: HashSet<String>) -> HashSet<String> {
39 let mut actual_tags: HashSet<String> = memedb_core::read_tags(path).unwrap();
40 actual_tags.par_extend(tags);
41 memedb_core::write_tags(path, &actual_tags).unwrap();
42 memedb_core::read_tags(path).unwrap()
43}
44
45pub fn delete_file_tags(path: &Path, tags: HashSet<String>) -> HashSet<String> {
46 let actual_tags = memedb_core::read_tags(path)
47 .unwrap()
48 .into_par_iter()
49 .filter(|tag| !tags.contains(tag))
50 .collect();
51 memedb_core::write_tags(path, &actual_tags).unwrap();
52 memedb_core::read_tags(path).unwrap()
53}
54
55pub fn read_files_by_tags(files: HashSet<&Path>, tags: HashSet<String>) -> HashSet<&Path> {
56 files
57 .into_par_iter()
58 .filter(|path| {
59 memedb_core::read_tags(path)
60 .unwrap()
61 .par_iter()
62 .any(|tag| tags.contains(tag))
63 })
64 .collect()
65}
66
67pub fn read_dir_by_tags(dir_path: &Path, tags: HashSet<String>) -> HashSet<PathBuf> {
68 fs::read_dir(dir_path)
69 .unwrap()
70 .map(|file| file.unwrap().path())
71 .filter(|file| {
72 memedb_core::read_tags(file.as_path())
73 .unwrap()
74 .par_iter()
75 .any(|tag| tags.contains(tag))
76 })
77 .collect()
78}
79
80#[cfg(test)]
81mod tests {
82 use super::*;
83
84 #[test]
85 fn test_read_tags() {
86 let path = Path::new("tests/3.jpg");
87 let mut res = HashSet::new();
88 res.insert("lol".to_string());
89 res.insert("xd".to_string());
90 assert_eq!(read_file_tags(path), res)
91 }
92
93 #[test]
94 fn test_read_all_tags() {
95 let path = Path::new("tests");
96 let mut res = HashSet::new();
97 res.insert("lol".to_string());
98 assert_eq!(read_dir_tags(path), res)
100 }
101
102 #[test]
103 fn test_write_tags() {
104 let path = Path::new("tests/4.png");
105 let mut tags = HashSet::new();
106 let mut res = HashSet::new();
107 tags.insert("lol".to_string());
108 tags.insert("xd".to_string());
109 res.insert("lol".to_string());
110 res.insert("xd".to_string());
111 write_file_tags(path, tags);
112 assert_eq!(read_file_tags(path), res)
113 }
114
115 #[test]
116 fn test_add_tags() {
117 let path = Path::new("tests/4.png");
118 let res = read_file_tags(path);
119 let mut tags = HashSet::new();
120 tags.insert("ahh".to_string());
121 tags.insert("xd".to_string());
122 add_file_tags(path, tags);
123 assert_eq!(read_file_tags(path), res)
124 }
125
126 #[test]
127 fn test_delete_tags() {
128 let path = Path::new("tests/4.png");
129 let res = read_file_tags(path);
130 let mut tags = HashSet::new();
131 tags.insert("ahh".to_string());
132 tags.insert("xd".to_string());
133 delete_file_tags(path, tags);
134 assert_eq!(read_file_tags(path), res)
135 }
136
137 #[test]
138 fn test_read_files_by_tags() {
139 let mut files = HashSet::new();
140 let mut tags = HashSet::new();
141 let mut dir_res = HashSet::new();
142 tags.insert("xd".to_string());
143 tags.insert("ahh".to_string());
144 files.insert(Path::new("tests\\3.jpg"));
145 files.insert(Path::new("tests\\4.png"));
146 dir_res.insert(Path::new("tests\\3.jpg"));
147 dir_res.insert(Path::new("tests\\4.png"));
148 assert_eq!(read_files_by_tags(files, tags), dir_res)
149 }
150}