mirror of
https://github.com/nushell/nushell.git
synced 2025-07-01 15:11:52 +02:00
Remove the Value::Block
case (#12582)
# Description `Value` describes the types of first-class values that users and scripts can create, manipulate, pass around, and store. However, `Block`s are not first-class values in the language, so this PR removes it from `Value`. This removes some unnecessary code, and this change should be invisible to the user except for the change to `scope modules` described below. # User-Facing Changes Breaking change: the output of `scope modules` was changed so that `env_block` is now `has_env_block` which is a boolean value instead of a `Block`. # After Submitting Update the language guide possibly.
This commit is contained in:
@ -276,8 +276,7 @@ pub fn debug_string_without_formatting(value: &Value) -> String {
|
||||
Ok(val) => debug_string_without_formatting(&val),
|
||||
Err(error) => format!("{error:?}"),
|
||||
},
|
||||
//TODO: It would be good to drill in deeper to blocks and closures.
|
||||
Value::Block { val, .. } => format!("<Block {val}>"),
|
||||
//TODO: It would be good to drill deeper into closures.
|
||||
Value::Closure { val, .. } => format!("<Closure {}>", val.block_id),
|
||||
Value::Nothing { .. } => String::new(),
|
||||
Value::Error { error, .. } => format!("{error:?}"),
|
||||
|
@ -173,8 +173,8 @@ impl Command for ViewSource {
|
||||
}
|
||||
}
|
||||
value => {
|
||||
if let Ok(block_id) = value.coerce_block() {
|
||||
let block = engine_state.get_block(block_id);
|
||||
if let Ok(closure) = value.as_closure() {
|
||||
let block = engine_state.get_block(closure.block_id);
|
||||
|
||||
if let Some(span) = block.span {
|
||||
let contents = engine_state.get_span_contents(span);
|
||||
|
12
crates/nu-command/src/env/export_env.rs
vendored
12
crates/nu-command/src/env/export_env.rs
vendored
@ -1,5 +1,4 @@
|
||||
use nu_engine::{command_prelude::*, get_eval_block, redirect_env};
|
||||
use nu_protocol::engine::Closure;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ExportEnv;
|
||||
@ -31,10 +30,15 @@ impl Command for ExportEnv {
|
||||
call: &Call,
|
||||
input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let capture_block: Closure = call.req(engine_state, caller_stack, 0)?;
|
||||
let block = engine_state.get_block(capture_block.block_id);
|
||||
let block_id = call
|
||||
.positional_nth(0)
|
||||
.expect("checked through parser")
|
||||
.as_block()
|
||||
.expect("internal error: missing block");
|
||||
|
||||
let block = engine_state.get_block(block_id);
|
||||
let mut callee_stack = caller_stack
|
||||
.captures_to_stack(capture_block.captures)
|
||||
.gather_captures(engine_state, &block.captures)
|
||||
.reset_pipes();
|
||||
|
||||
let eval_block = get_eval_block(engine_state);
|
||||
|
@ -522,7 +522,6 @@ fn value_should_be_printed(
|
||||
| Value::Date { .. }
|
||||
| Value::Range { .. }
|
||||
| Value::Float { .. }
|
||||
| Value::Block { .. }
|
||||
| Value::Closure { .. }
|
||||
| Value::Nothing { .. }
|
||||
| Value::Error { .. } => term_equals_value(term, &lower_value, span),
|
||||
|
@ -2,7 +2,6 @@ use nu_engine::{command_prelude::*, get_eval_block, EvalBlockFn};
|
||||
use nu_protocol::{
|
||||
ast::{Block, PathMember},
|
||||
engine::Closure,
|
||||
FromValue,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -132,25 +131,23 @@ fn insert(
|
||||
|
||||
let cell_path: CellPath = call.req(engine_state, stack, 0)?;
|
||||
let replacement: Value = call.req(engine_state, stack, 1)?;
|
||||
|
||||
let replacement_span = replacement.span();
|
||||
let ctrlc = engine_state.ctrlc.clone();
|
||||
|
||||
let eval_block = get_eval_block(engine_state);
|
||||
|
||||
match input {
|
||||
PipelineData::Value(mut value, metadata) => {
|
||||
if replacement.coerce_block().is_ok() {
|
||||
if let Value::Closure { val: closure, .. } = replacement {
|
||||
match (cell_path.members.first(), &mut value) {
|
||||
(Some(PathMember::String { .. }), Value::List { vals, .. }) => {
|
||||
let span = replacement.span();
|
||||
let capture_block = Closure::from_value(replacement)?;
|
||||
let block = engine_state.get_block(capture_block.block_id);
|
||||
let stack = stack.captures_to_stack(capture_block.captures.clone());
|
||||
let block = engine_state.get_block(closure.block_id);
|
||||
let stack = stack.captures_to_stack(closure.captures);
|
||||
for val in vals {
|
||||
let mut stack = stack.clone();
|
||||
insert_value_by_closure(
|
||||
val,
|
||||
span,
|
||||
replacement_span,
|
||||
engine_state,
|
||||
&mut stack,
|
||||
block,
|
||||
@ -163,7 +160,8 @@ fn insert(
|
||||
(first, _) => {
|
||||
insert_single_value_by_closure(
|
||||
&mut value,
|
||||
replacement,
|
||||
closure,
|
||||
replacement_span,
|
||||
engine_state,
|
||||
stack,
|
||||
&cell_path.members,
|
||||
@ -201,14 +199,12 @@ fn insert(
|
||||
}
|
||||
|
||||
if path.is_empty() {
|
||||
if replacement.coerce_block().is_ok() {
|
||||
let span = replacement.span();
|
||||
if let Value::Closure { val: closure, .. } = replacement {
|
||||
let value = stream.next();
|
||||
let end_of_stream = value.is_none();
|
||||
let value = value.unwrap_or(Value::nothing(span));
|
||||
let capture_block = Closure::from_value(replacement)?;
|
||||
let block = engine_state.get_block(capture_block.block_id);
|
||||
let mut stack = stack.captures_to_stack(capture_block.captures);
|
||||
let value = value.unwrap_or(Value::nothing(replacement_span));
|
||||
let block = engine_state.get_block(closure.block_id);
|
||||
let mut stack = stack.captures_to_stack(closure.captures);
|
||||
|
||||
if let Some(var) = block.signature.get_positional(0) {
|
||||
if let Some(var_id) = &var.var_id {
|
||||
@ -223,7 +219,7 @@ fn insert(
|
||||
value.clone().into_pipeline_data(),
|
||||
)?;
|
||||
|
||||
pre_elems.push(output.into_value(span));
|
||||
pre_elems.push(output.into_value(replacement_span));
|
||||
if !end_of_stream {
|
||||
pre_elems.push(value);
|
||||
}
|
||||
@ -231,10 +227,11 @@ fn insert(
|
||||
pre_elems.push(replacement);
|
||||
}
|
||||
} else if let Some(mut value) = stream.next() {
|
||||
if replacement.coerce_block().is_ok() {
|
||||
if let Value::Closure { val: closure, .. } = replacement {
|
||||
insert_single_value_by_closure(
|
||||
&mut value,
|
||||
replacement,
|
||||
closure,
|
||||
replacement_span,
|
||||
engine_state,
|
||||
stack,
|
||||
path,
|
||||
@ -256,12 +253,10 @@ fn insert(
|
||||
.into_iter()
|
||||
.chain(stream)
|
||||
.into_pipeline_data_with_metadata(metadata, ctrlc))
|
||||
} else if replacement.coerce_block().is_ok() {
|
||||
} else if let Value::Closure { val: closure, .. } = replacement {
|
||||
let engine_state = engine_state.clone();
|
||||
let replacement_span = replacement.span();
|
||||
let capture_block = Closure::from_value(replacement)?;
|
||||
let block = engine_state.get_block(capture_block.block_id).clone();
|
||||
let stack = stack.captures_to_stack(capture_block.captures.clone());
|
||||
let block = engine_state.get_block(closure.block_id).clone();
|
||||
let stack = stack.captures_to_stack(closure.captures);
|
||||
|
||||
Ok(stream
|
||||
.map(move |mut input| {
|
||||
@ -348,17 +343,16 @@ fn insert_value_by_closure(
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn insert_single_value_by_closure(
|
||||
value: &mut Value,
|
||||
replacement: Value,
|
||||
closure: Closure,
|
||||
span: Span,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
cell_path: &[PathMember],
|
||||
first_path_member_int: bool,
|
||||
eval_block_fn: EvalBlockFn,
|
||||
) -> Result<(), ShellError> {
|
||||
let span = replacement.span();
|
||||
let capture_block = Closure::from_value(replacement)?;
|
||||
let block = engine_state.get_block(capture_block.block_id);
|
||||
let mut stack = stack.captures_to_stack(capture_block.captures);
|
||||
let block = engine_state.get_block(closure.block_id);
|
||||
let mut stack = stack.captures_to_stack(closure.captures);
|
||||
|
||||
insert_value_by_closure(
|
||||
value,
|
||||
|
@ -2,7 +2,6 @@ use nu_engine::{command_prelude::*, get_eval_block, EvalBlockFn};
|
||||
use nu_protocol::{
|
||||
ast::{Block, PathMember},
|
||||
engine::Closure,
|
||||
FromValue,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -116,25 +115,23 @@ fn update(
|
||||
|
||||
let cell_path: CellPath = call.req(engine_state, stack, 0)?;
|
||||
let replacement: Value = call.req(engine_state, stack, 1)?;
|
||||
|
||||
let replacement_span = replacement.span();
|
||||
let ctrlc = engine_state.ctrlc.clone();
|
||||
|
||||
let eval_block = get_eval_block(engine_state);
|
||||
|
||||
match input {
|
||||
PipelineData::Value(mut value, metadata) => {
|
||||
if replacement.coerce_block().is_ok() {
|
||||
if let Value::Closure { val: closure, .. } = replacement {
|
||||
match (cell_path.members.first(), &mut value) {
|
||||
(Some(PathMember::String { .. }), Value::List { vals, .. }) => {
|
||||
let span = replacement.span();
|
||||
let capture_block = Closure::from_value(replacement)?;
|
||||
let block = engine_state.get_block(capture_block.block_id);
|
||||
let stack = stack.captures_to_stack(capture_block.captures.clone());
|
||||
let block = engine_state.get_block(closure.block_id);
|
||||
let stack = stack.captures_to_stack(closure.captures);
|
||||
for val in vals {
|
||||
let mut stack = stack.clone();
|
||||
update_value_by_closure(
|
||||
val,
|
||||
span,
|
||||
replacement_span,
|
||||
engine_state,
|
||||
&mut stack,
|
||||
block,
|
||||
@ -147,7 +144,8 @@ fn update(
|
||||
(first, _) => {
|
||||
update_single_value_by_closure(
|
||||
&mut value,
|
||||
replacement,
|
||||
closure,
|
||||
replacement_span,
|
||||
engine_state,
|
||||
stack,
|
||||
&cell_path.members,
|
||||
@ -189,10 +187,11 @@ fn update(
|
||||
// cannot fail since loop above does at least one iteration or returns an error
|
||||
let value = pre_elems.last_mut().expect("one element");
|
||||
|
||||
if replacement.coerce_block().is_ok() {
|
||||
if let Value::Closure { val: closure, .. } = replacement {
|
||||
update_single_value_by_closure(
|
||||
value,
|
||||
replacement,
|
||||
closure,
|
||||
replacement_span,
|
||||
engine_state,
|
||||
stack,
|
||||
path,
|
||||
@ -207,12 +206,10 @@ fn update(
|
||||
.into_iter()
|
||||
.chain(stream)
|
||||
.into_pipeline_data_with_metadata(metadata, ctrlc))
|
||||
} else if replacement.coerce_block().is_ok() {
|
||||
let replacement_span = replacement.span();
|
||||
} else if let Value::Closure { val: closure, .. } = replacement {
|
||||
let engine_state = engine_state.clone();
|
||||
let capture_block = Closure::from_value(replacement)?;
|
||||
let block = engine_state.get_block(capture_block.block_id).clone();
|
||||
let stack = stack.captures_to_stack(capture_block.captures.clone());
|
||||
let block = engine_state.get_block(closure.block_id).clone();
|
||||
let stack = stack.captures_to_stack(closure.captures);
|
||||
|
||||
Ok(stream
|
||||
.map(move |mut input| {
|
||||
@ -302,17 +299,16 @@ fn update_value_by_closure(
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn update_single_value_by_closure(
|
||||
value: &mut Value,
|
||||
replacement: Value,
|
||||
closure: Closure,
|
||||
span: Span,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
cell_path: &[PathMember],
|
||||
first_path_member_int: bool,
|
||||
eval_block_fn: EvalBlockFn,
|
||||
) -> Result<(), ShellError> {
|
||||
let span = replacement.span();
|
||||
let capture_block = Closure::from_value(replacement)?;
|
||||
let block = engine_state.get_block(capture_block.block_id);
|
||||
let mut stack = stack.captures_to_stack(capture_block.captures);
|
||||
let block = engine_state.get_block(closure.block_id);
|
||||
let mut stack = stack.captures_to_stack(closure.captures);
|
||||
|
||||
update_value_by_closure(
|
||||
value,
|
||||
|
@ -2,7 +2,6 @@ use nu_engine::{command_prelude::*, get_eval_block, EvalBlockFn};
|
||||
use nu_protocol::{
|
||||
ast::{Block, PathMember},
|
||||
engine::Closure,
|
||||
FromValue,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -162,24 +161,23 @@ fn upsert(
|
||||
|
||||
let cell_path: CellPath = call.req(engine_state, stack, 0)?;
|
||||
let replacement: Value = call.req(engine_state, stack, 1)?;
|
||||
let replacement_span = replacement.span();
|
||||
let eval_block = get_eval_block(engine_state);
|
||||
|
||||
let ctrlc = engine_state.ctrlc.clone();
|
||||
|
||||
match input {
|
||||
PipelineData::Value(mut value, metadata) => {
|
||||
if replacement.coerce_block().is_ok() {
|
||||
if let Value::Closure { val: closure, .. } = replacement {
|
||||
match (cell_path.members.first(), &mut value) {
|
||||
(Some(PathMember::String { .. }), Value::List { vals, .. }) => {
|
||||
let span = replacement.span();
|
||||
let capture_block = Closure::from_value(replacement)?;
|
||||
let block = engine_state.get_block(capture_block.block_id);
|
||||
let stack = stack.captures_to_stack(capture_block.captures.clone());
|
||||
let block = engine_state.get_block(closure.block_id);
|
||||
let stack = stack.captures_to_stack(closure.captures);
|
||||
for val in vals {
|
||||
let mut stack = stack.clone();
|
||||
upsert_value_by_closure(
|
||||
val,
|
||||
span,
|
||||
replacement_span,
|
||||
engine_state,
|
||||
&mut stack,
|
||||
block,
|
||||
@ -192,7 +190,8 @@ fn upsert(
|
||||
(first, _) => {
|
||||
upsert_single_value_by_closure(
|
||||
&mut value,
|
||||
replacement,
|
||||
closure,
|
||||
replacement_span,
|
||||
engine_state,
|
||||
stack,
|
||||
&cell_path.members,
|
||||
@ -230,12 +229,10 @@ fn upsert(
|
||||
}
|
||||
|
||||
if path.is_empty() {
|
||||
let span = replacement.span();
|
||||
let value = stream.next().unwrap_or(Value::nothing(span));
|
||||
if replacement.coerce_block().is_ok() {
|
||||
let capture_block = Closure::from_value(replacement)?;
|
||||
let block = engine_state.get_block(capture_block.block_id);
|
||||
let mut stack = stack.captures_to_stack(capture_block.captures);
|
||||
if let Value::Closure { val: closure, .. } = replacement {
|
||||
let block = engine_state.get_block(closure.block_id);
|
||||
let mut stack = stack.captures_to_stack(closure.captures);
|
||||
|
||||
if let Some(var) = block.signature.get_positional(0) {
|
||||
if let Some(var_id) = &var.var_id {
|
||||
@ -250,15 +247,16 @@ fn upsert(
|
||||
value.clone().into_pipeline_data(),
|
||||
)?;
|
||||
|
||||
pre_elems.push(output.into_value(span));
|
||||
pre_elems.push(output.into_value(replacement_span));
|
||||
} else {
|
||||
pre_elems.push(replacement);
|
||||
}
|
||||
} else if let Some(mut value) = stream.next() {
|
||||
if replacement.coerce_block().is_ok() {
|
||||
if let Value::Closure { val: closure, .. } = replacement {
|
||||
upsert_single_value_by_closure(
|
||||
&mut value,
|
||||
replacement,
|
||||
closure,
|
||||
replacement_span,
|
||||
engine_state,
|
||||
stack,
|
||||
path,
|
||||
@ -280,12 +278,10 @@ fn upsert(
|
||||
.into_iter()
|
||||
.chain(stream)
|
||||
.into_pipeline_data_with_metadata(metadata, ctrlc))
|
||||
} else if replacement.coerce_block().is_ok() {
|
||||
} else if let Value::Closure { val: closure, .. } = replacement {
|
||||
let engine_state = engine_state.clone();
|
||||
let replacement_span = replacement.span();
|
||||
let capture_block = Closure::from_value(replacement)?;
|
||||
let block = engine_state.get_block(capture_block.block_id).clone();
|
||||
let stack = stack.captures_to_stack(capture_block.captures.clone());
|
||||
let block = engine_state.get_block(closure.block_id).clone();
|
||||
let stack = stack.captures_to_stack(closure.captures);
|
||||
|
||||
Ok(stream
|
||||
.map(move |mut input| {
|
||||
@ -374,17 +370,16 @@ fn upsert_value_by_closure(
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn upsert_single_value_by_closure(
|
||||
value: &mut Value,
|
||||
replacement: Value,
|
||||
closure: Closure,
|
||||
span: Span,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
cell_path: &[PathMember],
|
||||
first_path_member_int: bool,
|
||||
eval_block_fn: EvalBlockFn,
|
||||
) -> Result<(), ShellError> {
|
||||
let span = replacement.span();
|
||||
let capture_block = Closure::from_value(replacement)?;
|
||||
let block = engine_state.get_block(capture_block.block_id);
|
||||
let mut stack = stack.captures_to_stack(capture_block.captures);
|
||||
let block = engine_state.get_block(closure.block_id);
|
||||
let mut stack = stack.captures_to_stack(closure.captures);
|
||||
|
||||
upsert_value_by_closure(
|
||||
value,
|
||||
|
@ -124,7 +124,7 @@ pub fn value_to_json_value(v: &Value) -> Result<nu_json::Value, ShellError> {
|
||||
|
||||
Value::List { vals, .. } => nu_json::Value::Array(json_list(vals)?),
|
||||
Value::Error { error, .. } => return Err(*error.clone()),
|
||||
Value::Closure { .. } | Value::Block { .. } | Value::Range { .. } => nu_json::Value::Null,
|
||||
Value::Closure { .. } | Value::Range { .. } => nu_json::Value::Null,
|
||||
Value::Binary { val, .. } => {
|
||||
nu_json::Value::Array(val.iter().map(|x| nu_json::Value::U64(*x as u64)).collect())
|
||||
}
|
||||
|
@ -134,7 +134,6 @@ fn local_into_string(value: Value, separator: &str, config: &Config) -> String {
|
||||
Ok(val) => local_into_string(val, separator, config),
|
||||
Err(error) => format!("{error:?}"),
|
||||
},
|
||||
Value::Block { val, .. } => format!("<Block {val}>"),
|
||||
Value::Closure { val, .. } => format!("<Closure {}>", val.block_id),
|
||||
Value::Nothing { .. } => String::new(),
|
||||
Value::Error { error, .. } => format!("{error:?}"),
|
||||
|
@ -67,11 +67,6 @@ fn helper(engine_state: &EngineState, v: &Value) -> Result<toml::Value, ShellErr
|
||||
helper(engine_state, &collected)?
|
||||
}
|
||||
Value::List { vals, .. } => toml::Value::Array(toml_list(engine_state, vals)?),
|
||||
Value::Block { .. } => {
|
||||
let code = engine_state.get_span_contents(span);
|
||||
let code = String::from_utf8_lossy(code).to_string();
|
||||
toml::Value::String(code)
|
||||
}
|
||||
Value::Closure { .. } => {
|
||||
let code = engine_state.get_span_contents(span);
|
||||
let code = String::from_utf8_lossy(code).to_string();
|
||||
|
@ -75,7 +75,6 @@ pub fn value_to_yaml_value(v: &Value) -> Result<serde_yaml::Value, ShellError> {
|
||||
|
||||
serde_yaml::Value::Sequence(out)
|
||||
}
|
||||
Value::Block { .. } => serde_yaml::Value::Null,
|
||||
Value::Closure { .. } => serde_yaml::Value::Null,
|
||||
Value::Nothing { .. } => serde_yaml::Value::Null,
|
||||
Value::Error { error, .. } => return Err(*error.clone()),
|
||||
|
Reference in New Issue
Block a user