pub struct Repl<'a> { /* private fields */ }
Expand description
Read-eval-print loop.
REPL is ment do be constructed using the builder pattern via Repl::builder()
.
Commands are added during building and currently cannot be added/removed/modified
after Repl
has been built. This is because the names are used to generate Trie
with all the names for fast name lookup and completion.
Repl
can be used in two ways: one can use the Repl::run
method directly to just
start the evaluation loop, or Repl::next
can be used to get back control between
loop steps.
Implementations§
Source§impl<'a> Repl<'a>
impl<'a> Repl<'a>
Sourcepub fn builder() -> ReplBuilder<'a>
pub fn builder() -> ReplBuilder<'a>
Start ReplBuilder
with default values.
Examples found in repository?
examples/matryoshka.rs (line 18)
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
examples/minimal.rs (line 5)
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}
examples/from_str.rs (line 8)
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}
examples/overload.rs (line 5)
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}
examples/shared_mut_state.rs (line 14)
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}
examples/mut_state.rs (line 8)
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}
Additional examples can be found in:
Sourcepub fn next(&mut self) -> Result<LoopStatus>
pub fn next(&mut self) -> Result<LoopStatus>
Run a single REPL iteration and return whether this is the last one or not.
Sourcepub fn run(&mut self) -> Result<()>
pub fn run(&mut self) -> Result<()>
Run the evaluation loop until LoopStatus::Break
is received.
Examples found in repository?
examples/matryoshka.rs (line 13)
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}
25
26fn main() -> anyhow::Result<()> {
27 let mut repl = matryoshka("".into())?;
28 repl.run().context("Critical REPL error")?;
29 Ok(())
30}
More examples
examples/minimal.rs (line 22)
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}
examples/from_str.rs (line 27)
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}
examples/overload.rs (line 29)
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}
examples/shared_mut_state.rs (line 33)
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}
examples/mut_state.rs (line 52)
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}
Additional examples can be found in:
Auto Trait Implementations§
impl<'a> Freeze for Repl<'a>
impl<'a> !RefUnwindSafe for Repl<'a>
impl<'a> !Send for Repl<'a>
impl<'a> !Sync for Repl<'a>
impl<'a> Unpin for Repl<'a>
impl<'a> !UnwindSafe for Repl<'a>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more