lcov2cobertura/
demangle.rs1use regex::Regex;
3use rustc_demangle::demangle;
4use std::borrow::Cow;
5use std::io::{self, BufRead, BufReader, Write};
6use std::process::{Child, ChildStdin, ChildStdout, Command, Stdio};
7
8pub trait Demangler<'a, 'b> {
10 fn demangle(&'b mut self, ident: &'a str) -> io::Result<Cow<'a, str>>;
12 fn stop(self) -> io::Result<()>;
14}
15
16pub struct CppDemangler {
20 child: Child,
21 child_in: ChildStdin,
22 child_out: BufReader<ChildStdout>,
23}
24
25impl CppDemangler {
26 #[allow(clippy::unwrap_used, clippy::unwrap_in_result)]
29 pub fn new(cmd: &str) -> io::Result<Self> {
30 let mut child = Command::new(cmd)
31 .stdin(Stdio::piped())
32 .stdout(Stdio::piped())
33 .spawn()?;
34 let child_in = child.stdin.take().unwrap();
35 let child_out = BufReader::new(child.stdout.take().unwrap());
36 Ok(Self {
37 child,
38 child_in,
39 child_out,
40 })
41 }
42}
43
44impl<'a> Demangler<'a, '_> for CppDemangler {
45 fn demangle(&mut self, ident: &str) -> io::Result<Cow<'a, str>> {
46 self.child_in.write_all(format!("{}\n", ident).as_bytes())?;
47 let mut line = String::new();
48 self.child_out.read_line(&mut line)?;
49 Ok(Cow::Owned(line.trim().into()))
50 }
51
52 fn stop(mut self) -> io::Result<()> {
53 self.child.kill()?;
54 Ok(())
55 }
56}
57
58pub struct RustDemangler {
60 disambiguator: Regex,
62}
63impl Default for RustDemangler {
64 fn default() -> Self {
65 Self::new()
66 }
67}
68
69impl RustDemangler {
70 #[allow(clippy::unwrap_used)]
73 pub fn new() -> Self {
74 Self {
75 disambiguator: Regex::new(r"\[[0-9a-f]{5,16}\]::").unwrap(),
76 }
77 }
78}
79impl<'a> Demangler<'a, '_> for RustDemangler {
80 fn demangle(&mut self, ident: &str) -> io::Result<Cow<'a, str>> {
81 let demangled = demangle(ident).to_string();
82 Ok(Cow::Owned(
83 self.disambiguator.replace_all(&demangled, "::").to_string(),
84 ))
85 }
86
87 fn stop(self) -> io::Result<()> {
88 Ok(())
89 }
90}
91
92pub struct NullDemangler {}
94impl Default for NullDemangler {
95 fn default() -> Self {
96 Self::new()
97 }
98}
99
100impl NullDemangler {
101 pub fn new() -> Self {
103 Self {}
104 }
105}
106impl<'a, 'b> Demangler<'a, 'b> for NullDemangler {
107 fn demangle(&'b mut self, ident: &'a str) -> io::Result<Cow<'a, str>> {
108 Ok(Cow::Borrowed(ident))
109 }
110
111 fn stop(self) -> io::Result<()> {
112 Ok(())
113 }
114}