use crate::{
app::App,
config::Config,
conversion_utils::{
ascii::convert_bytes_to_ascii,
from_one_byte_to_i8::add_byte_as_i8,
hexadecimal::convert_bytes_to_hex,
three_byte_numbers::{I24, U24},
FromBytes,
},
enums::{endian::Endian, format::Format, inputmodes::InputMode},
};
use anyhow::Result;
use crossterm::{
execute,
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
};
use ratatui::{
layout::{Constraint, Layout},
prelude::{CrosstermBackend, Frame, Terminal},
};
use std::error::Error;
use std::fs;
use strum::IntoEnumIterator;
use super::ui_helpers::{
create_converted_values_list, create_endianess_paragraph, create_help_message,
create_input_paragraph, create_instructions_paragraph, create_list_of_formats, update,
};
pub fn startup() -> Result<()> {
enable_raw_mode()?;
execute!(std::io::stderr(), EnterAlternateScreen)?;
Ok(())
}
pub fn shutdown() -> Result<()> {
execute!(std::io::stderr(), LeaveAlternateScreen)?;
disable_raw_mode()?;
Ok(())
}
pub fn generate_ui(config: Config) -> Result<(), Box<dyn Error>> {
let mut t = Terminal::new(CrosstermBackend::new(std::io::stderr()))?;
let bytes_read = fs::read(config.file_path)?;
let mut endianess = Endian::Big;
let mut u32_numbers = Vec::new();
let mut i32_numbers = Vec::new();
let mut converted_binary_to_hex = Vec::new();
let mut i8_numbers = Vec::new();
let mut u16_numbers = Vec::new();
let mut i16_numbers = Vec::new();
let mut u24_numbers = Vec::new();
let mut i24_numbers = Vec::new();
let mut u64_numbers = Vec::new();
let mut i64_numbers = Vec::new();
let mut f32_numbers = Vec::new();
let mut f64_numbers = Vec::new();
let mut converted_binary_to_ascii = Vec::new();
let format_list: Vec<Format> = Format::iter().collect();
if config.little_endianess {
endianess = Endian::Little;
}
let _ = (
u32::add_bytes(&bytes_read, endianess, &mut u32_numbers),
i32::add_bytes(&bytes_read, endianess, &mut i32_numbers),
u16::add_bytes(&bytes_read, endianess, &mut u16_numbers),
i16::add_bytes(&bytes_read, endianess, &mut i16_numbers),
U24::add_bytes(&bytes_read, endianess, &mut u24_numbers),
I24::add_bytes(&bytes_read, endianess, &mut i24_numbers),
u64::add_bytes(&bytes_read, endianess, &mut u64_numbers),
i64::add_bytes(&bytes_read, endianess, &mut i64_numbers),
f32::add_bytes(&bytes_read, endianess, &mut f32_numbers),
f64::add_bytes(&bytes_read, endianess, &mut f64_numbers),
);
add_byte_as_i8(&bytes_read, &mut i8_numbers)?;
convert_bytes_to_ascii(&bytes_read, &mut converted_binary_to_ascii)?;
convert_bytes_to_hex(&bytes_read, &mut converted_binary_to_hex)?;
let vec = &u32_numbers.clone();
let mut app = App {
bytes_read,
should_quit: false,
endianess,
converted_binary_to_u32: u32_numbers,
converted_binary_to_i32: i32_numbers,
converted_binary_to_hex,
converted_binary_to_i8: i8_numbers,
converted_binary_to_u16: u16_numbers,
converted_binary_to_i16: i16_numbers,
converted_binary_to_u24: u24_numbers,
converted_binary_to_i24: i24_numbers,
converted_binary_to_u64: u64_numbers,
converted_binary_to_i64: i64_numbers,
converted_binary_to_f32: f32_numbers,
converted_binary_to_f64: f64_numbers,
converted_binary_to_ascii,
start_of_window: 0,
end_of_window: 30,
current_format: Format::Hex,
format_list_index: 0,
format_list,
input: String::new(),
input_mode: InputMode::Normal,
cursor_position: 0,
max_length: vec.len(),
};
loop {
t.draw(|f| {
ui(&mut app, f);
})?;
update(&mut app)?;
if app.should_quit {
break;
}
}
Ok(())
}
fn ui(app: &mut App, f: &mut Frame) {
let constraints = [
Constraint::Percentage(25),
Constraint::Percentage(5),
Constraint::Percentage(50),
Constraint::Percentage(5),
Constraint::Percentage(4),
Constraint::Percentage(5),
Constraint::Percentage(5),
];
let layout = Layout::default()
.constraints(constraints.as_ref())
.split(f.size());
let list = create_converted_values_list(app);
let current_format_paragraph = create_list_of_formats(app);
let instructions_paragraph = create_instructions_paragraph();
let help_message = create_help_message(app);
let input = create_input_paragraph(app);
let endianess_paragraph = create_endianess_paragraph(app);
f.render_widget(current_format_paragraph, layout[0]);
f.render_widget(endianess_paragraph, layout[1]);
f.render_widget(list, layout[2]);
f.render_widget(instructions_paragraph, layout[3]);
f.render_widget(help_message, layout[5]);
f.render_widget(input, layout[4]);
if let InputMode::Editing = app.input_mode {
f.set_cursor(
layout[4].x + app.cursor_position as u16 + 1,
layout[4].y + 1,
)
}
}