mapfile_parser/
found_symbol_info.rs

1/* SPDX-FileCopyrightText: © 2023-2025 Decompollaborate */
2/* SPDX-License-Identifier: MIT */
3
4use std::fmt::Write;
5
6use crate::{section, symbol};
7
8#[derive(Debug, Clone)]
9pub struct FoundSymbolInfo<'a> {
10    pub section: &'a section::Section,
11
12    pub symbol: &'a symbol::Symbol,
13
14    pub offset: i64,
15}
16
17impl<'a> FoundSymbolInfo<'a> {
18    pub fn new(section: &'a section::Section, symbol: &'a symbol::Symbol, offset: i64) -> Self {
19        Self {
20            section,
21            symbol,
22            offset,
23        }
24    }
25
26    pub fn new_default(section: &'a section::Section, symbol: &'a symbol::Symbol) -> Self {
27        Self {
28            section,
29            symbol,
30            offset: 0,
31        }
32    }
33
34    pub fn get_as_str(&self) -> String {
35        format!(
36            "'{0}' (VRAM: {1}, VROM: {2}, SIZE: {3}, {4})",
37            self.symbol.name,
38            self.symbol.get_vram_str(),
39            self.symbol.get_vrom_str(),
40            self.symbol.get_size_str(),
41            self.section.filepath.to_string_lossy()
42        )
43    }
44
45    pub fn get_as_str_plus_offset(&self, sym_name: Option<String>) -> String {
46        let mut message;
47
48        if self.offset != 0 {
49            if let Some(name) = sym_name {
50                message = name;
51            } else {
52                message = format!("0x{0:X}", self.symbol.vram as i64 + self.offset);
53            }
54            write!(message, " is at 0x{0:X} bytes inside", self.offset).unwrap();
55        } else {
56            message = "Symbol".to_string();
57        }
58
59        format!("{0} {1}", message, self.get_as_str())
60    }
61}
62
63#[cfg(feature = "python_bindings")]
64#[allow(non_snake_case)]
65pub(crate) mod python_bindings {
66    use pyo3::prelude::*;
67
68    use crate::{section, symbol};
69
70    #[derive(Debug, Clone)]
71    #[pyclass(module = "mapfile_parser", name = "FoundSymbolInfo")]
72    pub struct PyFoundSymbolInfo {
73        pub section: section::Section,
74
75        pub symbol: symbol::Symbol,
76
77        pub offset: i64,
78    }
79
80    #[pymethods]
81    impl PyFoundSymbolInfo {
82        #[new]
83        #[pyo3(signature=(section, symbol, offset=0))]
84        fn new(section: section::Section, symbol: symbol::Symbol, offset: i64) -> Self {
85            Self {
86                section,
87                symbol,
88                offset,
89            }
90        }
91
92        /* Getters and setters */
93
94        #[getter]
95        fn get_section(&self) -> PyResult<section::Section> {
96            Ok(self.section.clone())
97        }
98
99        #[setter]
100        fn set_section(&mut self, value: section::Section) -> PyResult<()> {
101            self.section = value;
102            Ok(())
103        }
104
105        #[getter]
106        fn get_symbol(&self) -> PyResult<symbol::Symbol> {
107            Ok(self.symbol.clone())
108        }
109
110        #[setter]
111        fn set_symbol(&mut self, value: symbol::Symbol) -> PyResult<()> {
112            self.symbol = value;
113            Ok(())
114        }
115
116        #[getter]
117        fn get_offset(&self) -> PyResult<i64> {
118            Ok(self.offset)
119        }
120
121        #[setter]
122        fn set_offset(&mut self, value: i64) -> PyResult<()> {
123            self.offset = value;
124            Ok(())
125        }
126
127        /* Methods */
128
129        #[pyo3(name = "getAsStr")]
130        fn getAsStr(&self) -> String {
131            let temp = super::FoundSymbolInfo::from(self);
132            temp.get_as_str()
133        }
134
135        #[pyo3(name = "getAsStrPlusOffset")]
136        #[pyo3(signature = (sym_name=None))]
137        fn getAsStrPlusOffset(&self, sym_name: Option<String>) -> String {
138            let temp = super::FoundSymbolInfo::from(self);
139            temp.get_as_str_plus_offset(sym_name)
140        }
141    }
142
143    impl<'a> From<&'a PyFoundSymbolInfo> for super::FoundSymbolInfo<'a> {
144        fn from(value: &'a PyFoundSymbolInfo) -> Self {
145            Self::new(&value.section, &value.symbol, value.offset)
146        }
147    }
148
149    impl From<super::FoundSymbolInfo<'_>> for PyFoundSymbolInfo {
150        fn from(value: super::FoundSymbolInfo) -> Self {
151            Self::new(value.section.clone(), value.symbol.clone(), value.offset)
152        }
153    }
154}