1#![forbid(unsafe_code)]
2
3use std::path::{Path, PathBuf};
4
5#[derive(Debug, PartialEq)]
7pub struct ParsedPattern {
8 directory: PathBuf,
9 pattern: Vec<String>,
10}
11
12impl ParsedPattern {
13 pub fn new(path: &Path) -> Self {
32 Self {
33 directory: match path.parent() {
34 None => PathBuf::from("/"),
35 Some(directory) => directory.to_owned(),
36 },
37 pattern: match path.file_name() {
38 None => vec![String::from("")],
39 Some(file_name_pattern) => file_name_pattern
40 .to_str()
41 .unwrap()
42 .split("*")
43 .map(|part| part.to_string())
44 .filter(|str| !str.is_empty())
45 .collect(),
46 },
47 }
48 }
49
50 pub fn match_to_pattern(&self, file_name: &String) -> Result<Vec<String>, ()> {
71 if self.pattern.is_empty() {
72 return Ok(vec![file_name.clone()]);
73 }
74
75 if self.pattern.len() == 1 && self.pattern[0].is_empty() {
76 match file_name.is_empty() {
77 false => return Err(()),
78 true => return Ok(Vec::<String>::new()),
79 }
80 }
81
82 let mut file_name = file_name.clone();
83 let mut found_fragments = Vec::<String>::new();
84 let mut new_fragment = String::new();
85 let mut first_pattern = true;
86
87 for pattern_part in &self.pattern {
88 while !file_name.is_empty() && !file_name.starts_with(pattern_part) {
89 let (prefix, suffix) = file_name.split_at(1);
90 new_fragment += prefix;
91 file_name = suffix.to_string();
92 }
93
94 if file_name.starts_with(pattern_part) {
95 if !first_pattern || !new_fragment.is_empty() {
96 found_fragments.push(new_fragment);
97 }
98 first_pattern = false;
99 new_fragment = String::new();
100 let (_, new_file_name) = file_name.split_at(pattern_part.len());
101 file_name = new_file_name.to_string();
102 } else {
103 return Err(());
104 }
105 }
106
107 if !file_name.is_empty() {
108 found_fragments.push(file_name);
109 }
110
111 Ok(found_fragments)
112 }
113
114 pub fn get_directory(&self) -> &PathBuf {
115 &self.directory
116 }
117}
118
119#[test]
120fn test_new() {
121 let directory = PathBuf::from("/");
122 let pattern = vec![String::from("")];
123 let path = Path::new("");
124 assert_eq!(
125 ParsedPattern {
126 directory: directory,
127 pattern: pattern,
128 },
129 ParsedPattern::new(path)
130 );
131 let directory = PathBuf::from("src/");
132 let pattern = vec![String::from("test.txt")];
133 let path = Path::new("src/test.txt");
134 assert_eq!(
135 ParsedPattern {
136 directory: directory,
137 pattern: pattern,
138 },
139 ParsedPattern::new(path)
140 );
141 let directory = PathBuf::from("src/");
142 let pattern = vec![String::from("test.")];
143 let path = Path::new("src/test.*");
144 assert_eq!(
145 ParsedPattern {
146 directory: directory,
147 pattern: pattern,
148 },
149 ParsedPattern::new(path)
150 );
151 let directory = PathBuf::from("src/");
152 let pattern = vec![String::from("t"), String::from(".")];
153 let path = Path::new("src/t*.*");
154 assert_eq!(
155 ParsedPattern {
156 directory: directory,
157 pattern: pattern,
158 },
159 ParsedPattern::new(path)
160 );
161}
162
163#[test]
164fn test_matching() {
165 let directory = PathBuf::from("src/");
166 let pattern = vec![String::from("te"), String::from("t.")];
167 let path = Path::new("src/te*t.*");
168 let parsed_pattern = ParsedPattern::new(path);
169 assert_eq!(ParsedPattern { directory, pattern }, parsed_pattern);
170 assert_eq!(
171 Ok(vec![String::from("s"), String::from("txt")]),
172 parsed_pattern.match_to_pattern(&String::from("test.txt"))
173 );
174 let directory = PathBuf::from("src/");
175 let pattern = vec![];
176 let path = Path::new("src/*");
177 let parsed_pattern = ParsedPattern::new(path);
178 assert_eq!(ParsedPattern { directory, pattern }, parsed_pattern);
179 assert_eq!(
180 Ok(vec![String::from("test.txt")]),
181 parsed_pattern.match_to_pattern(&String::from("test.txt"))
182 );
183 let directory = PathBuf::from("/");
184 let pattern = vec![String::from("")];
185 let path = Path::new("");
186 let parsed_pattern = ParsedPattern::new(path);
187 assert_eq!(ParsedPattern { directory, pattern }, parsed_pattern);
188 assert_eq!(
189 Err(()),
190 parsed_pattern.match_to_pattern(&String::from("test.txt"))
191 );
192}