Rusty-tui 0.1.0

A simple TUI library for making CLI applications with ease.
Documentation
// inputBox.rs

use std::io::{self, Read, Write}; // Importing necessary modules for input/output operations

/// A structure representing an input box that allows the user to enter text.
pub struct InputBox {
    pub input: String,       // The text entered by the user
    pub placeholder: String, // A placeholder text to display when input is empty
    pub x: u16, // The x-coordinate (horizontal position) where the input box will be drawn
    pub y: u16, // The y-coordinate (vertical position) where the input box will be drawn
}

impl InputBox {
    /// Creates a new InputBox instance.
    ///
    /// # Arguments
    ///
    /// * `input` - A string slice that holds the initial text of the input box.
    /// * `placeholder` - A string slice that holds the placeholder text to display.
    /// * `x` - The horizontal position (x-coordinate) where the input box will be drawn.
    /// * `y` - The vertical position (y-coordinate) where the input box will be drawn.
    ///
    /// # Returns
    ///
    /// A new instance of `InputBox`.
    pub fn new(input: &str, placeholder: &str, x: u16, y: u16) -> Self {
        InputBox {
            input: input.to_string(), // Convert the input string slice into a String
            placeholder: placeholder.to_string(), // Convert the placeholder string slice into a String
            x,                                    // Set the x-coordinate
            y,                                    // Set the y-coordinate
        }
    }

    /// Retrieves input from the user and updates the input box.
    ///
    /// This function displays the input box at the specified position and handles user input,
    /// including entering characters and using the backspace key.
    ///
    /// # Returns
    ///
    /// An `io::Result<String>` that contains the input entered by the user or an error if
    /// the read operation fails.
    ///
    /// # Example
    ///
    /// ```
    /// let mut input_box = InputBox::new("", "Enter text here", 5, 10);
    /// let user_input = input_box.get_input().unwrap(); // Gets user input
    /// ```
    pub fn get_input(&mut self) -> io::Result<String> {
        let mut stdout = io::stdout(); // Handle to standard output
        let mut stdin = io::stdin(); // Handle to standard input

        // Move the cursor to the specified (x, y) position
        print!("\x1B[{};{}H", self.y + 1, self.x + 1);
        stdout.flush()?;

        // Display the placeholder if input is empty
        if self.input.is_empty() {
            print!("{}", self.placeholder);
        } else {
            print!("{}", self.input);
        }
        stdout.flush()?;

        // Read input from the user
        let mut buffer = [0; 1]; // Buffer to hold a single byte of input
        loop {
            stdin.read_exact(&mut buffer)?; // Read a single byte
            match buffer[0] {
                b'\n' => break, // Break the loop on Enter key
                b'\x08' | b'\x7F' => {
                    // Handle Backspace key (ASCII codes for backspace)
                    if !self.input.is_empty() {
                        self.input.pop(); // Remove last character from input
                                          // Move cursor back and clear the character
                        print!("\x1B[1D \x1B[1D"); // Move cursor left and overwrite with space
                    }
                }
                c => {
                    self.input.push(c as char); // Append character to input
                    print!("{}", c as char); // Print the character
                }
            }
            stdout.flush()?; // Flush the output to display the input in real-time
        }

        Ok(self.input.clone()) // Return the input string
    }
}