1use crate::error::YukiError;
2
3const FOLDERS: &[(&str, &[&str], i32)] = &[
5 ("inkoop", &["purchase"], 1),
6 ("verkoop", &["sales"], 2),
7 ("bank", &[], 3),
8 ("personeel", &["personnel"], 4),
9 ("belasting", &["tax"], 5),
10 ("uitzoeken", &[], 7),
11 ("overig-financieel", &["other"], 8),
12];
13
14pub fn known_folders() -> String {
16 FOLDERS
17 .iter()
18 .map(|(name, _, _)| *name)
19 .collect::<Vec<_>>()
20 .join(", ")
21}
22
23pub fn folder_id(name: &str) -> Result<i32, YukiError> {
29 let trimmed = name.trim();
30 if let Ok(id) = trimmed.parse::<i32>() {
31 return Ok(id);
32 }
33 let lowered = trimmed.to_ascii_lowercase();
34 FOLDERS
35 .iter()
36 .find(|(canonical, aliases, _)| {
37 *canonical == lowered || aliases.contains(&lowered.as_str())
38 })
39 .map(|(_, _, id)| *id)
40 .ok_or_else(|| {
41 YukiError::Config(format!(
42 "unknown folder: {name} (expected one of: {}, or a numeric folder ID)",
43 known_folders()
44 ))
45 })
46}
47
48#[cfg(test)]
49mod tests {
50 use super::*;
51
52 #[test]
53 fn resolves_canonical_names() {
54 assert_eq!(folder_id("inkoop").unwrap(), 1);
55 assert_eq!(folder_id("verkoop").unwrap(), 2);
56 assert_eq!(folder_id("bank").unwrap(), 3);
57 assert_eq!(folder_id("personeel").unwrap(), 4);
58 assert_eq!(folder_id("belasting").unwrap(), 5);
59 assert_eq!(folder_id("uitzoeken").unwrap(), 7);
60 assert_eq!(folder_id("overig-financieel").unwrap(), 8);
61 }
62
63 #[test]
64 fn resolves_english_aliases() {
65 assert_eq!(folder_id("purchase").unwrap(), 1);
66 assert_eq!(folder_id("sales").unwrap(), 2);
67 assert_eq!(folder_id("personnel").unwrap(), 4);
68 assert_eq!(folder_id("tax").unwrap(), 5);
69 assert_eq!(folder_id("other").unwrap(), 8);
70 }
71
72 #[test]
73 fn resolves_case_insensitively_and_trims() {
74 assert_eq!(folder_id("Verkoop").unwrap(), 2);
75 assert_eq!(folder_id(" VERKOOP ").unwrap(), 2);
76 }
77
78 #[test]
79 fn passes_through_numeric_ids() {
80 assert_eq!(folder_id("2").unwrap(), 2);
83 assert_eq!(folder_id("201").unwrap(), 201);
84 assert_eq!(folder_id("0").unwrap(), 0);
85 }
86
87 #[test]
88 fn unknown_name_is_an_error_not_folder_zero() {
89 let err = folder_id("bogusname").unwrap_err();
92 let msg = err.to_string();
93 assert!(msg.contains("unknown folder"), "got: {msg}");
94 assert!(
95 msg.contains("verkoop"),
96 "error should list valid names: {msg}"
97 );
98 }
99
100 #[test]
101 fn empty_name_is_an_error() {
102 assert!(folder_id("").is_err());
103 }
104}