diff options
Diffstat (limited to 'cli/tools/repl/mod.rs')
-rw-r--r-- | cli/tools/repl/mod.rs | 112 |
1 files changed, 66 insertions, 46 deletions
diff --git a/cli/tools/repl/mod.rs b/cli/tools/repl/mod.rs index ad2be7ec4..f1fef6d54 100644 --- a/cli/tools/repl/mod.rs +++ b/cli/tools/repl/mod.rs @@ -33,7 +33,57 @@ pub use session::REPL_INTERNALS_NAME; use super::test::TestEvent; use super::test::TestEventSender; -#[allow(clippy::await_holding_refcell_ref)] +struct Repl { + session: ReplSession, + editor: ReplEditor, + message_handler: RustylineSyncMessageHandler, +} + +impl Repl { + async fn run(&mut self) -> Result<(), AnyError> { + loop { + let line = read_line_and_poll( + &mut self.session, + &mut self.message_handler, + self.editor.clone(), + ) + .await; + match line { + Ok(line) => { + self.editor.set_should_exit_on_interrupt(false); + self.editor.update_history(line.clone()); + let output = self.session.evaluate_line_and_get_output(&line).await; + + // We check for close and break here instead of making it a loop condition to get + // consistent behavior in when the user evaluates a call to close(). + if self.session.closing().await? { + break; + } + + println!("{output}"); + } + Err(ReadlineError::Interrupted) => { + if self.editor.should_exit_on_interrupt() { + break; + } + self.editor.set_should_exit_on_interrupt(true); + println!("press ctrl+c again to exit"); + continue; + } + Err(ReadlineError::Eof) => { + break; + } + Err(err) => { + println!("Error: {err:?}"); + break; + } + } + } + + Ok(()) + } +} + async fn read_line_and_poll( repl_session: &mut ReplSession, message_handler: &mut RustylineSyncMessageHandler, @@ -42,7 +92,7 @@ async fn read_line_and_poll( let mut line_fut = spawn_blocking(move || editor.readline()); let mut poll_worker = true; let notifications_rc = repl_session.notifications.clone(); - let mut notifications = notifications_rc.borrow_mut(); + let mut notifications = notifications_rc.lock().await; loop { tokio::select! { @@ -131,7 +181,7 @@ pub async fn run(flags: Flags, repl_flags: ReplFlags) -> Result<i32, AnyError> { .await?; worker.setup_repl().await?; let worker = worker.into_main_worker(); - let mut repl_session = ReplSession::initialize( + let session = ReplSession::initialize( cli_options, npm_resolver, resolver, @@ -141,20 +191,27 @@ pub async fn run(flags: Flags, repl_flags: ReplFlags) -> Result<i32, AnyError> { test_event_receiver, ) .await?; - let mut rustyline_channel = rustyline_channel(); + let rustyline_channel = rustyline_channel(); let helper = EditorHelper { - context_id: repl_session.context_id, + context_id: session.context_id, sync_sender: rustyline_channel.0, }; let editor = ReplEditor::new(helper, history_file_path)?; + let mut repl = Repl { + session, + editor, + message_handler: rustyline_channel.1, + }; + if let Some(eval_files) = repl_flags.eval_files { for eval_file in eval_files { match read_eval_file(cli_options, file_fetcher, &eval_file).await { Ok(eval_source) => { - let output = repl_session + let output = repl + .session .evaluate_line_and_get_output(&eval_source) .await; // only output errors @@ -170,7 +227,7 @@ pub async fn run(flags: Flags, repl_flags: ReplFlags) -> Result<i32, AnyError> { } if let Some(eval) = repl_flags.eval { - let output = repl_session.evaluate_line_and_get_output(&eval).await; + let output = repl.session.evaluate_line_and_get_output(&eval).await; // only output errors if let EvaluationOutput::Error(error_text) = output { println!("Error in --eval flag: {error_text}"); @@ -191,44 +248,7 @@ pub async fn run(flags: Flags, repl_flags: ReplFlags) -> Result<i32, AnyError> { } } - loop { - let line = read_line_and_poll( - &mut repl_session, - &mut rustyline_channel.1, - editor.clone(), - ) - .await; - match line { - Ok(line) => { - editor.set_should_exit_on_interrupt(false); - editor.update_history(line.clone()); - let output = repl_session.evaluate_line_and_get_output(&line).await; - - // We check for close and break here instead of making it a loop condition to get - // consistent behavior in when the user evaluates a call to close(). - if repl_session.closing().await? { - break; - } - - println!("{output}"); - } - Err(ReadlineError::Interrupted) => { - if editor.should_exit_on_interrupt() { - break; - } - editor.set_should_exit_on_interrupt(true); - println!("press ctrl+c again to exit"); - continue; - } - Err(ReadlineError::Eof) => { - break; - } - Err(err) => { - println!("Error: {err:?}"); - break; - } - } - } + repl.run().await?; - Ok(repl_session.worker.exit_code()) + Ok(repl.session.worker.exit_code()) } |