rm-lisa 0.3.2

A logging library for rem-verse, with support for inputs, tasks, and more.
Documentation
use rm_lisa::{
	initialize_logging,
	input::{
		InputProvider, autocomplete::AutocompleteProvider, history::SimpleHistoryProvider,
		stdin::StdinInputProvider,
	},
};
use std::time::Duration;
use tokio::{signal::ctrl_c, sync::mpsc::channel, time::sleep as async_sleep};
use tracing::info;

#[tokio::main]
pub async fn main() {
	let (sender, mut receiver) = channel(8);
	let history_provider = SimpleHistoryProvider::new_in_memory(256);
	let console = initialize_logging("input").expect("Failed to initialize logging!");

	let mut iprovider = StdinInputProvider::new("input").expect("Failed to load input provider!");
	iprovider.set_autocomplete_provider(Box::new(SimpleAutocompleteSuggestionProvider));
	iprovider.set_history_provider(Box::new(history_provider));
	iprovider.set_newline_hook(Box::new(|data: &str| -> bool {
		data.chars().filter(|character| *character == '(').count()
			== data.chars().filter(|character| *character == ')').count()
	}));
	console.set_input_provider(iprovider);
	console.set_input_channel(sender);

	console
		.set_input_active(true)
		.expect("Failed to mark input active!");

	loop {
		if let Ok(input) = receiver.try_recv() {
			info!(from = "command", "{}", input);
		}

		info!(from = "timer", "Sample other log!");
		tokio::select! {
			_ = async_sleep(Duration::from_secs(1)) => {}
			_ = ctrl_c() => {
				break;
			}
		}
	}

	console.flush().await;
}

const AC_SUGGESTIONS: &[&str] = &[
	"this is a very long message that can be used to demonstrate that autocomplete messages can wrap around multiple lines this is really just a test for rendering, but you know maybe you'll really want to type all this out just to prove to me that it's for more than that. who am i to tell you otherwise after all? i'm just some non-sentient example program that's here to remind you to drink water. I hope you are drinking water. YOU BETTER BE OR IM GONNA LOSE IT. Not really, i'm just a program. I won't segfault I promise. Unless the developer messed something up which is possible I guess. Anyone can cause bugs at anytime, unless you're hatsune miku. If you are hatsune miku..... what's up?",
	"cos sdkversion",
	"autocomplete short",
	"autocomplete shorter",
];

struct SimpleAutocompleteSuggestionProvider;

impl AutocompleteProvider for SimpleAutocompleteSuggestionProvider {
	fn can_autocomplete(&self) -> bool {
		true
	}

	fn get_displayable_suggestion(&self, current_input: String) -> Option<String> {
		self.get_tab_completion(None, &current_input)
	}

	fn get_tab_completion(
		&self,
		last_completion_index: Option<usize>,
		input: &str,
	) -> Option<String> {
		let to_ignore_count = last_completion_index.map(|val| val + 1).unwrap_or_default();
		let mut ignored = 0_usize;
		for suggestion in AC_SUGGESTIONS {
			if input.len() >= suggestion.len() {
				continue;
			}

			if suggestion.starts_with(input) {
				if ignored >= to_ignore_count {
					return Some(suggestion[input.len()..].to_owned());
				} else {
					ignored += 1;
				}
			}
		}

		None
	}
}