1use serde::{Deserialize, Serialize};
15
16use crate::tax::Jurisdiction;
17
18#[derive(Debug, Clone, Serialize, Deserialize)]
19pub struct Issuer {
20 pub id: i64,
21 pub slug: String,
22 pub name: String,
23 pub legal_name: Option<String>,
24 pub jurisdiction: Jurisdiction,
25 pub tax_registered: bool,
26 pub tax_id: Option<String>,
27 pub company_no: Option<String>,
28 pub tagline: Option<String>,
29 pub address: Vec<String>,
30 pub email: Option<String>,
31 pub phone: Option<String>,
32 pub bank_details: Option<String>,
44 pub default_template: String,
45 pub currency: Option<String>,
46 pub symbol: Option<String>,
47 pub number_format: String,
48 pub logo_path: Option<String>,
51}
52
53#[derive(Debug, Clone, Serialize)]
56pub struct BankLine {
57 pub label: String,
58 pub value: String,
59}
60
61impl BankLine {
62 pub fn parse_all(details: &str) -> Vec<Self> {
66 details
67 .lines()
68 .map(str::trim)
69 .filter(|l| !l.is_empty())
70 .map(|line| match line.split_once(':') {
71 Some((label, value)) => Self {
72 label: label.trim().to_string(),
73 value: value.trim().to_string(),
74 },
75 None => Self {
76 label: String::new(),
77 value: line.to_string(),
78 },
79 })
80 .collect()
81 }
82}
83
84#[cfg(test)]
85mod tests {
86 use super::*;
87
88 #[test]
89 fn parses_sg_bank_details() {
90 let input = "Bank: Standard Chartered Bank (Singapore) Ltd\n\
91 Account: 7897262250\n\
92 Bank Code: 9496\n\
93 Branch Code: 001\n\
94 SWIFT: SCBLSG22";
95 let lines = BankLine::parse_all(input);
96 assert_eq!(lines.len(), 5);
97 assert_eq!(lines[0].label, "Bank");
98 assert_eq!(lines[0].value, "Standard Chartered Bank (Singapore) Ltd");
99 assert_eq!(lines[3].label, "Branch Code");
100 assert_eq!(lines[3].value, "001");
101 }
102
103 #[test]
104 fn handles_lines_without_colon() {
105 let input = "Use FAST for SG transfers\nAccount: 7897262250";
106 let lines = BankLine::parse_all(input);
107 assert_eq!(lines.len(), 2);
108 assert_eq!(lines[0].label, "");
109 assert_eq!(lines[0].value, "Use FAST for SG transfers");
110 assert_eq!(lines[1].label, "Account");
111 }
112
113 #[test]
114 fn skips_blank_lines() {
115 let input = "Bank: DBS\n\n\nAccount: 123";
116 assert_eq!(BankLine::parse_all(input).len(), 2);
117 }
118}