aboutsummaryrefslogtreecommitdiffstats
path: root/src/grid.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/grid.rs')
-rw-r--r--src/grid.rs79
1 files changed, 67 insertions, 12 deletions
diff --git a/src/grid.rs b/src/grid.rs
index 085e744..21fb03c 100644
--- a/src/grid.rs
+++ b/src/grid.rs
@@ -152,7 +152,8 @@ impl Grid {
pub fn current_row_mut(&mut self) -> &mut crate::row::Row {
self.drawing_row_mut(self.pos.row)
- .expect("cursor not pointing to a cell")
+ // we assume self.pos.row is always valid
+ .unwrap_or_else(|| unreachable!())
}
pub fn visible_cell(&self, pos: Pos) -> Option<&crate::cell::Cell> {
@@ -209,7 +210,9 @@ impl Grid {
let mut prev_pos = Pos::default();
let mut wrapping = false;
for (i, row) in self.visible_rows().enumerate() {
- let i = i.try_into().unwrap();
+ // we limit the number of cols to a u16 (see Size), so
+ // visible_rows() can never return more rows than will fit
+ let i = i.try_into().unwrap_or_else(|_| unreachable!());
let (new_pos, new_attrs) = row.write_contents_formatted(
contents,
0,
@@ -245,7 +248,9 @@ impl Grid {
for (i, (row, prev_row)) in
self.visible_rows().zip(prev.visible_rows()).enumerate()
{
- let i = i.try_into().unwrap();
+ // we limit the number of cols to a u16 (see Size), so
+ // visible_rows() can never return more rows than will fit
+ let i = i.try_into().unwrap_or_else(|_| unreachable!());
let (new_pos, new_attrs) = row.write_contents_diff(
contents,
prev_row,
@@ -289,10 +294,23 @@ impl Grid {
row: self.pos.row,
col: self.size.cols - 1,
};
- if self.drawing_cell(pos).unwrap().is_wide_continuation() {
+ if self
+ .drawing_cell(pos)
+ // we assume self.pos.row is always valid, and self.size.cols
+ // - 1 is always a valid column
+ .unwrap_or_else(|| unreachable!())
+ .is_wide_continuation()
+ {
pos.col = self.size.cols - 2;
}
- let cell = self.drawing_cell(pos).unwrap();
+ let cell =
+ // we assume self.pos.row is always valid, and self.size.cols
+ // - 2 must be a valid column because self.size.cols - 1 is
+ // always valid and we just checked that the cell at
+ // self.size.cols - 1 is a wide continuation character, which
+ // means that the first half of the wide character must be
+ // before it
+ self.drawing_cell(pos).unwrap_or_else(|| unreachable!());
if cell.has_contents() {
if let Some(prev_pos) = prev_pos {
crate::term::MoveFromTo::new(prev_pos, pos)
@@ -316,11 +334,27 @@ impl Grid {
for i in (0..self.pos.row).rev() {
pos.row = i;
pos.col = self.size.cols - 1;
- if self.drawing_cell(pos).unwrap().is_wide_continuation()
+ if self
+ .drawing_cell(pos)
+ // i is always less than self.pos.row, which we assume
+ // to be always valid, so it must also be valid.
+ // self.size.cols - 1 is always a valid col.
+ .unwrap_or_else(|| unreachable!())
+ .is_wide_continuation()
{
pos.col = self.size.cols - 2;
}
- let cell = self.drawing_cell(pos).unwrap();
+ let cell = self
+ .drawing_cell(pos)
+ // i is always less than self.pos.row, which we assume
+ // to be always valid, so it must also be valid.
+ // self.size.cols - 2 is valid because self.size.cols
+ // - 1 is always valid, and col gets set to
+ // self.size.cols - 2 when the cell at self.size.cols
+ // - 1 is a wide continuation character, meaning that
+ // the first half of the wide character must be before
+ // it
+ .unwrap_or_else(|| unreachable!());
if cell.has_contents() {
if let Some(prev_pos) = prev_pos {
if prev_pos.row != i
@@ -379,7 +413,11 @@ impl Grid {
contents.push(b' ');
// we know that the cell has no contents, but it still may
// have drawing attributes (background color, etc)
- let end_cell = self.drawing_cell(pos).unwrap();
+ let end_cell = self
+ .drawing_cell(pos)
+ // we assume self.pos.row is always valid, and
+ // self.size.cols - 1 is always a valid column
+ .unwrap_or_else(|| unreachable!());
end_cell
.attrs()
.write_escape_code_diff(contents, &prev_attrs);
@@ -449,7 +487,13 @@ impl Grid {
let size = self.size;
let pos = self.pos;
let wide = pos.col < size.cols
- && self.drawing_cell(pos).unwrap().is_wide_continuation();
+ && self
+ .drawing_cell(pos)
+ // we assume self.pos.row is always valid, and we know we are
+ // not off the end of a row because we just checked pos.col <
+ // size.cols
+ .unwrap_or_else(|| unreachable!())
+ .is_wide_continuation();
let row = self.current_row_mut();
for _ in 0..count {
if wide {
@@ -486,7 +530,11 @@ impl Grid {
for _ in 0..count {
self.rows.remove(self.scroll_bottom as usize);
self.rows.insert(self.pos.row as usize, self.new_row());
- self.rows[self.scroll_bottom as usize].wrap(false);
+ self.rows
+ .get_mut(self.scroll_bottom as usize)
+ // self.scroll_bottom is maintained to always be a valid row
+ .unwrap_or_else(|| unreachable!())
+ .wrap(false);
}
}
@@ -520,7 +568,11 @@ impl Grid {
for _ in 0..count {
self.rows.remove(self.scroll_bottom as usize);
self.rows.insert(self.scroll_top as usize, self.new_row());
- self.rows[self.scroll_bottom as usize].wrap(false);
+ self.rows
+ .get_mut(self.scroll_bottom as usize)
+ // self.scroll_bottom is maintained to always be a valid row
+ .unwrap_or_else(|| unreachable!())
+ .wrap(false);
}
}
@@ -625,7 +677,10 @@ impl Grid {
prev_pos.row -= scrolled;
let new_pos = self.pos;
self.drawing_row_mut(prev_pos.row)
- .unwrap()
+ // we assume self.pos.row is always valid, and so prev_pos.row
+ // must be valid because it is always less than or equal to
+ // self.pos.row
+ .unwrap_or_else(|| unreachable!())
.wrap(wrap && prev_pos.row + 1 == new_pos.row);
}
}