Add and use new Signals struct (#13314)

# Description
This PR introduces a new `Signals` struct to replace our adhoc passing
around of `ctrlc: Option<Arc<AtomicBool>>`. Doing so has a few benefits:
- We can better enforce when/where resetting or triggering an interrupt
is allowed.
- Consolidates `nu_utils::ctrl_c::was_pressed` and other ad-hoc
re-implementations into a single place: `Signals::check`.
- This allows us to add other types of signals later if we want. E.g.,
exiting or suspension.
- Similarly, we can more easily change the underlying implementation if
we need to in the future.
- Places that used to have a `ctrlc` of `None` now use
`Signals::empty()`, so we can double check these usages for correctness
in the future.
This commit is contained in:
Ian Manske
2024-07-07 22:29:01 +00:00
committed by GitHub
parent c6b6b1b7a8
commit 399a7c8836
246 changed files with 1332 additions and 1234 deletions

View File

@ -22,7 +22,7 @@ use crate::{EngineInterface, EvaluatedCall, Plugin};
/// Basic usage:
/// ```
/// # use nu_plugin::*;
/// # use nu_protocol::{Signature, PipelineData, Type, Value, LabeledError};
/// # use nu_protocol::{LabeledError, PipelineData, Signals, Signature, Type, Value};
/// struct LowercasePlugin;
/// struct Lowercase;
///
@ -55,7 +55,7 @@ use crate::{EngineInterface, EvaluatedCall, Plugin};
/// .map(|string| Value::string(string.to_lowercase(), span))
/// // Errors in a stream should be returned as values.
/// .unwrap_or_else(|err| Value::error(err, span))
/// }, None)?)
/// }, &Signals::empty())?)
/// }
/// }
///

View File

@ -12,7 +12,7 @@ use nu_plugin_protocol::{
};
use nu_protocol::{
engine::Closure, Config, LabeledError, PipelineData, PluginMetadata, PluginSignature,
ShellError, Span, Spanned, Value,
ShellError, Signals, Span, Spanned, Value,
};
use std::{
collections::{btree_map, BTreeMap, HashMap},
@ -274,7 +274,9 @@ impl InterfaceManager for EngineInterfaceManager {
PluginInput::Call(id, call) => {
let interface = self.interface_for_context(id);
// Read streams in the input
let call = match call.map_data(|input| self.read_pipeline_data(input, None)) {
let call = match call
.map_data(|input| self.read_pipeline_data(input, &Signals::empty()))
{
Ok(call) => call,
Err(err) => {
// If there's an error with initialization of the input stream, just send
@ -320,7 +322,7 @@ impl InterfaceManager for EngineInterfaceManager {
}
PluginInput::EngineCallResponse(id, response) => {
let response = response
.map_data(|header| self.read_pipeline_data(header, None))
.map_data(|header| self.read_pipeline_data(header, &Signals::empty()))
.unwrap_or_else(|err| {
// If there's an error with initializing this stream, change it to an engine
// call error response, but send it anyway

View File

@ -10,7 +10,7 @@ use nu_plugin_protocol::{
};
use nu_protocol::{
engine::Closure, ByteStreamType, Config, CustomValue, IntoInterruptiblePipelineData,
LabeledError, PipelineData, PluginSignature, ShellError, Span, Spanned, Value,
LabeledError, PipelineData, PluginSignature, ShellError, Signals, Span, Spanned, Value,
};
use std::{
collections::HashMap,
@ -59,7 +59,7 @@ fn manager_consume_all_exits_after_streams_and_interfaces_are_dropped() -> Resul
id: 0,
span: Span::test_data(),
}),
None,
&Signals::empty(),
)?;
// and an interface...
@ -115,7 +115,7 @@ fn manager_consume_all_propagates_io_error_to_readers() -> Result<(), ShellError
id: 0,
span: Span::test_data(),
}),
None,
&Signals::empty(),
)?;
manager
@ -162,7 +162,7 @@ fn manager_consume_all_propagates_message_error_to_readers() -> Result<(), Shell
span: Span::test_data(),
type_: ByteStreamType::Unknown,
}),
None,
&Signals::empty(),
)?;
manager
@ -615,7 +615,7 @@ fn manager_prepare_pipeline_data_deserializes_custom_values_in_streams() -> Resu
[Value::test_custom_value(Box::new(
test_plugin_custom_value(),
))]
.into_pipeline_data(Span::test_data(), None),
.into_pipeline_data(Span::test_data(), Signals::empty()),
)?;
let value = data
@ -647,7 +647,7 @@ fn manager_prepare_pipeline_data_embeds_deserialization_errors_in_streams() -> R
let span = Span::new(20, 30);
let data = manager.prepare_pipeline_data(
[Value::custom(Box::new(invalid_custom_value), span)]
.into_pipeline_data(Span::test_data(), None),
.into_pipeline_data(Span::test_data(), Signals::empty()),
)?;
let value = data
@ -730,7 +730,7 @@ fn interface_write_response_with_stream() -> Result<(), ShellError> {
interface
.write_response(Ok::<_, ShellError>(
[Value::test_int(3), Value::test_int(4), Value::test_int(5)]
.into_pipeline_data(Span::test_data(), None),
.into_pipeline_data(Span::test_data(), Signals::empty()),
))?
.write()?;
@ -1132,7 +1132,7 @@ fn interface_prepare_pipeline_data_serializes_custom_values_in_streams() -> Resu
[Value::test_custom_value(Box::new(
expected_test_custom_value(),
))]
.into_pipeline_data(Span::test_data(), None),
.into_pipeline_data(Span::test_data(), Signals::empty()),
&(),
)?;
@ -1191,7 +1191,7 @@ fn interface_prepare_pipeline_data_embeds_serialization_errors_in_streams() -> R
let span = Span::new(40, 60);
let data = interface.prepare_pipeline_data(
[Value::custom(Box::new(CantSerialize::BadVariant), span)]
.into_pipeline_data(Span::test_data(), None),
.into_pipeline_data(Span::test_data(), Signals::empty()),
&(),
)?;