hex_patch/app/asm/
assembly_line.rs

1use ratatui::text::Line;
2
3use crate::{
4    app::{comments::Comments, settings::color_settings::ColorSettings, App},
5    headers::Header,
6};
7
8use super::{instruction_tag::InstructionTag, section_tag::SectionTag};
9
10#[derive(Debug, Clone, PartialEq, Eq)]
11pub enum AssemblyLine {
12    Instruction(InstructionTag),
13    SectionTag(SectionTag),
14}
15
16impl AssemblyLine {
17    pub fn file_address(&self) -> u64 {
18        match self {
19            AssemblyLine::Instruction(instruction) => instruction.file_address,
20            AssemblyLine::SectionTag(section) => section.file_address,
21        }
22    }
23
24    pub fn virtual_address(&self) -> u64 {
25        match self {
26            AssemblyLine::Instruction(instruction) => instruction.instruction.ip(),
27            AssemblyLine::SectionTag(section) => section.virtual_address,
28        }
29    }
30
31    pub fn len(&self) -> usize {
32        match self {
33            AssemblyLine::Instruction(instruction) => instruction.instruction.len(),
34            AssemblyLine::SectionTag(section) => section.size,
35        }
36    }
37
38    pub fn is_empty(&self) -> bool {
39        match self {
40            AssemblyLine::Instruction(instruction) => instruction.instruction.is_empty(),
41            AssemblyLine::SectionTag(section) => section.size == 0,
42        }
43    }
44
45    pub fn to_line(
46        &self,
47        color_settings: &ColorSettings,
48        current_byte_index: usize,
49        header: &Header,
50        address_min_width: usize,
51        comments: &Comments,
52    ) -> Line {
53        match self {
54            AssemblyLine::Instruction(instruction) => {
55                let selected = current_byte_index >= instruction.file_address as usize
56                    && current_byte_index
57                        < instruction.file_address as usize + instruction.instruction.len();
58                App::instruction_to_line(
59                    color_settings,
60                    instruction,
61                    selected,
62                    header,
63                    address_min_width,
64                    comments.get(&instruction.file_address).map(|s| s.as_str()),
65                )
66            }
67            AssemblyLine::SectionTag(section) => {
68                let selected = current_byte_index >= section.file_address as usize
69                    && current_byte_index < section.file_address as usize + section.size;
70                App::section_to_line(
71                    color_settings,
72                    section,
73                    selected,
74                    address_min_width,
75                    comments.get(&section.file_address).map(|s| s.as_str()),
76                )
77            }
78        }
79    }
80
81    pub fn is_same_instruction(&self, other: &AssemblyLine) -> bool {
82        match (self, other) {
83            (
84                AssemblyLine::Instruction(instruction),
85                AssemblyLine::Instruction(other_instruction),
86            ) => {
87                instruction.instruction.bytes == other_instruction.instruction.bytes
88                    && instruction.instruction.virtual_address
89                        == other_instruction.instruction.virtual_address
90            }
91            _ => false,
92        }
93    }
94}