mod window_cursor;
mod window_cursor_2d;
use anyhow::{Result, bail};
pub use window_cursor::WindowCursor;
pub use window_cursor_2d::{CursorMoveHandler, Position, WindowCursor2D};
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Cursor {
position: usize,
size: usize,
}
impl Cursor {
pub fn new(size: usize) -> Self {
Cursor { position: 0, size }
}
pub fn end(&self) -> usize {
self.size.saturating_sub(1)
}
pub fn set_position(&mut self, pos: usize) {
if pos <= self.end() {
self.position = pos;
} else {
self.position = self.end();
}
}
pub fn set_size(&mut self, size: usize) -> Result<()> {
if size == 0 {
bail!("Size cannot be zero");
}
self.size = size;
if self.position > self.end() {
self.position = self.end();
}
Ok(())
}
pub fn move_forward(&mut self, steps: usize) {
if self.position + steps <= self.end() {
self.position += steps;
} else {
self.position = self.end();
}
}
pub fn move_backward(&mut self, steps: usize) {
if self.position >= steps {
self.position -= steps;
} else {
self.position = 0;
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_cursor_set_position() {
let mut cursor = Cursor::new(10);
cursor.set_position(5);
assert_eq!(cursor.position, 5);
cursor.set_position(15);
assert_eq!(cursor.position, 9);
}
#[test]
fn test_cursor_move_forward() {
let mut cursor = Cursor::new(10);
assert_eq!(cursor.position, 0);
cursor.move_forward(3);
assert_eq!(cursor.position, 3);
cursor.move_forward(10);
assert_eq!(cursor.position, 9);
}
#[test]
fn test_cursor_move_backward() {
let mut cursor = Cursor::new(10);
cursor.move_backward(3);
assert_eq!(cursor.position, 0);
cursor.move_forward(5);
assert_eq!(cursor.position, 5);
cursor.move_backward(3);
assert_eq!(cursor.position, 2);
cursor.move_backward(3);
assert_eq!(cursor.position, 0);
}
#[test]
fn test_cursor_size_zero_handling() {
let cursor = Cursor::new(0);
assert_eq!(cursor.end(), 0);
let mut cursor = Cursor::new(0);
cursor.move_forward(1);
assert_eq!(cursor.position, 0);
cursor.move_backward(1);
assert_eq!(cursor.position, 0);
}
#[test]
fn test_cursor_size_one() {
let mut cursor = Cursor::new(1);
assert_eq!(cursor.end(), 0);
cursor.move_forward(1);
assert_eq!(cursor.position, 0);
}
}