shell_client 0.1.0

Rust进程调试工具,封装了与Unix域套接字通信、命令行自动补全、以及内置命令处理等功能。Client 可以连接到一个进程,发送自定义命令,并处理来自该进程的输出。实现了命令行读取、命令解析、进程查找、自动补全、命令执行等功能,并提供了一个循环来不断读取用户输入并执行相应的命令
Documentation
//! 支持自动完成的读取器,输入过程中使用tab可以出发自动完成
use crate::completer::ShellCompleter;
use core::time::Duration;
use linefeed::{terminal::DefaultTerminal, Interface, ReadResult};
use std::sync::{Arc, Mutex};
use std::thread::sleep;

/// 自动完成读取器
/// - interface 读取接口,见linefeed库
/// - completer 自动完成器
pub struct AutoCompleteReader {
    interface: Interface<DefaultTerminal>,
    completer: Arc<ShellCompleter>,
}

impl AutoCompleteReader {
    pub fn read(&self) -> Result<String, String> {
        sleep(Duration::from_millis(10));
        match self
            .interface
            .read_line()
            .map_err(|err| format!("read error : {}", err))?
        {
            ReadResult::Input(line) => {
                if !line.trim().is_empty() {
                    self.interface.add_history(line.clone());
                }
                Ok(line)
            }
            ReadResult::Eof => {
                Ok("".to_owned())
            }
            ReadResult::Signal(s) => {
                Err(format!("recv signal {:?}", s))
            }
        }
    }
    pub fn set_debug_command_complete_data(&mut self, data: Vec<(String, String)>) {
        self.completer.set_autocomplete_data(data);
    }
    pub fn append_debug_command_complete_data(&mut self, data: Vec<(String, String)>) {
        self.completer.append_complete_data(data);
    }
    pub fn set_prompt(&mut self, p: &str) {
        self.interface.set_prompt(p).expect("set prompt failed");
    }
}

/// 完成器的注册接口
#[macro_export]
macro_rules! reg_completer {
    ($($t:ty),*) => {
        vec![
            $(
            (
                <$t>::filter as fn(&str, &str) -> bool,
                <$t>::new(),
            ),
            )*
        ]
    };
}

impl AutoCompleteReader {
    /// 创建读取器
    pub fn new() -> Result<Arc<Mutex<Box<AutoCompleteReader>>>, String> {
        let mut ret = Box::<AutoCompleteReader>::new(AutoCompleteReader {
            interface: Interface::new("ushell-rust").expect("create interface failed"),
            completer: ShellCompleter::new(),
        });

        ret.set_prompt(">> ");
        ret.interface.set_completer(ret.completer.clone());

        Ok(Arc::new(Mutex::new(ret)))
    }
}