baml_agent_tui/
context_bar.rs1use ratatui::prelude::*;
7use ratatui::widgets::{Block, Borders, Paragraph};
8
9#[derive(Debug, Clone, Default)]
11pub struct ProjectContext {
12 pub name: String,
13 pub files_total: usize,
14 pub files_analyzed: usize,
15 pub segments_total: usize,
16 pub top_score: f32,
17 pub timeline_secs: Option<f64>,
18 pub music_track: Option<String>,
19}
20
21impl ProjectContext {
22 pub fn render(&self, area: Rect, buf: &mut Buffer) {
24 if self.name.is_empty() {
25 let widget = Paragraph::new("No project")
26 .style(Style::default().fg(Color::DarkGray))
27 .block(Block::default().borders(Borders::ALL).title(" Context "));
28 widget.render(area, buf);
29 return;
30 }
31
32 let mut parts = vec![
33 format!("\u{1F4C2} {}", self.name),
34 format!("{}/{} files", self.files_analyzed, self.files_total),
35 format!("{} seg", self.segments_total),
36 ];
37
38 if self.top_score > 0.0 {
39 parts.push(format!("\u{2B50} {:.2}", self.top_score));
40 }
41
42 if let Some(ref track) = self.music_track {
43 let name = if track.len() > 20 {
45 format!("{}...", &track[..17])
46 } else {
47 track.clone()
48 };
49 parts.push(format!("\u{266B} {}", name));
50 }
51
52 if let Some(secs) = self.timeline_secs {
53 parts.push(format!("\u{23F1} {:.1}s", secs));
54 }
55
56 let text = parts.join(" \u{2502} ");
57 let widget = Paragraph::new(text)
58 .style(Style::default().fg(Color::White))
59 .block(
60 Block::default()
61 .borders(Borders::ALL)
62 .title(" Context ")
63 .border_style(Style::default().fg(Color::DarkGray)),
64 );
65 widget.render(area, buf);
66 }
67}
68
69#[cfg(test)]
70mod tests {
71 use super::*;
72 use ratatui::buffer::Buffer;
73
74 #[test]
75 fn empty_context_renders() {
76 let ctx = ProjectContext::default();
77 let area = Rect::new(0, 0, 40, 3);
78 let mut buf = Buffer::empty(area);
79 ctx.render(area, &mut buf);
80 }
82
83 #[test]
84 fn full_context_renders() {
85 let ctx = ProjectContext {
86 name: "trip.l2f".into(),
87 files_total: 5,
88 files_analyzed: 3,
89 segments_total: 42,
90 top_score: 0.87,
91 timeline_secs: Some(15.0),
92 music_track: Some("song.mp3".into()),
93 };
94 let area = Rect::new(0, 0, 80, 3);
95 let mut buf = Buffer::empty(area);
96 ctx.render(area, &mut buf);
97 }
98}