Refactor env conversion, yeet Value::follow_cell_path_not... (#10926)

# Description
Replaces the only usage of `Value::follow_cell_path_not_from_user_input`
with some `Record::get`s.

# User-Facing Changes
Breaking change for `nu-protocol`, since
`Value::follow_cell_path_not_from_user_input` was deleted.

Nushell now reports errors for when environment conversions are not
closures.
This commit is contained in:
Ian Manske 2023-11-08 22:57:24 +00:00 committed by GitHub
parent 92503e6571
commit aed4b626b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 84 deletions

View File

@ -1,7 +1,7 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use nu_protocol::ast::{Call, Expr, PathMember}; use nu_protocol::ast::{Call, Expr};
use nu_protocol::engine::{EngineState, Stack, StateWorkingSet, PWD_ENV}; use nu_protocol::engine::{EngineState, Stack, StateWorkingSet, PWD_ENV};
use nu_protocol::{Config, PipelineData, ShellError, Span, Value, VarId}; use nu_protocol::{Config, PipelineData, ShellError, Span, Value, VarId};
@ -367,27 +367,18 @@ fn get_converted_value(
orig_val: &Value, orig_val: &Value,
direction: &str, direction: &str,
) -> ConversionResult { ) -> ConversionResult {
if let Some(env_conversions) = stack.get_env_var(engine_state, ENV_CONVERSIONS) { let conversions = stack.get_env_var(engine_state, ENV_CONVERSIONS);
let env_span = env_conversions.span(); let conversion = conversions
let val_span = orig_val.span(); .as_ref()
.and_then(|val| val.as_record().ok())
.and_then(|record| record.get(name))
.and_then(|val| val.as_record().ok())
.and_then(|record| record.get(direction));
let path_members = &[ if let Some(conversion) = conversion {
PathMember::String { let from_span = conversion.span();
val: name.to_string(), match conversion.as_closure() {
span: env_span, Ok(val) => {
optional: false,
},
PathMember::String {
val: direction.to_string(),
span: env_span,
optional: false,
},
];
if let Ok(v) = env_conversions.follow_cell_path_not_from_user_input(path_members, false) {
let from_span = v.span();
match v {
Value::Closure { val, .. } => {
let block = engine_state.get_block(val.block_id); let block = engine_state.get_block(val.block_id);
if let Some(var) = block.signature.get_positional(0) { if let Some(var) = block.signature.get_positional(0) {
@ -396,6 +387,7 @@ fn get_converted_value(
stack.add_var(*var_id, orig_val.clone()); stack.add_var(*var_id, orig_val.clone());
} }
let val_span = orig_val.span();
let result = eval_block( let result = eval_block(
engine_state, engine_state,
&mut stack, &mut stack,
@ -416,10 +408,7 @@ fn get_converted_value(
}) })
} }
} }
_ => ConversionResult::CellPathError, Err(e) => ConversionResult::ConversionError(e),
}
} else {
ConversionResult::CellPathError
} }
} else { } else {
ConversionResult::CellPathError ConversionResult::CellPathError

View File

@ -919,23 +919,6 @@ impl Value {
self, self,
cell_path: &[PathMember], cell_path: &[PathMember],
insensitive: bool, insensitive: bool,
) -> Result<Value, ShellError> {
self.follow_cell_path_helper(cell_path, insensitive, true)
}
pub fn follow_cell_path_not_from_user_input(
self,
cell_path: &[PathMember],
insensitive: bool,
) -> Result<Value, ShellError> {
self.follow_cell_path_helper(cell_path, insensitive, false)
}
fn follow_cell_path_helper(
self,
cell_path: &[PathMember],
insensitive: bool,
from_user_input: bool,
) -> Result<Value, ShellError> { ) -> Result<Value, ShellError> {
let mut current = self; let mut current = self;
@ -1033,17 +1016,11 @@ impl Value {
current = found.1.clone(); current = found.1.clone();
} else if *optional { } else if *optional {
return Ok(Value::nothing(*origin_span)); // short-circuit return Ok(Value::nothing(*origin_span)); // short-circuit
} else { } else if let Some(suggestion) =
if from_user_input {
if let Some(suggestion) =
did_you_mean(val.columns(), column_name) did_you_mean(val.columns(), column_name)
{ {
return Err(ShellError::DidYouMean( return Err(ShellError::DidYouMean(suggestion, *origin_span));
suggestion, } else {
*origin_span,
));
}
}
return Err(ShellError::CantFindColumn { return Err(ShellError::CantFindColumn {
col_name: column_name.to_string(), col_name: column_name.to_string(),
span: *origin_span, span: *origin_span,
@ -1058,15 +1035,9 @@ impl Value {
current = val.get_column_value(column_name)?; current = val.get_column_value(column_name)?;
} else if *optional { } else if *optional {
return Ok(Value::nothing(*origin_span)); // short-circuit return Ok(Value::nothing(*origin_span)); // short-circuit
} else if let Some(suggestion) = did_you_mean(&columns, column_name) {
return Err(ShellError::DidYouMean(suggestion, *origin_span));
} else { } else {
if from_user_input {
if let Some(suggestion) = did_you_mean(&columns, column_name) {
return Err(ShellError::DidYouMean(
suggestion,
*origin_span,
));
}
}
return Err(ShellError::CantFindColumn { return Err(ShellError::CantFindColumn {
col_name: column_name.to_string(), col_name: column_name.to_string(),
span: *origin_span, span: *origin_span,