bettertui_engine 0.1.1

High-performance terminal UI framework
Documentation
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct CursorPosition {
    pub line: usize,
    pub column: usize,
}

impl CursorPosition {
    pub fn new(line: usize, column: usize) -> Self {
        Self { line, column }
    }

    pub fn zero() -> Self {
        Self { line: 0, column: 0 }
    }
}

impl Default for CursorPosition {
    fn default() -> Self {
        Self::zero()
    }
}

#[derive(Debug, Clone)]
pub struct Cursor {
    position: usize,
    line: usize,
    column: usize,
    desired_column: usize,
}

impl Default for Cursor {
    fn default() -> Self {
        Self::new()
    }
}

impl Cursor {
    pub fn new() -> Self {
        Self { position: 0, line: 0, column: 0, desired_column: 0 }
    }

    pub fn position(&self) -> usize {
        self.position
    }

    pub fn set_position(&mut self, pos: usize) {
        self.position = pos;
    }

    pub fn line(&self) -> usize {
        self.line
    }

    pub fn set_line(&mut self, line: usize) {
        self.line = line;
    }

    pub fn column(&self) -> usize {
        self.column
    }

    pub fn set_column(&mut self, column: usize) {
        self.column = column;
        self.desired_column = column;
    }

    pub fn cursor_position(&self) -> CursorPosition {
        CursorPosition::new(self.line, self.column)
    }

    pub fn move_left(&mut self) {
        if self.position > 0 {
            self.position -= 1;
            if self.column > 0 {
                self.column -= 1;
            }
        }
    }

    pub fn move_right(&mut self) {
        self.position += 1;
        self.column += 1;
    }

    pub fn move_left_by(&mut self, count: usize) {
        for _ in 0..count {
            self.move_left();
        }
    }

    pub fn move_right_by(&mut self, count: usize) {
        for _ in 0..count {
            self.move_right();
        }
    }

    pub fn move_up(&mut self, line_length: usize) {
        if self.line > 0 {
            self.line -= 1;
            self.column = self.desired_column;
            self.position -= line_length;
        }
    }

    pub fn move_down(&mut self, line_length: usize) {
        self.line += 1;
        self.column = self.desired_column;
        self.position += line_length;
    }

    pub fn move_to_start(&mut self) {
        self.position = 0;
        self.line = 0;
        self.column = 0;
        self.desired_column = 0;
    }

    pub fn move_to_end(&mut self, total_length: usize) {
        self.position = total_length;
        self.column = total_length;
        self.desired_column = total_length;
    }

    pub fn reset(&mut self) {
        self.position = 0;
        self.line = 0;
        self.column = 0;
        self.desired_column = 0;
    }

    pub fn is_at_start(&self) -> bool {
        self.position == 0
    }

    pub fn is_at_end(&self, total_length: usize) -> bool {
        self.position >= total_length
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn cursor_new() {
        let cursor = Cursor::new();
        assert_eq!(cursor.position(), 0);
    }

    #[test]
    fn cursor_default() {
        let cursor = Cursor::default();
        assert_eq!(cursor.position(), 0);
    }

    #[test]
    fn cursor_move_left() {
        let mut cursor = Cursor::new();
        cursor.move_right();
        cursor.move_left();
        assert_eq!(cursor.position(), 0);
    }

    #[test]
    fn cursor_move_right() {
        let mut cursor = Cursor::new();
        cursor.move_right();
        assert_eq!(cursor.position(), 1);
    }

    #[test]
    fn cursor_move_to_start() {
        let mut cursor = Cursor::new();
        cursor.move_right();
        cursor.move_right();
        cursor.move_to_start();
        assert_eq!(cursor.position(), 0);
    }

    #[test]
    fn cursor_move_to_end() {
        let mut cursor = Cursor::new();
        cursor.move_to_end(10);
        assert_eq!(cursor.position(), 10);
    }

    #[test]
    fn cursor_is_at_start() {
        let cursor = Cursor::new();
        assert!(cursor.is_at_start());
    }

    #[test]
    fn cursor_is_at_end() {
        let mut cursor = Cursor::new();
        cursor.move_to_end(10);
        assert!(cursor.is_at_end(10));
    }

    #[test]
    fn cursor_position_new() {
        let pos = CursorPosition::new(5, 10);
        assert_eq!(pos.line, 5);
        assert_eq!(pos.column, 10);
    }

    #[test]
    fn cursor_position_zero() {
        let pos = CursorPosition::zero();
        assert_eq!(pos.line, 0);
        assert_eq!(pos.column, 0);
    }
}