1#[cfg(feature = "ansi")]
4mod ansi_adapter {
5 use crate::DiffRow;
6 use anstyle::{Reset, Style};
7
8 #[derive(Debug, Clone, Copy, Default)]
10 pub struct AnsiDiffPalette {
11 pub header: Style,
13 pub context: Style,
15 pub addition: Style,
17 pub deletion: Style,
19 pub emphasis: Style,
21 }
22
23 #[must_use]
25 pub fn render_ansi_rows(rows: &[DiffRow], palette: AnsiDiffPalette, color: bool) -> Vec<String> {
26 rows.iter()
27 .map(|row| {
28 let mut output = String::new();
29 output.push(row.marker);
30 output.push(' ');
31 if let Some(cell) = &row.left {
32 render_cell(&mut output, cell, palette, color);
33 }
34 if let Some(cell) = &row.right {
35 output.push_str(" │ ");
36 render_cell(&mut output, cell, palette, color);
37 }
38 output
39 })
40 .collect()
41 }
42
43 fn render_cell(output: &mut String, cell: &crate::DiffCell, palette: AnsiDiffPalette, color: bool) {
44 let style = match cell.marker {
45 '+' => palette.addition,
46 '-' => palette.deletion,
47 '@' | '…' => palette.header,
48 _ => palette.context,
49 };
50 for segment in &cell.segments {
51 if color {
52 let selected = if segment.emphasized { palette.emphasis } else { style };
53 output.push_str(&selected.render().to_string());
54 output.push_str(&segment.text);
55 output.push_str(&Reset.render().to_string());
56 } else {
57 output.push_str(&segment.text);
58 }
59 }
60 }
61}
62
63#[cfg(feature = "ansi")]
64pub use ansi_adapter::{AnsiDiffPalette, render_ansi_rows};
65
66#[cfg(feature = "ratatui")]
67mod ratatui_adapter {
68 use crate::DiffRow;
69 use ratatui::text::{Line, Span};
70
71 #[must_use]
73 pub fn to_ratatui_lines(rows: &[DiffRow]) -> Vec<Line<'static>> {
74 rows.iter()
75 .map(|row| {
76 let mut spans = vec![Span::raw(format!("{} ", row.marker))];
77 if let Some(cell) = &row.left {
78 spans.extend(cell.segments.iter().map(|segment| Span::raw(segment.text.clone())));
79 }
80 if let Some(cell) = &row.right {
81 spans.push(Span::raw(" │ "));
82 spans.extend(cell.segments.iter().map(|segment| Span::raw(segment.text.clone())));
83 }
84 Line::from(spans)
85 })
86 .collect()
87 }
88}
89
90#[cfg(feature = "ratatui")]
91pub use ratatui_adapter::to_ratatui_lines;