Skip to main content

rust_code_analysis_code_split/output/
dump_ops.rs

1use std::io::Write;
2use termcolor::{Color, ColorChoice, StandardStream, StandardStreamLock};
3
4use crate::ops::Ops;
5
6use crate::tools::{color, intense_color};
7
8/// Dumps all operands and operators of a code.
9///
10/// Returns a [`Result`] value, when an error occurs.
11///
12/// # Examples
13///
14/// ```
15/// use std::path::PathBuf;
16///
17/// use rust_code_analysis::{dump_ops, operands_and_operators, CppParser, ParserTrait};
18///
19/// # fn main() {
20/// let source_code = "int a = 42;";
21///
22/// // The path to a dummy file used to contain the source code
23/// let path = PathBuf::from("foo.c");
24/// let source_as_vec = source_code.as_bytes().to_vec();
25///
26/// // The parser of the code, in this case a CPP parser
27/// let parser = CppParser::new(source_as_vec, &path, None);
28///
29/// // Retrieve all operands and operators
30/// let ops = operands_and_operators(&parser, &path).unwrap();
31///
32/// // Dump all operands and operators
33/// dump_ops(&ops).unwrap();
34/// # }
35/// ```
36///
37/// [`Result`]: #variant.Result
38pub fn dump_ops(ops: &Ops) -> std::io::Result<()> {
39    let stdout = StandardStream::stdout(ColorChoice::Always);
40    let mut stdout = stdout.lock();
41    dump_space(ops, "", true, &mut stdout)?;
42    color(&mut stdout, Color::White)?;
43
44    Ok(())
45}
46
47fn dump_space(
48    space: &Ops,
49    prefix: &str,
50    last: bool,
51    stdout: &mut StandardStreamLock,
52) -> std::io::Result<()> {
53    let (pref_child, pref) = if last { ("   ", "`- ") } else { ("|  ", "|- ") };
54
55    color(stdout, Color::Blue)?;
56    write!(stdout, "{prefix}{pref}")?;
57
58    intense_color(stdout, Color::Yellow)?;
59    write!(stdout, "{}: ", space.kind)?;
60
61    intense_color(stdout, Color::Cyan)?;
62    write!(stdout, "{}", space.name.as_ref().map_or("", |name| name))?;
63
64    intense_color(stdout, Color::Red)?;
65    writeln!(stdout, " (@{})", space.start_line)?;
66
67    let prefix = format!("{prefix}{pref_child}");
68    dump_space_ops(space, &prefix, space.spaces.is_empty(), stdout)?;
69
70    if let Some((last, spaces)) = space.spaces.split_last() {
71        for space in spaces {
72            dump_space(space, &prefix, false, stdout)?;
73        }
74        dump_space(last, &prefix, true, stdout)?;
75    }
76
77    Ok(())
78}
79
80fn dump_space_ops(
81    ops: &Ops,
82    prefix: &str,
83    last: bool,
84    stdout: &mut StandardStreamLock,
85) -> std::io::Result<()> {
86    dump_ops_values("operators", &ops.operators, prefix, last, stdout)?;
87    dump_ops_values("operands", &ops.operands, prefix, last, stdout)
88}
89
90fn dump_ops_values(
91    name: &str,
92    ops: &[String],
93    prefix: &str,
94    last: bool,
95    stdout: &mut StandardStreamLock,
96) -> std::io::Result<()> {
97    let (pref_child, pref) = if last { ("   ", "`- ") } else { ("|  ", "|- ") };
98
99    color(stdout, Color::Blue)?;
100    write!(stdout, "{prefix}{pref}")?;
101
102    intense_color(stdout, Color::Green)?;
103    writeln!(stdout, "{name}")?;
104
105    let prefix = format!("{prefix}{pref_child}");
106    for op in ops.iter().take(ops.len() - 1) {
107        color(stdout, Color::Blue)?;
108        write!(stdout, "{prefix}|- ")?;
109
110        color(stdout, Color::White)?;
111        writeln!(stdout, "{op}")?;
112    }
113
114    color(stdout, Color::Blue)?;
115    write!(stdout, "{prefix}`- ")?;
116
117    color(stdout, Color::White)?;
118    writeln!(stdout, "{}", ops.last().unwrap())
119}