Skip to main content

## Module repl_derive

Source
Available on crate feature `unstable-doc` only.
Expand description

## §Example: REPL (Derive API)

    use std::io::Write;

    use clap::{Parser, Subcommand};

    fn main() -> Result<(), String> {
        loop {
            let line = readline()?;
            let line = line.trim();
            if line.is_empty() {
                continue;
            }

            match respond(line) {
                Ok(quit) => {
                    if quit {
                        break;
                    }
                }
                Err(err) => {
                    write!(std::io::stdout(), "{err}").map_err(|e| e.to_string())?;
                    std::io::stdout().flush().map_err(|e| e.to_string())?;
                }
            }
        }

        Ok(())
    }

    fn respond(line: &str) -> Result<bool, String> {
        let args = shlex::split(line).ok_or("error: Invalid quoting")?;
        let cli = Cli::try_parse_from(args).map_err(|e| e.to_string())?;
        match cli.command {
            Commands::Ping => {
                write!(std::io::stdout(), "Pong").map_err(|e| e.to_string())?;
                std::io::stdout().flush().map_err(|e| e.to_string())?;
            }
            Commands::Exit => {
                write!(std::io::stdout(), "Exiting ...").map_err(|e| e.to_string())?;
                std::io::stdout().flush().map_err(|e| e.to_string())?;
                return Ok(true);
            }
        }
        Ok(false)
    }

    #[derive(Debug, Parser)]
    #[command(multicall = true)]
    struct Cli {
        #[command(subcommand)]
        command: Commands,
    }

    #[derive(Debug, Subcommand)]
    enum Commands {
        Ping,
        Exit,
    }

    fn readline() -> Result<String, String> {
        write!(std::io::stdout(), "$ ").map_err(|e| e.to_string())?;
        std::io::stdout().flush().map_err(|e| e.to_string())?;
        let mut buffer = String::new();
        std::io::stdin()
            .read_line(&mut buffer)
            .map_err(|e| e.to_string())?;
        Ok(buffer)
    }