on master help sign in
style: add component 'rule' for horizontal file delimiter
aa4000cTom Milligan
src/bin/bat/clap_app.rs+3−2
@@ -367,7 +367,7 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
367 .validator(|val| {
367 .validator(|val| {
368 let mut invalid_vals = val.split(',').filter(|style| {
368 let mut invalid_vals = val.split(',').filter(|style| {
369 !&[
369 !&[
370− "auto", "full", "plain", "header", "grid", "numbers", "snip",
370+ "auto", "full", "plain", "header", "grid", "rule", "numbers", "snip",
371 #[cfg(feature = "git")]
371 #[cfg(feature = "git")]
372 "changes",
372 "changes",
373 ]
373 ]
@@ -382,7 +382,7 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
382 })
382 })
383 .help(
383 .help(
384 "Comma-separated list of style elements to display \
384 "Comma-separated list of style elements to display \
385− (*auto*, full, plain, changes, header, grid, numbers, snip).",
385+ (*auto*, full, plain, changes, header, grid, rule, numbers, snip).",
386 )
386 )
387 .long_help(
387 .long_help(
388 "Configure which elements (line numbers, file headers, grid \
388 "Configure which elements (line numbers, file headers, grid \
@@ -400,6 +400,7 @@ pub fn build_app(interactive_output: bool) -> ClapApp<'static, 'static> {
400 * header: show filenames before the content.\n \
400 * header: show filenames before the content.\n \
401 * grid: vertical/horizontal lines to separate side bar\n \
401 * grid: vertical/horizontal lines to separate side bar\n \
402 and the header from the content.\n \
402 and the header from the content.\n \
403+ * rule: horizontal lines to delimit files.\n \
403 * numbers: show line numbers in the side bar.\n \
404 * numbers: show line numbers in the side bar.\n \
404 * snip: draw separation lines between distinct line ranges.",
405 * snip: draw separation lines between distinct line ranges.",
405 ),
406 ),
src/pretty_printer.rs+10
@@ -23,6 +23,7 @@ struct ActiveStyleComponents {
23 header: bool,
23 header: bool,
24 vcs_modification_markers: bool,
24 vcs_modification_markers: bool,
25 grid: bool,
25 grid: bool,
26+ rule: bool,
26 line_numbers: bool,
27 line_numbers: bool,
27 snip: bool,
28 snip: bool,
28}
29}
@@ -179,6 +180,12 @@ impl<'a> PrettyPrinter<'a> {
179 self
180 self
180 }
181 }
181
182
183+ /// Whether to paint a horizontal rule to delimit files
184+ pub fn rule(&mut self, yes: bool) -> &mut Self {
185+ self.active_style_components.rule = yes;
186+ self
187+ }
188+
182 /// Whether to show modification markers for VCS changes. This has no effect if
189 /// Whether to show modification markers for VCS changes. This has no effect if
183 /// the `git` feature is not activated.
190 /// the `git` feature is not activated.
184 #[cfg_attr(
191 #[cfg_attr(
@@ -285,6 +292,9 @@ impl<'a> PrettyPrinter<'a> {
285 if self.active_style_components.grid {
292 if self.active_style_components.grid {
286 style_components.push(StyleComponent::Grid);
293 style_components.push(StyleComponent::Grid);
287 }
294 }
295+ if self.active_style_components.rule {
296+ style_components.push(StyleComponent::Rule);
297+ }
288 if self.active_style_components.header {
298 if self.active_style_components.header {
289 style_components.push(StyleComponent::Header);
299 style_components.push(StyleComponent::Header);
290 }
300 }
src/printer.rs+18−6
@@ -200,13 +200,18 @@ impl<'a> InteractivePrinter<'a> {
200 })
200 })
201 }
201 }
202
202
203+ fn print_horizontal_line_term(&mut self, handle: &mut dyn Write, style: Style) -> Result<()> {
204+ writeln!(
205+ handle,
206+ "{}",
207+ style.paint("─".repeat(self.config.term_width))
208+ )?;
209+ Ok(())
210+ }
211+
203 fn print_horizontal_line(&mut self, handle: &mut dyn Write, grid_char: char) -> Result<()> {
212 fn print_horizontal_line(&mut self, handle: &mut dyn Write, grid_char: char) -> Result<()> {
204 if self.panel_width == 0 {
213 if self.panel_width == 0 {
205− writeln!(
214+ self.print_horizontal_line_term(handle, self.colors.grid)?;
206− handle,
207− "{}",
208− self.colors.grid.paint("─".repeat(self.config.term_width))
209− )?;
210 } else {
215 } else {
211 let hline = "─".repeat(self.config.term_width - (self.panel_width + 1));
216 let hline = "─".repeat(self.config.term_width - (self.panel_width + 1));
212 let hline = format!("{}{}{}", "─".repeat(self.panel_width), grid_char, hline);
217 let hline = format!("{}{}{}", "─".repeat(self.panel_width), grid_char, hline);
@@ -251,6 +256,10 @@ impl<'a> Printer for InteractivePrinter<'a> {
251 input: &OpenedInput,
256 input: &OpenedInput,
252 add_header_padding: bool,
257 add_header_padding: bool,
253 ) -> Result<()> {
258 ) -> Result<()> {
259+ if add_header_padding && self.config.style_components.rule() {
260+ self.print_horizontal_line_term(handle, self.colors.rule)?;
261+ }
262+
254 if !self.config.style_components.header() {
263 if !self.config.style_components.header() {
255 if Some(ContentType::BINARY) == self.content_type && !self.config.show_nonprintable {
264 if Some(ContentType::BINARY) == self.content_type && !self.config.show_nonprintable {
256 writeln!(
265 writeln!(
@@ -279,7 +288,8 @@ impl<'a> Printer for InteractivePrinter<'a> {
279 .paint(if self.panel_width > 0 { "│ " } else { "" }),
288 .paint(if self.panel_width > 0 { "│ " } else { "" }),
280 )?;
289 )?;
281 } else {
290 } else {
291+ // Only pad space between files, if we haven't already drawn a horizontal rule
282− if add_header_padding {
292+ if add_header_padding && !self.config.style_components.rule() {
283 writeln!(handle)?;
293 writeln!(handle)?;
284 }
294 }
285 write!(handle, "{}", " ".repeat(self.panel_width))?;
295 write!(handle, "{}", " ".repeat(self.panel_width))?;
@@ -603,6 +613,7 @@ const DEFAULT_GUTTER_COLOR: u8 = 238;
603#[derive(Debug, Default)]
613#[derive(Debug, Default)]
604pub struct Colors {
614pub struct Colors {
605 pub grid: Style,
615 pub grid: Style,
616+ pub rule: Style,
606 pub filename: Style,
617 pub filename: Style,
607 pub git_added: Style,
618 pub git_added: Style,
608 pub git_removed: Style,
619 pub git_removed: Style,
@@ -624,6 +635,7 @@ impl Colors {
624
635
625 Colors {
636 Colors {
626 grid: gutter_color.normal(),
637 grid: gutter_color.normal(),
638+ rule: gutter_color.normal(),
627 filename: Style::new().bold(),
639 filename: Style::new().bold(),
628 git_added: Green.normal(),
640 git_added: Green.normal(),
629 git_removed: Red.normal(),
641 git_removed: Red.normal(),
src/style.rs+7
@@ -9,6 +9,7 @@ pub enum StyleComponent {
9 #[cfg(feature = "git")]
9 #[cfg(feature = "git")]
10 Changes,
10 Changes,
11 Grid,
11 Grid,
12+ Rule,
12 Header,
13 Header,
13 LineNumbers,
14 LineNumbers,
14 Snip,
15 Snip,
@@ -29,6 +30,7 @@ impl StyleComponent {
29 #[cfg(feature = "git")]
30 #[cfg(feature = "git")]
30 StyleComponent::Changes => &[StyleComponent::Changes],
31 StyleComponent::Changes => &[StyleComponent::Changes],
31 StyleComponent::Grid => &[StyleComponent::Grid],
32 StyleComponent::Grid => &[StyleComponent::Grid],
33+ StyleComponent::Rule => &[StyleComponent::Rule],
32 StyleComponent::Header => &[StyleComponent::Header],
34 StyleComponent::Header => &[StyleComponent::Header],
33 StyleComponent::LineNumbers => &[StyleComponent::LineNumbers],
35 StyleComponent::LineNumbers => &[StyleComponent::LineNumbers],
34 StyleComponent::Snip => &[StyleComponent::Snip],
36 StyleComponent::Snip => &[StyleComponent::Snip],
@@ -54,6 +56,7 @@ impl FromStr for StyleComponent {
54 #[cfg(feature = "git")]
56 #[cfg(feature = "git")]
55 "changes" => Ok(StyleComponent::Changes),
57 "changes" => Ok(StyleComponent::Changes),
56 "grid" => Ok(StyleComponent::Grid),
58 "grid" => Ok(StyleComponent::Grid),
59+ "rule" => Ok(StyleComponent::Rule),
57 "header" => Ok(StyleComponent::Header),
60 "header" => Ok(StyleComponent::Header),
58 "numbers" => Ok(StyleComponent::LineNumbers),
61 "numbers" => Ok(StyleComponent::LineNumbers),
59 "snip" => Ok(StyleComponent::Snip),
62 "snip" => Ok(StyleComponent::Snip),
@@ -81,6 +84,10 @@ impl StyleComponents {
81 self.0.contains(&StyleComponent::Grid)
84 self.0.contains(&StyleComponent::Grid)
82 }
85 }
83
86
87+ pub fn rule(&self) -> bool {
88+ self.0.contains(&StyleComponent::Rule)
89+ }
90+
84 pub fn header(&self) -> bool {
91 pub fn header(&self) -> bool {
85 self.0.contains(&StyleComponent::Header)
92 self.0.contains(&StyleComponent::Header)
86 }
93 }
tests/integration_tests.rs+12
@@ -570,6 +570,18 @@ fn empty_file_leads_to_empty_output_with_grid_enabled() {
570 .stdout("");
570 .stdout("");
571}
571}
572
572
573+#[test]
574+fn empty_file_leads_to_empty_output_with_rule_enabled() {
575+ bat()
576+ .arg("empty.txt")
577+ .arg("--style=rule")
578+ .arg("--decorations=always")
579+ .arg("--terminal-width=80")
580+ .assert()
581+ .success()
582+ .stdout("");
583+}
584+
573#[test]
585#[test]
574fn filename_basic() {
586fn filename_basic() {
575 bat()
587 bat()
tests/snapshot_tests.rs+10
@@ -19,17 +19,27 @@ snapshot_tests! {
19 grid: "grid",
19 grid: "grid",
20 header: "header",
20 header: "header",
21 numbers: "numbers",
21 numbers: "numbers",
22+ rule: "rule",
22 changes_grid: "changes,grid",
23 changes_grid: "changes,grid",
23 changes_header: "changes,header",
24 changes_header: "changes,header",
24 changes_numbers: "changes,numbers",
25 changes_numbers: "changes,numbers",
26+ changes_rule: "changes,rule",
25 grid_header: "grid,header",
27 grid_header: "grid,header",
26 grid_numbers: "grid,numbers",
28 grid_numbers: "grid,numbers",
29+ grid_rule: "grid,rule",
27 header_numbers: "header,numbers",
30 header_numbers: "header,numbers",
31+ header_rule: "header,rule",
28 changes_grid_header: "changes,grid,header",
32 changes_grid_header: "changes,grid,header",
29 changes_grid_numbers: "changes,grid,numbers",
33 changes_grid_numbers: "changes,grid,numbers",
34+ changes_grid_rule: "changes,grid,rule",
30 changes_header_numbers: "changes,header,numbers",
35 changes_header_numbers: "changes,header,numbers",
36+ changes_header_rule: "changes,header,rule",
31 grid_header_numbers: "grid,header,numbers",
37 grid_header_numbers: "grid,header,numbers",
38+ grid_header_rule: "grid,header,rule",
39+ header_numbers_rule: "header,numbers,rule",
32 changes_grid_header_numbers: "changes,grid,header,numbers",
40 changes_grid_header_numbers: "changes,grid,header,numbers",
41+ changes_grid_header_rule: "changes,grid,header,rule",
42+ changes_grid_header_numbers_rule: "changes,grid,header,numbers,rule",
33 full: "full",
43 full: "full",
34 plain: "plain",
44 plain: "plain",
35}
45}
tests/snapshots/generate_snapshots.py+1−1
@@ -7,7 +7,7 @@ import shutil
7
7
8
8
9def generate_snapshots():
9def generate_snapshots():
10− single_styles = ["changes", "grid", "header", "numbers"]
10+ single_styles = ["changes", "grid", "header", "numbers", "rule"]
11 collective_styles = ["full", "plain"]
11 collective_styles = ["full", "plain"]
12
12
13 for num in range(len(single_styles)):
13 for num in range(len(single_styles)):
tests/snapshots/output/changes_grid_header_numbers_rule.snapshot.txtnew file+26
@@ -0,0 +1,26 @@
1+───────┬────────────────────────────────────────────────────────────────────────
2+ │ File: sample.rs
3+───────┼────────────────────────────────────────────────────────────────────────
4+ 1 │ struct Rectangle {
5+ 2 │ width: u32,
6+ 3 │ height: u32,
7+ 4 │ }
8+ 5 │
9+ 6 _ │ fn main() {
10+ 7 │ let rect1 = Rectangle { width: 30, height: 50 };
11+ 8 │
12+ 9 │ println!(
13+ 10 ~ │ "The perimeter of the rectangle is {} pixels.",
14+ 11 ~ │ perimeter(&rect1)
15+ 12 │ );
16+ 13 + │ println!(r#"This line contains invalid utf8: "�����"#;
17+ 14 │ }
18+ 15 │
19+ 16 │ fn area(rectangle: &Rectangle) -> u32 {
20+ 17 │ rectangle.width * rectangle.height
21+ 18 │ }
22+ 19 + │
23+ 20 + │ fn perimeter(rectangle: &Rectangle) -> u32 {
24+ 21 + │ (rectangle.width + rectangle.height) * 2
25+ 22 + │ }
26+───────┴────────────────────────────────────────────────────────────────────────
tests/snapshots/output/changes_grid_header_rule.snapshot.txtnew file+26
@@ -0,0 +1,26 @@
1+──┬─────────────────────────────────────────────────────────────────────────────
2+ │ File: sample.rs
3+──┼─────────────────────────────────────────────────────────────────────────────
4+ │ struct Rectangle {
5+ │ width: u32,
6+ │ height: u32,
7+ │ }
8+ │
9+_ │ fn main() {
10+ │ let rect1 = Rectangle { width: 30, height: 50 };
11+ │
12+ │ println!(
13+~ │ "The perimeter of the rectangle is {} pixels.",
14+~ │ perimeter(&rect1)
15+ │ );
16++ │ println!(r#"This line contains invalid utf8: "�����"#;
17+ │ }
18+ │
19+ │ fn area(rectangle: &Rectangle) -> u32 {
20+ │ rectangle.width * rectangle.height
21+ │ }
22++ │
23++ │ fn perimeter(rectangle: &Rectangle) -> u32 {
24++ │ (rectangle.width + rectangle.height) * 2
25++ │ }
26+──┴─────────────────────────────────────────────────────────────────────────────
tests/snapshots/output/changes_grid_numbers_rule.snapshot.txtnew file+24
@@ -0,0 +1,24 @@
1+───────┬────────────────────────────────────────────────────────────────────────
2+ 1 │ struct Rectangle {
3+ 2 │ width: u32,
4+ 3 │ height: u32,
5+ 4 │ }
6+ 5 │
7+ 6 _ │ fn main() {
8+ 7 │ let rect1 = Rectangle { width: 30, height: 50 };
9+ 8 │
10+ 9 │ println!(
11+ 10 ~ │ "The perimeter of the rectangle is {} pixels.",
12+ 11 ~ │ perimeter(&rect1)
13+ 12 │ );
14+ 13 + │ println!(r#"This line contains invalid utf8: "�����"#;
15+ 14 │ }
16+ 15 │
17+ 16 │ fn area(rectangle: &Rectangle) -> u32 {
18+ 17 │ rectangle.width * rectangle.height
19+ 18 │ }
20+ 19 + │
21+ 20 + │ fn perimeter(rectangle: &Rectangle) -> u32 {
22+ 21 + │ (rectangle.width + rectangle.height) * 2
23+ 22 + │ }
24+───────┴────────────────────────────────────────────────────────────────────────
tests/snapshots/output/changes_grid_rule.snapshot.txtnew file+24
@@ -0,0 +1,24 @@
1+──┬─────────────────────────────────────────────────────────────────────────────
2+ │ struct Rectangle {
3+ │ width: u32,
4+ │ height: u32,
5+ │ }
6+ │
7+_ │ fn main() {
8+ │ let rect1 = Rectangle { width: 30, height: 50 };
9+ │
10+ │ println!(
11+~ │ "The perimeter of the rectangle is {} pixels.",
12+~ │ perimeter(&rect1)
13+ │ );
14++ │ println!(r#"This line contains invalid utf8: "�����"#;
15+ │ }
16+ │
17+ │ fn area(rectangle: &Rectangle) -> u32 {
18+ │ rectangle.width * rectangle.height
19+ │ }
20++ │
21++ │ fn perimeter(rectangle: &Rectangle) -> u32 {
22++ │ (rectangle.width + rectangle.height) * 2
23++ │ }
24+──┴─────────────────────────────────────────────────────────────────────────────
tests/snapshots/output/changes_header_numbers_rule.snapshot.txtnew file+23
@@ -0,0 +1,23 @@
1+ File: sample.rs
2+ 1 struct Rectangle {
3+ 2 width: u32,
4+ 3 height: u32,
5+ 4 }
6+ 5
7+ 6 _ fn main() {
8+ 7 let rect1 = Rectangle { width: 30, height: 50 };
9+ 8
10+ 9 println!(
11+ 10 ~ "The perimeter of the rectangle is {} pixels.",
12+ 11 ~ perimeter(&rect1)
13+ 12 );
14+ 13 + println!(r#"This line contains invalid utf8: "�����"#;
15+ 14 }
16+ 15
17+ 16 fn area(rectangle: &Rectangle) -> u32 {
18+ 17 rectangle.width * rectangle.height
19+ 18 }
20+ 19 +
21+ 20 + fn perimeter(rectangle: &Rectangle) -> u32 {
22+ 21 + (rectangle.width + rectangle.height) * 2
23+ 22 + }
tests/snapshots/output/changes_header_rule.snapshot.txtnew file+23
@@ -0,0 +1,23 @@
1+ File: sample.rs
2+ struct Rectangle {
3+ width: u32,
4+ height: u32,
5+ }
6+
7+_ fn main() {
8+ let rect1 = Rectangle { width: 30, height: 50 };
9+
10+ println!(
11+~ "The perimeter of the rectangle is {} pixels.",
12+~ perimeter(&rect1)
13+ );
14++ println!(r#"This line contains invalid utf8: "�����"#;
15+ }
16+
17+ fn area(rectangle: &Rectangle) -> u32 {
18+ rectangle.width * rectangle.height
19+ }
20++
21++ fn perimeter(rectangle: &Rectangle) -> u32 {
22++ (rectangle.width + rectangle.height) * 2
23++ }
tests/snapshots/output/changes_numbers_rule.snapshot.txtnew file+22
@@ -0,0 +1,22 @@
1+ 1 struct Rectangle {
2+ 2 width: u32,
3+ 3 height: u32,
4+ 4 }
5+ 5
6+ 6 _ fn main() {
7+ 7 let rect1 = Rectangle { width: 30, height: 50 };
8+ 8
9+ 9 println!(
10+ 10 ~ "The perimeter of the rectangle is {} pixels.",
11+ 11 ~ perimeter(&rect1)
12+ 12 );
13+ 13 + println!(r#"This line contains invalid utf8: "�����"#;
14+ 14 }
15+ 15
16+ 16 fn area(rectangle: &Rectangle) -> u32 {
17+ 17 rectangle.width * rectangle.height
18+ 18 }
19+ 19 +
20+ 20 + fn perimeter(rectangle: &Rectangle) -> u32 {
21+ 21 + (rectangle.width + rectangle.height) * 2
22+ 22 + }
tests/snapshots/output/changes_rule.snapshot.txtnew file+22
@@ -0,0 +1,22 @@
1+ struct Rectangle {
2+ width: u32,
3+ height: u32,
4+ }
5+
6+_ fn main() {
7+ let rect1 = Rectangle { width: 30, height: 50 };
8+
9+ println!(
10+~ "The perimeter of the rectangle is {} pixels.",
11+~ perimeter(&rect1)
12+ );
13++ println!(r#"This line contains invalid utf8: "�����"#;
14+ }
15+
16+ fn area(rectangle: &Rectangle) -> u32 {
17+ rectangle.width * rectangle.height
18+ }
19++
20++ fn perimeter(rectangle: &Rectangle) -> u32 {
21++ (rectangle.width + rectangle.height) * 2
22++ }
tests/snapshots/output/grid_header_numbers_rule.snapshot.txtnew file+26
@@ -0,0 +1,26 @@
1+─────┬──────────────────────────────────────────────────────────────────────────
2+ │ File: sample.rs
3+─────┼──────────────────────────────────────────────────────────────────────────
4+ 1 │ struct Rectangle {
5+ 2 │ width: u32,
6+ 3 │ height: u32,
7+ 4 │ }
8+ 5 │
9+ 6 │ fn main() {
10+ 7 │ let rect1 = Rectangle { width: 30, height: 50 };
11+ 8 │
12+ 9 │ println!(
13+ 10 │ "The perimeter of the rectangle is {} pixels.",
14+ 11 │ perimeter(&rect1)
15+ 12 │ );
16+ 13 │ println!(r#"This line contains invalid utf8: "�����"#;
17+ 14 │ }
18+ 15 │
19+ 16 │ fn area(rectangle: &Rectangle) -> u32 {
20+ 17 │ rectangle.width * rectangle.height
21+ 18 │ }
22+ 19 │
23+ 20 │ fn perimeter(rectangle: &Rectangle) -> u32 {
24+ 21 │ (rectangle.width + rectangle.height) * 2
25+ 22 │ }
26+─────┴──────────────────────────────────────────────────────────────────────────
tests/snapshots/output/grid_header_rule.snapshot.txtnew file+26
@@ -0,0 +1,26 @@
1+────────────────────────────────────────────────────────────────────────────────
2+File: sample.rs
3+────────────────────────────────────────────────────────────────────────────────
4+struct Rectangle {
5+ width: u32,
6+ height: u32,
7+}
8+
9+fn main() {
10+ let rect1 = Rectangle { width: 30, height: 50 };
11+
12+ println!(
13+ "The perimeter of the rectangle is {} pixels.",
14+ perimeter(&rect1)
15+ );
16+ println!(r#"This line contains invalid utf8: "�����"#;
17+}
18+
19+fn area(rectangle: &Rectangle) -> u32 {
20+ rectangle.width * rectangle.height
21+}
22+
23+fn perimeter(rectangle: &Rectangle) -> u32 {
24+ (rectangle.width + rectangle.height) * 2
25+}
26+────────────────────────────────────────────────────────────────────────────────
tests/snapshots/output/grid_numbers_rule.snapshot.txtnew file+24
@@ -0,0 +1,24 @@
1+─────┬──────────────────────────────────────────────────────────────────────────
2+ 1 │ struct Rectangle {
3+ 2 │ width: u32,
4+ 3 │ height: u32,
5+ 4 │ }
6+ 5 │
7+ 6 │ fn main() {
8+ 7 │ let rect1 = Rectangle { width: 30, height: 50 };
9+ 8 │
10+ 9 │ println!(
11+ 10 │ "The perimeter of the rectangle is {} pixels.",
12+ 11 │ perimeter(&rect1)
13+ 12 │ );
14+ 13 │ println!(r#"This line contains invalid utf8: "�����"#;
15+ 14 │ }
16+ 15 │
17+ 16 │ fn area(rectangle: &Rectangle) -> u32 {
18+ 17 │ rectangle.width * rectangle.height
19+ 18 │ }
20+ 19 │
21+ 20 │ fn perimeter(rectangle: &Rectangle) -> u32 {
22+ 21 │ (rectangle.width + rectangle.height) * 2
23+ 22 │ }
24+─────┴──────────────────────────────────────────────────────────────────────────
tests/snapshots/output/grid_rule.snapshot.txtnew file+24
@@ -0,0 +1,24 @@
1+────────────────────────────────────────────────────────────────────────────────
2+struct Rectangle {
3+ width: u32,
4+ height: u32,
5+}
6+
7+fn main() {
8+ let rect1 = Rectangle { width: 30, height: 50 };
9+
10+ println!(
11+ "The perimeter of the rectangle is {} pixels.",
12+ perimeter(&rect1)
13+ );
14+ println!(r#"This line contains invalid utf8: "�����"#;
15+}
16+
17+fn area(rectangle: &Rectangle) -> u32 {
18+ rectangle.width * rectangle.height
19+}
20+
21+fn perimeter(rectangle: &Rectangle) -> u32 {
22+ (rectangle.width + rectangle.height) * 2
23+}
24+────────────────────────────────────────────────────────────────────────────────
tests/snapshots/output/header_numbers_rule.snapshot.txtnew file+23
@@ -0,0 +1,23 @@
1+ File: sample.rs
2+ 1 struct Rectangle {
3+ 2 width: u32,
4+ 3 height: u32,
5+ 4 }
6+ 5
7+ 6 fn main() {
8+ 7 let rect1 = Rectangle { width: 30, height: 50 };
9+ 8
10+ 9 println!(
11+ 10 "The perimeter of the rectangle is {} pixels.",
12+ 11 perimeter(&rect1)
13+ 12 );
14+ 13 println!(r#"This line contains invalid utf8: "�����"#;
15+ 14 }
16+ 15
17+ 16 fn area(rectangle: &Rectangle) -> u32 {
18+ 17 rectangle.width * rectangle.height
19+ 18 }
20+ 19
21+ 20 fn perimeter(rectangle: &Rectangle) -> u32 {
22+ 21 (rectangle.width + rectangle.height) * 2
23+ 22 }
tests/snapshots/output/header_rule.snapshot.txtnew file+23
@@ -0,0 +1,23 @@
1+File: sample.rs
2+struct Rectangle {
3+ width: u32,
4+ height: u32,
5+}
6+
7+fn main() {
8+ let rect1 = Rectangle { width: 30, height: 50 };
9+
10+ println!(
11+ "The perimeter of the rectangle is {} pixels.",
12+ perimeter(&rect1)
13+ );
14+ println!(r#"This line contains invalid utf8: "�����"#;
15+}
16+
17+fn area(rectangle: &Rectangle) -> u32 {
18+ rectangle.width * rectangle.height
19+}
20+
21+fn perimeter(rectangle: &Rectangle) -> u32 {
22+ (rectangle.width + rectangle.height) * 2
23+}
tests/snapshots/output/numbers_rule.snapshot.txtnew file+22
@@ -0,0 +1,22 @@
1+ 1 struct Rectangle {
2+ 2 width: u32,
3+ 3 height: u32,
4+ 4 }
5+ 5
6+ 6 fn main() {
7+ 7 let rect1 = Rectangle { width: 30, height: 50 };
8+ 8
9+ 9 println!(
10+ 10 "The perimeter of the rectangle is {} pixels.",
11+ 11 perimeter(&rect1)
12+ 12 );
13+ 13 println!(r#"This line contains invalid utf8: "�����"#;
14+ 14 }
15+ 15
16+ 16 fn area(rectangle: &Rectangle) -> u32 {
17+ 17 rectangle.width * rectangle.height
18+ 18 }
19+ 19
20+ 20 fn perimeter(rectangle: &Rectangle) -> u32 {
21+ 21 (rectangle.width + rectangle.height) * 2
22+ 22 }
tests/snapshots/output/rule.snapshot.txtnew file+22
@@ -0,0 +1,22 @@
1+struct Rectangle {
2+ width: u32,
3+ height: u32,
4+}
5+
6+fn main() {
7+ let rect1 = Rectangle { width: 30, height: 50 };
8+
9+ println!(
10+ "The perimeter of the rectangle is {} pixels.",
11+ perimeter(&rect1)
12+ );
13+ println!(r#"This line contains invalid utf8: "�����"#;
14+}
15+
16+fn area(rectangle: &Rectangle) -> u32 {
17+ rectangle.width * rectangle.height
18+}
19+
20+fn perimeter(rectangle: &Rectangle) -> u32 {
21+ (rectangle.width + rectangle.height) * 2
22+}