big_code_analysis/output/
dump_ops.rs1use std::io::Write;
2use termcolor::{Color, ColorChoice, StandardStream, StandardStreamLock};
3
4use crate::ops::Ops;
5
6use crate::tools::{color, intense_color};
7
8pub fn dump_ops(ops: &Ops) -> std::io::Result<()> {
38 let stdout = StandardStream::stdout(ColorChoice::Always);
39 let mut stdout = stdout.lock();
40 dump_space(ops, "", true, &mut stdout)?;
41 color(&mut stdout, Color::White)?;
42
43 Ok(())
44}
45
46fn dump_space(
47 space: &Ops,
48 prefix: &str,
49 last: bool,
50 stdout: &mut StandardStreamLock,
51) -> std::io::Result<()> {
52 let (pref_child, pref) = if last { (" ", "`- ") } else { ("| ", "|- ") };
53
54 color(stdout, Color::Blue)?;
55 write!(stdout, "{prefix}{pref}")?;
56
57 intense_color(stdout, Color::Yellow)?;
58 write!(stdout, "{}: ", space.kind)?;
59
60 intense_color(stdout, Color::Cyan)?;
61 write!(stdout, "{}", space.name.as_ref().map_or("", |name| name))?;
62
63 intense_color(stdout, Color::Red)?;
64 writeln!(stdout, " (@{})", space.start_line)?;
65
66 let prefix = format!("{prefix}{pref_child}");
67 dump_space_ops(space, &prefix, space.spaces.is_empty(), stdout)?;
68
69 if let Some((last, spaces)) = space.spaces.split_last() {
70 for space in spaces {
71 dump_space(space, &prefix, false, stdout)?;
72 }
73 dump_space(last, &prefix, true, stdout)?;
74 }
75
76 Ok(())
77}
78
79fn dump_space_ops(
80 ops: &Ops,
81 prefix: &str,
82 last: bool,
83 stdout: &mut StandardStreamLock,
84) -> std::io::Result<()> {
85 dump_ops_values("operators", &ops.operators, prefix, last, stdout)?;
86 dump_ops_values("operands", &ops.operands, prefix, last, stdout)
87}
88
89fn dump_ops_values(
90 name: &str,
91 ops: &[String],
92 prefix: &str,
93 last: bool,
94 stdout: &mut StandardStreamLock,
95) -> std::io::Result<()> {
96 let (pref_child, pref) = if last { (" ", "`- ") } else { ("| ", "|- ") };
97
98 color(stdout, Color::Blue)?;
99 write!(stdout, "{prefix}{pref}")?;
100
101 intense_color(stdout, Color::Green)?;
102 writeln!(stdout, "{name}")?;
103
104 let Some((last_op, rest)) = ops.split_last() else {
105 return Ok(());
106 };
107
108 let prefix = format!("{prefix}{pref_child}");
109 for op in rest {
110 color(stdout, Color::Blue)?;
111 write!(stdout, "{prefix}|- ")?;
112
113 color(stdout, Color::White)?;
114 writeln!(stdout, "{op}")?;
115 }
116
117 color(stdout, Color::Blue)?;
118 write!(stdout, "{prefix}`- ")?;
119
120 color(stdout, Color::White)?;
121 writeln!(stdout, "{last_op}")
122}
123
124#[cfg(test)]
125#[allow(
126 clippy::float_cmp,
127 clippy::cast_precision_loss,
128 clippy::cast_possible_truncation,
129 clippy::cast_sign_loss,
130 clippy::similar_names,
131 clippy::doc_markdown,
132 clippy::needless_raw_string_hashes,
133 clippy::too_many_lines
134)]
135mod tests {
136 use super::*;
137 use crate::spaces::SpaceKind;
138
139 #[test]
140 fn dump_ops_empty_operators_and_operands_does_not_panic() {
141 let ops = Ops {
145 name: Some("unit".to_string()),
146 name_was_lossy: false,
147 start_line: 1,
148 end_line: 1,
149 kind: SpaceKind::Unit,
150 spaces: vec![],
151 operands: vec![],
152 operators: vec![],
153 };
154 assert!(dump_ops(&ops).is_ok());
155 }
156}