pub struct ReplBuilder { /* 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 ReplBuilder
impl ReplBuilder
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?
105async fn main() -> anyhow::Result<()> {
106 let outside_x = Rc::new(RefCell::new(String::from("Out x")));
107
108 #[rustfmt::skip]
109 let mut repl = Repl::builder()
110 .description("Example REPL")
111 .prompt("=> ")
112 .text_width(60 as usize)
113 .add("count", Command::new(
114 "Count from X to Y",
115 vec![
116 CommandArgInfo::new_with_name(CommandArgType::I32, "X"),
117 CommandArgInfo::new_with_name(CommandArgType::I32, "Y"),
118 ],
119 Box::new(CountCommandHandler::new()),
120 ))
121 .add("say", Command::new(
122 "Say X",
123 vec![CommandArgInfo::new_with_name(CommandArgType::F32, "X")],
124 Box::new(SayCommandHandler::new()),
125 ))
126 .add("outx", Command::new(
127 "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.",
128 vec![],
129 Box::new(OutXCommandHandler::new(outside_x.clone())),
130 ))
131 .build().context("Failed to create repl")?;
132
133 repl.run().await.context("Critical REPL error")?;
134
135 Ok(())
136}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?
105async fn main() -> anyhow::Result<()> {
106 let outside_x = Rc::new(RefCell::new(String::from("Out x")));
107
108 #[rustfmt::skip]
109 let mut repl = Repl::builder()
110 .description("Example REPL")
111 .prompt("=> ")
112 .text_width(60 as usize)
113 .add("count", Command::new(
114 "Count from X to Y",
115 vec![
116 CommandArgInfo::new_with_name(CommandArgType::I32, "X"),
117 CommandArgInfo::new_with_name(CommandArgType::I32, "Y"),
118 ],
119 Box::new(CountCommandHandler::new()),
120 ))
121 .add("say", Command::new(
122 "Say X",
123 vec![CommandArgInfo::new_with_name(CommandArgType::F32, "X")],
124 Box::new(SayCommandHandler::new()),
125 ))
126 .add("outx", Command::new(
127 "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.",
128 vec![],
129 Box::new(OutXCommandHandler::new(outside_x.clone())),
130 ))
131 .build().context("Failed to create repl")?;
132
133 repl.run().await.context("Critical REPL error")?;
134
135 Ok(())
136}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?
105async fn main() -> anyhow::Result<()> {
106 let outside_x = Rc::new(RefCell::new(String::from("Out x")));
107
108 #[rustfmt::skip]
109 let mut repl = Repl::builder()
110 .description("Example REPL")
111 .prompt("=> ")
112 .text_width(60 as usize)
113 .add("count", Command::new(
114 "Count from X to Y",
115 vec![
116 CommandArgInfo::new_with_name(CommandArgType::I32, "X"),
117 CommandArgInfo::new_with_name(CommandArgType::I32, "Y"),
118 ],
119 Box::new(CountCommandHandler::new()),
120 ))
121 .add("say", Command::new(
122 "Say X",
123 vec![CommandArgInfo::new_with_name(CommandArgType::F32, "X")],
124 Box::new(SayCommandHandler::new()),
125 ))
126 .add("outx", Command::new(
127 "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.",
128 vec![],
129 Box::new(OutXCommandHandler::new(outside_x.clone())),
130 ))
131 .build().context("Failed to create repl")?;
132
133 repl.run().await.context("Critical REPL error")?;
134
135 Ok(())
136}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|vebut 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) -> Self
pub fn add(self, name: &str, cmd: Command) -> Self
Add a command with given name. Use along with the [command!] macro.
Examples found in repository?
77async fn main() -> anyhow::Result<()> {
78 #[rustfmt::skip]
79 let mut repl = Repl::builder()
80 .add("ls", Command::new(
81 "List files in a directory",
82 vec![CommandArgInfo::new_with_name(CommandArgType::Custom, "dir")],
83 Box::new(LsCommandHandler::new()),
84 ))
85 .add("ipaddr", Command::new(
86 "Just parse and print the given IP address".into(),
87 vec![CommandArgInfo::new_with_name(CommandArgType::Custom, "ip")],
88 Box::new(IpAddrCommandHandler::new()),
89 ))
90 .build()
91 .context("Failed to create repl")?;
92
93 repl.run().await.context("Critical REPL error")
94}More examples
67async fn main() -> anyhow::Result<()> {
68 let hello_cmd = Command::new(
69 "Say hello",
70 vec![CommandArgInfo::new_with_name(
71 CommandArgType::String,
72 "name",
73 )],
74 Box::new(SayHelloCommandHandler::new()),
75 );
76
77 let add_cmd = Command::new(
78 "Add X to Y",
79 vec![
80 CommandArgInfo::new_with_name(CommandArgType::I32, "X"),
81 CommandArgInfo::new_with_name(CommandArgType::I32, "Y"),
82 ],
83 Box::new(AddCommandHandler::new()),
84 );
85
86 #[rustfmt::skip]
87 let mut repl = Repl::builder()
88 .add("hello", hello_cmd)
89 .add("add", add_cmd)
90 .build()
91 .context("Failed to create repl")?;
92
93 repl.run().await.context("Critical REPL error")?;
94
95 Ok(())
96}93async fn main() -> anyhow::Result<()> {
94 #[rustfmt::skip]
95 let mut repl = Repl::builder()
96 .add("describe", Command::new(
97 "Variant 1",
98 vec![],
99 Box::new(DescribeCommandHandler::new()),
100 ))
101 .add("describe", Command::new(
102 "Variant 2",
103 vec![
104 CommandArgInfo::new_with_name(CommandArgType::I32, "a"),
105 CommandArgInfo::new_with_name(CommandArgType::I32, "b"),
106 ],
107 Box::new(DescribeCommandHandler::new()),
108 ))
109 .add("describe", Command::new(
110 "Variant 3",
111 vec![
112 CommandArgInfo::new_with_name(CommandArgType::I32, "a"),
113 CommandArgInfo::new_with_name(CommandArgType::String, "b"),
114 ],
115 Box::new(DescribeCommandHandler::new()),
116 ))
117 .build()
118 .context("Failed to create repl")?;
119
120 repl.run().await.context("Critical REPL error")?;
121
122 Ok(())
123}105async fn main() -> anyhow::Result<()> {
106 let outside_x = Rc::new(RefCell::new(String::from("Out x")));
107
108 #[rustfmt::skip]
109 let mut repl = Repl::builder()
110 .description("Example REPL")
111 .prompt("=> ")
112 .text_width(60 as usize)
113 .add("count", Command::new(
114 "Count from X to Y",
115 vec![
116 CommandArgInfo::new_with_name(CommandArgType::I32, "X"),
117 CommandArgInfo::new_with_name(CommandArgType::I32, "Y"),
118 ],
119 Box::new(CountCommandHandler::new()),
120 ))
121 .add("say", Command::new(
122 "Say X",
123 vec![CommandArgInfo::new_with_name(CommandArgType::F32, "X")],
124 Box::new(SayCommandHandler::new()),
125 ))
126 .add("outx", Command::new(
127 "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.",
128 vec![],
129 Box::new(OutXCommandHandler::new(outside_x.clone())),
130 ))
131 .build().context("Failed to create repl")?;
132
133 repl.run().await.context("Critical REPL error")?;
134
135 Ok(())
136}134async fn main() -> anyhow::Result<()> {
135 #[rustfmt::skip]
136 let mut repl = Repl::builder()
137 .add("ok", Command::new(
138 "Run a command that just succeeds",
139 vec![],
140 Box::new(OkCommandHandler::new()),
141 ))
142 .add("error", Command::new(
143 "Command with recoverable error handled by the REPL",
144 vec![CommandArgInfo::new_with_name(CommandArgType::String, "text")],
145 Box::new(RecoverableErrorHandler::new()),
146 ))
147 .add("critical", Command::new(
148 "Command returns a critical error that must be handled outside of REPL",
149 vec![CommandArgInfo::new_with_name(CommandArgType::String, "text")],
150 Box::new(CriticalErrorHandler::new()),
151 ))
152 .add("roulette", Command::new(
153 "Feeling lucky?",
154 vec![],
155 Box::new(RouletteErrorHandler::new(Instant::now())),
156 ))
157 .build()
158 .context("Failed to create repl")?;
159
160 let repl_res = repl.run().await;
161 match repl_res {
162 Ok(_) => Ok(()),
163 Err(_) => {
164 println!("Repl halted. Quitting.");
165 Ok(())
166 }
167 }
168}Sourcepub fn build(self) -> Result<Repl, BuilderError>
pub fn build(self) -> Result<Repl, BuilderError>
Finalize the configuration and return the REPL or error.
Examples found in repository?
77async fn main() -> anyhow::Result<()> {
78 #[rustfmt::skip]
79 let mut repl = Repl::builder()
80 .add("ls", Command::new(
81 "List files in a directory",
82 vec![CommandArgInfo::new_with_name(CommandArgType::Custom, "dir")],
83 Box::new(LsCommandHandler::new()),
84 ))
85 .add("ipaddr", Command::new(
86 "Just parse and print the given IP address".into(),
87 vec![CommandArgInfo::new_with_name(CommandArgType::Custom, "ip")],
88 Box::new(IpAddrCommandHandler::new()),
89 ))
90 .build()
91 .context("Failed to create repl")?;
92
93 repl.run().await.context("Critical REPL error")
94}More examples
67async fn main() -> anyhow::Result<()> {
68 let hello_cmd = Command::new(
69 "Say hello",
70 vec![CommandArgInfo::new_with_name(
71 CommandArgType::String,
72 "name",
73 )],
74 Box::new(SayHelloCommandHandler::new()),
75 );
76
77 let add_cmd = Command::new(
78 "Add X to Y",
79 vec![
80 CommandArgInfo::new_with_name(CommandArgType::I32, "X"),
81 CommandArgInfo::new_with_name(CommandArgType::I32, "Y"),
82 ],
83 Box::new(AddCommandHandler::new()),
84 );
85
86 #[rustfmt::skip]
87 let mut repl = Repl::builder()
88 .add("hello", hello_cmd)
89 .add("add", add_cmd)
90 .build()
91 .context("Failed to create repl")?;
92
93 repl.run().await.context("Critical REPL error")?;
94
95 Ok(())
96}93async fn main() -> anyhow::Result<()> {
94 #[rustfmt::skip]
95 let mut repl = Repl::builder()
96 .add("describe", Command::new(
97 "Variant 1",
98 vec![],
99 Box::new(DescribeCommandHandler::new()),
100 ))
101 .add("describe", Command::new(
102 "Variant 2",
103 vec![
104 CommandArgInfo::new_with_name(CommandArgType::I32, "a"),
105 CommandArgInfo::new_with_name(CommandArgType::I32, "b"),
106 ],
107 Box::new(DescribeCommandHandler::new()),
108 ))
109 .add("describe", Command::new(
110 "Variant 3",
111 vec![
112 CommandArgInfo::new_with_name(CommandArgType::I32, "a"),
113 CommandArgInfo::new_with_name(CommandArgType::String, "b"),
114 ],
115 Box::new(DescribeCommandHandler::new()),
116 ))
117 .build()
118 .context("Failed to create repl")?;
119
120 repl.run().await.context("Critical REPL error")?;
121
122 Ok(())
123}105async fn main() -> anyhow::Result<()> {
106 let outside_x = Rc::new(RefCell::new(String::from("Out x")));
107
108 #[rustfmt::skip]
109 let mut repl = Repl::builder()
110 .description("Example REPL")
111 .prompt("=> ")
112 .text_width(60 as usize)
113 .add("count", Command::new(
114 "Count from X to Y",
115 vec![
116 CommandArgInfo::new_with_name(CommandArgType::I32, "X"),
117 CommandArgInfo::new_with_name(CommandArgType::I32, "Y"),
118 ],
119 Box::new(CountCommandHandler::new()),
120 ))
121 .add("say", Command::new(
122 "Say X",
123 vec![CommandArgInfo::new_with_name(CommandArgType::F32, "X")],
124 Box::new(SayCommandHandler::new()),
125 ))
126 .add("outx", Command::new(
127 "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.",
128 vec![],
129 Box::new(OutXCommandHandler::new(outside_x.clone())),
130 ))
131 .build().context("Failed to create repl")?;
132
133 repl.run().await.context("Critical REPL error")?;
134
135 Ok(())
136}134async fn main() -> anyhow::Result<()> {
135 #[rustfmt::skip]
136 let mut repl = Repl::builder()
137 .add("ok", Command::new(
138 "Run a command that just succeeds",
139 vec![],
140 Box::new(OkCommandHandler::new()),
141 ))
142 .add("error", Command::new(
143 "Command with recoverable error handled by the REPL",
144 vec![CommandArgInfo::new_with_name(CommandArgType::String, "text")],
145 Box::new(RecoverableErrorHandler::new()),
146 ))
147 .add("critical", Command::new(
148 "Command returns a critical error that must be handled outside of REPL",
149 vec![CommandArgInfo::new_with_name(CommandArgType::String, "text")],
150 Box::new(CriticalErrorHandler::new()),
151 ))
152 .add("roulette", Command::new(
153 "Feeling lucky?",
154 vec![],
155 Box::new(RouletteErrorHandler::new(Instant::now())),
156 ))
157 .build()
158 .context("Failed to create repl")?;
159
160 let repl_res = repl.run().await;
161 match repl_res {
162 Ok(_) => Ok(()),
163 Err(_) => {
164 println!("Repl halted. Quitting.");
165 Ok(())
166 }
167 }
168}Trait Implementations§
Auto Trait Implementations§
impl Freeze for ReplBuilder
impl !RefUnwindSafe for ReplBuilder
impl !Send for ReplBuilder
impl !Sync for ReplBuilder
impl Unpin for ReplBuilder
impl !UnwindSafe for ReplBuilder
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
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more