Master Domain Interaction Mode in Rust CLI with interactcli-rs

This article explains how interactcli-rs implements a domain‑specific interactive mode for command‑line programs, detailing the run function, the main parsing loop, prompt handling, history management, and configuration of rustyline, with full Rust code examples.

JD Cloud Developers
JD Cloud Developers
JD Cloud Developers
Master Domain Interaction Mode in Rust CLI with interactcli-rs

Basic Principle

interactcli-rs implements a domain interaction mode by continuously parsing each input line using rustyline, then delegating the line to a command‑parsing function for response logic.

Activating Domain Mode

When the -i flag is supplied, the library executes interact::run() (i.e., interact → cli → run).

pub fn run() {
    let config = Config::builder()
        .history_ignore_space(true)
        .completion_type(CompletionType::List)
        .output_stream(OutputStreamType::Stdout)
        .build();

    let h = MyHelper {
        completer: get_command_completer(),
        highlighter: MatchingBracketHighlighter::new(),
        hinter: HistoryHinter {},
        colored_prompt: "".to_owned(),
        validator: MatchingBracketValidator::new(),
    };

    let mut rl = Editor::with_config(config);
    rl.set_helper(Some(h));

    if rl.load_history("/tmp/history").is_err() {
        println!("No previous history.");
    }

    loop {
        let p = format!("{}> ", "interact-rs");
        rl.helper_mut().expect("No helper").colored_prompt =
            format!("\x1b[1;32m{}\x1b[0m", p);
        let readline = rl.readline(&p);
        match readline {
            Ok(line) => {
                if line.trim_start().is_empty() { continue; }
                rl.add_history_entry(line.as_str());
                match split(line.as_str()).as_mut() {
                    Ok(arg) => {
                        if arg[0] == "exit" {
                            println!("bye!");
                            break;
                        }
                        arg.insert(0, "clisample".to_string());
                        run_from(arg.to_vec())
                    }
                    Err(err) => {
                        println!("{}", err)
                    }
                }
            }
            Err(ReadlineError::Interrupted) => {
                println!("CTRL-C");
                break;
            }
            Err(ReadlineError::Eof) => {
                println!("CTRL-D");
                break;
            }
            Err(err) => {
                println!("Error: {:?}", err);
                break;
            }
        }
    }
    rl.append_history("/tmp/history")
        .map_err(|err| error!("{}", err))
        .ok();
}

Parsing Main Logic

Define a prompt (e.g., mysql>) to indicate the active program.

Read each input line and parse it.

Add the command to the history file so previous commands can be recalled with arrow keys.

Convert the line into an argument vector and pass it to cmd::run_from for execution.

Handle interruptions (Ctrl‑C, Ctrl‑D) by exiting gracefully.

Other Code in run

The function first builds a

rustyline
Config

that controls history behavior, completion type, and output stream.

let config = Config::builder()
    .history_ignore_space(true)
    .completion_type(CompletionType::List)
    .output_stream(OutputStreamType::Stdout)
    .build();

A MyHelper instance is created to provide autocomplete, bracket highlighting, and validation.

let h = MyHelper {
    completer: get_command_completer(),
    highlighter: MatchingBracketHighlighter::new(),
    hinter: HistoryHinter {},
    colored_prompt: "".to_owned(),
    validator: MatchingBracketValidator::new(),
};

Finally, the program configures a history file ( /tmp/history) so that command history persists across sessions.

rl.append_history("/tmp/history")
    .map_err(|err| error!("{}", err))
    .ok();

The article concludes by promising a future deep dive into the autocomplete implementation.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

CLIcommand-linerustylineinteractcli-rsinteractive mode
JD Cloud Developers
Written by

JD Cloud Developers

JD Cloud Developers (Developer of JD Technology) is a JD Technology Group platform offering technical sharing and communication for AI, cloud computing, IoT and related developers. It publishes JD product technical information, industry content, and tech event news. Embrace technology and partner with developers to envision the future.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.