Skip to content

Commit

Permalink
Make FromValue take owned Values (#10900)
Browse files Browse the repository at this point in the history
# Description
Changes `FromValue` to take owned `Value`s instead of borrowed `Value`s.
This eliminates some unnecessary clones (e.g., in `call_ext.rs`).

# User-Facing Changes
Breaking API change for `nu_protocol`.
  • Loading branch information
IanManske authored Oct 31, 2023
1 parent 1c52b11 commit 15c22db
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 116 deletions.
7 changes: 4 additions & 3 deletions crates/nu-cmd-dataframe/src/dataframe/utils.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
use nu_protocol::{FromValue, ShellError, Value};

pub fn extract_strings(value: Value) -> Result<Vec<String>, ShellError> {
let span = value.span();
match (
<String as FromValue>::from_value(&value),
<Vec<String> as FromValue>::from_value(&value),
<String as FromValue>::from_value(value.clone()),
<Vec<String> as FromValue>::from_value(value),
) {
(Ok(col), Err(_)) => Ok(vec![col]),
(Err(_), Ok(cols)) => Ok(cols),
_ => Err(ShellError::IncompatibleParametersSingle {
msg: "Expected a string or list of strings".into(),
span: value.span(),
span,
}),
}
}
2 changes: 1 addition & 1 deletion crates/nu-command/src/filters/drop/column.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ fn get_cellpath_columns(keep_cols: Vec<String>, span: Span) -> Vec<CellPath> {
let mut output = vec![];
for keep_col in keep_cols {
let val = Value::string(keep_col, span);
let cell_path = match CellPath::from_value(&val) {
let cell_path = match CellPath::from_value(val) {
Ok(v) => v,
Err(_) => return vec![],
};
Expand Down
8 changes: 3 additions & 5 deletions crates/nu-command/src/filters/drop/nth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use nu_engine::CallExt;
use nu_protocol::ast::{Call, RangeInclusion};
use nu_protocol::engine::{Command, EngineState, Stack};
use nu_protocol::{
Category, Example, FromValue, IntoInterruptiblePipelineData, PipelineData, PipelineIterator,
Range, ShellError, Signature, Span, Spanned, SyntaxShape, Type, Value,
Category, Example, IntoInterruptiblePipelineData, PipelineData, PipelineIterator, Range,
ShellError, Signature, Span, Spanned, SyntaxShape, Type, Value,
};

#[derive(Clone)]
Expand Down Expand Up @@ -185,9 +185,7 @@ fn extract_int_or_range(
let value = call.req::<Value>(engine_state, stack, 0)?;

let int_opt = value.as_int().map(Either::Left).ok();
let range_opt: Result<nu_protocol::Range, ShellError> = FromValue::from_value(&value);

let range_opt = range_opt.map(Either::Right).ok();
let range_opt = value.as_range().map(|r| Either::Right(r.clone())).ok();

int_opt
.or(range_opt)
Expand Down
2 changes: 1 addition & 1 deletion crates/nu-command/src/filters/insert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ fn insert(

// Replace is a block, so set it up and run it instead of using it as the replacement
if replacement.as_block().is_ok() {
let capture_block: Closure = FromValue::from_value(&replacement)?;
let capture_block = Closure::from_value(replacement)?;
let block = engine_state.get_block(capture_block.block_id).clone();

let mut stack = stack.captures_to_stack(&capture_block.captures);
Expand Down
2 changes: 1 addition & 1 deletion crates/nu-command/src/filters/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ fn update(

// Replace is a block, so set it up and run it instead of using it as the replacement
if replacement.as_block().is_ok() {
let capture_block: Closure = FromValue::from_value(&replacement)?;
let capture_block = Closure::from_value(replacement)?;
let block = engine_state.get_block(capture_block.block_id).clone();

let mut stack = stack.captures_to_stack(&capture_block.captures);
Expand Down
2 changes: 1 addition & 1 deletion crates/nu-command/src/filters/upsert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ fn upsert(

// Replace is a block, so set it up and run it instead of using it as the replacement
if replacement.as_block().is_ok() {
let capture_block: Closure = FromValue::from_value(&replacement)?;
let capture_block = Closure::from_value(replacement)?;
let block = engine_state.get_block(capture_block.block_id).clone();

let mut stack = stack.captures_to_stack(&capture_block.captures);
Expand Down
16 changes: 8 additions & 8 deletions crates/nu-engine/src/call_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ impl CallExt for Call {
) -> Result<Option<T>, ShellError> {
if let Some(expr) = self.get_flag_expr(name) {
let result = eval_expression(engine_state, stack, &expr)?;
FromValue::from_value(&result).map(Some)
FromValue::from_value(result).map(Some)
} else {
Ok(None)
}
Expand All @@ -84,7 +84,7 @@ impl CallExt for Call {
) -> Result<Option<T>, ShellError> {
if let Some(expr) = self.get_flag_expr(name) {
let result = eval_constant(working_set, &expr)?;
FromValue::from_value(&result).map(Some)
FromValue::from_value(result).map(Some)
} else {
Ok(None)
}
Expand All @@ -100,7 +100,7 @@ impl CallExt for Call {

for expr in self.positional_iter().skip(starting_pos) {
let result = eval_expression(engine_state, stack, expr)?;
output.push(FromValue::from_value(&result)?);
output.push(FromValue::from_value(result)?);
}

Ok(output)
Expand All @@ -115,7 +115,7 @@ impl CallExt for Call {

for expr in self.positional_iter().skip(starting_pos) {
let result = eval_constant(working_set, expr)?;
output.push(FromValue::from_value(&result)?);
output.push(FromValue::from_value(result)?);
}

Ok(output)
Expand All @@ -129,7 +129,7 @@ impl CallExt for Call {
) -> Result<Option<T>, ShellError> {
if let Some(expr) = self.positional_nth(pos) {
let result = eval_expression(engine_state, stack, expr)?;
FromValue::from_value(&result).map(Some)
FromValue::from_value(result).map(Some)
} else {
Ok(None)
}
Expand All @@ -143,7 +143,7 @@ impl CallExt for Call {
) -> Result<T, ShellError> {
if let Some(expr) = self.positional_nth(pos) {
let result = eval_expression(engine_state, stack, expr)?;
FromValue::from_value(&result)
FromValue::from_value(result)
} else if self.positional_len() == 0 {
Err(ShellError::AccessEmptyContent { span: self.head })
} else {
Expand All @@ -161,7 +161,7 @@ impl CallExt for Call {
) -> Result<T, ShellError> {
if let Some(expr) = self.positional_nth(pos) {
let result = eval_constant(working_set, expr)?;
FromValue::from_value(&result)
FromValue::from_value(result)
} else if self.positional_len() == 0 {
Err(ShellError::AccessEmptyContent { span: self.head })
} else {
Expand All @@ -180,7 +180,7 @@ impl CallExt for Call {
) -> Result<T, ShellError> {
if let Some(expr) = self.get_parser_info(name) {
let result = eval_expression(engine_state, stack, expr)?;
FromValue::from_value(&result)
FromValue::from_value(result)
} else if self.parser_info.is_empty() {
Err(ShellError::AccessEmptyContent { span: self.head })
} else {
Expand Down
8 changes: 4 additions & 4 deletions crates/nu-plugin/src/protocol/evaluated_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ impl EvaluatedCall {
/// ```
pub fn get_flag<T: FromValue>(&self, name: &str) -> Result<Option<T>, ShellError> {
if let Some(value) = self.get_flag_value(name) {
FromValue::from_value(&value).map(Some)
FromValue::from_value(value).map(Some)
} else {
Ok(None)
}
Expand Down Expand Up @@ -272,7 +272,7 @@ impl EvaluatedCall {
self.positional
.iter()
.skip(starting_pos)
.map(|value| FromValue::from_value(value))
.map(|value| FromValue::from_value(value.clone()))
.collect()
}

Expand All @@ -283,7 +283,7 @@ impl EvaluatedCall {
/// or an error that can be passed back to the shell on error.
pub fn opt<T: FromValue>(&self, pos: usize) -> Result<Option<T>, ShellError> {
if let Some(value) = self.nth(pos) {
FromValue::from_value(&value).map(Some)
FromValue::from_value(value).map(Some)
} else {
Ok(None)
}
Expand All @@ -296,7 +296,7 @@ impl EvaluatedCall {
/// be passed back to the shell.
pub fn req<T: FromValue>(&self, pos: usize) -> Result<T, ShellError> {
if let Some(value) = self.nth(pos) {
FromValue::from_value(&value)
FromValue::from_value(value)
} else if self.positional.is_empty() {
Err(ShellError::AccessEmptyContent { span: self.head })
} else {
Expand Down
Loading

0 comments on commit 15c22db

Please sign in to comment.