rpos 0.4.0

Cursor Manager on Table
Documentation

rpos

Crates.io License: MIT

A cursor manager on table for Rust.

Overview

rpos provides a simple and intuitive way to manage cursor position on a 2D table. The cursor can navigate within the table using directional movements (up, down, left, right) or by setting specific positions. By default, movement wraps at edges, and clamp mode can be enabled when needed. Tables support both uniform (rectangular) and jagged (non-uniform) rows where each row can have a different number of columns.

Installation

Add this to your Cargo.toml:

[dependencies]
rpos = "0.3.1"

Usage

Creating a Table with Cursor

use rpos::table::Table;

fn main() {
    // Create a 3x4 table (height=3, width=4)
    let mut table = Table::new(3, 4).unwrap();
    
    // Get current cursor position (0-indexed)
    assert_eq!(table.cursor.current(), (0, 0));
}

Moving the Cursor

use rpos::table::Table;

fn main() {
    let mut table = Table::new(3, 4).unwrap();

    // Move cursor down
    table.cursor.down();
    assert_eq!(table.cursor.current(), (1, 0));

    // Move cursor right
    table.cursor.right();
    assert_eq!(table.cursor.current(), (1, 1));

    // Move cursor up
    table.cursor.up();
    assert_eq!(table.cursor.current(), (0, 1));

    // Move cursor left
    table.cursor.left();
    assert_eq!(table.cursor.current(), (0, 0));
}

Setting Cursor Position

use rpos::table::Table;

fn main() {
    let mut table = Table::new(3, 4).unwrap();

    // Set cursor to specific position (line, column)
    table.cursor.set(2, 3).unwrap();
    assert_eq!(table.cursor.current(), (2, 3));

    // Set only the line
    table.cursor.set_line(1).unwrap();
    assert_eq!(table.cursor.current(), (1, 3));

    // Set only the column
    table.cursor.set_column(0).unwrap();
    assert_eq!(table.cursor.current(), (1, 0));
}

Wraparound Movement

Wrap mode is the default and wraps around table edges when moving:

use rpos::table::Table;

fn main() {
    let mut table = Table::new(3, 4).unwrap();

    // Cursor wraps around edges
    table.cursor.up(); // From top row, wraps to bottom row
    table.cursor.left(); // From left edge, wraps to right edge
    assert_eq!(table.cursor.current(), (2, 3));

    // Setting out-of-bounds position returns an error
    let result = table.cursor.set(10, 10);
    assert!(result.is_err());
}

Clamp Mode

Clamp mode keeps the cursor at the table edges:

use rpos::{table::Table, WrapMode};

fn main() {
    let mut table = Table::new(3, 4).unwrap();

    table.cursor.set(0, 0).unwrap();
    table.cursor.up();
    table.cursor.left();
    assert_eq!(table.cursor.current(), (0, 0));
}

Jagged (Non-Uniform) Tables

Tables can have rows with different column counts. When moving to a row with fewer columns, the column is automatically clamped to the last valid position:

use rpos::table::Table;

fn main() {
    // Row 0: 4 columns, Row 1: 2 columns, Row 2: 3 columns
    let mut table = Table::new_jagged(vec![4, 2, 3]).unwrap();

    table.cursor.set(0, 3).unwrap(); // column 3 on row 0
    assert_eq!(table.cursor.current(), (0, 3));

    table.cursor.down(); // move to row 1 (only 2 columns)
    assert_eq!(table.cursor.current(), (1, 1)); // column clamped to 1

    table.cursor.down(); // move to row 2 (3 columns)
    assert_eq!(table.cursor.current(), (2, 1)); // column stays at 1

    // Left/right movement uses the current row's width
    table.cursor.set(1, 0).unwrap();
    table.cursor.right();
    assert_eq!(table.cursor.current(), (1, 1)); // row 1 max
    table.cursor.right(); // wraps within row 1
    assert_eq!(table.cursor.current(), (1, 0));
}

API Reference

Table

Method Description
Table::new(height, width) Creates a new table with specified dimensions
Table::new_jagged(widths) Creates a jagged table with per-row column widths
table.wrap_mode(mode) Sets wrap mode (builder pattern, chainable after new / new_jagged)

WrapMode

Variant Description
WrapMode::Wrap Wraps cursor movement at table edges
WrapMode::Clamp Clamps cursor movement at table edges

Cursor

Method Description
current() Returns current position as (line, column)
set(line, column) Sets cursor to specific position
set_line(line) Sets cursor line (row), clamping column if needed
set_column(column) Sets cursor column
wrap_mode() Returns current wrap mode
set_wrap_mode(wrap_mode) Sets wrap mode for movement
up() Moves cursor up one position
down() Moves cursor down one position
left() Moves cursor left one position
right() Moves cursor right one position

License

MIT License - see LICENSE for details.