use std::ops::Range;
use ratatui::buffer::Buffer;
use ratatui::layout::Rect;
pub trait EventListener<Event> {
fn on_event(&mut self, context: &Event);
}
pub fn paste(child: &Buffer, rows: Range<u16>, into: Rect, parent: &mut Buffer) {
let source = *child.area();
let clip = into.intersection(*parent.area());
let width = usize::from(source.width.min(clip.width));
if clip.is_empty() || width == 0 {
return;
}
for (offset, row) in (rows.start..rows.end.min(source.height)).enumerate() {
let Ok(offset) = u16::try_from(offset) else {
break;
};
if offset >= clip.height {
break;
}
let from = child.index_of(source.x, source.y + row);
let to = parent.index_of(clip.x, clip.y + offset);
parent.content[to..to + width].clone_from_slice(&child.content[from..from + width]);
}
}
#[cfg(test)]
mod tests {
use super::*;
fn marked(width: u16, height: u16) -> Buffer {
let mut cells = Buffer::empty(Rect::new(0, 0, width, height));
for y in 0..height {
cells[(0, y)].set_symbol(&y.to_string());
}
cells
}
#[test]
fn pasting_shifts_a_child_slice_without_wrapping_past_the_parent() {
let child = marked(2, 6);
let mut parent = Buffer::empty(Rect::new(0, 0, 4, 3));
paste(&child, 2..5, Rect::new(1, 0, 2, 3), &mut parent);
assert_eq!(parent[(1, 0)].symbol(), "2");
assert_eq!(parent[(1, 2)].symbol(), "4");
assert_eq!(parent[(0, 0)].symbol(), " ");
}
#[test]
fn pasting_drops_rows_and_columns_beyond_the_parent() {
let child = marked(6, 4);
let mut parent = Buffer::empty(Rect::new(0, 0, 4, 2));
paste(&child, 0..4, Rect::new(2, 1, 6, 4), &mut parent);
assert_eq!(parent[(2, 1)].symbol(), "0");
assert_eq!(parent[(2, 0)].symbol(), " ");
}
}