rust_code_analysis_code_split/
function.rs1use std::io::Write;
2use std::path::PathBuf;
3
4use serde::Serialize;
5use termcolor::{Color, ColorChoice, StandardStream, StandardStreamLock};
6
7use crate::traits::*;
8
9use crate::checker::Checker;
10use crate::getter::Getter;
11
12use crate::tools::{color, intense_color};
13
14#[derive(Debug, Serialize)]
16pub struct FunctionSpan {
17 pub name: String,
19 pub start_line: usize,
21 pub end_line: usize,
23 pub error: bool,
26}
27
28pub fn function<T: ParserTrait>(parser: &T) -> Vec<FunctionSpan> {
34 let root = parser.get_root();
35 let code = parser.get_code();
36 let mut spans = Vec::new();
37 root.act_on_node(&mut |n| {
38 if T::Checker::is_func(n) {
39 let start_line = n.start_row() + 1;
40 let end_line = n.end_row() + 1;
41 if let Some(name) = T::Getter::get_func_name(n, code) {
42 spans.push(FunctionSpan {
43 name: name.to_string(),
44 start_line,
45 end_line,
46 error: false,
47 });
48 } else {
49 spans.push(FunctionSpan {
50 name: "".to_string(),
51 start_line,
52 end_line,
53 error: true,
54 });
55 }
56 }
57 });
58
59 spans
60}
61
62fn dump_span(
63 span: FunctionSpan,
64 stdout: &mut StandardStreamLock,
65 last: bool,
66) -> std::io::Result<()> {
67 let pref = if last { " `- " } else { " |- " };
72
73 color(stdout, Color::Blue)?;
74 write!(stdout, "{pref}")?;
75
76 if span.error {
77 intense_color(stdout, Color::Red)?;
78 write!(stdout, "error: ")?;
79 } else {
80 intense_color(stdout, Color::Magenta)?;
81 write!(stdout, "{}: ", span.name)?;
82 }
83
84 color(stdout, Color::Green)?;
85 write!(stdout, "from line ")?;
86
87 color(stdout, Color::White)?;
88 write!(stdout, "{}", span.start_line)?;
89
90 color(stdout, Color::Green)?;
91 write!(stdout, " to line ")?;
92
93 color(stdout, Color::White)?;
94 writeln!(stdout, "{}.", span.end_line)
95}
96
97fn dump_spans(mut spans: Vec<FunctionSpan>, path: PathBuf) -> std::io::Result<()> {
98 if !spans.is_empty() {
99 let stdout = StandardStream::stdout(ColorChoice::Always);
100 let mut stdout = stdout.lock();
101
102 intense_color(&mut stdout, Color::Yellow)?;
103 writeln!(&mut stdout, "In file {}", path.to_str().unwrap_or("..."))?;
104
105 for span in spans.drain(..spans.len() - 1) {
106 dump_span(span, &mut stdout, false)?;
107 }
108 dump_span(spans.pop().unwrap(), &mut stdout, true)?;
109 color(&mut stdout, Color::White)?;
110 }
111 Ok(())
112}
113
114#[derive(Debug)]
117pub struct FunctionCfg {
118 pub path: PathBuf,
120}
121
122pub struct Function {
123 _guard: (),
124}
125
126impl Callback for Function {
127 type Res = std::io::Result<()>;
128 type Cfg = FunctionCfg;
129
130 fn call<T: ParserTrait>(cfg: Self::Cfg, parser: &T) -> Self::Res {
131 dump_spans(function(parser), cfg.path)
132 }
133}