mirror of
https://github.com/nushell/nushell.git
synced 2025-08-12 14:28:09 +02:00
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:
@ -1,10 +1,10 @@
|
||||
//! Implements the stream multiplexing interface for both the plugin side and the engine side.
|
||||
|
||||
use nu_plugin_protocol::{ByteStreamInfo, ListStreamInfo, PipelineDataHeader, StreamMessage};
|
||||
use nu_protocol::{ByteStream, IntoSpanned, ListStream, PipelineData, Reader, ShellError};
|
||||
use nu_protocol::{ByteStream, IntoSpanned, ListStream, PipelineData, Reader, ShellError, Signals};
|
||||
use std::{
|
||||
io::{Read, Write},
|
||||
sync::{atomic::AtomicBool, Arc, Mutex},
|
||||
sync::Mutex,
|
||||
thread,
|
||||
};
|
||||
|
||||
@ -170,7 +170,7 @@ pub trait InterfaceManager {
|
||||
fn read_pipeline_data(
|
||||
&self,
|
||||
header: PipelineDataHeader,
|
||||
ctrlc: Option<&Arc<AtomicBool>>,
|
||||
signals: &Signals,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
self.prepare_pipeline_data(match header {
|
||||
PipelineDataHeader::Empty => PipelineData::Empty,
|
||||
@ -178,12 +178,12 @@ pub trait InterfaceManager {
|
||||
PipelineDataHeader::ListStream(info) => {
|
||||
let handle = self.stream_manager().get_handle();
|
||||
let reader = handle.read_stream(info.id, self.get_interface())?;
|
||||
ListStream::new(reader, info.span, ctrlc.cloned()).into()
|
||||
ListStream::new(reader, info.span, signals.clone()).into()
|
||||
}
|
||||
PipelineDataHeader::ByteStream(info) => {
|
||||
let handle = self.stream_manager().get_handle();
|
||||
let reader = handle.read_stream(info.id, self.get_interface())?;
|
||||
ByteStream::from_result_iter(reader, info.span, ctrlc.cloned(), info.type_).into()
|
||||
ByteStream::from_result_iter(reader, info.span, signals.clone(), info.type_).into()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ use nu_plugin_protocol::{
|
||||
};
|
||||
use nu_protocol::{
|
||||
ByteStream, ByteStreamSource, ByteStreamType, DataSource, ListStream, PipelineData,
|
||||
PipelineMetadata, ShellError, Span, Value,
|
||||
PipelineMetadata, ShellError, Signals, Span, Value,
|
||||
};
|
||||
use std::{path::Path, sync::Arc};
|
||||
|
||||
@ -129,7 +129,7 @@ fn read_pipeline_data_empty() -> Result<(), ShellError> {
|
||||
let header = PipelineDataHeader::Empty;
|
||||
|
||||
assert!(matches!(
|
||||
manager.read_pipeline_data(header, None)?,
|
||||
manager.read_pipeline_data(header, &Signals::empty())?,
|
||||
PipelineData::Empty
|
||||
));
|
||||
Ok(())
|
||||
@ -141,7 +141,7 @@ fn read_pipeline_data_value() -> Result<(), ShellError> {
|
||||
let value = Value::test_int(4);
|
||||
let header = PipelineDataHeader::Value(value.clone());
|
||||
|
||||
match manager.read_pipeline_data(header, None)? {
|
||||
match manager.read_pipeline_data(header, &Signals::empty())? {
|
||||
PipelineData::Value(read_value, ..) => assert_eq!(value, read_value),
|
||||
PipelineData::ListStream(..) => panic!("unexpected ListStream"),
|
||||
PipelineData::ByteStream(..) => panic!("unexpected ByteStream"),
|
||||
@ -168,7 +168,7 @@ fn read_pipeline_data_list_stream() -> Result<(), ShellError> {
|
||||
span: Span::test_data(),
|
||||
});
|
||||
|
||||
let pipe = manager.read_pipeline_data(header, None)?;
|
||||
let pipe = manager.read_pipeline_data(header, &Signals::empty())?;
|
||||
assert!(
|
||||
matches!(pipe, PipelineData::ListStream(..)),
|
||||
"unexpected PipelineData: {pipe:?}"
|
||||
@ -212,7 +212,7 @@ fn read_pipeline_data_byte_stream() -> Result<(), ShellError> {
|
||||
type_: ByteStreamType::Unknown,
|
||||
});
|
||||
|
||||
let pipe = manager.read_pipeline_data(header, None)?;
|
||||
let pipe = manager.read_pipeline_data(header, &Signals::empty())?;
|
||||
|
||||
// need to consume input
|
||||
manager.consume_all()?;
|
||||
@ -257,7 +257,7 @@ fn read_pipeline_data_prepared_properly() -> Result<(), ShellError> {
|
||||
id: 0,
|
||||
span: Span::test_data(),
|
||||
});
|
||||
match manager.read_pipeline_data(header, None)? {
|
||||
match manager.read_pipeline_data(header, &Signals::empty())? {
|
||||
PipelineData::ListStream(_, meta) => match meta {
|
||||
Some(PipelineMetadata { data_source, .. }) => match data_source {
|
||||
DataSource::FilePath(path) => {
|
||||
@ -353,7 +353,11 @@ fn write_pipeline_data_list_stream() -> Result<(), ShellError> {
|
||||
|
||||
// Set up pipeline data for a list stream
|
||||
let pipe = PipelineData::ListStream(
|
||||
ListStream::new(values.clone().into_iter(), Span::test_data(), None),
|
||||
ListStream::new(
|
||||
values.clone().into_iter(),
|
||||
Span::test_data(),
|
||||
Signals::empty(),
|
||||
),
|
||||
None,
|
||||
);
|
||||
|
||||
@ -406,7 +410,7 @@ fn write_pipeline_data_byte_stream() -> Result<(), ShellError> {
|
||||
ByteStream::read(
|
||||
std::io::Cursor::new(expected),
|
||||
span,
|
||||
None,
|
||||
Signals::empty(),
|
||||
ByteStreamType::Unknown,
|
||||
),
|
||||
None,
|
||||
|
Reference in New Issue
Block a user