reactive_graph/client/repl/
repl_helper.rs1use std::borrow::Cow;
2
3use clap::Parser;
4use colored::Colorize;
5use rustyline::Context;
6use rustyline::Helper;
7use rustyline::Result;
8use rustyline::completion::Completer;
9use rustyline::highlight::Highlighter;
10use rustyline::hint::Hinter;
11use rustyline::validate::ValidationContext;
12use rustyline::validate::ValidationResult;
13use rustyline::validate::Validator;
14use shellwords::split;
15
16use crate::client::repl::args::ReplArgs;
17use crate::client::repl::hint::HinterMatch;
18
19pub struct ReplHelper {}
20
21impl ReplHelper {
22 pub fn new() -> Self {
23 Self {}
24 }
25}
26
27impl Completer for ReplHelper {
28 type Candidate = &'static str;
29}
30
31impl Highlighter for ReplHelper {
32 fn highlight_hint<'h>(&self, hint: &'h str) -> Cow<'h, str> {
33 Cow::Owned(hint.cyan().to_string())
34 }
35}
36
37impl Validator for ReplHelper {
38 fn validate(&self, _: &mut ValidationContext) -> Result<ValidationResult> {
39 Ok(ValidationResult::Valid(None))
40 }
41}
42
43impl Hinter for ReplHelper {
44 type Hint = HinterMatch;
45
46 fn hint(&self, line: &str, _pos: usize, _ctx: &Context<'_>) -> Option<Self::Hint> {
47 let Ok(args) = split(line).map(|mut args| {
48 args.insert(0, String::from(" "));
49 args
50 }) else {
51 return None;
52 };
53 let hinter_match = match ReplArgs::try_parse_from(args.clone()) {
54 Ok(command) => HinterMatch::new_from_args_and_command(args, command),
55 Err(error) => HinterMatch::new_from_args_and_error(args, error),
56 };
57 Some(hinter_match)
58 }
59}
60
61impl Helper for ReplHelper {}