Struct ReplBuilder

Source
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>

Source

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?
examples/mut_state.rs (line 9)
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}
Source

pub fn prompt<T: Into<String>>(self, v: T) -> Self

Prompt string, defaults to "> ".

Examples found in repository?
examples/matryoshka.rs (line 19)
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
Hide additional examples
examples/mut_state.rs (line 10)
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}
Source

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?
examples/mut_state.rs (line 11)
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}
Source

pub fn editor_config<T: Into<Config>>(self, v: T) -> Self

Configuration for rustyline. Some sane defaults are used.

Source

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).

Source

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.

Source

pub fn with_completion<T: Into<bool>>(self, v: T) -> Self

Use completion. Defaults to true.

Source

pub fn with_filename_completion<T: Into<bool>>(self, v: T) -> Self

Add filename completion, besides command completion. Defaults to false.

Source

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.

Source

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?
examples/matryoshka.rs (line 20)
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
Hide additional examples
examples/minimal.rs (lines 6-12)
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 (lines 9-17)
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 (lines 6-12)
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 (lines 15-22)
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 (lines 12-21)
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}
Source

pub fn build(self) -> Result<Repl<'a>, BuilderError>

Finalize the configuration and return the REPL or error.

Examples found in repository?
examples/matryoshka.rs (line 21)
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
Hide additional examples
examples/minimal.rs (line 20)
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 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}
examples/overload.rs (line 27)
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 31)
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 50)
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}

Trait Implementations§

Source§

impl<'a> Default for ReplBuilder<'a>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl<'a> Freeze for ReplBuilder<'a>

§

impl<'a> !RefUnwindSafe for ReplBuilder<'a>

§

impl<'a> !Send for ReplBuilder<'a>

§

impl<'a> !Sync for ReplBuilder<'a>

§

impl<'a> Unpin for ReplBuilder<'a>

§

impl<'a> !UnwindSafe for ReplBuilder<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.