1#[derive(Debug, Clone)]
5pub struct CardData {
6 pub personal: Option<Personal>,
7 pub card: Option<Card>,
8 pub nhso: Option<Nhso>,
9}
10
11#[derive(Debug, Clone)]
13pub struct Personal {
14 pub cid: String,
15 pub name: Name,
16 pub name_en: Name,
17 pub dob: String,
18 pub gender: String,
19 pub card_issuer: String,
20 pub issue_date: String,
21 pub expire_date: String,
22 pub address: Address,
23 pub face_image: String,
24}
25
26#[derive(Debug, Clone)]
28pub struct Name {
29 pub prefix: String,
30 pub first_name: String,
31 pub middle_name: String,
32 pub last_name: String,
33 pub full_name: String,
34}
35
36#[derive(Debug, Clone)]
38pub struct Address {
39 pub house_no: String,
40 pub moo: String,
41 pub soi: String,
42 pub street: String,
43 pub subdistrict: String,
44 pub district: String,
45 pub province: String,
46 pub full_address: String,
47}
48
49#[derive(Debug, Clone)]
51pub struct Card {
52 pub laser_id: String,
53}
54
55#[derive(Debug, Clone)]
57pub struct Nhso {
58 pub main_inscl: String,
59 pub sub_inscl: String,
60 pub main_hospital: String,
61 pub sub_hospital: String,
62 pub paid_type: String,
63 pub issue_date: String,
64 pub expire_date: String,
65 pub update_date: String,
66 pub change_hospital_amount: String,
67}
68
69pub fn parse_name(raw: &str) -> Name {
71 let parts: Vec<&str> = raw.split('#').collect();
72 let prefix = parts.first().unwrap_or(&"").to_string();
73 let first_name = parts.get(1).unwrap_or(&"").to_string();
74 let middle_name = parts.get(2).unwrap_or(&"").to_string();
75 let last_name = parts.get(3).unwrap_or(&"").to_string();
76
77 let full_name = if middle_name.is_empty() {
78 format!("{}{} {}", prefix, first_name, last_name)
79 } else {
80 format!("{}{} {} {}", prefix, first_name, middle_name, last_name)
81 };
82
83 Name {
84 prefix,
85 first_name,
86 middle_name,
87 last_name,
88 full_name,
89 }
90}
91
92pub fn parse_address(raw: &str) -> Address {
94 let parts: Vec<&str> = raw.split('#').collect();
95 let mut addr = Address {
96 house_no: String::new(),
97 moo: String::new(),
98 soi: String::new(),
99 street: String::new(),
100 subdistrict: String::new(),
101 district: String::new(),
102 province: String::new(),
103 full_address: String::new(),
104 };
105
106 if parts.is_empty() {
107 return addr;
108 }
109
110 addr.house_no = parts[0].to_string();
111
112 if parts.len() > 1 {
114 let trimmed = parts[1].trim();
115 if let Some(val) = trimmed.strip_prefix("หมู่ที่") {
116 addr.moo = val.trim().to_string();
117 }
118 if let Some(val) = trimmed.strip_prefix("ซอย") {
119 addr.soi = val.trim().to_string();
120 }
121 }
122
123 if parts.len() > 4 {
125 let street_parts: Vec<&str> = parts[2..parts.len() - 3].to_vec();
126 addr.street = street_parts.join(" ").trim().to_string();
127 }
128
129 if parts.len() > 3 {
131 let sd = parts[parts.len() - 3].trim();
132 addr.subdistrict = sd
133 .strip_prefix("ตำบล")
134 .or_else(|| sd.strip_prefix("แขวง"))
135 .unwrap_or(sd)
136 .trim()
137 .to_string();
138 }
139
140 if parts.len() > 2 {
142 let d = parts[parts.len() - 2].trim();
143 addr.district = d
144 .strip_prefix("อำเภอ")
145 .or_else(|| d.strip_prefix("เขต"))
146 .unwrap_or(d)
147 .trim()
148 .to_string();
149 }
150
151 if let Some(last) = parts.last() {
153 let p = last.trim();
154 addr.province = p.strip_prefix("จังหวัด").unwrap_or(p).trim().to_string();
155 }
156
157 let non_empty: Vec<&str> = parts.iter().filter(|s| !s.is_empty()).copied().collect();
158 addr.full_address = non_empty.join(" ");
159
160 addr
161}
162
163pub fn format_date(raw: &str) -> String {
165 if raw.len() != 8 {
166 return String::new();
167 }
168 let year: i32 = raw[0..4].parse().unwrap_or(0);
169 let month = &raw[4..6];
170 let day = &raw[6..8];
171 format!("{:04}-{}-{}", year - 543, month, day)
172}