iso8583_parser/
gui.rs

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; // Uncheck the other
36                }
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; // Uncheck the other
42                }
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) // You can adjust this value based on your needs
78                .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}