mirror of
https://github.com/nushell/nushell.git
synced 2025-08-09 01:54:57 +02:00
Reduce again the number of match calls (#7815)
- Reduce the number of match calls (see commit messages) - A few miscellaneous improvements
This commit is contained in:
@ -1119,34 +1119,22 @@ impl Value {
|
||||
// Reconstruct
|
||||
let mut hook_cols = vec![];
|
||||
let mut hook_vals = vec![];
|
||||
match &config.hooks.pre_prompt {
|
||||
Some(v) => {
|
||||
hook_cols.push("pre_prompt".into());
|
||||
hook_vals.push(v.clone());
|
||||
}
|
||||
None => (),
|
||||
};
|
||||
match &config.hooks.pre_execution {
|
||||
Some(v) => {
|
||||
hook_cols.push("pre_execution".into());
|
||||
hook_vals.push(v.clone());
|
||||
}
|
||||
None => (),
|
||||
};
|
||||
match &config.hooks.env_change {
|
||||
Some(v) => {
|
||||
hook_cols.push("env_change".into());
|
||||
hook_vals.push(v.clone());
|
||||
}
|
||||
None => (),
|
||||
};
|
||||
match &config.hooks.display_output {
|
||||
Some(v) => {
|
||||
hook_cols.push("display_output".into());
|
||||
hook_vals.push(v.clone());
|
||||
}
|
||||
None => (),
|
||||
};
|
||||
if let Some(ref value) = config.hooks.pre_prompt {
|
||||
hook_cols.push("pre_prompt".into());
|
||||
hook_vals.push(value.clone());
|
||||
}
|
||||
if let Some(ref value) = config.hooks.pre_execution {
|
||||
hook_cols.push("pre_execution".into());
|
||||
hook_vals.push(value.clone());
|
||||
}
|
||||
if let Some(ref value) = config.hooks.env_change {
|
||||
hook_cols.push("env_change".into());
|
||||
hook_vals.push(value.clone());
|
||||
}
|
||||
if let Some(ref value) = config.hooks.display_output {
|
||||
hook_cols.push("display_output".into());
|
||||
hook_vals.push(value.clone());
|
||||
}
|
||||
vals.push(Value::Record {
|
||||
cols: hook_cols,
|
||||
vals: hook_vals,
|
||||
@ -1496,8 +1484,8 @@ fn try_parse_trim_strategy(
|
||||
}
|
||||
|
||||
fn try_parse_trim_methodology(value: &Value) -> Option<TrimStrategy> {
|
||||
match value.as_string() {
|
||||
Ok(value) => match value.to_lowercase().as_str() {
|
||||
if let Ok(value) = value.as_string() {
|
||||
match value.to_lowercase().as_str() {
|
||||
"wrapping" => {
|
||||
return Some(TrimStrategy::Wrap {
|
||||
try_to_keep_words: false,
|
||||
@ -1505,8 +1493,9 @@ fn try_parse_trim_methodology(value: &Value) -> Option<TrimStrategy> {
|
||||
}
|
||||
"truncating" => return Some(TrimStrategy::Truncate { suffix: None }),
|
||||
_ => eprintln!("unrecognized $config.table.trim.methodology value; expected either 'truncating' or 'wrapping'"),
|
||||
},
|
||||
Err(_) => eprintln!("$env.config.table.trim.methodology is not a string"),
|
||||
}
|
||||
} else {
|
||||
eprintln!("$env.config.table.trim.methodology is not a string")
|
||||
}
|
||||
|
||||
None
|
||||
@ -1548,18 +1537,11 @@ fn create_hooks(value: &Value) -> Result<Hooks, ShellError> {
|
||||
|
||||
Ok(hooks)
|
||||
}
|
||||
v => match v.span() {
|
||||
Ok(span) => Err(ShellError::UnsupportedConfigValue(
|
||||
"record for 'hooks' config".into(),
|
||||
"non-record value".into(),
|
||||
span,
|
||||
)),
|
||||
_ => Err(ShellError::UnsupportedConfigValue(
|
||||
"record for 'hooks' config".into(),
|
||||
"non-record value".into(),
|
||||
Span::unknown(),
|
||||
)),
|
||||
},
|
||||
v => Err(ShellError::UnsupportedConfigValue(
|
||||
"record for 'hooks' config".into(),
|
||||
"non-record value".into(),
|
||||
v.span().unwrap_or_else(|_| Span::unknown()),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -484,15 +484,17 @@ impl EngineState {
|
||||
serde_json::to_string_pretty(&decl.signature())
|
||||
.map(|signature| {
|
||||
// Extracting the possible path to the shell used to load the plugin
|
||||
let shell_str = match shell {
|
||||
Some(path) => format!(
|
||||
"-s {}",
|
||||
path.to_str().expect(
|
||||
"shell path was checked during registration as a str"
|
||||
let shell_str = shell
|
||||
.as_ref()
|
||||
.map(|path| {
|
||||
format!(
|
||||
"-s {}",
|
||||
path.to_str().expect(
|
||||
"shell path was checked during registration as a str"
|
||||
)
|
||||
)
|
||||
),
|
||||
None => "".into(),
|
||||
};
|
||||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
// Each signature is stored in the plugin file with the shell and signature
|
||||
// This information will be used when loading the plugin
|
||||
@ -1020,9 +1022,10 @@ impl TypeScope {
|
||||
}
|
||||
|
||||
pub fn add_type(&mut self, input: Type) {
|
||||
match self.outputs.last_mut() {
|
||||
Some(v) => v.push(input),
|
||||
None => self.outputs.push(vec![input]),
|
||||
if let Some(v) = self.outputs.last_mut() {
|
||||
v.push(input)
|
||||
} else {
|
||||
self.outputs.push(vec![input])
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -225,9 +225,10 @@ impl OverlayFrame {
|
||||
}
|
||||
|
||||
pub fn get_decl(&self, name: &[u8], input: &Type) -> Option<DeclId> {
|
||||
match self.decls.get(&(name, input) as &dyn DeclKey) {
|
||||
Some(decl) => Some(*decl),
|
||||
None => self.decls.get(&(name, &Type::Any) as &dyn DeclKey).cloned(),
|
||||
if let Some(decl) = self.decls.get(&(name, input) as &dyn DeclKey) {
|
||||
Some(*decl)
|
||||
} else {
|
||||
self.decls.get(&(name, &Type::Any) as &dyn DeclKey).cloned()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -157,11 +157,12 @@ fn find_best_match_for_name_impl<'c>(
|
||||
let mut dist = dist.unwrap_or_else(|| cmp::max(lookup.len(), 3) / 3);
|
||||
let mut best = None;
|
||||
for c in candidates {
|
||||
match if use_substring_score {
|
||||
let lev_dist = if use_substring_score {
|
||||
lev_distance_with_substrings(lookup, c, dist)
|
||||
} else {
|
||||
lev_distance(lookup, c, dist)
|
||||
} {
|
||||
};
|
||||
match lev_dist {
|
||||
Some(0) => return Some(*c),
|
||||
Some(d) => {
|
||||
dist = d - 1;
|
||||
|
@ -266,13 +266,7 @@ impl PipelineData {
|
||||
let mut output = String::new();
|
||||
|
||||
for val in s {
|
||||
match val {
|
||||
Ok(val) => match val.as_string() {
|
||||
Ok(s) => output.push_str(&s),
|
||||
Err(err) => return Err(err),
|
||||
},
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
output.push_str(&val?.as_string()?);
|
||||
}
|
||||
if trim_end_newline {
|
||||
output.truncate(output.trim_end_matches(LINE_ENDING_PATTERN).len());
|
||||
@ -449,12 +443,10 @@ impl PipelineData {
|
||||
.into_pipeline_data(ctrlc))
|
||||
}
|
||||
}
|
||||
PipelineData::Value(Value::Range { val, .. }, ..) => {
|
||||
match val.into_range_iter(ctrlc.clone()) {
|
||||
Ok(iter) => Ok(iter.flat_map(f).into_pipeline_data(ctrlc)),
|
||||
Err(error) => Err(error),
|
||||
}
|
||||
}
|
||||
PipelineData::Value(Value::Range { val, .. }, ..) => Ok(val
|
||||
.into_range_iter(ctrlc.clone())?
|
||||
.flat_map(f)
|
||||
.into_pipeline_data(ctrlc)),
|
||||
PipelineData::Value(v, ..) => Ok(f(v).into_iter().into_pipeline_data(ctrlc)),
|
||||
}
|
||||
}
|
||||
@ -558,10 +550,10 @@ impl PipelineData {
|
||||
let stderr = stderr.map(|stderr_stream| {
|
||||
let stderr_ctrlc = stderr_stream.ctrlc.clone();
|
||||
let stderr_span = stderr_stream.span;
|
||||
let stderr_bytes = match stderr_stream.into_bytes() {
|
||||
Err(_) => vec![],
|
||||
Ok(bytes) => bytes.item,
|
||||
};
|
||||
let stderr_bytes = stderr_stream
|
||||
.into_bytes()
|
||||
.map(|bytes| bytes.item)
|
||||
.unwrap_or_default();
|
||||
RawStream::new(
|
||||
Box::new(vec![Ok(stderr_bytes)].into_iter()),
|
||||
stderr_ctrlc,
|
||||
@ -642,20 +634,17 @@ impl PipelineData {
|
||||
*/
|
||||
}
|
||||
|
||||
match engine_state.find_decl("table".as_bytes(), &[]) {
|
||||
Some(decl_id) => {
|
||||
let command = engine_state.get_decl(decl_id);
|
||||
if command.get_block_id().is_some() {
|
||||
return self.write_all_and_flush(engine_state, config, no_newline, to_stderr);
|
||||
}
|
||||
|
||||
let table = command.run(engine_state, stack, &Call::new(Span::new(0, 0)), self)?;
|
||||
|
||||
table.write_all_and_flush(engine_state, config, no_newline, to_stderr)?;
|
||||
}
|
||||
None => {
|
||||
self.write_all_and_flush(engine_state, config, no_newline, to_stderr)?;
|
||||
if let Some(decl_id) = engine_state.find_decl("table".as_bytes(), &[]) {
|
||||
let command = engine_state.get_decl(decl_id);
|
||||
if command.get_block_id().is_some() {
|
||||
return self.write_all_and_flush(engine_state, config, no_newline, to_stderr);
|
||||
}
|
||||
|
||||
let table = command.run(engine_state, stack, &Call::new(Span::new(0, 0)), self)?;
|
||||
|
||||
table.write_all_and_flush(engine_state, config, no_newline, to_stderr)?;
|
||||
} else {
|
||||
self.write_all_and_flush(engine_state, config, no_newline, to_stderr)?;
|
||||
};
|
||||
|
||||
Ok(0)
|
||||
|
@ -197,9 +197,6 @@ impl Value {
|
||||
Value::Binary { val, .. } => Ok(match std::str::from_utf8(val) {
|
||||
Ok(s) => s.to_string(),
|
||||
Err(_) => {
|
||||
// println!("{:?}", e);
|
||||
// println!("bytes: {}", pretty_hex::pretty_hex(&val));
|
||||
// panic!("let's see it");
|
||||
return Err(ShellError::CantConvert(
|
||||
"string".into(),
|
||||
"binary".into(),
|
||||
@ -495,9 +492,10 @@ impl Value {
|
||||
separator: &str,
|
||||
config: &Config,
|
||||
) -> Result<String, ShellError> {
|
||||
match self {
|
||||
Value::Error { error } => Err(error.to_owned()),
|
||||
_ => Ok(self.into_string(separator, config)),
|
||||
if let Value::Error { error } = self {
|
||||
Err(error.to_owned())
|
||||
} else {
|
||||
Ok(self.into_string(separator, config))
|
||||
}
|
||||
}
|
||||
|
||||
@ -1813,10 +1811,13 @@ impl PartialOrd for Value {
|
||||
result
|
||||
}
|
||||
}
|
||||
Value::LazyRecord { val, .. } => match val.collect() {
|
||||
Ok(rhs) => self.partial_cmp(&rhs),
|
||||
Err(_) => None,
|
||||
},
|
||||
Value::LazyRecord { val, .. } => {
|
||||
if let Ok(rhs) = val.collect() {
|
||||
self.partial_cmp(&rhs)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
Value::List { .. } => Some(Ordering::Less),
|
||||
Value::Block { .. } => Some(Ordering::Less),
|
||||
Value::Closure { .. } => Some(Ordering::Less),
|
||||
@ -1967,10 +1968,13 @@ impl PartialOrd for Value {
|
||||
Value::CustomValue { .. } => Some(Ordering::Less),
|
||||
},
|
||||
(Value::CustomValue { val: lhs, .. }, rhs) => lhs.partial_cmp(rhs),
|
||||
(Value::LazyRecord { val, .. }, rhs) => match val.collect() {
|
||||
Ok(val) => val.partial_cmp(rhs),
|
||||
Err(_) => None,
|
||||
},
|
||||
(Value::LazyRecord { val, .. }, rhs) => {
|
||||
if let Ok(val) = val.collect() {
|
||||
val.partial_cmp(rhs)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2012,13 +2016,14 @@ impl Value {
|
||||
span,
|
||||
}),
|
||||
(Value::Date { val: lhs, .. }, Value::Duration { val: rhs, .. }) => {
|
||||
match lhs.checked_add_signed(chrono::Duration::nanoseconds(*rhs)) {
|
||||
Some(val) => Ok(Value::Date { val, span }),
|
||||
_ => Err(ShellError::OperatorOverflow(
|
||||
if let Some(val) = lhs.checked_add_signed(chrono::Duration::nanoseconds(*rhs)) {
|
||||
Ok(Value::Date { val, span })
|
||||
} else {
|
||||
Err(ShellError::OperatorOverflow(
|
||||
"addition operation overflowed".into(),
|
||||
span,
|
||||
"".into(),
|
||||
)),
|
||||
))
|
||||
}
|
||||
}
|
||||
(Value::Duration { val: lhs, .. }, Value::Duration { val: rhs, .. }) => {
|
||||
@ -2114,13 +2119,14 @@ impl Value {
|
||||
(Value::Date { val: lhs, .. }, Value::Date { val: rhs, .. }) => {
|
||||
let result = lhs.signed_duration_since(*rhs);
|
||||
|
||||
match result.num_nanoseconds() {
|
||||
Some(v) => Ok(Value::Duration { val: v, span }),
|
||||
None => Err(ShellError::OperatorOverflow(
|
||||
if let Some(v) = result.num_nanoseconds() {
|
||||
Ok(Value::Duration { val: v, span })
|
||||
} else {
|
||||
Err(ShellError::OperatorOverflow(
|
||||
"subtraction operation overflowed".into(),
|
||||
span,
|
||||
"".into(),
|
||||
)),
|
||||
))
|
||||
}
|
||||
}
|
||||
(Value::Date { val: lhs, .. }, Value::Duration { val: rhs, .. }) => {
|
||||
@ -2552,18 +2558,19 @@ impl Value {
|
||||
return Err(ShellError::TypeMismatch("compatible type".to_string(), op));
|
||||
}
|
||||
|
||||
match self.partial_cmp(rhs) {
|
||||
Some(ordering) => Ok(Value::Bool {
|
||||
if let Some(ordering) = self.partial_cmp(rhs) {
|
||||
Ok(Value::Bool {
|
||||
val: matches!(ordering, Ordering::Less),
|
||||
span,
|
||||
}),
|
||||
None => Err(ShellError::OperatorMismatch {
|
||||
})
|
||||
} else {
|
||||
Err(ShellError::OperatorMismatch {
|
||||
op_span: op,
|
||||
lhs_ty: self.get_type(),
|
||||
lhs_span: self.span()?,
|
||||
rhs_ty: rhs.get_type(),
|
||||
rhs_span: rhs.span()?,
|
||||
}),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -2584,19 +2591,18 @@ impl Value {
|
||||
return Err(ShellError::TypeMismatch("compatible type".to_string(), op));
|
||||
}
|
||||
|
||||
match self.partial_cmp(rhs) {
|
||||
Some(ordering) => Ok(Value::Bool {
|
||||
self.partial_cmp(rhs)
|
||||
.map(|ordering| Value::Bool {
|
||||
val: matches!(ordering, Ordering::Less | Ordering::Equal),
|
||||
span,
|
||||
}),
|
||||
None => Err(ShellError::OperatorMismatch {
|
||||
})
|
||||
.ok_or(ShellError::OperatorMismatch {
|
||||
op_span: op,
|
||||
lhs_ty: self.get_type(),
|
||||
lhs_span: self.span()?,
|
||||
rhs_ty: rhs.get_type(),
|
||||
rhs_span: rhs.span()?,
|
||||
}),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn gt(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
|
||||
@ -2616,19 +2622,18 @@ impl Value {
|
||||
return Err(ShellError::TypeMismatch("compatible type".to_string(), op));
|
||||
}
|
||||
|
||||
match self.partial_cmp(rhs) {
|
||||
Some(ordering) => Ok(Value::Bool {
|
||||
self.partial_cmp(rhs)
|
||||
.map(|ordering| Value::Bool {
|
||||
val: matches!(ordering, Ordering::Greater),
|
||||
span,
|
||||
}),
|
||||
None => Err(ShellError::OperatorMismatch {
|
||||
})
|
||||
.ok_or(ShellError::OperatorMismatch {
|
||||
op_span: op,
|
||||
lhs_ty: self.get_type(),
|
||||
lhs_span: self.span()?,
|
||||
rhs_ty: rhs.get_type(),
|
||||
rhs_span: rhs.span()?,
|
||||
}),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn gte(&self, op: Span, rhs: &Value, span: Span) -> Result<Value, ShellError> {
|
||||
@ -2668,12 +2673,13 @@ impl Value {
|
||||
return lhs.operation(*span, Operator::Comparison(Comparison::Equal), op, rhs);
|
||||
}
|
||||
|
||||
match self.partial_cmp(rhs) {
|
||||
Some(ordering) => Ok(Value::Bool {
|
||||
if let Some(ordering) = self.partial_cmp(rhs) {
|
||||
Ok(Value::Bool {
|
||||
val: matches!(ordering, Ordering::Equal),
|
||||
span,
|
||||
}),
|
||||
None => match (self, rhs) {
|
||||
})
|
||||
} else {
|
||||
match (self, rhs) {
|
||||
(Value::Nothing { .. }, _) | (_, Value::Nothing { .. }) => {
|
||||
Ok(Value::Bool { val: false, span })
|
||||
}
|
||||
@ -2684,7 +2690,7 @@ impl Value {
|
||||
rhs_ty: rhs.get_type(),
|
||||
rhs_span: rhs.span()?,
|
||||
}),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2693,12 +2699,13 @@ impl Value {
|
||||
return lhs.operation(*span, Operator::Comparison(Comparison::NotEqual), op, rhs);
|
||||
}
|
||||
|
||||
match self.partial_cmp(rhs) {
|
||||
Some(ordering) => Ok(Value::Bool {
|
||||
if let Some(ordering) = self.partial_cmp(rhs) {
|
||||
Ok(Value::Bool {
|
||||
val: !matches!(ordering, Ordering::Equal),
|
||||
span,
|
||||
}),
|
||||
None => match (self, rhs) {
|
||||
})
|
||||
} else {
|
||||
match (self, rhs) {
|
||||
(Value::Nothing { .. }, _) | (_, Value::Nothing { .. }) => {
|
||||
Ok(Value::Bool { val: true, span })
|
||||
}
|
||||
@ -2709,7 +2716,7 @@ impl Value {
|
||||
rhs_ty: rhs.get_type(),
|
||||
rhs_span: rhs.span()?,
|
||||
}),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2844,9 +2851,10 @@ impl Value {
|
||||
},
|
||||
) => {
|
||||
let is_match = match engine_state.regex_cache.try_lock() {
|
||||
Ok(mut cache) => match cache.get(rhs) {
|
||||
Some(regex) => regex.is_match(lhs),
|
||||
None => {
|
||||
Ok(mut cache) => {
|
||||
if let Some(regex) = cache.get(rhs) {
|
||||
regex.is_match(lhs)
|
||||
} else {
|
||||
let regex = Regex::new(rhs).map_err(|e| {
|
||||
ShellError::UnsupportedInput(
|
||||
format!("{e}"),
|
||||
@ -2859,7 +2867,7 @@ impl Value {
|
||||
cache.put(rhs.clone(), regex);
|
||||
ret
|
||||
}
|
||||
},
|
||||
}
|
||||
Err(_) => {
|
||||
let regex = Regex::new(rhs).map_err(|e| {
|
||||
ShellError::UnsupportedInput(
|
||||
|
@ -84,28 +84,24 @@ impl Iterator for RawStream {
|
||||
|
||||
// If we know we're already binary, just output that
|
||||
if self.is_binary {
|
||||
match self.stream.next() {
|
||||
Some(buffer) => match buffer {
|
||||
Ok(mut v) => {
|
||||
if !self.leftover.is_empty() {
|
||||
while let Some(b) = self.leftover.pop() {
|
||||
v.insert(0, b);
|
||||
}
|
||||
self.stream.next().map(|buffer| {
|
||||
buffer.map(|mut v| {
|
||||
if !self.leftover.is_empty() {
|
||||
for b in self.leftover.drain(..).rev() {
|
||||
v.insert(0, b);
|
||||
}
|
||||
Some(Ok(Value::Binary {
|
||||
val: v,
|
||||
span: self.span,
|
||||
}))
|
||||
}
|
||||
Err(e) => Some(Err(e)),
|
||||
},
|
||||
None => None,
|
||||
}
|
||||
Value::Binary {
|
||||
val: v,
|
||||
span: self.span,
|
||||
}
|
||||
})
|
||||
})
|
||||
} else {
|
||||
// We *may* be text. We're only going to try utf-8. Other decodings
|
||||
// needs to be taken as binary first, then passed through `decode`.
|
||||
match self.stream.next() {
|
||||
Some(buffer) => match buffer {
|
||||
if let Some(buffer) = self.stream.next() {
|
||||
match buffer {
|
||||
Ok(mut v) => {
|
||||
if !self.leftover.is_empty() {
|
||||
while let Some(b) = self.leftover.pop() {
|
||||
@ -164,20 +160,17 @@ impl Iterator for RawStream {
|
||||
}
|
||||
}
|
||||
Err(e) => Some(Err(e)),
|
||||
},
|
||||
None => {
|
||||
if !self.leftover.is_empty() {
|
||||
let output = Ok(Value::Binary {
|
||||
val: self.leftover.clone(),
|
||||
span: self.span,
|
||||
});
|
||||
self.leftover.clear();
|
||||
|
||||
Some(output)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
} else if !self.leftover.is_empty() {
|
||||
let output = Ok(Value::Binary {
|
||||
val: self.leftover.clone(),
|
||||
span: self.span,
|
||||
});
|
||||
self.leftover.clear();
|
||||
|
||||
Some(output)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user