mirror of
https://github.com/nushell/nushell.git
synced 2025-07-01 07:00:37 +02:00
Improve external output in subexprs (#294)
This commit is contained in:
@ -178,7 +178,11 @@ pub fn eval_expression(
|
||||
}),
|
||||
Expr::ValueWithUnit(e, unit) => match eval_expression(engine_state, stack, e)? {
|
||||
Value::Int { val, .. } => Ok(compute(val, unit.item, unit.span)),
|
||||
_ => Err(ShellError::CantConvert("unit value".into(), e.span)),
|
||||
x => Err(ShellError::CantConvert(
|
||||
"unit value".into(),
|
||||
x.get_type().to_string(),
|
||||
e.span,
|
||||
)),
|
||||
},
|
||||
Expr::Range(from, next, to, operator) => {
|
||||
let from = if let Some(f) = from {
|
||||
@ -224,7 +228,10 @@ pub fn eval_expression(
|
||||
Expr::RowCondition(_, expr) => eval_expression(engine_state, stack, expr),
|
||||
Expr::Call(call) => {
|
||||
// FIXME: protect this collect with ctrl-c
|
||||
Ok(eval_call(engine_state, stack, call, PipelineData::new())?.into_value())
|
||||
Ok(
|
||||
eval_call(engine_state, stack, call, PipelineData::new(call.head))?
|
||||
.into_value(call.head),
|
||||
)
|
||||
}
|
||||
Expr::ExternalCall(name, span, args) => {
|
||||
// FIXME: protect this collect with ctrl-c
|
||||
@ -234,10 +241,10 @@ pub fn eval_expression(
|
||||
name,
|
||||
span,
|
||||
args,
|
||||
PipelineData::new(),
|
||||
PipelineData::new(*span),
|
||||
true,
|
||||
)?
|
||||
.into_value())
|
||||
.into_value(*span))
|
||||
}
|
||||
Expr::Operator(_) => Ok(Value::Nothing { span: expr.span }),
|
||||
Expr::BinaryOp(lhs, op, rhs) => {
|
||||
@ -271,7 +278,10 @@ pub fn eval_expression(
|
||||
let block = engine_state.get_block(*block_id);
|
||||
|
||||
// FIXME: protect this collect with ctrl-c
|
||||
Ok(eval_block(engine_state, stack, block, PipelineData::new())?.into_value())
|
||||
Ok(
|
||||
eval_subexpression(engine_state, stack, block, PipelineData::new(expr.span))?
|
||||
.into_value(expr.span),
|
||||
)
|
||||
}
|
||||
Expr::Block(block_id) => Ok(Value::Block {
|
||||
val: *block_id,
|
||||
@ -370,6 +380,64 @@ pub fn eval_block(
|
||||
Ok(input)
|
||||
}
|
||||
|
||||
pub fn eval_subexpression(
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
block: &Block,
|
||||
mut input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
for stmt in block.stmts.iter() {
|
||||
if let Statement::Pipeline(pipeline) = stmt {
|
||||
for (i, elem) in pipeline.expressions.iter().enumerate() {
|
||||
match elem {
|
||||
Expression {
|
||||
expr: Expr::Call(call),
|
||||
..
|
||||
} => {
|
||||
input = eval_call(engine_state, stack, call, input)?;
|
||||
}
|
||||
Expression {
|
||||
expr: Expr::ExternalCall(name, name_span, args),
|
||||
..
|
||||
} => {
|
||||
input = eval_external(
|
||||
engine_state,
|
||||
stack,
|
||||
name,
|
||||
name_span,
|
||||
args,
|
||||
input,
|
||||
false,
|
||||
)?;
|
||||
|
||||
if i == pipeline.expressions.len() - 1 {
|
||||
// We're at the end, so drain as a string for the value
|
||||
// to be used later
|
||||
// FIXME: the trimming of the end probably needs to live in a better place
|
||||
|
||||
let mut s = input.collect_string();
|
||||
if s.ends_with('\n') {
|
||||
s.pop();
|
||||
}
|
||||
input = Value::String {
|
||||
val: s.to_string(),
|
||||
span: *name_span,
|
||||
}
|
||||
.into_pipeline_data()
|
||||
}
|
||||
}
|
||||
|
||||
elem => {
|
||||
input = eval_expression(engine_state, stack, elem)?.into_pipeline_data();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(input)
|
||||
}
|
||||
|
||||
pub fn eval_variable(
|
||||
engine_state: &EngineState,
|
||||
stack: &Stack,
|
||||
|
@ -32,7 +32,11 @@ impl FromValue for Spanned<i64> {
|
||||
span: *span,
|
||||
}),
|
||||
|
||||
v => Err(ShellError::CantConvert("integer".into(), v.span()?)),
|
||||
v => Err(ShellError::CantConvert(
|
||||
"integer".into(),
|
||||
v.get_type().to_string(),
|
||||
v.span()?,
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -44,7 +48,11 @@ impl FromValue for i64 {
|
||||
Value::Filesize { val, .. } => Ok(*val as i64),
|
||||
Value::Duration { val, .. } => Ok(*val as i64),
|
||||
|
||||
v => Err(ShellError::CantConvert("integer".into(), v.span()?)),
|
||||
v => Err(ShellError::CantConvert(
|
||||
"integer".into(),
|
||||
v.get_type().to_string(),
|
||||
v.span()?,
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -61,7 +69,11 @@ impl FromValue for Spanned<f64> {
|
||||
span: *span,
|
||||
}),
|
||||
|
||||
v => Err(ShellError::CantConvert("float".into(), v.span()?)),
|
||||
v => Err(ShellError::CantConvert(
|
||||
"float".into(),
|
||||
v.get_type().to_string(),
|
||||
v.span()?,
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -71,7 +83,11 @@ impl FromValue for f64 {
|
||||
match v {
|
||||
Value::Float { val, .. } => Ok(*val),
|
||||
Value::Int { val, .. } => Ok(*val as f64),
|
||||
v => Err(ShellError::CantConvert("float".into(), v.span()?)),
|
||||
v => Err(ShellError::CantConvert(
|
||||
"float".into(),
|
||||
v.get_type().to_string(),
|
||||
v.span()?,
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -109,7 +125,11 @@ impl FromValue for CellPath {
|
||||
span,
|
||||
}],
|
||||
}),
|
||||
_ => Err(ShellError::CantConvert("cell path".into(), span)),
|
||||
x => Err(ShellError::CantConvert(
|
||||
"cell path".into(),
|
||||
x.get_type().to_string(),
|
||||
span,
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -118,7 +138,11 @@ impl FromValue for bool {
|
||||
fn from_value(v: &Value) -> Result<Self, ShellError> {
|
||||
match v {
|
||||
Value::Bool { val, .. } => Ok(*val),
|
||||
v => Err(ShellError::CantConvert("bool".into(), v.span()?)),
|
||||
v => Err(ShellError::CantConvert(
|
||||
"bool".into(),
|
||||
v.get_type().to_string(),
|
||||
v.span()?,
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -130,7 +154,11 @@ impl FromValue for Spanned<bool> {
|
||||
item: *val,
|
||||
span: *span,
|
||||
}),
|
||||
v => Err(ShellError::CantConvert("bool".into(), v.span()?)),
|
||||
v => Err(ShellError::CantConvert(
|
||||
"bool".into(),
|
||||
v.get_type().to_string(),
|
||||
v.span()?,
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -139,7 +167,11 @@ impl FromValue for DateTime<FixedOffset> {
|
||||
fn from_value(v: &Value) -> Result<Self, ShellError> {
|
||||
match v {
|
||||
Value::Date { val, .. } => Ok(*val),
|
||||
v => Err(ShellError::CantConvert("date".into(), v.span()?)),
|
||||
v => Err(ShellError::CantConvert(
|
||||
"date".into(),
|
||||
v.get_type().to_string(),
|
||||
v.span()?,
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -151,7 +183,11 @@ impl FromValue for Spanned<DateTime<FixedOffset>> {
|
||||
item: *val,
|
||||
span: *span,
|
||||
}),
|
||||
v => Err(ShellError::CantConvert("date".into(), v.span()?)),
|
||||
v => Err(ShellError::CantConvert(
|
||||
"date".into(),
|
||||
v.get_type().to_string(),
|
||||
v.span()?,
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -160,7 +196,11 @@ impl FromValue for Range {
|
||||
fn from_value(v: &Value) -> Result<Self, ShellError> {
|
||||
match v {
|
||||
Value::Range { val, .. } => Ok((**val).clone()),
|
||||
v => Err(ShellError::CantConvert("range".into(), v.span()?)),
|
||||
v => Err(ShellError::CantConvert(
|
||||
"range".into(),
|
||||
v.get_type().to_string(),
|
||||
v.span()?,
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -172,7 +212,11 @@ impl FromValue for Spanned<Range> {
|
||||
item: (**val).clone(),
|
||||
span: *span,
|
||||
}),
|
||||
v => Err(ShellError::CantConvert("range".into(), v.span()?)),
|
||||
v => Err(ShellError::CantConvert(
|
||||
"range".into(),
|
||||
v.get_type().to_string(),
|
||||
v.span()?,
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -182,7 +226,11 @@ impl FromValue for Vec<u8> {
|
||||
match v {
|
||||
Value::Binary { val, .. } => Ok(val.clone()),
|
||||
Value::String { val, .. } => Ok(val.bytes().collect()),
|
||||
v => Err(ShellError::CantConvert("binary data".into(), v.span()?)),
|
||||
v => Err(ShellError::CantConvert(
|
||||
"binary data".into(),
|
||||
v.get_type().to_string(),
|
||||
v.span()?,
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user