rust_sql_organizer/sorter/
mod.rs1use phf::{phf_map, Map};
2use regex::Regex;
3use std::{cmp::Ordering, path::PathBuf};
4
5use lazy_static::lazy_static;
6
7#[derive(Debug, Eq, PartialEq, Clone)]
8pub enum Key {
9 Num(i32),
10 Text(String),
11}
12
13impl Ord for Key {
14 fn cmp(&self, other: &Self) -> Ordering {
15 match (self, other) {
16 (Key::Num(a), Key::Num(b)) => a.cmp(b),
17 (Key::Text(a), Key::Text(b)) => a.cmp(b),
18 (Key::Num(_), Key::Text(_)) => Ordering::Less,
19 (Key::Text(_), Key::Num(_)) => Ordering::Greater,
20 }
21 }
22}
23
24impl PartialOrd for Key {
25 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
26 Some(self.cmp(other))
27 }
28}
29
30pub type OrdFn = fn(&PathBuf) -> Key;
31
32lazy_static! {
33 static ref NUMBER_RE: Regex = Regex::new("[0-9]+").unwrap();
34 pub static ref SORTING_STRATEGIES: Map<&'static str, OrdFn> = phf_map! {
35 "first_number" => |path| {
36 let file_name = path.file_name().unwrap().to_str().unwrap_or("");
37 let num: i32 = match NUMBER_RE.find(file_name) {
38 Some(m) => m.as_str().parse().unwrap(),
39 None => 0,
40 };
41 Key::Num(num)
42 },
43 "last_number" => |path| {
44 let file_name = path.file_name().unwrap().to_str().unwrap_or("");
45 let num: i32 = match NUMBER_RE.find_iter(file_name).last() {
46 Some(m) => m.as_str().parse().unwrap(),
47 None => 0,
48 };
49 Key::Num(num)
50 },
51 "folder" => |path| {
52 let last_folder_name = match path.parent() {
53 Some(p) => match p.file_name() {
54 Some(name) => name.to_str().unwrap(),
55 None => return Key::Num(0),
56 },
57 None => return Key::Num(0),
58 };
59 Key::Text(last_folder_name.to_string())
60 }
61 };
62}
63
64#[cfg(test)]
65mod test_sorters {
66 use std::path::Path;
67
68 use super::{Key, SORTING_STRATEGIES};
69
70 #[test]
71 fn test_first_number() {
72 let first_number_strat = SORTING_STRATEGIES.get("first_number").unwrap();
73 assert_eq!(
74 first_number_strat(&Path::new("folder/100_deploy_20.sql").to_path_buf()),
75 Key::Num(100)
76 );
77 }
78
79 #[test]
80 fn test_last_number() {
81 let strat = SORTING_STRATEGIES.get("last_number").unwrap();
82 assert_eq!(
83 strat(&Path::new("folder/100_deploy_20.sql").to_path_buf()),
84 Key::Num(20)
85 );
86 }
87
88 #[test]
89 fn test_folder() {
90 let strat = SORTING_STRATEGIES.get("folder").unwrap();
91 assert_eq!(
92 strat(&Path::new("folder/100_deploy_20.sql").to_path_buf()),
93 Key::Text("folder".to_string())
94 )
95 }
96
97 #[test]
98 fn test_folder_no_folder() {
99 let strat = SORTING_STRATEGIES.get("folder").unwrap();
100 assert_eq!(
101 strat(&Path::new("/100_deploy_20.sql").to_path_buf()),
102 Key::Num(0)
103 )
104 }
105}