New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(buffer): add Buffer::get_opt, get_mut_opt and index implementations #1084
base: main
Are you sure you want to change the base?
Conversation
Code which previously called `buf.get(x, y)` or `buf.get_mut(x, y)` can now use index operators, or be transitioned to `buf_get_opt` or `buf.get_mut_opt` for safe access that avoids panics. The new methods accept `Into<Position>` instead of `x` and `y` coordinates, which makes them more ergonomic to use. ```rust let mut buffer = Buffer::empty(Rect::new(0, 0, 10, 10)); let cell = buf[(0, 0)]; let cell = buf[Position::new(0, 0)]; let symbol = buf.get_opt((0, 0)).map(|cell| cell.symbol()); let symbol = buf.get_opt(Position::new(0, 0)).map(|cell| cell.symbol()); buf[(0, 0)].set_symbol("🐀"); buf[Position::new(0, 0)].set_symbol("🐀"); buf.get_mut_opt((0, 0)).map(|cell| cell.set_symbol("🐀")); buf.get_mut_opt(Position::new(0, 0)).map(|cell| cell.set_symbol("🐀")); ```
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #1084 +/- ##
=======================================
- Coverage 94.3% 94.2% -0.1%
=======================================
Files 61 61
Lines 14771 14826 +55
=======================================
+ Hits 13930 13977 +47
- Misses 841 849 +8 ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason why this was not done with pos_of
too?
Lines 241 to 250 in 30a6fb2
pub const fn pos_of_opt(&self, i: usize) -> Option<(u16, u16)> { | |
if i < self.area.area() as usize { | |
Some(( | |
self.area.x + (i as u16) % self.area.width, | |
self.area.y + (i as u16) / self.area.width, | |
)) | |
} else { | |
None | |
} | |
} |
@@ -370,6 +449,52 @@ impl Buffer { | |||
} | |||
} | |||
|
|||
impl<P: Into<Position>> Index<P> for Buffer { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Increase readability by clarifying what exactly is implemented here inline. When first reading this I thought there is yet another ratatui trait. (same for IndexMut
)
impl<P: Into<Position>> Index<P> for Buffer { | |
impl<P: Into<Position>> std::ops::Index<P> for Buffer { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed this back to just Index as the trait has to be in scope for links to a trait defined method in a doc comment to resolve correctly.
I don't think |
This looks good to me but maybe we can get more reviewers on this? PR title + description should be updated. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the usage of the Index trait. It is still panicking like before but should have the same performance.
src/buffer/buffer.rs
Outdated
/// | ||
/// Returns `None` if the index is out of bounds. | ||
/// | ||
/// Note that unlike `get`, this method accepts a `Position` instead of `x` and `y` coordinates. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure whether I would keep this comment… either Index is used or cell. The latter has easy viewable documentation, so this comment doesn't provide much use. It would be more useful on using the index but documenting it is harder there 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replacing this with some better docs in the next commit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// Returns `None` if the given coordinates are outside of the Buffer's area. | ||
/// | ||
/// Note that this is private because of <https://github.com/ratatui-org/ratatui/issues/1122> | ||
const fn index_of_opt(&self, x: u16, y: u16) -> Option<usize> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This and other methods here could get a #[must_use]
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
area
and content
also look like must_use candidates… Guess we should get that lint enabled for the full repo
Co-authored-by: EdJoPaTo <rfc-conform-git-commit-email@funny-long-domain-label-everyone-hates-as-it-is-too-long.edjopato.de>
I actually intended to put the deprecation of the existing methods in #1123, but accidentally pushed the commit to this PR. Happy to do it either way (though it would be easier at this point to just keep it in this PR and update the main PR comment. |
Code which previously called
buf.get(x, y)
orbuf.get_mut(x, y)
cannow use index operators, or be transitioned to
buf_get_opt
orbuf.get_mut_opt
for safe access that avoids panics.The new methods accept
Into<Position>
instead ofx
andy
coordinates, which makes them more ergonomic to use.
Partially addresses #1011