1pub(crate) mod delimiter;
2pub(crate) mod extractor;
3pub(crate) mod format;
4pub(crate) mod inputs;
5pub(crate) mod rename;
6pub(crate) mod replacer;
7pub(crate) mod selector;
8pub(crate) mod trim;
9
10use crate::Error::InvalidValue;
11use crate::processor::inputs::InputType;
12use crate::processor::rename::{TextRenamer, filename_as_string_lossy, FileRenamer, RenameProcessor};
13use crate::{
14 Delimiter, Error, Extractor, Format, Renamed, Replacer, Selector,
15 Trim,
16};
17use indexmap::IndexSet;
18use log::trace;
19
20#[derive(Debug)]
22pub struct ProcessorBuilder {
23 delimiters: Vec<Delimiter>,
24 extractors: Vec<Extractor>,
25 format: Format,
26 inputs: IndexSet<InputType>,
27 replacers: Vec<Replacer>,
28 selectors: Vec<Selector>,
29 trims: Vec<Trim>,
30}
31
32impl ProcessorBuilder {
33 pub fn new(format: Format) -> Self {
35 Self {
36 delimiters: Vec::new(),
37 extractors: Vec::new(),
38 format,
39 inputs: IndexSet::new(),
40 replacers: Vec::new(),
41 selectors: Vec::new(),
42 trims: Vec::new(),
43 }
44 }
45
46 pub fn delimiter(mut self, delimiter: Delimiter) -> Self {
48 self.delimiters.push(delimiter);
49 self
50 }
51
52 pub fn delimiters(mut self, delimiters: Vec<Delimiter>) -> Self {
54 self.delimiters.extend(delimiters);
55 self
56 }
57
58 pub fn extractor(mut self, extractor: Extractor) -> Self {
60 self.extractors.push(extractor);
61 self
62 }
63
64 pub fn extractors(mut self, extractors: Vec<Extractor>) -> Self {
66 self.extractors.extend(extractors);
67 self
68 }
69
70 pub fn input(mut self, input: InputType) -> Self {
72 self.inputs.insert(input);
73 self
74 }
75
76 pub fn inputs(mut self, inputs: Vec<InputType>) -> Self {
78 self.inputs.extend(inputs);
79 self
80 }
81
82 pub fn replacer(mut self, trim: Replacer) -> Self {
84 self.replacers.push(trim);
85 self
86 }
87
88 pub fn replacers(mut self, trims: Vec<Replacer>) -> Self {
90 self.replacers.extend(trims);
91 self
92 }
93
94 pub fn selector(mut self, selector: Selector) -> Self {
96 self.selectors.push(selector);
97 self
98 }
99
100 pub fn selectors(mut self, selectors: Vec<Selector>) -> Self {
102 self.selectors.extend(selectors);
103 self
104 }
105
106 pub fn trim(mut self, trim: Trim) -> Self {
108 self.trims.push(trim);
109 self
110 }
111
112 pub fn trims(mut self, trims: Vec<Trim>) -> Self {
114 self.trims.extend(trims);
115 self
116 }
117
118 pub fn process(&self) -> Result<Vec<Box<dyn Renamed>>, Error> {
120 let mut renamed = Vec::new();
121 renamed.extend(self.process_inputs(None)?);
122 Ok(renamed)
123 }
124
125 pub fn process_subset(&self, processing_limit: usize) -> Result<Vec<Box<dyn Renamed>>, Error> {
127 match processing_limit == 0 {
128 true => Err(InvalidValue(
129 "processing_limit must be greater than 0".to_string(),
130 )),
131 false => {
132 let mut renamed = Vec::new();
133 renamed.extend(self.process_inputs(Some(processing_limit))?);
134 Ok(renamed)
135 }
136 }
137 }
138
139 fn process_inputs(
140 &self,
141 processing_limit: Option<usize>,
142 ) -> Result<Vec<Box<dyn Renamed>>, Error> {
143 let mut renamed = Vec::new();
144 for input_type in self.inputs.iter() {
145 let process_string = match input_type {
146 InputType::File(i) => filename_as_string_lossy(i.value()),
147 InputType::Text(i) => i.value().into(),
148 };
149
150 let extracted = self.process_extractors(process_string.as_str());
151 let process_strings = vec![process_string];
152 let segments = self.process_delimiters(process_strings.as_slice());
153 let segments = self.process_trims(segments);
154 let segments = self.process_replacers(segments);
155 let selected = self.process_selectors(segments.as_slice());
156 renamed.push(match input_type {
157 InputType::File(i) => FileRenamer::new(
158 i.value(),
159 segments,
160 selected,
161 extracted,
162 self.format.clone(),
163 )
164 .rename(),
165 InputType::Text(i) => TextRenamer::new(
166 i.value(),
167 segments,
168 selected,
169 extracted,
170 self.format.clone(),
171 )
172 .rename(),
173 });
174 if let Some(limit) = processing_limit {
175 if renamed.len() == limit {
176 break;
177 }
178 }
179 }
180 Ok(renamed)
181 }
182
183 fn process_delimiters<S: AsRef<str>>(&self, value: &[S]) -> Vec<String> {
184 let mut output = Vec::new();
185 for delimiter in &self.delimiters {
186 for seg in value {
187 let mut segments = delimiter.split(seg);
188 output.append(&mut segments);
189 }
190 trace!(
191 "After Delimiter: |{}| --- Output Segments Count: {}",
192 delimiter,
193 output.len()
194 )
195 }
196 output
197 }
198
199 fn process_selectors(&self, segments: &[String]) -> Vec<Option<String>> {
200 self.selectors
201 .iter()
202 .map(|s| s.match_segment(segments))
203 .collect()
204 }
205
206 fn process_extractors<S: AsRef<str>>(&self, value: S) -> Vec<Option<String>> {
207 self.extractors
208 .iter()
209 .map(|e| e.extract(value.as_ref()))
210 .collect()
211 }
212
213 fn process_trims(&self, segments: Vec<String>) -> Vec<String> {
214 let mut output = segments;
215 for t in self.trims.as_slice() {
216 output = t.trim_slice(output.as_slice())
217 }
218 output
219 }
220
221 fn process_replacers(&self, segments: Vec<String>) -> Vec<String> {
222 let mut output = segments;
223 for r in self.replacers.as_slice() {
224 output = r.replace_slice(output.as_slice())
225 }
226 output
227 }
228}