easy_repl/lib.rs
1#![deny(missing_docs)]
2
3//! An easy to use REPL, ideal when there is a need to crate an ad-hoc shell.
4//!
5//! This library provides a fast and convenient way to generate a
6//! [REPL](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop)
7//! for your application. It comes with easy to use [`command!`] macro that
8//! will automatically validate and parse command arguments, doing all the type
9//! checking for you. The REPL comes with handy help messages, input validation,
10//! hints and TAB-completion. Many REPL features can be configured.
11//!
12//! # Example
13//!
14//! This is a basic example corresponding to `examples/minimal.rs`. For more examples
15//! see the `examples/` directory, which among others shows how to handle errors, access
16//! variables outside of handler closures and how to create REPL inside REPL, inside REPL, inside...
17//!
18//! ```rust
19//! use easy_repl::{Repl, CommandStatus, command};
20//!
21//! let mut repl = Repl::builder()
22//! .add("hello", command! {
23//! "Say hello",
24//! (name: String) => |name| {
25//! println!("Hello {}!", name);
26//! Ok(CommandStatus::Done)
27//! }
28//! })
29//! .add("add", command! {
30//! "Add X to Y",
31//! (X:i32, Y:i32) => |x, y| {
32//! println!("{} + {} = {}", x, y, x + y);
33//! Ok(CommandStatus::Done)
34//! }
35//! })
36//! .build().expect("Failed to create repl");
37//!
38//! repl.run().expect("Critical REPL error");
39//! ```
40//!
41//! The generated REPL can be used as:
42//! ```text
43//! > hello world
44//! Hello world!
45//! ```
46//!
47//! It comes with argument number checking...
48//! ```text
49//! > add 1
50//! Error: wrong number of arguments: got 1, expected 2
51//! Usage: add X:i32 Y:i32
52//! > hello easy repl
53//! Error: wrong number of arguments: got 2, expected 1
54//! Usage: hello name:String
55//! > hello "easy repl"
56//! Hello easy repl!
57//! ```
58//!
59//! ...and type checking!
60//! ```text
61//! > add 1 world
62//! Error: failed to parse argument value 'world': invalid digit found in string
63//! Usage: add X:i32 Y:i32
64//! ```
65//!
66//! It includes automatic `help` and `quit` commands. The help message is auto-generated:
67//! ```text
68//! > help
69//! Available commands:
70//! add X:i32 Y:i32 Add X to Y
71//! hello name:String Say hello
72//!
73//! Other commands:
74//! help Show this help message
75//! quit Quit repl
76//! ```
77//!
78//! By default user does not have to use full command names, if the command name can be
79//! resloved unambigiously (i.e. prefix matches only a single command), e.g.
80//! ```text
81//! > a 1 2
82//! 1 + 2 = 3
83//! ```
84//! but if the input is ambigious, an error will be printed with command suggestions:
85//! ```text
86//! > h world
87//! Command not found: h
88//! Candidates:
89//! hello
90//! help
91//! Use 'help' to see available commands.
92//! ```
93//!
94//! The REPL also by default automatically implements command hints and TAB-completion (see [`rustyline::hint`], [`rustyline::completion`]).
95
96pub mod command;
97mod completion;
98pub mod repl;
99
100pub use anyhow;
101
102pub use command::{Command, CommandStatus, Critical, CriticalError};
103pub use repl::Repl;