use super::imiop::{self, Imiop};
use crate::config::Config;
use crate::shell::{Shell, ShellState};
use crate::translator::ioprocessor::IOProcessor;
use crate::translator::lang::Language;
use crate::translator::new_translator;
use crate::utils::console::InputEvent;
pub(super) struct RuntimeProps {
pub config: Config,
language: Language,
last_state: ShellState,
state_changed: bool,
imiop: Box<dyn Imiop>,
}
impl RuntimeProps {
pub(super) fn new(interactive: bool, config: Config, language: Language) -> RuntimeProps {
RuntimeProps {
config: config.clone(),
language: language,
last_state: ShellState::Unknown,
state_changed: true,
imiop: RuntimeProps::init_imiop(interactive, &config, language),
}
}
pub(super) fn get_last_state(&self) -> ShellState {
self.last_state
}
pub(super) fn get_state_changed(&self) -> bool {
self.state_changed
}
pub(super) fn update_state(&mut self, new_state: ShellState) {
self.last_state = new_state;
self.state_changed = true;
}
pub(super) fn report_state_changed_notified(&mut self) {
self.state_changed = false;
}
pub(super) fn handle_input_event(&mut self, ev: InputEvent, shell: &mut Shell) {
self.switch_imiop();
self.imiop.handle_input_event(ev, shell);
}
fn init_imiop(interactive: bool, config: &Config, language: Language) -> Box<dyn Imiop> {
match interactive {
true => Box::new(imiop::shiop::ShIop::new(
config.clone(),
IOProcessor::new(language, new_translator(language)),
)),
false => Box::new(imiop::subprociop::SubProcIop::new(
config.clone(),
IOProcessor::new(language, new_translator(language)),
)),
}
}
fn switch_imiop(&mut self) {
if self.get_state_changed() {
self.imiop = match self.get_last_state() {
ShellState::Shell => Box::new(imiop::shiop::ShIop::new(
self.config.clone(),
IOProcessor::new(self.language, new_translator(self.language)),
)),
ShellState::SubprocessRunning => Box::new(imiop::subprociop::SubProcIop::new(
self.config.clone(),
IOProcessor::new(self.language, new_translator(self.language)),
)),
_ => Box::new(imiop::shiop::ShIop::new(
self.config.clone(),
IOProcessor::new(self.language, new_translator(self.language)),
)),
};
self.report_state_changed_notified();
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::config::Config;
use crate::translator::lang::Language;
use std::thread::sleep;
use std::time::Duration;
#[test]
fn test_runtimeprops_new() {
let props: RuntimeProps = new_runtime_props(true);
assert!(props.config.get_alias(&String::from("ll")).is_none());
assert_eq!(props.language, Language::Russian);
assert_eq!(props.last_state, ShellState::Unknown);
assert_eq!(props.state_changed, true);
}
#[test]
fn test_runtimeprops_update_state() {
let mut props: RuntimeProps = new_runtime_props(true);
assert_eq!(props.get_last_state(), ShellState::Unknown);
assert_eq!(props.get_state_changed(), true);
props.report_state_changed_notified();
assert_eq!(props.get_state_changed(), false);
props.update_state(ShellState::Shell);
assert_eq!(props.get_last_state(), ShellState::Shell);
assert_eq!(props.get_state_changed(), true);
}
#[test]
fn test_runtimeprops_switch_imiop() {
let mut props: RuntimeProps = new_runtime_props(true);
props.state_changed = false;
props.last_state = ShellState::Shell;
props.switch_imiop();
props.state_changed = true;
props.last_state = ShellState::SubprocessRunning;
props.switch_imiop();
props.state_changed = true;
props.last_state = ShellState::Shell;
props.switch_imiop();
props.state_changed = true;
props.last_state = ShellState::Unknown;
props.switch_imiop();
}
#[test]
fn test_runtimeprops_handle_input_event() {
let mut props: RuntimeProps = new_runtime_props(true);
let config: Config = Config::default();
let mut shell: Shell = Shell::start(
String::from("sh"),
Vec::new(),
&config.prompt_config,
)
.unwrap();
sleep(Duration::from_millis(500)); props.handle_input_event(InputEvent::Enter, &mut shell);
props.handle_input_event(InputEvent::Ctrl(3), &mut shell);
sleep(Duration::from_millis(500)); let _ = shell.stop();
sleep(Duration::from_millis(500)); }
#[test]
fn test_runtimeprops_handle_input_event_not_interactive() {
let mut props: RuntimeProps = new_runtime_props(false);
let config: Config = Config::default();
let mut shell: Shell = Shell::start(
String::from("sh"),
Vec::new(),
&config.prompt_config,
)
.unwrap();
sleep(Duration::from_millis(500)); props.handle_input_event(InputEvent::Enter, &mut shell);
props.handle_input_event(InputEvent::Ctrl(3), &mut shell);
sleep(Duration::from_millis(500)); let _ = shell.stop();
sleep(Duration::from_millis(500)); }
fn new_runtime_props(interactive: bool) -> RuntimeProps {
RuntimeProps::new(interactive, Config::default(), Language::Russian)
}
}