turbopack_cli_utils/
source_context.rs1use std::fmt::{Display, Write};
2
3use owo_colors::OwoColorize;
4use turbo_tasks_fs::source_context::{SourceContextLine, SourceContextLines};
5
6struct MarkerRange {
7 start: char,
8 end: char,
9 pos: usize,
10 len: usize,
11}
12
13impl Display for MarkerRange {
14 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
15 for _ in 0..self.pos {
16 f.write_char(' ')?;
17 }
18 f.write_char(self.start)?;
19 if self.len > 1 {
20 for _ in 2..self.len {
21 f.write_char('-')?;
22 }
23 f.write_char(self.end)?;
24 }
25 Ok(())
26 }
27}
28
29pub fn format_source_context_lines(ctx: &SourceContextLines, f: &mut impl Write) {
30 const PADDING: usize = 6;
31 const SPACE: char = ' ';
32 for line in &ctx.0 {
33 match line {
34 SourceContextLine::Context { line, outside } => {
35 writeln!(
36 f,
37 "{}",
38 format_args!("{line:>PADDING$} | {outside}").dimmed()
39 )
40 .unwrap();
41 }
42 SourceContextLine::Start {
43 line,
44 before,
45 inside,
46 } => {
47 writeln!(
48 f,
49 "{SPACE:PADDING$} | {}",
50 MarkerRange {
51 start: 'v',
52 end: '-',
53 pos: before.len(),
54 len: inside.len(),
55 }
56 .bold(),
57 )
58 .unwrap();
59 writeln!(f, "{line:>PADDING$} + {}{}", before.dimmed(), inside.bold()).unwrap();
60 }
61 SourceContextLine::End {
62 line,
63 inside,
64 after,
65 } => {
66 writeln!(f, "{line:>PADDING$} + {}{}", inside.bold(), after.dimmed()).unwrap();
67 writeln!(
68 f,
69 "{SPACE:PADDING$} +{}",
70 MarkerRange {
71 start: '-',
72 end: '^',
73 pos: 0,
74 len: inside.len() + 1,
75 }
76 .bold()
77 )
78 .unwrap();
79 }
80 SourceContextLine::StartAndEnd {
81 line,
82 before,
83 inside,
84 after,
85 } => {
86 writeln!(
87 f,
88 "{SPACE:PADDING$} + {}",
89 MarkerRange {
90 start: 'v',
91 end: 'v',
92 pos: before.len(),
93 len: inside.len(),
94 }
95 .bold()
96 )
97 .unwrap();
98 if inside.len() >= 2 {
99 writeln!(
100 f,
101 "{line:>PADDING$} + {}{}{}",
102 before.dimmed(),
103 inside.bold(),
104 after.dimmed()
105 )
106 .unwrap();
107 } else {
108 writeln!(
109 f,
110 "{line:>PADDING$} + {}{}{}",
111 before.bold(),
112 inside.bold(),
113 after.bold()
114 )
115 .unwrap();
116 }
117 writeln!(
118 f,
119 "{SPACE:PADDING$} + {}",
120 MarkerRange {
121 start: '^',
122 end: '^',
123 pos: before.len(),
124 len: inside.len(),
125 }
126 .bold()
127 )
128 .unwrap();
129 }
130 SourceContextLine::Inside { line, inside } => {
131 writeln!(f, "{:>PADDING$} + {}", line.bold(), inside.bold()).unwrap();
132 }
133 }
134 }
135}