1use std::str::FromStr;
2
3use crate::{
4 DebugError, Variable, VariableCache, VariableLocation, VariableName, VariableValue,
5 language::parsing::ValueExt,
6};
7
8use probe_rs::MemoryInterface;
9
10pub trait Value {
12 fn get_value(
14 variable: &Variable,
15 memory: &mut dyn MemoryInterface,
16 _variable_cache: &VariableCache,
17 ) -> Result<Self, DebugError>
18 where
19 Self: Sized;
20
21 fn update_value(
25 variable: &Variable,
26 memory: &mut dyn MemoryInterface,
27 new_value: &str,
28 ) -> Result<(), DebugError>;
29}
30
31impl<V> From<Result<V, DebugError>> for VariableValue
32where
33 V: Value + ToString,
34{
35 fn from(val: Result<V, DebugError>) -> Self {
36 val.map_or_else(
37 |err| VariableValue::Error(format!("{err:?}")),
38 |value| VariableValue::Valid(value.to_string()),
39 )
40 }
41}
42
43impl Value for bool {
44 fn get_value(
45 variable: &Variable,
46 memory: &mut dyn MemoryInterface,
47 _variable_cache: &VariableCache,
48 ) -> Result<Self, DebugError> {
49 let mem_data = memory.read_word_8(variable.memory_location.memory_address()?)?;
50 let ret_value: bool = mem_data != 0;
51 Ok(ret_value)
52 }
53
54 fn update_value(
55 variable: &Variable,
56 memory: &mut dyn MemoryInterface,
57 new_value: &str,
58 ) -> Result<(), DebugError> {
59 if let VariableLocation::RegisterValue(_) = variable.memory_location {
60 return Err(DebugError::NotImplemented(
61 "Updating a register value is not implemented",
62 ));
63 }
64
65 memory
66 .write_word_8(
67 variable.memory_location.memory_address()?,
68 <bool as FromStr>::from_str(new_value).map_err(|error| {
69 DebugError::WarnAndContinue {
70 message: format!(
71 "Invalid data conversion from value: {new_value:?}. {error:?}"
72 ),
73 }
74 })? as u8,
75 )
76 .map_err(|error| DebugError::WarnAndContinue {
77 message: format!("{error:?}"),
78 })
79 }
80}
81impl Value for char {
82 fn get_value(
83 variable: &Variable,
84 memory: &mut dyn MemoryInterface,
85 _variable_cache: &VariableCache,
86 ) -> Result<Self, DebugError> {
87 let mem_data = memory.read_word_32(variable.memory_location.memory_address()?)?;
88 if let Some(return_value) = char::from_u32(mem_data) {
89 Ok(return_value)
90 } else {
91 Ok('?')
92 }
93 }
94
95 fn update_value(
96 variable: &Variable,
97 memory: &mut dyn MemoryInterface,
98 new_value: &str,
99 ) -> Result<(), DebugError> {
100 if let VariableLocation::RegisterValue(_) = variable.memory_location {
101 return Err(DebugError::NotImplemented(
102 "Updating a register value is not implemented",
103 ));
104 }
105
106 memory
107 .write_word_32(
108 variable.memory_location.memory_address()?,
109 <char as FromStr>::from_str(new_value).map_err(|error| {
110 DebugError::WarnAndContinue {
111 message: format!(
112 "Invalid data conversion from value: {new_value:?}. {error:?}"
113 ),
114 }
115 })? as u32,
116 )
117 .map_err(|error| DebugError::WarnAndContinue {
118 message: format!("{error:?}"),
119 })
120 }
121}
122impl Value for String {
123 fn get_value(
124 variable: &Variable,
125 memory: &mut dyn MemoryInterface,
126 variable_cache: &VariableCache,
127 ) -> Result<Self, DebugError> {
128 let mut str_value: String = "".to_owned();
129 let children: Vec<_> = variable_cache.get_children(variable.variable_key).collect();
130 if !children.is_empty() {
131 let mut string_length = match children.iter().find(|child_variable| {
132 matches!(child_variable.name, VariableName::Named(ref name) if name == "length")
133 }) {
134 Some(string_length) => {
135 if let VariableValue::Valid(length_value) = &string_length.value {
137 length_value.parse().unwrap_or(0_usize)
138 } else {
139 0_usize
140 }
141 }
142 None => 0_usize,
143 };
144
145 let string_location = match children.iter().find(|child_variable| {
146 matches!(child_variable.name, VariableName::Named(ref name) if name == "data_ptr")
147 }) {
148 Some(location_value) => {
149 let mut child_variables = variable_cache.get_children(location_value.variable_key);
150 if let Some(first_child) = child_variables.next() {
151 first_child.memory_location.memory_address()?
152 } else {
153 0_u64
154 }
155 }
156 None => 0_u64,
157 };
158 if string_location == 0 {
159 str_value = "Error: Failed to determine &str memory location".to_string();
160 } else {
161 if string_length > 200 {
167 tracing::warn!(
168 "Very long string ({} bytes), truncating to 200 bytes.",
169 string_length
170 );
171 string_length = 200;
172 }
173
174 if string_length == 0 {
175 } else {
177 let mut buff = vec![0u8; string_length];
178 memory.read(string_location, &mut buff)?;
179 std::str::from_utf8(&buff)?.clone_into(&mut str_value);
180 }
181 }
182 } else {
183 str_value = "Error: Failed to evaluate &str value".to_string();
184 }
185 Ok(str_value)
186 }
187
188 fn update_value(
189 _variable: &Variable,
190 _memory: &mut dyn MemoryInterface,
191 _new_value: &str,
192 ) -> Result<(), DebugError> {
193 Err(DebugError::WarnAndContinue { message:"Unsupported datatype: \"String\". Please only update variables with a base data type.".to_string()})
194 }
195}
196
197impl Value for i8 {
198 fn get_value(
199 variable: &Variable,
200 memory: &mut dyn MemoryInterface,
201 _variable_cache: &VariableCache,
202 ) -> Result<Self, DebugError> {
203 Self::read_from_location(variable, memory)
204 }
205
206 fn update_value(
207 variable: &Variable,
208 memory: &mut dyn MemoryInterface,
209 new_value: &str,
210 ) -> Result<(), DebugError> {
211 if let VariableLocation::RegisterValue(_) = variable.memory_location {
212 return Err(DebugError::NotImplemented(
213 "Updating a register value is not implemented",
214 ));
215 }
216
217 let buff = i8::parse_to_bytes(new_value)?;
218 memory
219 .write_word_8(variable.memory_location.memory_address()?, buff[0])
220 .map_err(|error| DebugError::WarnAndContinue {
221 message: format!("{error:?}"),
222 })
223 }
224}
225impl Value for i16 {
226 fn get_value(
227 variable: &Variable,
228 memory: &mut dyn MemoryInterface,
229 _variable_cache: &VariableCache,
230 ) -> Result<Self, DebugError> {
231 Self::read_from_location(variable, memory)
232 }
233
234 fn update_value(
235 variable: &Variable,
236 memory: &mut dyn MemoryInterface,
237 new_value: &str,
238 ) -> Result<(), DebugError> {
239 if let VariableLocation::RegisterValue(_) = variable.memory_location {
240 return Err(DebugError::NotImplemented(
241 "Updating a register value is not implemented",
242 ));
243 }
244
245 let buff = i16::parse_to_bytes(new_value)?;
246 memory
247 .write_8(variable.memory_location.memory_address()?, &buff)
248 .map_err(|error| DebugError::WarnAndContinue {
249 message: format!("{error:?}"),
250 })
251 }
252}
253impl Value for i32 {
254 fn get_value(
255 variable: &Variable,
256 memory: &mut dyn MemoryInterface,
257 _variable_cache: &VariableCache,
258 ) -> Result<Self, DebugError> {
259 Self::read_from_location(variable, memory)
260 }
261
262 fn update_value(
263 variable: &Variable,
264 memory: &mut dyn MemoryInterface,
265 new_value: &str,
266 ) -> Result<(), DebugError> {
267 if let VariableLocation::RegisterValue(_) = variable.memory_location {
268 return Err(DebugError::NotImplemented(
269 "Updating a register value is not implemented",
270 ));
271 }
272
273 let buff = i32::parse_to_bytes(new_value)?;
274 memory
275 .write_8(variable.memory_location.memory_address()?, &buff)
276 .map_err(|error| DebugError::WarnAndContinue {
277 message: format!("{error:?}"),
278 })
279 }
280}
281impl Value for i64 {
282 fn get_value(
283 variable: &Variable,
284 memory: &mut dyn MemoryInterface,
285 _variable_cache: &VariableCache,
286 ) -> Result<Self, DebugError> {
287 Self::read_from_location(variable, memory)
288 }
289
290 fn update_value(
291 variable: &Variable,
292 memory: &mut dyn MemoryInterface,
293 new_value: &str,
294 ) -> Result<(), DebugError> {
295 if let VariableLocation::RegisterValue(_) = variable.memory_location {
296 return Err(DebugError::NotImplemented(
297 "Updating a register value is not implemented",
298 ));
299 }
300
301 let buff = i64::parse_to_bytes(new_value)?;
302 memory
303 .write_8(variable.memory_location.memory_address()?, &buff)
304 .map_err(|error| DebugError::WarnAndContinue {
305 message: format!("{error:?}"),
306 })
307 }
308}
309impl Value for i128 {
310 fn get_value(
311 variable: &Variable,
312 memory: &mut dyn MemoryInterface,
313 _variable_cache: &VariableCache,
314 ) -> Result<Self, DebugError> {
315 Self::read_from_location(variable, memory)
316 }
317
318 fn update_value(
319 variable: &Variable,
320 memory: &mut dyn MemoryInterface,
321 new_value: &str,
322 ) -> Result<(), DebugError> {
323 if let VariableLocation::RegisterValue(_) = variable.memory_location {
324 return Err(DebugError::NotImplemented(
325 "Updating a register value is not implemented",
326 ));
327 }
328
329 let buff = i128::parse_to_bytes(new_value)?;
330 memory
331 .write_8(variable.memory_location.memory_address()?, &buff)
332 .map_err(|error| DebugError::WarnAndContinue {
333 message: format!("{error:?}"),
334 })
335 }
336}
337impl Value for u8 {
338 fn get_value(
339 variable: &Variable,
340 memory: &mut dyn MemoryInterface,
341 _variable_cache: &VariableCache,
342 ) -> Result<Self, DebugError> {
343 Self::read_from_location(variable, memory)
344 }
345
346 fn update_value(
347 variable: &Variable,
348 memory: &mut dyn MemoryInterface,
349 new_value: &str,
350 ) -> Result<(), DebugError> {
351 if let VariableLocation::RegisterValue(_) = variable.memory_location {
352 return Err(DebugError::NotImplemented(
353 "Updating a register value is not implemented",
354 ));
355 }
356
357 let buff = u8::parse_to_bytes(new_value)?;
358 memory
359 .write_word_8(variable.memory_location.memory_address()?, buff[0])
360 .map_err(|error| DebugError::WarnAndContinue {
361 message: format!("{error:?}"),
362 })
363 }
364}
365impl Value for u16 {
366 fn get_value(
367 variable: &Variable,
368 memory: &mut dyn MemoryInterface,
369 _variable_cache: &VariableCache,
370 ) -> Result<Self, DebugError> {
371 Self::read_from_location(variable, memory)
372 }
373
374 fn update_value(
375 variable: &Variable,
376 memory: &mut dyn MemoryInterface,
377 new_value: &str,
378 ) -> Result<(), DebugError> {
379 if let VariableLocation::RegisterValue(_) = variable.memory_location {
380 return Err(DebugError::NotImplemented(
381 "Updating a register value is not implemented",
382 ));
383 }
384
385 let buff = u16::parse_to_bytes(new_value)?;
386 memory
387 .write_8(variable.memory_location.memory_address()?, &buff)
388 .map_err(|error| DebugError::WarnAndContinue {
389 message: format!("{error:?}"),
390 })
391 }
392}
393impl Value for u32 {
394 fn get_value(
395 variable: &Variable,
396 memory: &mut dyn MemoryInterface,
397 _variable_cache: &VariableCache,
398 ) -> Result<Self, DebugError> {
399 Self::read_from_location(variable, memory)
400 }
401
402 fn update_value(
403 variable: &Variable,
404 memory: &mut dyn MemoryInterface,
405 new_value: &str,
406 ) -> Result<(), DebugError> {
407 if let VariableLocation::RegisterValue(_) = variable.memory_location {
408 return Err(DebugError::NotImplemented(
409 "Updating a register value is not implemented",
410 ));
411 }
412
413 let buff = u32::parse_to_bytes(new_value)?;
414 memory
415 .write_8(variable.memory_location.memory_address()?, &buff)
416 .map_err(|error| DebugError::WarnAndContinue {
417 message: format!("{error:?}"),
418 })
419 }
420}
421impl Value for u64 {
422 fn get_value(
423 variable: &Variable,
424 memory: &mut dyn MemoryInterface,
425 _variable_cache: &VariableCache,
426 ) -> Result<Self, DebugError> {
427 Self::read_from_location(variable, memory)
428 }
429
430 fn update_value(
431 variable: &Variable,
432 memory: &mut dyn MemoryInterface,
433 new_value: &str,
434 ) -> Result<(), DebugError> {
435 if let VariableLocation::RegisterValue(_) = variable.memory_location {
436 return Err(DebugError::NotImplemented(
437 "Updating a register value is not implemented",
438 ));
439 }
440
441 let buff = u64::parse_to_bytes(new_value)?;
442 memory
443 .write_8(variable.memory_location.memory_address()?, &buff)
444 .map_err(|error| DebugError::WarnAndContinue {
445 message: format!("{error:?}"),
446 })
447 }
448}
449impl Value for u128 {
450 fn get_value(
451 variable: &Variable,
452 memory: &mut dyn MemoryInterface,
453 _variable_cache: &VariableCache,
454 ) -> Result<Self, DebugError> {
455 Self::read_from_location(variable, memory)
456 }
457
458 fn update_value(
459 variable: &Variable,
460 memory: &mut dyn MemoryInterface,
461 new_value: &str,
462 ) -> Result<(), DebugError> {
463 if let VariableLocation::RegisterValue(_) = variable.memory_location {
464 return Err(DebugError::NotImplemented(
465 "Updating a register value is not implemented",
466 ));
467 }
468
469 let buff = u128::parse_to_bytes(new_value)?;
470 memory
471 .write_8(variable.memory_location.memory_address()?, &buff)
472 .map_err(|error| DebugError::WarnAndContinue {
473 message: format!("{error:?}"),
474 })
475 }
476}
477impl Value for f32 {
478 fn get_value(
479 variable: &Variable,
480 memory: &mut dyn MemoryInterface,
481 _variable_cache: &VariableCache,
482 ) -> Result<Self, DebugError> {
483 Self::read_from_location(variable, memory)
484 }
485
486 fn update_value(
487 variable: &Variable,
488 memory: &mut dyn MemoryInterface,
489 new_value: &str,
490 ) -> Result<(), DebugError> {
491 if let VariableLocation::RegisterValue(_) = variable.memory_location {
492 return Err(DebugError::NotImplemented(
493 "Updating a register value is not implemented",
494 ));
495 }
496
497 let buff = f32::parse_to_bytes(new_value)?;
498 memory
499 .write_8(variable.memory_location.memory_address()?, &buff)
500 .map_err(|error| DebugError::WarnAndContinue {
501 message: format!("{error:?}"),
502 })
503 }
504}
505impl Value for f64 {
506 fn get_value(
507 variable: &Variable,
508 memory: &mut dyn MemoryInterface,
509 _variable_cache: &VariableCache,
510 ) -> Result<Self, DebugError> {
511 Self::read_from_location(variable, memory)
512 }
513
514 fn update_value(
515 variable: &Variable,
516 memory: &mut dyn MemoryInterface,
517 new_value: &str,
518 ) -> Result<(), DebugError> {
519 if let VariableLocation::RegisterValue(_) = variable.memory_location {
520 return Err(DebugError::NotImplemented(
521 "Updating a register value is not implemented",
522 ));
523 }
524
525 let buff = f64::parse_to_bytes(new_value)?;
526 memory
527 .write_8(variable.memory_location.memory_address()?, &buff)
528 .map_err(|error| DebugError::WarnAndContinue {
529 message: format!("{error:?}"),
530 })
531 }
532}
533
534pub fn format_float(value: f64) -> String {
536 let mut s = format!("{value}");
537 if !s.contains('.') {
538 s.push('.');
539 }
540 while s.ends_with('0') {
541 s.pop();
542 }
543 if s.ends_with('.') {
544 s.push('0');
545 }
546
547 s
548}