playdate_symbolize/
trace.rs

1use std::ops::Range;
2
3use crate::fmt::addr::Addr;
4
5
6#[derive(Debug)]
7pub enum TraceLine<'t> {
8	Addr {
9		addr: Addr,
10		/// System task or thread name 🤷🏻‍♂️
11		task: Option<&'t str>,
12		/// Indent level (start .. start+len)
13		level: Range<usize>,
14	},
15	Other {
16		text: &'t str,
17		/// Indent level (start .. start+len)
18		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	// count indent in spaces:
31	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}