errors/
errors.rs

1use std::time::Instant;
2
3use easy_repl::{Repl, CommandStatus, Critical, command};
4use anyhow::{self, Context};
5
6// this could be any funcion returining Result with an error implementing Error
7// here for simplicity we make use of the Other variant of std::io::Error
8fn may_throw(description: String) -> Result<(), std::io::Error> {
9    Err(std::io::Error::new(std::io::ErrorKind::Other, description))
10}
11
12fn main() -> anyhow::Result<()> {
13    let start = Instant::now();
14
15    let mut repl = Repl::builder()
16        .add("ok", command! {
17            "Run a command that just succeeds",
18            () => || Ok(CommandStatus::Done)
19        })
20        .add("error", command! {
21            "Command with recoverable error handled by the REPL",
22            (text:String) => |text| {
23                may_throw(text)?;
24                Ok(CommandStatus::Done)
25            },
26        })
27        .add("critical", command! {
28            "Command returns a critical error that must be handled outside of REPL",
29            (text:String) => |text| {
30                // Short notation using the Critical trait
31                may_throw(text).into_critical()?;
32                // More explicitly it could be:
33                //   if let Err(err) = may_throw(text) {
34                //       Err(easy_repl::CriticalError::Critical(err.into()))?;
35                //   }
36                // or even:
37                //   if let Err(err) = may_throw(text) {
38                //       return Err(easy_repl::CriticalError::Critical(err.into())).into();
39                //   }
40                Ok(CommandStatus::Done)
41            },
42        })
43        .add("roulette", command! {
44            "Feeling lucky?",
45            () => || {
46                let ns = Instant::now().duration_since(start).as_nanos();
47                let cylinder = ns % 6;
48                match cylinder {
49                    0 => may_throw("Bang!".into()).into_critical()?,
50                    1..=2 => may_throw("Blank cartridge?".into())?,
51                    _ => (),
52                }
53                Ok(CommandStatus::Done)
54            },
55        })
56        .build().context("Failed to create repl")?;
57
58    repl.run().context("Critical REPL error")?;
59
60    Ok(())
61}
62