use crate::{
arrangement::{Position, Size},
style::Style,
};
#[derive(Clone, Copy, PartialEq, Eq)]
pub struct Cell {
pub symbol: char,
pub style: Style,
}
impl Default for Cell {
fn default() -> Self {
Cell {
symbol: ' ',
style: Style::default(),
}
}
}
pub struct Buffer {
content: Vec<Cell>,
size: Size,
}
impl Buffer {
pub fn new(size: Size) -> Buffer {
Buffer {
content: vec![Cell::default(); size.area() as usize],
size,
}
}
pub fn size(&self) -> Size {
self.size
}
pub fn resize(&mut self, size: Size) {
self.content
.resize_with(size.area().into(), Default::default);
self.size = size;
}
fn index_of(&self, position: Position) -> Option<usize> {
if position.row > self.size.rows || position.column > self.size.columns {
return None;
}
let index = (position.row * self.size.columns) + position.column;
Some((index).into())
}
pub fn cell(&self, position: Position) -> Option<&Cell> {
let index = self.index_of(position)?;
Some(&self.content[index])
}
pub fn cell_mut(&mut self, position: Position) -> Option<&mut Cell> {
let index = self.index_of(position)?;
Some(&mut self.content[index])
}
pub fn diff<'d>(
&self,
other: &'d Buffer,
position: Position,
size: Size,
) -> Vec<(&'d Cell, Position)> {
let mut diff = Vec::new();
for row in position.row..size.rows {
for column in position.column..size.columns {
let position = Position::from(row, column);
match (other.cell(position), self.cell(position)) {
(Some(other_cell), Some(buffer_cell)) => {
if other_cell != buffer_cell {
diff.push((other_cell, position));
}
}
(Some(other_cell), None) => diff.push((other_cell, position)),
_ => (),
}
}
}
diff
}
}