tokio/runtime/task/trace/
symbol.rs1use backtrace::BacktraceSymbol;
2use std::fmt;
3use std::hash::{Hash, Hasher};
4use std::ptr;
5
6#[derive(Clone)]
19pub(super) struct Symbol {
20 pub(super) symbol: BacktraceSymbol,
21 pub(super) parent_hash: u64,
22}
23
24impl Hash for Symbol {
25 fn hash<H>(&self, state: &mut H)
26 where
27 H: Hasher,
28 {
29 if let Some(name) = self.symbol.name() {
30 name.as_bytes().hash(state);
31 }
32
33 if let Some(addr) = self.symbol.addr() {
34 ptr::hash(addr, state);
35 }
36
37 self.symbol.filename().hash(state);
38 self.symbol.lineno().hash(state);
39 self.symbol.colno().hash(state);
40 self.parent_hash.hash(state);
41 }
42}
43
44impl PartialEq for Symbol {
45 fn eq(&self, other: &Self) -> bool {
46 (self.parent_hash == other.parent_hash)
47 && match (self.symbol.name(), other.symbol.name()) {
48 (None, None) => true,
49 (Some(lhs_name), Some(rhs_name)) => lhs_name.as_bytes() == rhs_name.as_bytes(),
50 _ => false,
51 }
52 && match (self.symbol.addr(), other.symbol.addr()) {
53 (None, None) => true,
54 (Some(lhs_addr), Some(rhs_addr)) => ptr::eq(lhs_addr, rhs_addr),
55 _ => false,
56 }
57 && (self.symbol.filename() == other.symbol.filename())
58 && (self.symbol.lineno() == other.symbol.lineno())
59 && (self.symbol.colno() == other.symbol.colno())
60 }
61}
62
63impl Eq for Symbol {}
64
65impl fmt::Display for Symbol {
66 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67 if let Some(name) = self.symbol.name() {
68 let name = name.to_string();
69 let name = if let Some((name, _)) = name.rsplit_once("::") {
70 name
71 } else {
72 &name
73 };
74 fmt::Display::fmt(&name, f)?;
75 }
76
77 if let Some(filename) = self.symbol.filename() {
78 f.write_str(" at ")?;
79 filename.to_string_lossy().fmt(f)?;
80 if let Some(lineno) = self.symbol.lineno() {
81 f.write_str(":")?;
82 fmt::Display::fmt(&lineno, f)?;
83 if let Some(colno) = self.symbol.colno() {
84 f.write_str(":")?;
85 fmt::Display::fmt(&colno, f)?;
86 }
87 }
88 }
89
90 Ok(())
91 }
92}