mirror of
https://github.com/nushell/nushell.git
synced 2024-11-22 08:23:24 +01:00
Reuse Closure
type in Value::Closure
(#10894)
# Description Reuses the existing `Closure` type in `Value::Closure`. This will help with the span refactoring for `Value`. Additionally, this allows us to more easily box or unbox the `Closure` case should we chose to do so in the future. # User-Facing Changes Breaking API change for `nu_protocol`.
This commit is contained in:
parent
d4cbab454e
commit
72cb4b6032
@ -40,13 +40,9 @@ fn get_prompt_string(
|
|||||||
stack
|
stack
|
||||||
.get_env_var(engine_state, prompt)
|
.get_env_var(engine_state, prompt)
|
||||||
.and_then(|v| match v {
|
.and_then(|v| match v {
|
||||||
Value::Closure {
|
Value::Closure { val, .. } => {
|
||||||
val: block_id,
|
let block = engine_state.get_block(val.block_id);
|
||||||
captures,
|
let mut stack = stack.captures_to_stack(&val.captures);
|
||||||
..
|
|
||||||
} => {
|
|
||||||
let block = engine_state.get_block(block_id);
|
|
||||||
let mut stack = stack.captures_to_stack(&captures);
|
|
||||||
// Use eval_subexpression to force a redirection of output, so we can use everything in prompt
|
// Use eval_subexpression to force a redirection of output, so we can use everything in prompt
|
||||||
let ret_val =
|
let ret_val =
|
||||||
eval_subexpression(engine_state, &mut stack, block, PipelineData::empty());
|
eval_subexpression(engine_state, &mut stack, block, PipelineData::empty());
|
||||||
|
@ -248,11 +248,11 @@ pub(crate) fn add_columnar_menu(
|
|||||||
Value::Nothing { .. } => {
|
Value::Nothing { .. } => {
|
||||||
Ok(line_editor.with_menu(ReedlineMenu::EngineCompleter(Box::new(columnar_menu))))
|
Ok(line_editor.with_menu(ReedlineMenu::EngineCompleter(Box::new(columnar_menu))))
|
||||||
}
|
}
|
||||||
Value::Closure { val, captures, .. } => {
|
Value::Closure { val, .. } => {
|
||||||
let menu_completer = NuMenuCompleter::new(
|
let menu_completer = NuMenuCompleter::new(
|
||||||
*val,
|
val.block_id,
|
||||||
span,
|
span,
|
||||||
stack.captures_to_stack(captures),
|
stack.captures_to_stack(&val.captures),
|
||||||
engine_state,
|
engine_state,
|
||||||
only_buffer_difference,
|
only_buffer_difference,
|
||||||
);
|
);
|
||||||
@ -330,11 +330,11 @@ pub(crate) fn add_list_menu(
|
|||||||
Value::Nothing { .. } => {
|
Value::Nothing { .. } => {
|
||||||
Ok(line_editor.with_menu(ReedlineMenu::HistoryMenu(Box::new(list_menu))))
|
Ok(line_editor.with_menu(ReedlineMenu::HistoryMenu(Box::new(list_menu))))
|
||||||
}
|
}
|
||||||
Value::Closure { val, captures, .. } => {
|
Value::Closure { val, .. } => {
|
||||||
let menu_completer = NuMenuCompleter::new(
|
let menu_completer = NuMenuCompleter::new(
|
||||||
*val,
|
val.block_id,
|
||||||
span,
|
span,
|
||||||
stack.captures_to_stack(captures),
|
stack.captures_to_stack(&val.captures),
|
||||||
engine_state,
|
engine_state,
|
||||||
only_buffer_difference,
|
only_buffer_difference,
|
||||||
);
|
);
|
||||||
@ -448,11 +448,11 @@ pub(crate) fn add_description_menu(
|
|||||||
completer,
|
completer,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
Value::Closure { val, captures, .. } => {
|
Value::Closure { val, .. } => {
|
||||||
let menu_completer = NuMenuCompleter::new(
|
let menu_completer = NuMenuCompleter::new(
|
||||||
*val,
|
val.block_id,
|
||||||
span,
|
span,
|
||||||
stack.captures_to_stack(captures),
|
stack.captures_to_stack(&val.captures),
|
||||||
engine_state,
|
engine_state,
|
||||||
only_buffer_difference,
|
only_buffer_difference,
|
||||||
);
|
);
|
||||||
|
@ -166,41 +166,37 @@ pub fn eval_hook(
|
|||||||
value.clone().follow_cell_path(&[condition_path], false)
|
value.clone().follow_cell_path(&[condition_path], false)
|
||||||
{
|
{
|
||||||
let other_span = condition.span();
|
let other_span = condition.span();
|
||||||
match condition {
|
if let Ok(block_id) = condition.as_block() {
|
||||||
Value::Block { val: block_id, .. } | Value::Closure { val: block_id, .. } => {
|
match run_hook_block(
|
||||||
match run_hook_block(
|
engine_state,
|
||||||
engine_state,
|
stack,
|
||||||
stack,
|
block_id,
|
||||||
block_id,
|
None,
|
||||||
None,
|
arguments.clone(),
|
||||||
arguments.clone(),
|
other_span,
|
||||||
other_span,
|
) {
|
||||||
) {
|
Ok(pipeline_data) => {
|
||||||
Ok(pipeline_data) => {
|
if let PipelineData::Value(Value::Bool { val, .. }, ..) = pipeline_data
|
||||||
if let PipelineData::Value(Value::Bool { val, .. }, ..) =
|
{
|
||||||
pipeline_data
|
val
|
||||||
{
|
} else {
|
||||||
val
|
return Err(ShellError::UnsupportedConfigValue(
|
||||||
} else {
|
"boolean output".to_string(),
|
||||||
return Err(ShellError::UnsupportedConfigValue(
|
"other PipelineData variant".to_string(),
|
||||||
"boolean output".to_string(),
|
other_span,
|
||||||
"other PipelineData variant".to_string(),
|
));
|
||||||
other_span,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
return Err(err);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Err(err) => {
|
||||||
|
return Err(err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
other => {
|
} else {
|
||||||
return Err(ShellError::UnsupportedConfigValue(
|
return Err(ShellError::UnsupportedConfigValue(
|
||||||
"block".to_string(),
|
"block".to_string(),
|
||||||
format!("{}", other.get_type()),
|
format!("{}", condition.get_type()),
|
||||||
other_span,
|
other_span,
|
||||||
));
|
));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// always run the hook
|
// always run the hook
|
||||||
@ -280,11 +276,11 @@ pub fn eval_hook(
|
|||||||
source_span,
|
source_span,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
Value::Closure { val: block_id, .. } => {
|
Value::Closure { val, .. } => {
|
||||||
run_hook_block(
|
run_hook_block(
|
||||||
engine_state,
|
engine_state,
|
||||||
stack,
|
stack,
|
||||||
block_id,
|
val.block_id,
|
||||||
input,
|
input,
|
||||||
arguments,
|
arguments,
|
||||||
source_span,
|
source_span,
|
||||||
@ -303,8 +299,8 @@ pub fn eval_hook(
|
|||||||
Value::Block { val: block_id, .. } => {
|
Value::Block { val: block_id, .. } => {
|
||||||
output = run_hook_block(engine_state, stack, *block_id, input, arguments, span)?;
|
output = run_hook_block(engine_state, stack, *block_id, input, arguments, span)?;
|
||||||
}
|
}
|
||||||
Value::Closure { val: block_id, .. } => {
|
Value::Closure { val, .. } => {
|
||||||
output = run_hook_block(engine_state, stack, *block_id, input, arguments, span)?;
|
output = run_hook_block(engine_state, stack, val.block_id, input, arguments, span)?;
|
||||||
}
|
}
|
||||||
other => {
|
other => {
|
||||||
return Err(ShellError::UnsupportedConfigValue(
|
return Err(ShellError::UnsupportedConfigValue(
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
ast::Call,
|
ast::Call,
|
||||||
engine::{Command, EngineState, Stack, StateWorkingSet},
|
engine::{Closure, Command, EngineState, Stack, StateWorkingSet},
|
||||||
record, Category, Example, IntoPipelineData, PipelineData, PipelineMetadata, Record,
|
record, Category, Example, IntoPipelineData, PipelineData, PipelineMetadata, Record,
|
||||||
ShellError, Signature, Type, Value,
|
ShellError, Signature, Type, Value,
|
||||||
};
|
};
|
||||||
@ -328,7 +328,11 @@ fn describe_value(
|
|||||||
),
|
),
|
||||||
head,
|
head,
|
||||||
),
|
),
|
||||||
Value::Block { val, .. } | Value::Closure { val, .. } => {
|
Value::Block { val, .. }
|
||||||
|
| Value::Closure {
|
||||||
|
val: Closure { block_id: val, .. },
|
||||||
|
..
|
||||||
|
} => {
|
||||||
let block = engine_state.map(|engine_state| engine_state.get_block(val));
|
let block = engine_state.map(|engine_state| engine_state.get_block(val));
|
||||||
|
|
||||||
if let Some(block) = block {
|
if let Some(block) = block {
|
||||||
|
@ -57,15 +57,11 @@ impl<'a> StyleComputer<'a> {
|
|||||||
Some(ComputableStyle::Closure(v)) => {
|
Some(ComputableStyle::Closure(v)) => {
|
||||||
let span = v.span();
|
let span = v.span();
|
||||||
match v {
|
match v {
|
||||||
Value::Closure {
|
Value::Closure { val, .. } => {
|
||||||
val: block_id,
|
let block = self.engine_state.get_block(val.block_id).clone();
|
||||||
captures,
|
|
||||||
..
|
|
||||||
} => {
|
|
||||||
let block = self.engine_state.get_block(*block_id).clone();
|
|
||||||
// Because captures_to_stack() clones, we don't need to use with_env() here
|
// Because captures_to_stack() clones, we don't need to use with_env() here
|
||||||
// (contrast with_env() usage in `each` or `do`).
|
// (contrast with_env() usage in `each` or `do`).
|
||||||
let mut stack = self.stack.captures_to_stack(captures);
|
let mut stack = self.stack.captures_to_stack(&val.captures);
|
||||||
|
|
||||||
// Support 1-argument blocks as well as 0-argument blocks.
|
// Support 1-argument blocks as well as 0-argument blocks.
|
||||||
if let Some(var) = block.signature.get_positional(0) {
|
if let Some(var) = block.signature.get_positional(0) {
|
||||||
|
@ -178,7 +178,10 @@ impl PartialEq for HashableValue {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use nu_protocol::ast::{CellPath, PathMember};
|
use nu_protocol::{
|
||||||
|
ast::{CellPath, PathMember},
|
||||||
|
engine::Closure,
|
||||||
|
};
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -237,7 +240,13 @@ mod test {
|
|||||||
let span = Span::test_data();
|
let span = Span::test_data();
|
||||||
let values = [
|
let values = [
|
||||||
Value::list(vec![Value::bool(true, span)], span),
|
Value::list(vec![Value::bool(true, span)], span),
|
||||||
Value::closure(0, HashMap::new(), span),
|
Value::closure(
|
||||||
|
Closure {
|
||||||
|
block_id: 0,
|
||||||
|
captures: HashMap::new(),
|
||||||
|
},
|
||||||
|
span,
|
||||||
|
),
|
||||||
Value::nothing(span),
|
Value::nothing(span),
|
||||||
Value::error(ShellError::DidYouMean("what?".to_string(), span), span),
|
Value::error(ShellError::DidYouMean("what?".to_string(), span), span),
|
||||||
Value::cell_path(
|
Value::cell_path(
|
||||||
|
@ -259,7 +259,7 @@ fn nu_value_to_string(value: Value, separator: &str) -> String {
|
|||||||
Err(error) => format!("{error:?}"),
|
Err(error) => format!("{error:?}"),
|
||||||
},
|
},
|
||||||
Value::Block { val, .. } => format!("<Block {val}>"),
|
Value::Block { val, .. } => format!("<Block {val}>"),
|
||||||
Value::Closure { val, .. } => format!("<Closure {val}>"),
|
Value::Closure { val, .. } => format!("<Closure {}>", val.block_id),
|
||||||
Value::Nothing { .. } => String::new(),
|
Value::Nothing { .. } => String::new(),
|
||||||
Value::Error { error, .. } => format!("{error:?}"),
|
Value::Error { error, .. } => format!("{error:?}"),
|
||||||
Value::Binary { val, .. } => format!("{val:?}"),
|
Value::Binary { val, .. } => format!("{val:?}"),
|
||||||
|
@ -253,7 +253,7 @@ pub fn debug_string_without_formatting(value: &Value) -> String {
|
|||||||
},
|
},
|
||||||
//TODO: It would be good to drill in deeper to blocks and closures.
|
//TODO: It would be good to drill in deeper to blocks and closures.
|
||||||
Value::Block { val, .. } => format!("<Block {val}>"),
|
Value::Block { val, .. } => format!("<Block {val}>"),
|
||||||
Value::Closure { val, .. } => format!("<Closure {val}>"),
|
Value::Closure { val, .. } => format!("<Closure {}>", val.block_id),
|
||||||
Value::Nothing { .. } => String::new(),
|
Value::Nothing { .. } => String::new(),
|
||||||
Value::Error { error, .. } => format!("{error:?}"),
|
Value::Error { error, .. } => format!("{error:?}"),
|
||||||
Value::Binary { val, .. } => format!("{val:?}"),
|
Value::Binary { val, .. } => format!("{val:?}"),
|
||||||
|
@ -37,17 +37,6 @@ impl Command for ViewSource {
|
|||||||
let arg_span = arg.span();
|
let arg_span = arg.span();
|
||||||
|
|
||||||
match arg {
|
match arg {
|
||||||
Value::Block { val: block_id, .. } | Value::Closure { val: block_id, .. } => {
|
|
||||||
let block = engine_state.get_block(block_id);
|
|
||||||
|
|
||||||
if let Some(span) = block.span {
|
|
||||||
let contents = engine_state.get_span_contents(span);
|
|
||||||
Ok(Value::string(String::from_utf8_lossy(contents), call.head)
|
|
||||||
.into_pipeline_data())
|
|
||||||
} else {
|
|
||||||
Ok(Value::string("<internal command>", call.head).into_pipeline_data())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Value::String { val, .. } => {
|
Value::String { val, .. } => {
|
||||||
if let Some(decl_id) = engine_state.find_decl(val.as_bytes(), &[]) {
|
if let Some(decl_id) = engine_state.find_decl(val.as_bytes(), &[]) {
|
||||||
// arg is a command
|
// arg is a command
|
||||||
@ -139,13 +128,27 @@ impl Command for ViewSource {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => Err(ShellError::GenericError(
|
value => {
|
||||||
"Cannot view value".to_string(),
|
if let Ok(block_id) = value.as_block() {
|
||||||
"this value cannot be viewed".to_string(),
|
let block = engine_state.get_block(block_id);
|
||||||
Some(arg_span),
|
|
||||||
None,
|
if let Some(span) = block.span {
|
||||||
Vec::new(),
|
let contents = engine_state.get_span_contents(span);
|
||||||
)),
|
Ok(Value::string(String::from_utf8_lossy(contents), call.head)
|
||||||
|
.into_pipeline_data())
|
||||||
|
} else {
|
||||||
|
Ok(Value::string("<internal command>", call.head).into_pipeline_data())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Err(ShellError::GenericError(
|
||||||
|
"Cannot view value".to_string(),
|
||||||
|
"this value cannot be viewed".to_string(),
|
||||||
|
Some(arg_span),
|
||||||
|
None,
|
||||||
|
Vec::new(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ fn local_into_string(value: Value, separator: &str, config: &Config) -> String {
|
|||||||
Err(error) => format!("{error:?}"),
|
Err(error) => format!("{error:?}"),
|
||||||
},
|
},
|
||||||
Value::Block { val, .. } => format!("<Block {val}>"),
|
Value::Block { val, .. } => format!("<Block {val}>"),
|
||||||
Value::Closure { val, .. } => format!("<Closure {val}>"),
|
Value::Closure { val, .. } => format!("<Closure {}>", val.block_id),
|
||||||
Value::Nothing { .. } => String::new(),
|
Value::Nothing { .. } => String::new(),
|
||||||
Value::Error { error, .. } => format!("{error:?}"),
|
Value::Error { error, .. } => format!("{error:?}"),
|
||||||
Value::Binary { val, .. } => format!("{val:?}"),
|
Value::Binary { val, .. } => format!("{val:?}"),
|
||||||
|
@ -387,8 +387,8 @@ fn get_converted_value(
|
|||||||
if let Ok(v) = env_conversions.follow_cell_path_not_from_user_input(path_members, false) {
|
if let Ok(v) = env_conversions.follow_cell_path_not_from_user_input(path_members, false) {
|
||||||
let from_span = v.span();
|
let from_span = v.span();
|
||||||
match v {
|
match v {
|
||||||
Value::Closure { val: block_id, .. } => {
|
Value::Closure { val, .. } => {
|
||||||
let block = engine_state.get_block(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) {
|
||||||
let mut stack = stack.gather_captures(engine_state, &block.captures);
|
let mut stack = stack.gather_captures(engine_state, &block.captures);
|
||||||
|
@ -5,7 +5,7 @@ use nu_protocol::{
|
|||||||
eval_operator, Argument, Assignment, Bits, Block, Boolean, Call, Comparison, Expr,
|
eval_operator, Argument, Assignment, Bits, Block, Boolean, Call, Comparison, Expr,
|
||||||
Expression, Math, Operator, PathMember, PipelineElement, Redirection,
|
Expression, Math, Operator, PathMember, PipelineElement, Redirection,
|
||||||
},
|
},
|
||||||
engine::{EngineState, Stack},
|
engine::{Closure, EngineState, Stack},
|
||||||
IntoInterruptiblePipelineData, IntoPipelineData, PipelineData, Range, Record, ShellError, Span,
|
IntoInterruptiblePipelineData, IntoPipelineData, PipelineData, Range, Record, ShellError, Span,
|
||||||
Spanned, Unit, Value, VarId, ENV_VARIABLE_ID,
|
Spanned, Unit, Value, VarId, ENV_VARIABLE_ID,
|
||||||
};
|
};
|
||||||
@ -530,7 +530,13 @@ pub fn eval_expression(
|
|||||||
for var_id in &block.captures {
|
for var_id in &block.captures {
|
||||||
captures.insert(*var_id, stack.get_var(*var_id, expr.span)?);
|
captures.insert(*var_id, stack.get_var(*var_id, expr.span)?);
|
||||||
}
|
}
|
||||||
Ok(Value::closure(*block_id, captures, expr.span))
|
Ok(Value::closure(
|
||||||
|
Closure {
|
||||||
|
block_id: *block_id,
|
||||||
|
captures,
|
||||||
|
},
|
||||||
|
expr.span,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
Expr::Block(block_id) => Ok(Value::block(*block_id, expr.span)),
|
Expr::Block(block_id) => Ok(Value::block(*block_id, expr.span)),
|
||||||
Expr::List(x) => {
|
Expr::List(x) => {
|
||||||
|
@ -2,7 +2,9 @@ use std::collections::HashMap;
|
|||||||
|
|
||||||
use crate::{BlockId, Value, VarId};
|
use crate::{BlockId, Value, VarId};
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
pub struct Closure {
|
pub struct Closure {
|
||||||
pub block_id: BlockId,
|
pub block_id: BlockId,
|
||||||
pub captures: HashMap<VarId, Value>,
|
pub captures: HashMap<VarId, Value>,
|
||||||
|
@ -500,10 +500,7 @@ impl FromValue for Record {
|
|||||||
impl FromValue for Closure {
|
impl FromValue for Closure {
|
||||||
fn from_value(v: &Value) -> Result<Self, ShellError> {
|
fn from_value(v: &Value) -> Result<Self, ShellError> {
|
||||||
match v {
|
match v {
|
||||||
Value::Closure { val, captures, .. } => Ok(Closure {
|
Value::Closure { val, .. } => Ok(val.clone()),
|
||||||
block_id: *val,
|
|
||||||
captures: captures.clone(),
|
|
||||||
}),
|
|
||||||
Value::Block { val, .. } => Ok(Closure {
|
Value::Block { val, .. } => Ok(Closure {
|
||||||
block_id: *val,
|
block_id: *val,
|
||||||
captures: HashMap::new(),
|
captures: HashMap::new(),
|
||||||
@ -536,11 +533,8 @@ impl FromValue for Spanned<Closure> {
|
|||||||
fn from_value(v: &Value) -> Result<Self, ShellError> {
|
fn from_value(v: &Value) -> Result<Self, ShellError> {
|
||||||
let span = v.span();
|
let span = v.span();
|
||||||
match v {
|
match v {
|
||||||
Value::Closure { val, captures, .. } => Ok(Spanned {
|
Value::Closure { val, .. } => Ok(Spanned {
|
||||||
item: Closure {
|
item: val.clone(),
|
||||||
block_id: *val,
|
|
||||||
captures: captures.clone(),
|
|
||||||
},
|
|
||||||
span,
|
span,
|
||||||
}),
|
}),
|
||||||
v => Err(ShellError::CantConvert {
|
v => Err(ShellError::CantConvert {
|
||||||
|
@ -9,9 +9,9 @@ mod unit;
|
|||||||
|
|
||||||
use crate::ast::{Bits, Boolean, CellPath, Comparison, MatchPattern, PathMember};
|
use crate::ast::{Bits, Boolean, CellPath, Comparison, MatchPattern, PathMember};
|
||||||
use crate::ast::{Math, Operator};
|
use crate::ast::{Math, Operator};
|
||||||
use crate::engine::EngineState;
|
use crate::engine::{Closure, EngineState};
|
||||||
use crate::ShellError;
|
use crate::ShellError;
|
||||||
use crate::{did_you_mean, BlockId, Config, Span, Spanned, Type, VarId};
|
use crate::{did_you_mean, BlockId, Config, Span, Spanned, Type};
|
||||||
|
|
||||||
use byte_unit::ByteUnit;
|
use byte_unit::ByteUnit;
|
||||||
use chrono::{DateTime, Datelike, Duration, FixedOffset, Locale, TimeZone};
|
use chrono::{DateTime, Datelike, Duration, FixedOffset, Locale, TimeZone};
|
||||||
@ -26,7 +26,6 @@ use num_format::ToFormattedString;
|
|||||||
pub use range::*;
|
pub use range::*;
|
||||||
pub use record::Record;
|
pub use record::Record;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
use std::{
|
use std::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
@ -109,8 +108,7 @@ pub enum Value {
|
|||||||
internal_span: Span,
|
internal_span: Span,
|
||||||
},
|
},
|
||||||
Closure {
|
Closure {
|
||||||
val: BlockId,
|
val: Closure,
|
||||||
captures: HashMap<VarId, Value>,
|
|
||||||
// note: spans are being refactored out of Value
|
// note: spans are being refactored out of Value
|
||||||
// please use .span() instead of matching this span value
|
// please use .span() instead of matching this span value
|
||||||
internal_span: Span,
|
internal_span: Span,
|
||||||
@ -202,13 +200,8 @@ impl Clone for Value {
|
|||||||
val: *val,
|
val: *val,
|
||||||
internal_span: *internal_span,
|
internal_span: *internal_span,
|
||||||
},
|
},
|
||||||
Value::Closure {
|
Value::Closure { val, internal_span } => Value::Closure {
|
||||||
val,
|
val: val.clone(),
|
||||||
captures,
|
|
||||||
internal_span,
|
|
||||||
} => Value::Closure {
|
|
||||||
val: *val,
|
|
||||||
captures: captures.clone(),
|
|
||||||
internal_span: *internal_span,
|
internal_span: *internal_span,
|
||||||
},
|
},
|
||||||
Value::Nothing { internal_span } => Value::Nothing {
|
Value::Nothing { internal_span } => Value::Nothing {
|
||||||
@ -443,7 +436,7 @@ impl Value {
|
|||||||
pub fn as_block(&self) -> Result<BlockId, ShellError> {
|
pub fn as_block(&self) -> Result<BlockId, ShellError> {
|
||||||
match self {
|
match self {
|
||||||
Value::Block { val, .. } => Ok(*val),
|
Value::Block { val, .. } => Ok(*val),
|
||||||
Value::Closure { val, .. } => Ok(*val),
|
Value::Closure { val, .. } => Ok(val.block_id),
|
||||||
x => Err(ShellError::CantConvert {
|
x => Err(ShellError::CantConvert {
|
||||||
to_type: "block".into(),
|
to_type: "block".into(),
|
||||||
from_type: x.get_type().to_string(),
|
from_type: x.get_type().to_string(),
|
||||||
@ -453,9 +446,9 @@ impl Value {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_closure(&self) -> Result<(BlockId, &HashMap<VarId, Value>), ShellError> {
|
pub fn as_closure(&self) -> Result<&Closure, ShellError> {
|
||||||
match self {
|
match self {
|
||||||
Value::Closure { val, captures, .. } => Ok((*val, captures)),
|
Value::Closure { val, .. } => Ok(val),
|
||||||
x => Err(ShellError::CantConvert {
|
x => Err(ShellError::CantConvert {
|
||||||
to_type: "closure".into(),
|
to_type: "closure".into(),
|
||||||
from_type: x.get_type().to_string(),
|
from_type: x.get_type().to_string(),
|
||||||
@ -732,7 +725,7 @@ impl Value {
|
|||||||
collected.into_string(separator, config)
|
collected.into_string(separator, config)
|
||||||
}
|
}
|
||||||
Value::Block { val, .. } => format!("<Block {val}>"),
|
Value::Block { val, .. } => format!("<Block {val}>"),
|
||||||
Value::Closure { val, .. } => format!("<Closure {val}>"),
|
Value::Closure { val, .. } => format!("<Closure {}>", val.block_id),
|
||||||
Value::Nothing { .. } => String::new(),
|
Value::Nothing { .. } => String::new(),
|
||||||
Value::Error { error, .. } => format!("{error:?}"),
|
Value::Error { error, .. } => format!("{error:?}"),
|
||||||
Value::Binary { val, .. } => format!("{val:?}"),
|
Value::Binary { val, .. } => format!("{val:?}"),
|
||||||
@ -787,7 +780,7 @@ impl Value {
|
|||||||
Err(error) => format!("{error:?}"),
|
Err(error) => format!("{error:?}"),
|
||||||
},
|
},
|
||||||
Value::Block { val, .. } => format!("<Block {val}>"),
|
Value::Block { val, .. } => format!("<Block {val}>"),
|
||||||
Value::Closure { val, .. } => format!("<Closure {val}>"),
|
Value::Closure { val, .. } => format!("<Closure {}>", val.block_id),
|
||||||
Value::Nothing { .. } => String::new(),
|
Value::Nothing { .. } => String::new(),
|
||||||
Value::Error { error, .. } => format!("{error:?}"),
|
Value::Error { error, .. } => format!("{error:?}"),
|
||||||
Value::Binary { val, .. } => format!("{val:?}"),
|
Value::Binary { val, .. } => format!("{val:?}"),
|
||||||
@ -895,7 +888,7 @@ impl Value {
|
|||||||
Err(error) => format!("{error:?}"),
|
Err(error) => format!("{error:?}"),
|
||||||
},
|
},
|
||||||
Value::Block { val, .. } => format!("<Block {val}>"),
|
Value::Block { val, .. } => format!("<Block {val}>"),
|
||||||
Value::Closure { val, .. } => format!("<Closure {val}>"),
|
Value::Closure { val, .. } => format!("<Closure {}>", val.block_id),
|
||||||
Value::Nothing { .. } => String::new(),
|
Value::Nothing { .. } => String::new(),
|
||||||
Value::Error { error, .. } => format!("{error:?}"),
|
Value::Error { error, .. } => format!("{error:?}"),
|
||||||
Value::Binary { val, .. } => format!("{val:?}"),
|
Value::Binary { val, .. } => format!("{val:?}"),
|
||||||
@ -1836,10 +1829,9 @@ impl Value {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn closure(val: BlockId, captures: HashMap<VarId, Value>, span: Span) -> Value {
|
pub fn closure(val: Closure, span: Span) -> Value {
|
||||||
Value::Closure {
|
Value::Closure {
|
||||||
val,
|
val,
|
||||||
captures,
|
|
||||||
internal_span: span,
|
internal_span: span,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1961,8 +1953,8 @@ impl Value {
|
|||||||
|
|
||||||
/// Note: Only use this for test data, *not* live data, as it will point into unknown source
|
/// Note: Only use this for test data, *not* live data, as it will point into unknown source
|
||||||
/// when used in errors.
|
/// when used in errors.
|
||||||
pub fn test_closure(val: BlockId, captures: HashMap<VarId, Value>) -> Value {
|
pub fn test_closure(val: Closure) -> Value {
|
||||||
Value::closure(val, captures, Span::test_data())
|
Value::closure(val, Span::test_data())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Note: Only use this for test data, *not* live data, as it will point into unknown source
|
/// Note: Only use this for test data, *not* live data, as it will point into unknown source
|
||||||
@ -2288,7 +2280,7 @@ impl PartialOrd for Value {
|
|||||||
Value::LazyRecord { .. } => Some(Ordering::Greater),
|
Value::LazyRecord { .. } => Some(Ordering::Greater),
|
||||||
Value::List { .. } => Some(Ordering::Greater),
|
Value::List { .. } => Some(Ordering::Greater),
|
||||||
Value::Block { .. } => Some(Ordering::Greater),
|
Value::Block { .. } => Some(Ordering::Greater),
|
||||||
Value::Closure { val: rhs, .. } => lhs.partial_cmp(rhs),
|
Value::Closure { val: rhs, .. } => lhs.block_id.partial_cmp(&rhs.block_id),
|
||||||
Value::Nothing { .. } => Some(Ordering::Less),
|
Value::Nothing { .. } => Some(Ordering::Less),
|
||||||
Value::Error { .. } => Some(Ordering::Less),
|
Value::Error { .. } => Some(Ordering::Less),
|
||||||
Value::Binary { .. } => Some(Ordering::Less),
|
Value::Binary { .. } => Some(Ordering::Less),
|
||||||
|
Loading…
Reference in New Issue
Block a user