1use crate::*;
5use alloc::string::String;
6use alloc::vec::Vec;
7
8pub trait SymbolResolver {
12 fn symbol(
22 &mut self, instruction: &Instruction, operand: u32, instruction_operand: Option<u32>, address: u64, address_size: u32,
23 ) -> Option<SymbolResult<'_>>;
24}
25
26#[derive(Debug, Clone, Eq, PartialEq, Hash)]
28pub enum SymResString<'a> {
29 Str(#[doc = "The str"] &'a str),
31 String(#[doc = "The string"] String),
33}
34impl Default for SymResString<'_> {
35 #[must_use]
36 #[inline]
37 fn default() -> Self {
38 SymResString::Str("")
39 }
40}
41impl SymResString<'_> {
42 pub(super) fn to_owned<'b>(self) -> SymResString<'b> {
43 match self {
44 SymResString::Str(s) => SymResString::String(String::from(s)),
45 SymResString::String(s) => SymResString::String(s),
46 }
47 }
48
49 pub(super) fn to_owned2<'b>(&self) -> SymResString<'b> {
50 match self {
51 &SymResString::Str(s) => SymResString::String(String::from(s)),
52 SymResString::String(s) => SymResString::String(s.clone()),
53 }
54 }
55}
56
57#[derive(Debug, Default, Clone, Eq, PartialEq, Hash)]
59pub struct SymResTextPart<'a> {
60 pub text: SymResString<'a>,
62 pub color: FormatterTextKind,
64}
65
66impl<'a> SymResTextPart<'a> {
67 #[must_use]
74 #[inline]
75 pub const fn new(text: &'a str, color: FormatterTextKind) -> Self {
76 Self { text: SymResString::Str(text), color }
77 }
78
79 #[must_use]
86 #[inline]
87 pub const fn with_string(text: String, color: FormatterTextKind) -> Self {
88 Self { text: SymResString::String(text), color }
89 }
90
91 pub(super) fn to_owned<'b>(self) -> SymResTextPart<'b> {
92 SymResTextPart { text: self.text.to_owned(), color: self.color }
93 }
94
95 pub(super) fn to_owned2<'b>(&self) -> SymResTextPart<'b> {
96 SymResTextPart { text: self.text.to_owned2(), color: self.color }
97 }
98}
99
100#[derive(Debug, Clone, Eq, PartialEq, Hash)]
104pub enum SymResTextInfo<'a> {
105 Text(#[doc = "Text and color"] SymResTextPart<'a>),
107 TextVec(#[doc = "Text and color"] &'a [SymResTextPart<'a>]),
109}
110
111impl<'a> SymResTextInfo<'a> {
112 #[must_use]
119 #[inline]
120 pub const fn new(text: &'a str, color: FormatterTextKind) -> Self {
121 SymResTextInfo::Text(SymResTextPart::new(text, color))
122 }
123
124 #[must_use]
131 #[inline]
132 pub const fn with_string(text: String, color: FormatterTextKind) -> Self {
133 SymResTextInfo::Text(SymResTextPart::with_string(text, color))
134 }
135
136 #[must_use]
142 #[inline]
143 pub const fn with_text(text: SymResTextPart<'a>) -> Self {
144 SymResTextInfo::Text(text)
145 }
146
147 #[must_use]
153 #[inline]
154 pub const fn with_vec(text: &'a [SymResTextPart<'a>]) -> Self {
155 SymResTextInfo::TextVec(text)
156 }
157
158 pub(super) fn to_owned<'b>(self, vec: &'b mut Vec<SymResTextPart<'b>>) -> SymResTextInfo<'b> {
159 match self {
160 SymResTextInfo::Text(part) => SymResTextInfo::Text(part.to_owned()),
161 SymResTextInfo::TextVec(parts) => {
162 vec.clear();
163 vec.extend(parts.iter().map(SymResTextPart::to_owned2));
164 SymResTextInfo::TextVec(vec)
165 }
166 }
167 }
168}
169
170#[derive(Debug, Clone, Eq, PartialEq, Hash)]
174pub struct SymbolResult<'a> {
175 pub address: u64,
177
178 pub text: SymResTextInfo<'a>,
180
181 pub flags: u32,
185
186 pub symbol_size: Option<MemorySize>,
188}
189
190impl<'a> SymbolResult<'a> {
191 const DEFAULT_KIND: FormatterTextKind = FormatterTextKind::Label;
192
193 #[must_use]
200 #[inline]
201 pub const fn with_str(address: u64, text: &'a str) -> Self {
202 Self { address, text: SymResTextInfo::new(text, SymbolResult::DEFAULT_KIND), flags: SymbolFlags::NONE, symbol_size: None }
203 }
204
205 #[must_use]
213 #[inline]
214 pub const fn with_str_size(address: u64, text: &'a str, size: MemorySize) -> Self {
215 Self { address, text: SymResTextInfo::new(text, SymbolResult::DEFAULT_KIND), flags: SymbolFlags::NONE, symbol_size: Some(size) }
216 }
217
218 #[must_use]
226 #[inline]
227 pub const fn with_str_kind(address: u64, text: &'a str, color: FormatterTextKind) -> Self {
228 Self { address, text: SymResTextInfo::new(text, color), flags: SymbolFlags::NONE, symbol_size: None }
229 }
230
231 #[must_use]
242 #[inline]
243 pub const fn with_str_kind_flags(address: u64, text: &'a str, color: FormatterTextKind, flags: u32) -> Self {
244 Self { address, text: SymResTextInfo::new(text, color), flags, symbol_size: None }
245 }
246
247 #[must_use]
254 #[inline]
255 pub const fn with_string(address: u64, text: String) -> Self {
256 Self { address, text: SymResTextInfo::with_string(text, SymbolResult::DEFAULT_KIND), flags: SymbolFlags::NONE, symbol_size: None }
257 }
258
259 #[must_use]
267 #[inline]
268 pub const fn with_string_size(address: u64, text: String, size: MemorySize) -> Self {
269 Self { address, text: SymResTextInfo::with_string(text, SymbolResult::DEFAULT_KIND), flags: SymbolFlags::NONE, symbol_size: Some(size) }
270 }
271
272 #[must_use]
280 #[inline]
281 pub const fn with_string_kind(address: u64, text: String, color: FormatterTextKind) -> Self {
282 Self { address, text: SymResTextInfo::with_string(text, color), flags: SymbolFlags::NONE, symbol_size: None }
283 }
284
285 #[must_use]
296 #[inline]
297 pub const fn with_string_kind_flags(address: u64, text: String, color: FormatterTextKind, flags: u32) -> Self {
298 Self { address, text: SymResTextInfo::with_string(text, color), flags, symbol_size: None }
299 }
300
301 #[must_use]
308 #[inline]
309 pub const fn with_text(address: u64, text: SymResTextInfo<'a>) -> Self {
310 Self { address, text, flags: SymbolFlags::NONE, symbol_size: None }
311 }
312
313 #[must_use]
321 #[inline]
322 pub const fn with_text_size(address: u64, text: SymResTextInfo<'a>, size: MemorySize) -> Self {
323 Self { address, text, flags: SymbolFlags::NONE, symbol_size: Some(size) }
324 }
325
326 #[must_use]
336 #[inline]
337 pub const fn with_text_flags(address: u64, text: SymResTextInfo<'a>, flags: u32) -> Self {
338 Self { address, text, flags, symbol_size: None }
339 }
340
341 #[must_use]
352 #[inline]
353 pub const fn with_text_flags_size(address: u64, text: SymResTextInfo<'a>, flags: u32, size: MemorySize) -> Self {
354 Self { address, text, flags, symbol_size: Some(size) }
355 }
356
357 pub(super) fn to_owned<'b>(self, vec: &'b mut Vec<SymResTextPart<'b>>) -> SymbolResult<'b> {
358 SymbolResult { address: self.address, text: self.text.to_owned(vec), flags: self.flags, symbol_size: self.symbol_size }
359 }
360}