pub struct ReplBuilder<'a> { /* private fields */ }
Expand description
Builder pattern implementation for Repl
.
All setter methods take owned self
so the calls can be chained, for example:
let repl = Repl::builder()
.description("My REPL")
.prompt("repl> ")
.build()
.expect("Failed to build REPL");
Implementations§
Source§impl<'a> ReplBuilder<'a>
impl<'a> ReplBuilder<'a>
Sourcepub fn description<T: Into<String>>(self, v: T) -> Self
pub fn description<T: Into<String>>(self, v: T) -> Self
Repl description shown in Repl::help
. Defaults to an empty string.
Examples found in repository?
4fn main() -> anyhow::Result<()> {
5 let mut outside_x = String::from("Out x");
6 let mut outside_y = String::from("Out y");
7
8 let mut repl = Repl::builder()
9 .description("Example REPL")
10 .prompt("=> ")
11 .text_width(60 as usize)
12 .add("count", command! {
13 "Count from X to Y",
14 (X:i32, Y:i32) => |x, y| {
15 for i in x..=y {
16 print!(" {}", i);
17 }
18 println!();
19 Ok(CommandStatus::Done)
20 }
21 })
22 .add("say", command! {
23 "Say X",
24 (:f32) => |x| {
25 println!("x is equal to {}", x);
26 Ok(CommandStatus::Done)
27 },
28 })
29 .add("outx", command! {
30 "Use mutably outside var x. This command has a really long description so we need to wrap it somehow, it is interesting how actually the wrapping will be performed.",
31 () => || {
32 outside_x += "x";
33 println!("{}", outside_x);
34 Ok(CommandStatus::Done)
35 },
36 })
37 // this shows how to create Command manually with the help of the validator! macro
38 // one could also implement arguments validation manually
39 .add("outy", easy_repl::Command {
40 description: "Use mutably outside var y".into(),
41 args_info: vec!["appended".into()],
42 handler: Box::new(|args| {
43 let validator = validator!(i32);
44 validator(args)?;
45 outside_y += args[0];
46 println!("{}", outside_y);
47 Ok(CommandStatus::Done)
48 }),
49 })
50 .build().context("Failed to create repl")?;
51
52 repl.run().context("Critical REPL error")?;
53
54 Ok(())
55}
Sourcepub fn prompt<T: Into<String>>(self, v: T) -> Self
pub fn prompt<T: Into<String>>(self, v: T) -> Self
Prompt string, defaults to "> "
.
Examples found in repository?
4fn matryoshka(name: String) -> anyhow::Result<Repl<'static>> {
5 let prompt = format!("{}> ", name);
6
7 let cloned_prompt = prompt.clone(); // need to move it into closure
8 let new = command! {
9 "Enter new repl",
10 (name:String) => |name: String| {
11 let name = cloned_prompt.clone() + &name;
12 let mut repl = matryoshka(name)?;
13 repl.run()?;
14 Ok(CommandStatus::Done)
15 }
16 };
17
18 let repl = Repl::builder()
19 .prompt(prompt)
20 .add("new", new)
21 .build()?;
22
23 Ok(repl)
24}
More examples
4fn main() -> anyhow::Result<()> {
5 let mut outside_x = String::from("Out x");
6 let mut outside_y = String::from("Out y");
7
8 let mut repl = Repl::builder()
9 .description("Example REPL")
10 .prompt("=> ")
11 .text_width(60 as usize)
12 .add("count", command! {
13 "Count from X to Y",
14 (X:i32, Y:i32) => |x, y| {
15 for i in x..=y {
16 print!(" {}", i);
17 }
18 println!();
19 Ok(CommandStatus::Done)
20 }
21 })
22 .add("say", command! {
23 "Say X",
24 (:f32) => |x| {
25 println!("x is equal to {}", x);
26 Ok(CommandStatus::Done)
27 },
28 })
29 .add("outx", command! {
30 "Use mutably outside var x. This command has a really long description so we need to wrap it somehow, it is interesting how actually the wrapping will be performed.",
31 () => || {
32 outside_x += "x";
33 println!("{}", outside_x);
34 Ok(CommandStatus::Done)
35 },
36 })
37 // this shows how to create Command manually with the help of the validator! macro
38 // one could also implement arguments validation manually
39 .add("outy", easy_repl::Command {
40 description: "Use mutably outside var y".into(),
41 args_info: vec!["appended".into()],
42 handler: Box::new(|args| {
43 let validator = validator!(i32);
44 validator(args)?;
45 outside_y += args[0];
46 println!("{}", outside_y);
47 Ok(CommandStatus::Done)
48 }),
49 })
50 .build().context("Failed to create repl")?;
51
52 repl.run().context("Critical REPL error")?;
53
54 Ok(())
55}
Sourcepub fn text_width<T: Into<usize>>(self, v: T) -> Self
pub fn text_width<T: Into<usize>>(self, v: T) -> Self
Width of the text used when wrapping the help message. Defaults to 80.
Examples found in repository?
4fn main() -> anyhow::Result<()> {
5 let mut outside_x = String::from("Out x");
6 let mut outside_y = String::from("Out y");
7
8 let mut repl = Repl::builder()
9 .description("Example REPL")
10 .prompt("=> ")
11 .text_width(60 as usize)
12 .add("count", command! {
13 "Count from X to Y",
14 (X:i32, Y:i32) => |x, y| {
15 for i in x..=y {
16 print!(" {}", i);
17 }
18 println!();
19 Ok(CommandStatus::Done)
20 }
21 })
22 .add("say", command! {
23 "Say X",
24 (:f32) => |x| {
25 println!("x is equal to {}", x);
26 Ok(CommandStatus::Done)
27 },
28 })
29 .add("outx", command! {
30 "Use mutably outside var x. This command has a really long description so we need to wrap it somehow, it is interesting how actually the wrapping will be performed.",
31 () => || {
32 outside_x += "x";
33 println!("{}", outside_x);
34 Ok(CommandStatus::Done)
35 },
36 })
37 // this shows how to create Command manually with the help of the validator! macro
38 // one could also implement arguments validation manually
39 .add("outy", easy_repl::Command {
40 description: "Use mutably outside var y".into(),
41 args_info: vec!["appended".into()],
42 handler: Box::new(|args| {
43 let validator = validator!(i32);
44 validator(args)?;
45 outside_y += args[0];
46 println!("{}", outside_y);
47 Ok(CommandStatus::Done)
48 }),
49 })
50 .build().context("Failed to create repl")?;
51
52 repl.run().context("Critical REPL error")?;
53
54 Ok(())
55}
Sourcepub fn editor_config<T: Into<Config>>(self, v: T) -> Self
pub fn editor_config<T: Into<Config>>(self, v: T) -> Self
Configuration for rustyline
. Some sane defaults are used.
Sourcepub fn out<T: Into<Box<dyn Write>>>(self, v: T) -> Self
pub fn out<T: Into<Box<dyn Write>>>(self, v: T) -> Self
Where to print REPL output. By default std::io::Stderr
is used.
Note that rustyline
will always use std::io::Stderr
or std::io::Stdout
.
These must be configured in ReplBuilder::editor_config
, and currently there seems to be no way
to use other output stream for rustyline
(which probably also makes little sense).
Sourcepub fn with_hints<T: Into<bool>>(self, v: T) -> Self
pub fn with_hints<T: Into<bool>>(self, v: T) -> Self
Print command hints. Defaults to true
.
Hints will show the end of a command if there is only one avaliable.
For example, assuming commands "move"
and "make"
, in the following position (|
indicates the cursor):
> mo|
a hint will be shown as
> mo|ve
but when there is only
> m|
then no hints will be shown.
Sourcepub fn with_completion<T: Into<bool>>(self, v: T) -> Self
pub fn with_completion<T: Into<bool>>(self, v: T) -> Self
Use completion. Defaults to true
.
Sourcepub fn with_filename_completion<T: Into<bool>>(self, v: T) -> Self
pub fn with_filename_completion<T: Into<bool>>(self, v: T) -> Self
Add filename completion, besides command completion. Defaults to false
.
Sourcepub fn predict_commands<T: Into<bool>>(self, v: T) -> Self
pub fn predict_commands<T: Into<bool>>(self, v: T) -> Self
Execute commands when entering incomplete names. Defaults to true
.
With this option commands can be executed by entering only part of command name.
If there is only a single command mathing given prefix, then it will be executed.
For example, with commands "make"
and “move
”, entering just mo
will resolve
to move
and the command will be executed, but entering m
will result in an error.
Sourcepub fn add(self, name: &str, cmd: Command<'a>) -> Self
pub fn add(self, name: &str, cmd: Command<'a>) -> Self
Add a command with given name
. Use along with the [command!
] macro.
Examples found in repository?
4fn matryoshka(name: String) -> anyhow::Result<Repl<'static>> {
5 let prompt = format!("{}> ", name);
6
7 let cloned_prompt = prompt.clone(); // need to move it into closure
8 let new = command! {
9 "Enter new repl",
10 (name:String) => |name: String| {
11 let name = cloned_prompt.clone() + &name;
12 let mut repl = matryoshka(name)?;
13 repl.run()?;
14 Ok(CommandStatus::Done)
15 }
16 };
17
18 let repl = Repl::builder()
19 .prompt(prompt)
20 .add("new", new)
21 .build()?;
22
23 Ok(repl)
24}
More examples
4fn main() -> anyhow::Result<()> {
5 let mut repl = Repl::builder()
6 .add("hello", command! {
7 "Say hello",
8 (name: String) => |name| {
9 println!("Hello {}!", name);
10 Ok(CommandStatus::Done)
11 }
12 })
13 .add("add", command! {
14 "Add X to Y",
15 (X:i32, Y:i32) => |x, y| {
16 println!("{} + {} = {}", x, y, x + y);
17 Ok(CommandStatus::Done)
18 }
19 })
20 .build().context("Failed to create repl")?;
21
22 repl.run().context("Critical REPL error")?;
23
24 Ok(())
25}
7fn main() -> anyhow::Result<()> {
8 let mut repl = Repl::builder()
9 .add("ls", command! {
10 "List files in a directory",
11 (dir: PathBuf) => |dir: PathBuf| {
12 for entry in dir.read_dir()? {
13 println!("{}", entry?.path().to_string_lossy());
14 }
15 Ok(CommandStatus::Done)
16 }
17 })
18 .add("ipaddr", command! {
19 "Just parse and print the given IP address",
20 (ip: IpAddr) => |ip: IpAddr| {
21 println!("{}", ip);
22 Ok(CommandStatus::Done)
23 }
24 })
25 .build().context("Failed to create repl")?;
26
27 repl.run().context("Critical REPL error")
28}
4fn main() -> anyhow::Result<()> {
5 let mut repl = Repl::builder()
6 .add("describe", command! {
7 "Variant 1",
8 () => || {
9 println!("No arguments");
10 Ok(CommandStatus::Done)
11 }
12 })
13 .add("describe", command! {
14 "Variant 2",
15 (a: i32, b: i32) => |a, b| {
16 println!("Got two integers: {} {}", a, b);
17 Ok(CommandStatus::Done)
18 }
19 })
20 .add("describe", command! {
21 "Variant 3",
22 (a: i32, b: String) => |a, b| {
23 println!("An integer `{}` and a string `{}`", a, b);
24 Ok(CommandStatus::Done)
25 }
26 })
27 .build().context("Failed to create repl")?;
28
29 repl.run().context("Critical REPL error")?;
30
31 Ok(())
32}
5fn main() -> anyhow::Result<()> {
6 // To use a value in multiple commands we need shared ownership
7 // combined with some kind of references.
8 // This could be Rc<RefCell<_>>, but in this example it's possible
9 // to avoid smart pointers and just use two references &RefCell<_>.
10 let counter = RefCell::new(0);
11 let ref1 = &counter;
12 let ref2 = &counter;
13
14 let mut repl = Repl::builder()
15 .add("inc", command! {
16 "Increment counter",
17 () => || {
18 *ref1.borrow_mut() += 1;
19 println!("counter = {}", ref1.borrow());
20 Ok(CommandStatus::Done)
21 },
22 })
23 .add("dec", command! {
24 "Decrement counter",
25 () => || {
26 *ref2.borrow_mut() -= 1;
27 println!("counter = {}", ref2.borrow());
28 Ok(CommandStatus::Done)
29 },
30 })
31 .build().context("Failed to create repl")?;
32
33 repl.run().context("Critical REPL error")?;
34
35 Ok(())
36}
4fn main() -> anyhow::Result<()> {
5 let mut outside_x = String::from("Out x");
6 let mut outside_y = String::from("Out y");
7
8 let mut repl = Repl::builder()
9 .description("Example REPL")
10 .prompt("=> ")
11 .text_width(60 as usize)
12 .add("count", command! {
13 "Count from X to Y",
14 (X:i32, Y:i32) => |x, y| {
15 for i in x..=y {
16 print!(" {}", i);
17 }
18 println!();
19 Ok(CommandStatus::Done)
20 }
21 })
22 .add("say", command! {
23 "Say X",
24 (:f32) => |x| {
25 println!("x is equal to {}", x);
26 Ok(CommandStatus::Done)
27 },
28 })
29 .add("outx", command! {
30 "Use mutably outside var x. This command has a really long description so we need to wrap it somehow, it is interesting how actually the wrapping will be performed.",
31 () => || {
32 outside_x += "x";
33 println!("{}", outside_x);
34 Ok(CommandStatus::Done)
35 },
36 })
37 // this shows how to create Command manually with the help of the validator! macro
38 // one could also implement arguments validation manually
39 .add("outy", easy_repl::Command {
40 description: "Use mutably outside var y".into(),
41 args_info: vec!["appended".into()],
42 handler: Box::new(|args| {
43 let validator = validator!(i32);
44 validator(args)?;
45 outside_y += args[0];
46 println!("{}", outside_y);
47 Ok(CommandStatus::Done)
48 }),
49 })
50 .build().context("Failed to create repl")?;
51
52 repl.run().context("Critical REPL error")?;
53
54 Ok(())
55}
Sourcepub fn build(self) -> Result<Repl<'a>, BuilderError>
pub fn build(self) -> Result<Repl<'a>, BuilderError>
Finalize the configuration and return the REPL or error.
Examples found in repository?
4fn matryoshka(name: String) -> anyhow::Result<Repl<'static>> {
5 let prompt = format!("{}> ", name);
6
7 let cloned_prompt = prompt.clone(); // need to move it into closure
8 let new = command! {
9 "Enter new repl",
10 (name:String) => |name: String| {
11 let name = cloned_prompt.clone() + &name;
12 let mut repl = matryoshka(name)?;
13 repl.run()?;
14 Ok(CommandStatus::Done)
15 }
16 };
17
18 let repl = Repl::builder()
19 .prompt(prompt)
20 .add("new", new)
21 .build()?;
22
23 Ok(repl)
24}
More examples
4fn main() -> anyhow::Result<()> {
5 let mut repl = Repl::builder()
6 .add("hello", command! {
7 "Say hello",
8 (name: String) => |name| {
9 println!("Hello {}!", name);
10 Ok(CommandStatus::Done)
11 }
12 })
13 .add("add", command! {
14 "Add X to Y",
15 (X:i32, Y:i32) => |x, y| {
16 println!("{} + {} = {}", x, y, x + y);
17 Ok(CommandStatus::Done)
18 }
19 })
20 .build().context("Failed to create repl")?;
21
22 repl.run().context("Critical REPL error")?;
23
24 Ok(())
25}
7fn main() -> anyhow::Result<()> {
8 let mut repl = Repl::builder()
9 .add("ls", command! {
10 "List files in a directory",
11 (dir: PathBuf) => |dir: PathBuf| {
12 for entry in dir.read_dir()? {
13 println!("{}", entry?.path().to_string_lossy());
14 }
15 Ok(CommandStatus::Done)
16 }
17 })
18 .add("ipaddr", command! {
19 "Just parse and print the given IP address",
20 (ip: IpAddr) => |ip: IpAddr| {
21 println!("{}", ip);
22 Ok(CommandStatus::Done)
23 }
24 })
25 .build().context("Failed to create repl")?;
26
27 repl.run().context("Critical REPL error")
28}
4fn main() -> anyhow::Result<()> {
5 let mut repl = Repl::builder()
6 .add("describe", command! {
7 "Variant 1",
8 () => || {
9 println!("No arguments");
10 Ok(CommandStatus::Done)
11 }
12 })
13 .add("describe", command! {
14 "Variant 2",
15 (a: i32, b: i32) => |a, b| {
16 println!("Got two integers: {} {}", a, b);
17 Ok(CommandStatus::Done)
18 }
19 })
20 .add("describe", command! {
21 "Variant 3",
22 (a: i32, b: String) => |a, b| {
23 println!("An integer `{}` and a string `{}`", a, b);
24 Ok(CommandStatus::Done)
25 }
26 })
27 .build().context("Failed to create repl")?;
28
29 repl.run().context("Critical REPL error")?;
30
31 Ok(())
32}
5fn main() -> anyhow::Result<()> {
6 // To use a value in multiple commands we need shared ownership
7 // combined with some kind of references.
8 // This could be Rc<RefCell<_>>, but in this example it's possible
9 // to avoid smart pointers and just use two references &RefCell<_>.
10 let counter = RefCell::new(0);
11 let ref1 = &counter;
12 let ref2 = &counter;
13
14 let mut repl = Repl::builder()
15 .add("inc", command! {
16 "Increment counter",
17 () => || {
18 *ref1.borrow_mut() += 1;
19 println!("counter = {}", ref1.borrow());
20 Ok(CommandStatus::Done)
21 },
22 })
23 .add("dec", command! {
24 "Decrement counter",
25 () => || {
26 *ref2.borrow_mut() -= 1;
27 println!("counter = {}", ref2.borrow());
28 Ok(CommandStatus::Done)
29 },
30 })
31 .build().context("Failed to create repl")?;
32
33 repl.run().context("Critical REPL error")?;
34
35 Ok(())
36}
4fn main() -> anyhow::Result<()> {
5 let mut outside_x = String::from("Out x");
6 let mut outside_y = String::from("Out y");
7
8 let mut repl = Repl::builder()
9 .description("Example REPL")
10 .prompt("=> ")
11 .text_width(60 as usize)
12 .add("count", command! {
13 "Count from X to Y",
14 (X:i32, Y:i32) => |x, y| {
15 for i in x..=y {
16 print!(" {}", i);
17 }
18 println!();
19 Ok(CommandStatus::Done)
20 }
21 })
22 .add("say", command! {
23 "Say X",
24 (:f32) => |x| {
25 println!("x is equal to {}", x);
26 Ok(CommandStatus::Done)
27 },
28 })
29 .add("outx", command! {
30 "Use mutably outside var x. This command has a really long description so we need to wrap it somehow, it is interesting how actually the wrapping will be performed.",
31 () => || {
32 outside_x += "x";
33 println!("{}", outside_x);
34 Ok(CommandStatus::Done)
35 },
36 })
37 // this shows how to create Command manually with the help of the validator! macro
38 // one could also implement arguments validation manually
39 .add("outy", easy_repl::Command {
40 description: "Use mutably outside var y".into(),
41 args_info: vec!["appended".into()],
42 handler: Box::new(|args| {
43 let validator = validator!(i32);
44 validator(args)?;
45 outside_y += args[0];
46 println!("{}", outside_y);
47 Ok(CommandStatus::Done)
48 }),
49 })
50 .build().context("Failed to create repl")?;
51
52 repl.run().context("Critical REPL error")?;
53
54 Ok(())
55}