rm-lisa 0.3.2

A logging library for rem-verse, with support for inputs, tasks, and more.
Documentation
//! Handle receiving input from somewhere, and use it to produce strings
//! somewhere else.
//!
//! NOTE: Inputs do not actually have to come from STDIN. They can come from
//! anywhere, e.g. a server listening on a unix socket. Of course accepting
//! commands from remote places that aren't on STDIN could introduce security
//! concerns, that's for you to deal with, but is possible.
//!
//! Input Providers also _are not in charge_ of rendering inputs, and should
//! _hide_ any input that users are putting in. They should instead keep a
//! buffer of the current input string, and pass it the display when asked for.
//! The display will then render the command however it sees fit.

pub mod autocomplete;
pub mod history;
pub mod stdin;

use crate::{
	errors::LisaError,
	input::{autocomplete::AutocompleteProvider, history::HistoryProvider},
};

/// An input provider is something that is capable of receiving input from
/// users, holding it, and producing a value to some console at some point
/// in time.
///
/// The input providers job is to provide input events to displays (and
/// potentially others) and keep state of the current input.
pub trait InputProvider: Send + Sync {
	/// If this input is coming from STDIN, and as such an input
	/// display should be rendered.
	#[must_use]
	fn is_stdin(&self) -> bool;

	/// If the input provider is active, and accepting input.
	#[must_use]
	fn is_active(&self) -> bool;
	/// Set this terminal as 'active'.
	///
	/// ## Errors
	///
	/// If the underlying provider cannot do what it needs to be made active.
	fn set_active(&mut self, active: bool) -> Result<(), LisaError>;

	/// If this provider has some active input, and someone is actively
	/// 'typing'.
	#[must_use]
	fn input_in_progress(&self) -> bool;
	/// Get any current input that has been provided.
	#[must_use]
	fn current_input(&self) -> String;
	/// Poll for any active input events.
	#[must_use]
	fn poll_for_input(&mut self, ansi_supported: bool) -> Vec<TerminalInputEvent>;

	/// Set the current autocomplete provider for this input provider.
	fn set_autocomplete_provider(&mut self, autocomplete: Box<dyn AutocompleteProvider>);
	/// Get the current autocomplete suggestion.
	#[must_use]
	fn current_autocomplete_suggestion(&self) -> Option<String>;
	/// If an autocomplete suggestion is pending, but not yet completed.
	#[must_use]
	fn autocomplete_suggestion_pending(&self) -> bool;

	/// Set the current history provider.
	fn set_history_provider(&mut self, history: Box<dyn HistoryProvider>);
	/// Get the current history search value that is being found.
	#[must_use]
	fn current_history_search_value(&self) -> Option<String>;
	// If we're actively doing a history search.
	#[must_use]
	fn is_doing_history_search(&self) -> bool;

	/// Get any fully complete inputs that have occured since things last ran.
	#[must_use]
	fn inputs(&mut self) -> Vec<String>;
}

/// A terminal input event has occured.
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum TerminalInputEvent {
	/// Clear the screen if the renderer supports this.
	ClearScreen,
	/// Input has been cancelled.
	InputCancelled,
	/// The input has had text appended to the end of it.
	///
	/// This will only ever be fired when a user has typed/pasted text at the end
	/// of the line (e.g. not in the midddle).
	InputAppend(char),
	/// A lot of inputs have been appended all at once.
	InputMassAppend(String),
	/// The input has changed in a way that wasn't an append.
	///
	/// A character has been removed, text has been pasted in the middle, etc.
	InputChanged(usize),
	/// The input has finished being applied.
	InputFinished,
	/// Input has started being input by the user.
	InputStarted,
	/// Cursor goes ahead and moves left 'backwards' through the input N spaces.
	CursorMoveLeft(usize),
	/// Cursor goes ahead and moves right 'forwards' through the input N spaces.
	CursorMoveRight(usize),
	/// Toggle pausing or un-pausing STDOUT/STDERR.
	ToggleOutputPause,
}