flake_edit/tui/components/confirm/
view.rs1use ratatui::{
2 buffer::Buffer,
3 layout::Rect,
4 text::Span,
5 widgets::{Block, Borders, Paragraph, Widget, Wrap},
6};
7
8use crate::tui::components::footer::Footer;
9use crate::tui::helpers::{color_diff_lines, context_span, layouts};
10use crate::tui::style::{BORDER_STYLE, HIGHLIGHT_STYLE};
11
12pub struct Confirm<'a> {
14 diff: &'a str,
15 context: &'a str,
16}
17
18impl<'a> Confirm<'a> {
19 pub fn new(diff: &'a str, context: &'a str) -> Self {
20 Self { diff, context }
21 }
22}
23
24impl Widget for Confirm<'_> {
25 fn render(self, area: Rect, buf: &mut Buffer) {
26 let (content_area, footer_area) = layouts::content_with_footer(area);
27
28 let content = Paragraph::new(color_diff_lines(self.diff))
29 .block(
30 Block::default()
31 .borders(Borders::TOP | Borders::BOTTOM)
32 .border_style(BORDER_STYLE),
33 )
34 .wrap(Wrap { trim: false });
35 content.render(content_area, buf);
36
37 Footer::new(
38 vec![
39 context_span(self.context),
40 Span::raw(" Apply? "),
41 Span::styled(" y ", HIGHLIGHT_STYLE),
42 Span::raw("es "),
43 Span::styled(" n ", HIGHLIGHT_STYLE),
44 Span::raw("o "),
45 Span::styled(" b ", HIGHLIGHT_STYLE),
46 Span::raw("ack"),
47 ],
48 vec![],
49 )
50 .render(footer_area, buf);
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57 use ratatui::{Terminal, backend::TestBackend};
58
59 fn create_test_terminal(width: u16, height: u16) -> Terminal<TestBackend> {
60 let backend = TestBackend::new(width, height);
61 Terminal::new(backend).unwrap()
62 }
63
64 fn buffer_to_plain_text(terminal: &Terminal<TestBackend>) -> String {
65 let buffer = terminal.backend().buffer();
66 let mut lines = Vec::new();
67 for y in 0..buffer.area.height {
68 let mut line = String::new();
69 for x in 0..buffer.area.width {
70 line.push(buffer[(x, y)].symbol().chars().next().unwrap_or(' '));
71 }
72 lines.push(line.trim_end().to_string());
73 }
74 while lines.last().is_some_and(|l| l.is_empty()) {
75 lines.pop();
76 }
77 lines.join("\n")
78 }
79
80 #[test]
81 fn test_render_confirm() {
82 let mut terminal = create_test_terminal(80, 10);
83 let diff = r#"@@ -1,3 +1,3 @@
84 inputs = {
85- nixpkgs.url = "github:nixos/nixpkgs";
86+ nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
87 };"#;
88
89 terminal
90 .draw(|frame| {
91 Confirm::new(diff, "Change").render(frame.area(), frame.buffer_mut());
92 })
93 .unwrap();
94
95 let output = buffer_to_plain_text(&terminal);
96 insta::assert_snapshot!(output);
97 }
98}