mirror of
https://github.com/nushell/nushell
synced 2024-12-28 22:13:10 +00:00
Merge pull request #130 from nushell/custom_switch
Custom switch support
This commit is contained in:
commit
270e4fdd4c
4 changed files with 88 additions and 9 deletions
|
@ -62,11 +62,13 @@ fn eval_call(context: &EvaluationContext, call: &Call, input: Value) -> Result<V
|
|||
}
|
||||
|
||||
for named in decl.signature().named {
|
||||
let var_id = named
|
||||
.var_id
|
||||
.expect("internal error: all custom parameters must have var_ids");
|
||||
|
||||
let mut found = false;
|
||||
for call_named in &call.named {
|
||||
if call_named.0.item == named.long {
|
||||
let var_id = named
|
||||
.var_id
|
||||
.expect("internal error: all custom parameters must have var_ids");
|
||||
if let Some(arg) = &call_named.1 {
|
||||
let result = eval_expression(&state, arg)?;
|
||||
|
||||
|
@ -80,8 +82,19 @@ fn eval_call(context: &EvaluationContext, call: &Call, input: Value) -> Result<V
|
|||
},
|
||||
)
|
||||
}
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if !found && named.arg.is_none() {
|
||||
state.add_var(
|
||||
var_id,
|
||||
Value::Bool {
|
||||
val: false,
|
||||
span: call.head,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
let engine_state = state.engine_state.borrow();
|
||||
let block = engine_state.get_block(block_id);
|
||||
|
|
|
@ -1664,6 +1664,7 @@ pub fn parse_shape_name(
|
|||
b"variable" => SyntaxShape::Variable,
|
||||
b"signature" => SyntaxShape::Signature,
|
||||
b"expr" => SyntaxShape::Expression,
|
||||
b"bool" => SyntaxShape::Boolean,
|
||||
_ => return (SyntaxShape::Any, Some(ParseError::UnknownType(span))),
|
||||
};
|
||||
|
||||
|
@ -1671,10 +1672,17 @@ pub fn parse_shape_name(
|
|||
}
|
||||
|
||||
pub fn parse_type(_working_set: &StateWorkingSet, bytes: &[u8]) -> Type {
|
||||
if bytes == b"int" {
|
||||
Type::Int
|
||||
} else {
|
||||
Type::Unknown
|
||||
match bytes {
|
||||
b"int" => Type::Int,
|
||||
b"bool" => Type::Bool,
|
||||
b"string" => Type::String,
|
||||
b"block" => Type::Block,
|
||||
b"float" => Type::Float,
|
||||
b"filesize" => Type::Filesize,
|
||||
b"binary" => Type::Binary,
|
||||
b"date" => Type::Date,
|
||||
|
||||
_ => Type::Unknown,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2153,8 +2161,11 @@ pub fn parse_signature_helper(
|
|||
*shape = syntax_shape;
|
||||
}
|
||||
Arg::Flag(Flag { arg, var_id, .. }) => {
|
||||
working_set.set_variable_type(var_id.expect("internal error: all custom parameters must have var_ids"), syntax_shape.to_type());
|
||||
*arg = Some(syntax_shape)
|
||||
// Flags with a boolean type are just present/not-present switches
|
||||
if syntax_shape != SyntaxShape::Boolean {
|
||||
working_set.set_variable_type(var_id.expect("internal error: all custom parameters must have var_ids"), syntax_shape.to_type());
|
||||
*arg = Some(syntax_shape)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2689,6 +2700,25 @@ pub fn parse_value(
|
|||
error,
|
||||
)
|
||||
}
|
||||
SyntaxShape::Boolean => {
|
||||
// Redundant, though we catch bad boolean parses here
|
||||
if bytes == b"$true" || bytes == b"$false" {
|
||||
(
|
||||
Expression {
|
||||
expr: Expr::Bool(true),
|
||||
span,
|
||||
ty: Type::Bool,
|
||||
custom_completion: None,
|
||||
},
|
||||
None,
|
||||
)
|
||||
} else {
|
||||
(
|
||||
garbage(span),
|
||||
Some(ParseError::Expected("bool".into(), span)),
|
||||
)
|
||||
}
|
||||
}
|
||||
SyntaxShape::Any => {
|
||||
if bytes.starts_with(b"[") {
|
||||
parse_value(working_set, span, &SyntaxShape::Table)
|
||||
|
|
|
@ -73,6 +73,9 @@ pub enum SyntaxShape {
|
|||
/// A general expression, eg `1 + 2` or `foo --bar`
|
||||
Expression,
|
||||
|
||||
/// A boolean value
|
||||
Boolean,
|
||||
|
||||
/// A custom shape with custom completion logic
|
||||
Custom(Box<SyntaxShape>, String),
|
||||
}
|
||||
|
@ -102,6 +105,7 @@ impl SyntaxShape {
|
|||
SyntaxShape::Operator => Type::Unknown,
|
||||
SyntaxShape::Range => Type::Unknown,
|
||||
SyntaxShape::RowCondition => Type::Bool,
|
||||
SyntaxShape::Boolean => Type::Bool,
|
||||
SyntaxShape::Signature => Type::Unknown,
|
||||
SyntaxShape::String => Type::String,
|
||||
SyntaxShape::Table => Type::List(Box::new(Type::Unknown)), // FIXME
|
||||
|
|
32
src/tests.rs
32
src/tests.rs
|
@ -727,3 +727,35 @@ fn flag_param_value() -> TestResult {
|
|||
fn do_rest_args() -> TestResult {
|
||||
run_test(r#"(do { |...rest| $rest } 1 2).1 + 10"#, "12")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn custom_switch1() -> TestResult {
|
||||
run_test(
|
||||
r#"def florb [ --dry-run: bool ] { if ($dry-run) { "foo" } else { "bar" } }; florb --dry-run"#,
|
||||
"foo",
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn custom_switch2() -> TestResult {
|
||||
run_test(
|
||||
r#"def florb [ --dry-run: bool ] { if ($dry-run) { "foo" } else { "bar" } }; florb"#,
|
||||
"bar",
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn custom_switch3() -> TestResult {
|
||||
run_test(
|
||||
r#"def florb [ --dry-run ] { if ($dry-run) { "foo" } else { "bar" } }; florb --dry-run"#,
|
||||
"foo",
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn custom_switch4() -> TestResult {
|
||||
run_test(
|
||||
r#"def florb [ --dry-run ] { if ($dry-run) { "foo" } else { "bar" } }; florb"#,
|
||||
"bar",
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue