1use clap::Parser;
29use std::iter::FromIterator;
30use std::path::Path;
31use std::process;
32
33#[derive(Parser, Debug)]
35#[command(version, about, long_about = None)]
36pub struct Args {
37 #[arg(short, long)]
39 pub path: String,
40
41 #[arg(short, long)]
43 pub title: String,
44
45 #[arg(short, long)]
47 pub date: String,
48
49 #[arg(short, long)]
51 pub artist: String,
52
53 #[arg(short, long)]
55 pub zola: bool,
56}
57
58pub fn set_filename(song_title: &str) -> String {
65 let credits_file: String = format!(
66 "{}-credits.md",
67 song_title
68 .replace(
69 &['/', '\\', '(', ')', '[', ']', '<', '>', '{', '}', ' ', '\'', '"', '?', '!'][..],
70 "-"
71 )
72 .to_lowercase()
73 );
74 credits_file
75}
76
77pub fn set_frontmatter(song_title: &str, song_date: &str, song_artist: &str) -> String {
98 format!(
99 "+++
100title=\"{song_title} Credits\"
101date={song_date}
102
103[taxonomies]
104tags=[\"Freesound\", \"{song_artist}\", \"Credits\"]
105+++
106
107"
108 )
109}
110
111pub fn set_header(song_title: &str) -> String {
129 format!(
130 "## Credits
131
132*{song_title}* includes the following samples from
133[Freesound](https://freesound.org). Used under a [Creative
134Commons](https://creativecommons.org) license:
135
136",
137 )
138}
139
140pub fn get_list_of_samples(samples_path: &str) -> Vec<String> {
147 let path: &Path = Path::new(&samples_path);
148 let mut all_samples: Vec<String> = vec![];
149
150 for entry in path
151 .read_dir()
152 .unwrap_or_else(|error| {
153 eprintln!("Problem listing samples from the provided path: {error}");
154 process::exit(2);
155 })
156 .flatten()
157 {
158 if entry.path().is_file() || entry.path().is_dir() {
159 let mut sample: String = format!(
160 "{:?}",
161 entry.path().file_stem().unwrap_or_else(|| {
162 eprintln!("Problem reading the sample file name.");
163 process::exit(2);
164 })
165 )
166 .replace(&['(', ')', '\'', '"'][..], "");
167
168 if let Some(extension) = entry.path().extension() {
170 if is_not_metadata(extension.to_str().unwrap()) && is_freesound_sample(&sample) {
171 all_samples.push(sample);
172 }
173 } else if sample.contains("Instrument") {
175 sample = sample
176 .split_whitespace()
177 .last()
178 .unwrap_or_else(|| {
179 eprintln!("Problem splitting Instrument into sample string");
180 process::exit(2);
181 })
182 .to_string();
183
184 if is_freesound_sample(&sample) {
185 all_samples.push(sample);
186 }
187 }
188 }
189 }
190 all_samples
191}
192
193fn is_not_metadata(extension: &str) -> bool {
194 let metadata_extensions = ["asd", "reapeaks"];
195
196 !metadata_extensions.contains(&extension)
197}
198
199fn is_freesound_sample(sample: &str) -> bool {
201 sample.chars().next().unwrap().is_numeric() && sample.contains('_')
202}
203
204pub fn set_credit(sample: &str) -> String {
216 let mut sample_line_vec: Vec<&str> = vec![];
217
218 if sample.contains("__") {
219 sample_line_vec = sample.split("__").collect();
220 } else if sample.contains('_') {
221 sample_line_vec = sample.split('_').collect();
222 }
223
224 let credit_id: String = sample_line_vec
225 .first()
226 .unwrap_or_else(|| {
227 eprintln!("Problem reading credit ID");
228 process::exit(2);
229 })
230 .to_string();
231
232 let credit_artist: String = sample_line_vec
233 .get(1)
234 .unwrap_or_else(|| {
235 eprintln!("Problem reading credit artist");
236 process::exit(2);
237 })
238 .to_string();
239
240 let credit_sound: String = Vec::from_iter(sample_line_vec[2..].iter().cloned()).join("_");
241
242 let credit_line: String = format!(
243 "- [{credit_sound}](https://freesound.org/people/{credit_artist}/sounds/{credit_id}/)\n",
244 );
245 credit_line
246}
247
248#[cfg(test)]
249mod tests {
250 use super::*;
251
252 #[test]
253 fn check_filename() {
254 let song_title = "Field Notes";
255
256 assert_eq!("field-notes-credits.md", set_filename(song_title));
257 }
258
259 #[test]
260 fn fail_filename() {
261 let song_title = "Field Notes";
262
263 assert_ne!("Field-Notes-credits.md", set_filename(song_title));
264 }
265
266 #[test]
267 fn check_frontmatter() {
268 let song_title = "Field Notes";
269 let song_artist = "Aner Andros";
270 let song_date = "2025-01-09";
271 let frontmatter = "+++
272title=\"Field Notes Credits\"
273date=2025-01-09
274
275[taxonomies]
276tags=[\"Freesound\", \"Aner Andros\", \"Credits\"]
277+++
278
279";
280
281 assert_eq!(
282 frontmatter,
283 set_frontmatter(song_title, song_date, song_artist)
284 );
285 }
286
287 #[test]
288 fn check_header() {
289 let song_title = "Field Notes";
290 let header = "## Credits
291
292*Field Notes* includes the following samples from
293[Freesound](https://freesound.org). Used under a [Creative
294Commons](https://creativecommons.org) license:
295
296";
297
298 assert_eq!(header, set_header(song_title));
299 }
300
301 #[test]
302 fn check_credit_new() {
303 let credit = "275012__alienxxx__squadron_leader_form_up";
304
305 assert_eq!(
306 "- [squadron_leader_form_up](https://freesound.org/people/alienxxx/sounds/275012/)\n",
307 set_credit(credit)
308 );
309 }
310
311 #[test]
312 fn check_credit_old() {
313 let credit = "275012_alienxxx_squadron_leader_form_up";
314
315 assert_eq!(
316 "- [squadron_leader_form_up](https://freesound.org/people/alienxxx/sounds/275012/)\n",
317 set_credit(credit)
318 );
319 }
320}