rm-lisa 0.3.2

A logging library for rem-verse, with support for inputs, tasks, and more.
Documentation
//! The active processing state for the standard input.
//!
//! This is where all the 'logic' of standard input processing goes, what
//! actually keeps buffers of input around, and is responsible for updating
//! them, and keeping them in actual sync.
//!
//! ## Rough Overview ##
//!
//! This is a large file that handles the actual logic of reading things
//! out of standard in. Think of this all like the state machine that our
//! [`crate::input::stdin::StdinInputProvider`] can turn into a series of
//! events that a renderer can handle.
//!
//! Our state machine comes in the flavor of three structs (though not all
//! are exported for public use). These are:
//!
//! 1. [`StdinInputState`]: A global wrapper around the underlying input state,
//!    provides some methods for querying the current input, but mostly is just
//!    a thin 'Read-Write Lock' style interface. Can provide safe concurrent
//!    access to the current state.
//! 2. [`self::transaction::ProcessingInputState`]: Effectively a 'write lock' handle to the
//!    current input state. The idea is you'd call [`StdinInputState::process`]
//!    anytime you get input from a read call or otherwise, and then call
//!    methods on processing input state, before finally dropping the write
//!    lock (there is certain state that is kept for one set of inputs).
//! 3. [`self::raw::UnlockedStdinInputState`]: The actual 'state'.
//!
//! ## Notes ##
//!
//! As of v0.1.0 most of the methods have some strange-ish return types. These
//! were mostly built to quickly be used by the input provider and it's quickly
//! written internals. Read the documentation for functions on what they
//! return. In the future we hope to actually make the method return types and
//! interacting with these structures easier for non input providers.

mod raw;
pub mod transaction;

use crate::input::stdin::state::{
	raw::UnlockedStdinInputState, transaction::InputStateTransaction,
};

/// A 'read-write' lock style type around the actual state of what has been
/// received over standard input.
///
/// All methods take a read lock to get info (such as if input has started),
/// except [`StdinInputState::process`] which returns effectively a write
/// lock to the state.
#[derive(Debug)]
pub struct StdinInputState {
	/// The actual underlying state, hidden behind a `RwLock` for thread safety.
	underlying: UnlockedStdinInputState,
}

impl StdinInputState {
	/// Construct a new locked state machine for stdin.
	#[must_use]
	pub fn new() -> Self {
		Self {
			underlying: UnlockedStdinInputState::new(),
		}
	}

	/// Check if stdin has actively started being typed on.
	#[must_use]
	pub fn started(&self) -> bool {
		self.underlying.started()
	}

	/// Get a reference to the underlying input (what has actively been typed,
	/// or accepted by the user).
	#[must_use]
	pub fn input(&self) -> String {
		self.underlying.buffer().to_string()
	}

	/// Get the current cursor position in terms of characters.
	///
	/// E.g. '1' means we are right after the first character that is typed
	/// regardless of how many bytes that character is.
	#[must_use]
	pub fn cursor_position(&self) -> usize {
		self.underlying.cursor_position()
	}

	/// Check if an autocomplete suggestion is pending.
	#[must_use]
	pub fn autocomplete_pending(&self) -> bool {
		self.underlying.autocompleted_buffer().is_some()
	}

	/// Get the current history search value.
	#[must_use]
	pub fn current_history_search_value(&self) -> Option<String> {
		self.underlying
			.history_search_buffer()
			.map(ToOwned::to_owned)
	}

	/// If we're actively doing a history search.
	#[must_use]
	pub fn is_doing_history_search(&self) -> bool {
		self.underlying.in_history_search()
	}

	/// Start modifying our input, represents 'one processing' call.
	#[must_use]
	pub fn process(&mut self) -> InputStateTransaction<'_> {
		InputStateTransaction::new(&mut self.underlying)
	}
}