pub struct Repl { /* 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 Repl
impl Repl
Sourcepub fn builder() -> ReplBuilder
pub fn builder() -> ReplBuilder
Start ReplBuilder with default values.
Examples found in repository?
examples/from_str.rs (line 79)
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
examples/minimal.rs (line 87)
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}examples/overload.rs (line 95)
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}examples/mut_state.rs (line 109)
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}examples/errors.rs (line 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 async fn next(&mut self) -> Result<LoopStatus>
pub async fn next(&mut self) -> Result<LoopStatus>
Run a single REPL iteration and return whether this is the last one or not.
Sourcepub async fn run(&mut self) -> Result<()>
pub async fn run(&mut self) -> Result<()>
Run the evaluation loop until LoopStatus::Break is received.
Examples found in repository?
examples/from_str.rs (line 93)
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
examples/minimal.rs (line 93)
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}examples/overload.rs (line 120)
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}examples/mut_state.rs (line 133)
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}examples/errors.rs (line 160)
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}Auto Trait Implementations§
impl Freeze for Repl
impl !RefUnwindSafe for Repl
impl !Send for Repl
impl !Sync for Repl
impl Unpin for Repl
impl !UnwindSafe for Repl
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
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>
Converts
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>
Converts
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