use std::path::{Path, PathBuf};
use ratatui::buffer::{Buffer, Cell};
use crate::app;
pub fn session_folder(base: &Path, session_id: &str) -> PathBuf {
app::session::session_folder(base, session_id)
}
pub fn rendered_text_start_cell<'a>(buffer: &'a Buffer, needle: &str) -> Option<&'a Cell> {
rendered_text_start_cells(buffer, needle).into_iter().next()
}
pub fn rendered_text_start_cells<'a>(buffer: &'a Buffer, needle: &str) -> Vec<&'a Cell> {
let width = usize::from(buffer.area.width.max(1));
let needle_symbols = needle.chars().map(|character| character.to_string());
let needle_symbols = needle_symbols.collect::<Vec<_>>();
let content = buffer.content();
let mut cells = Vec::new();
for row_start in (0..content.len()).step_by(width) {
let row_end = row_start + width.min(content.len().saturating_sub(row_start));
let row = &content[row_start..row_end];
for (index, window) in row.windows(needle_symbols.len()).enumerate() {
let window_matches = window
.iter()
.zip(&needle_symbols)
.all(|(cell, symbol)| cell.symbol() == symbol);
if window_matches {
cells.push(&row[index]);
}
}
}
cells
}
#[cfg(test)]
mod tests {
use ratatui::style::{Color, Style};
use super::*;
#[test]
fn rendered_text_start_cell_returns_first_match() {
let mut buffer = Buffer::empty(ratatui::layout::Rect::new(0, 0, 12, 2));
buffer.set_string(1, 0, "one", Style::default().fg(Color::Green));
buffer.set_string(1, 1, "one", Style::default().fg(Color::Yellow));
let cell = rendered_text_start_cell(&buffer, "one").expect("text should render");
assert_eq!(cell.fg, Color::Green);
}
#[test]
fn rendered_text_start_cells_returns_all_matches() {
let mut buffer = Buffer::empty(ratatui::layout::Rect::new(0, 0, 12, 2));
buffer.set_string(1, 0, "same", Style::default().fg(Color::Green));
buffer.set_string(1, 1, "same", Style::default().fg(Color::Yellow));
let cells = rendered_text_start_cells(&buffer, "same");
let colors = cells.iter().map(|cell| cell.fg).collect::<Vec<_>>();
assert_eq!(colors, vec![Color::Green, Color::Yellow]);
}
#[test]
fn rendered_text_start_cell_returns_none_for_missing_text() {
let mut buffer = Buffer::empty(ratatui::layout::Rect::new(0, 0, 12, 1));
buffer.set_string(1, 0, "present", Style::default());
let cell = rendered_text_start_cell(&buffer, "missing");
assert!(cell.is_none());
}
}