playdate_symbolize/
trace.rs1use std::ops::Range;
2
3use crate::fmt::addr::Addr;
4
5
6#[derive(Debug)]
7pub enum TraceLine<'t> {
8 Addr {
9 addr: Addr,
10 task: Option<&'t str>,
12 level: Range<usize>,
14 },
15 Other {
16 text: &'t str,
17 level: Range<usize>,
19 },
20 Error {
21 line: &'t str,
22 error: anyhow::Error,
23 },
24}
25
26
27pub fn parse_trace_line(line: &str) -> TraceLine<'_> {
28 let line = line.trim_end();
29
30 let i = line.chars().into_iter().take_while(|c| *c == ' ').count();
32
33 let addr_task = line.trim_start().strip_prefix("~tr:").map(str::trim);
34 let trimmed = line.trim();
35
36 if let Some(text) = addr_task {
37 let addr;
38 let task;
39
40 if let Some((addr_, task_)) = text.split_once('\t').or_else(|| text.split_once(' ')) {
41 addr = addr_.trim();
42 task = Some(task_.trim());
43 } else {
44 addr = text;
45 task = None;
46 }
47
48 match crate::fmt::addr::parse_addr(addr) {
49 Ok(addr) => {
50 TraceLine::Addr { addr: addr as _,
51 task,
52 level: i..(trimmed.len() + i) }
53 },
54 Err(err) => {
55 TraceLine::Error { line: trimmed,
56 error: err }
57 },
58 }
59 } else {
60 TraceLine::Other { text: trimmed,
61 level: i..(trimmed.len() + i) }
62 }
63}