1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
use crate::config::ExtractionConfig;
/// Supported out-of-the-box bank statement templates.
///
/// Each preset contains standard column coordinates and label mappings
/// for common Indian banks.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BankPreset {
/// HDFC Bank India statement template.
Hdfc,
/// State Bank of India (SBI) statement template.
Sbi,
/// Canara Bank statement template.
Canara,
/// Union Bank of India statement template.
Union,
/// UCO Bank statement template.
Uco,
}
impl BankPreset {
/// Returns the human-readable display name of the bank preset.
pub fn name(&self) -> &'static str {
match self {
Self::Hdfc => "HDFC Bank India",
Self::Sbi => "State Bank of India (SBI)",
Self::Canara => "Canara Bank",
Self::Union => "Union Bank of India",
Self::Uco => "UCO Bank",
}
}
/// Returns the pre-configured [`ExtractionConfig`] for the specific bank.
pub fn config(&self) -> ExtractionConfig {
let mut config = ExtractionConfig::default();
match self {
Self::Hdfc => {
config.col_guides = vec![0.11, 0.42, 0.52, 0.62, 0.75, 0.88];
config.col_mappings = vec![
"date".to_string(),
"description".to_string(),
"reference".to_string(),
"skip".to_string(),
"debit".to_string(),
"credit".to_string(),
"balance".to_string(),
];
config.filter_only_date = true;
}
Self::Sbi => {
config.col_guides = vec![0.10, 0.20, 0.52, 0.64, 0.76, 0.88];
config.col_mappings = vec![
"date".to_string(),
"skip".to_string(),
"description".to_string(),
"reference".to_string(),
"debit".to_string(),
"credit".to_string(),
"balance".to_string(),
];
config.filter_only_date = true;
config.y_tolerance = 15.0;
}
Self::Canara => {
config.col_guides = vec![0.12, 0.48, 0.60, 0.74, 0.87];
config.col_mappings = vec![
"date".to_string(),
"description".to_string(),
"reference".to_string(),
"debit".to_string(),
"credit".to_string(),
"balance".to_string(),
];
config.filter_only_date = true;
}
Self::Union => {
config.col_guides = vec![0.11, 0.42, 0.52, 0.62, 0.75, 0.88];
config.col_mappings = vec![
"date".to_string(),
"description".to_string(),
"reference".to_string(),
"skip".to_string(),
"debit".to_string(),
"credit".to_string(),
"balance".to_string(),
];
config.filter_only_date = true;
}
Self::Uco => {
config.col_guides = vec![0.12, 0.24, 0.60, 0.74, 0.87];
config.col_mappings = vec![
"date".to_string(),
"reference".to_string(),
"description".to_string(),
"debit".to_string(),
"credit".to_string(),
"balance".to_string(),
];
config.filter_only_date = true;
}
}
config
}
/// Attempts to parse a case-insensitive string into a [`BankPreset`].
/// Returns `None` if the name is unrecognized.
pub fn from_str(s: &str) -> Option<Self> {
match s.to_lowercase().as_str() {
"hdfc" => Some(Self::Hdfc),
"sbi" => Some(Self::Sbi),
"canara" => Some(Self::Canara),
"union" => Some(Self::Union),
"uco" => Some(Self::Uco),
_ => None,
}
}
}