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

@ -23,7 +23,7 @@ use crate::{
ast::{Bits, Boolean, CellPath, Comparison, Math, Operator, PathMember},
did_you_mean,
engine::{Closure, EngineState},
Config, ShellError, Span, Type,
Config, ShellError, Signals, Span, Type,
};
use chrono::{DateTime, Datelike, FixedOffset, Locale, TimeZone};
use chrono_humanize::HumanTime;
@ -1017,8 +1017,9 @@ impl Value {
}
}
Value::Range { ref val, .. } => {
if let Some(item) =
val.into_range_iter(current.span(), None).nth(*count)
if let Some(item) = val
.into_range_iter(current.span(), Signals::empty())
.nth(*count)
{
current = item;
} else if *optional {

View File

@ -1,25 +1,13 @@
//! A Range is an iterator over integers or floats.
use crate::{ast::RangeInclusion, ShellError, Signals, Span, Value};
use serde::{Deserialize, Serialize};
use std::{
cmp::Ordering,
fmt::Display,
sync::{atomic::AtomicBool, Arc},
};
use crate::{ast::RangeInclusion, ShellError, Span, Value};
use std::{cmp::Ordering, fmt::Display};
mod int_range {
use std::{
cmp::Ordering,
fmt::Display,
ops::Bound,
sync::{atomic::AtomicBool, Arc},
};
use crate::{ast::RangeInclusion, ShellError, Signals, Span, Value};
use serde::{Deserialize, Serialize};
use crate::{ast::RangeInclusion, ShellError, Span, Value};
use std::{cmp::Ordering, fmt::Display, ops::Bound};
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct IntRange {
@ -123,12 +111,12 @@ mod int_range {
}
}
pub fn into_range_iter(self, ctrlc: Option<Arc<AtomicBool>>) -> Iter {
pub fn into_range_iter(self, signals: Signals) -> Iter {
Iter {
current: Some(self.start),
step: self.step,
end: self.end,
ctrlc,
signals,
}
}
}
@ -202,7 +190,7 @@ mod int_range {
current: Option<i64>,
step: i64,
end: Bound<i64>,
ctrlc: Option<Arc<AtomicBool>>,
signals: Signals,
}
impl Iterator for Iter {
@ -218,7 +206,7 @@ mod int_range {
(_, Bound::Unbounded) => true, // will stop once integer overflows
};
if not_end && !nu_utils::ctrl_c::was_pressed(&self.ctrlc) {
if not_end && !self.signals.interrupted() {
self.current = current.checked_add(self.step);
Some(current)
} else {
@ -233,16 +221,9 @@ mod int_range {
}
mod float_range {
use std::{
cmp::Ordering,
fmt::Display,
ops::Bound,
sync::{atomic::AtomicBool, Arc},
};
use crate::{ast::RangeInclusion, IntRange, Range, ShellError, Signals, Span, Value};
use serde::{Deserialize, Serialize};
use crate::{ast::RangeInclusion, IntRange, Range, ShellError, Span, Value};
use std::{cmp::Ordering, fmt::Display, ops::Bound};
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct FloatRange {
@ -365,13 +346,13 @@ mod float_range {
}
}
pub fn into_range_iter(self, ctrlc: Option<Arc<AtomicBool>>) -> Iter {
pub fn into_range_iter(self, signals: Signals) -> Iter {
Iter {
start: self.start,
step: self.step,
end: self.end,
iter: Some(0),
ctrlc,
signals,
}
}
}
@ -477,7 +458,7 @@ mod float_range {
step: f64,
end: Bound<f64>,
iter: Option<u64>,
ctrlc: Option<Arc<AtomicBool>>,
signals: Signals,
}
impl Iterator for Iter {
@ -495,7 +476,7 @@ mod float_range {
(_, Bound::Unbounded) => current.is_finite(),
};
if not_end && !nu_utils::ctrl_c::was_pressed(&self.ctrlc) {
if not_end && !self.signals.interrupted() {
self.iter = iter.checked_add(1);
Some(current)
} else {
@ -549,10 +530,10 @@ impl Range {
}
}
pub fn into_range_iter(self, span: Span, ctrlc: Option<Arc<AtomicBool>>) -> Iter {
pub fn into_range_iter(self, span: Span, signals: Signals) -> Iter {
match self {
Range::IntRange(range) => Iter::IntIter(range.into_range_iter(ctrlc), span),
Range::FloatRange(range) => Iter::FloatIter(range.into_range_iter(ctrlc), span),
Range::IntRange(range) => Iter::IntIter(range.into_range_iter(signals), span),
Range::FloatRange(range) => Iter::FloatIter(range.into_range_iter(signals), span),
}
}
}