1use eframe::egui;
2use crate::parse_iso8583;
3
4pub struct ISO8583ParserApp {
5 message: String,
6 include_length_header: bool,
7 parse_private_tlv: bool,
8 parse_private_ltv: bool,
9 parsed_output: String,
10 has_error: bool,
11}
12
13impl Default for ISO8583ParserApp {
14 fn default() -> Self {
15 Self {
16 message: String::new(),
17 include_length_header: false,
18 parse_private_tlv: false,
19 parse_private_ltv: false,
20 parsed_output: String::new(),
21 has_error: false,
22 }
23 }
24}
25
26impl eframe::App for ISO8583ParserApp {
27 fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
28 egui::CentralPanel::default().show(ctx, |ui| {
29 ui.heading("ISO8583 Message Parser");
30 ui.add_space(10.0);
31
32 ui.checkbox(&mut self.include_length_header, "The message includes length and header");
33 if ui.checkbox(&mut self.parse_private_tlv, "Parse Private TLV").clicked() {
34 if self.parse_private_tlv {
35 self.parse_private_ltv = false; }
37 }
38
39 if ui.checkbox(&mut self.parse_private_ltv, "Parse Private LTV").clicked() {
40 if self.parse_private_ltv {
41 self.parse_private_tlv = false; }
43 }
44 ui.add_space(10.0);
45
46 ui.label("Enter the message:");
47 ui.label(egui::RichText::new("(e.g. '01002000000000000000930000')").color(egui::Color32::GRAY));
48 ui.label(egui::RichText::new("(e.g. '0012600008000001002000000000000000930000' while including header and length)")
49 .color(egui::Color32::GRAY));
50
51 ui.add_space(5.0);
52
53 ui.add_sized(
54 [ui.available_width(), 150.0],
55 egui::TextEdit::multiline(&mut self.message)
56 .desired_rows(10)
57 .hint_text("Enter ISO8583 message here"),
58 );
59
60 if ui.button("Parse Message").clicked() && !self.message.is_empty() {
61 self.parse_message();
62 }
63
64 ui.add_space(20.0);
65
66 if !self.parsed_output.is_empty() {
67 ui.heading("Parsed Message:");
68 ui.add_space(5.0);
69
70 let output_text = if self.has_error {
71 egui::RichText::new(&self.parsed_output).color(egui::Color32::RED)
72 } else {
73 egui::RichText::new(&self.parsed_output).monospace()
74 };
75
76 egui::ScrollArea::vertical()
77 .max_height(200.0) .show(ui, |ui| {
79 ui.add(egui::Label::new(output_text).wrap());
80 });
81 }
82 });
83 }
84}
85
86impl ISO8583ParserApp {
87 fn parse_message(&mut self) {
88 match parse_iso8583(
89 &self.message,
90 self.include_length_header,
91 self.parse_private_tlv,
92 self.parse_private_ltv,
93 ) {
94 Ok(result) => {
95 let mut output = String::new();
96
97 if let Some(len) = result.message_length {
98 output.push_str(&format!("Length Of Message: {}\n", len));
99 }
100
101 if let Some(header) = result.header {
102 output.push_str(&format!("Header: {}\n", header));
103 }
104
105 output.push_str(&format!("MTI: {}\n", result.mti));
106 output.push_str(&format!("First Bit Map: {:?}\n\n", result.bitmap));
107
108 for field in result.fields {
109 output.push_str(&format!("{}\n", field));
110 }
111
112 if !result.unparsed.is_empty() {
113 output.push_str(&format!("\nNot parsed Part: {}", result.unparsed));
114 }
115
116 self.has_error = false;
117 self.parsed_output = output;
118 }
119 Err(e) => {
120 self.has_error = true;
121 self.parsed_output = format!("Error parsing message: {}", e);
122 }
123 }
124 }
125}