diff --git a/crates/nu-cli/src/completions/command_completions.rs b/crates/nu-cli/src/completions/command_completions.rs index 1f49718db..731b51b57 100644 --- a/crates/nu-cli/src/completions/command_completions.rs +++ b/crates/nu-cli/src/completions/command_completions.rs @@ -94,10 +94,7 @@ impl CommandCompletion { value: String::from_utf8_lossy(&x.0).to_string(), description: x.1, extra: None, - span: reedline::Span { - start: span.start - offset, - end: span.end - offset, - }, + span: reedline::Span::new(span.start - offset, span.end - offset), append_whitespace: true, }); @@ -108,10 +105,7 @@ impl CommandCompletion { value: String::from_utf8_lossy(&x).to_string(), description: None, extra: None, - span: reedline::Span { - start: span.start - offset, - end: span.end - offset, - }, + span: reedline::Span::new(span.start - offset, span.end - offset), append_whitespace: true, }); @@ -128,10 +122,7 @@ impl CommandCompletion { value: x, description: None, extra: None, - span: reedline::Span { - start: span.start - offset, - end: span.end - offset, - }, + span: reedline::Span::new(span.start - offset, span.end - offset), append_whitespace: true, }); @@ -187,10 +178,7 @@ impl Completer for CommandCompletion { let subcommands = if let Some(last) = last { self.complete_commands( working_set, - Span { - start: last.0.start, - end: pos, - }, + Span::new(last.0.start, pos), offset, false, options.match_algorithm, diff --git a/crates/nu-cli/src/completions/completer.rs b/crates/nu-cli/src/completions/completer.rs index a2c666455..5651523a6 100644 --- a/crates/nu-cli/src/completions/completer.rs +++ b/crates/nu-cli/src/completions/completer.rs @@ -101,14 +101,8 @@ impl NuCompleter { Ok(pd) => { let value = pd.into_value(span); if let Value::List { vals, span: _ } = value { - let result = map_value_completions( - vals.iter(), - Span { - start: span.start, - end: span.end, - }, - offset, - ); + let result = + map_value_completions(vals.iter(), Span::new(span.start, span.end), offset); return Some(result); } @@ -165,15 +159,12 @@ impl NuCompleter { // Create a new span let new_span = if flat_idx == 0 { - Span { - start: flat.0.start, - end: flat.0.end - 1 - span_offset, - } + Span::new(flat.0.start, flat.0.end - 1 - span_offset) } else { - Span { - start: flat.0.start - span_offset, - end: flat.0.end - 1 - span_offset, - } + Span::new( + flat.0.start - span_offset, + flat.0.end - 1 - span_offset, + ) }; // Parses the prefix. Completion should look up to the cursor position, not after. diff --git a/crates/nu-cli/src/completions/custom_completions.rs b/crates/nu-cli/src/completions/custom_completions.rs index 2dd465960..a2710ba01 100644 --- a/crates/nu-cli/src/completions/custom_completions.rs +++ b/crates/nu-cli/src/completions/custom_completions.rs @@ -52,13 +52,13 @@ impl Completer for CustomCompletion { head: span, arguments: vec![ Argument::Positional(Expression { - span: Span { start: 0, end: 0 }, + span: Span::unknown(), ty: Type::String, expr: Expr::String(self.line.clone()), custom_completion: None, }), Argument::Positional(Expression { - span: Span { start: 0, end: 0 }, + span: Span::unknown(), ty: Type::Int, expr: Expr::Int(line_pos as i64), custom_completion: None, diff --git a/crates/nu-cli/src/completions/variable_completions.rs b/crates/nu-cli/src/completions/variable_completions.rs index 6d8618983..d10f55157 100644 --- a/crates/nu-cli/src/completions/variable_completions.rs +++ b/crates/nu-cli/src/completions/variable_completions.rs @@ -111,10 +111,7 @@ impl Completer for VariableCompletion { &self.engine_state, &self.stack, nu_protocol::NU_VARIABLE_ID, - nu_protocol::Span { - start: current_span.start, - end: current_span.end, - }, + nu_protocol::Span::new(current_span.start, current_span.end), ) { for suggestion in nested_suggestions(nuval, self.var_context.1.clone(), current_span) @@ -134,13 +131,7 @@ impl Completer for VariableCompletion { // Completion other variable types if let Some(var_id) = var_id { // Extract the variable value from the stack - let var = self.stack.get_var( - var_id, - Span { - start: span.start, - end: span.end, - }, - ); + let var = self.stack.get_var(var_id, Span::new(span.start, span.end)); // If the value exists and it's of type Record if let Ok(value) = var { @@ -281,7 +272,7 @@ fn recursive_value(val: Value, sublevels: Vec>) -> Value { // Current sublevel value not found return Value::Nothing { - span: Span { start: 0, end: 0 }, + span: Span::unknown(), }; } _ => return val, diff --git a/crates/nu-cli/src/repl.rs b/crates/nu-cli/src/repl.rs index 2b0838fa5..bce9ec4e2 100644 --- a/crates/nu-cli/src/repl.rs +++ b/crates/nu-cli/src/repl.rs @@ -76,7 +76,7 @@ pub fn evaluate_repl( "CMD_DURATION_MS".into(), Value::String { val: "0823".to_string(), - span: Span { start: 0, end: 0 }, + span: Span::unknown(), }, ); @@ -84,7 +84,7 @@ pub fn evaluate_repl( "LAST_EXIT_CODE".into(), Value::Int { val: 0, - span: Span { start: 0, end: 0 }, + span: Span::unknown(), }, ); @@ -375,7 +375,7 @@ pub fn evaluate_repl( "OLDPWD".into(), Value::String { val: cwd.clone(), - span: Span { start: 0, end: 0 }, + span: Span::unknown(), }, ); @@ -385,7 +385,7 @@ pub fn evaluate_repl( "PWD".into(), Value::String { val: path.clone(), - span: Span { start: 0, end: 0 }, + span: Span::unknown(), }, ); let cwd = Value::String { val: cwd, span }; @@ -440,7 +440,7 @@ pub fn evaluate_repl( "CMD_DURATION_MS".into(), Value::String { val: format!("{}", cmd_duration.as_millis()), - span: Span { start: 0, end: 0 }, + span: Span::unknown(), }, ); @@ -997,7 +997,7 @@ fn run_ansi_sequence(seq: &str) -> Result<(), ShellError> { return Err(ShellError::GenericError( "Error writing ansi sequence".into(), err.to_string(), - Some(Span { start: 0, end: 0 }), + Some(Span::unknown()), None, Vec::new(), )); @@ -1007,7 +1007,7 @@ fn run_ansi_sequence(seq: &str) -> Result<(), ShellError> { ShellError::GenericError( "Error flushing stdio".into(), e.to_string(), - Some(Span { start: 0, end: 0 }), + Some(Span::unknown()), None, Vec::new(), ) diff --git a/crates/nu-cli/src/syntax_highlight.rs b/crates/nu-cli/src/syntax_highlight.rs index 1714ad300..1f585acda 100644 --- a/crates/nu-cli/src/syntax_highlight.rs +++ b/crates/nu-cli/src/syntax_highlight.rs @@ -149,7 +149,7 @@ fn split_span_by_highlight_positions( for pos in highlight_positions { if start <= *pos && pos < &span.end { if start < *pos { - result.push((Span { start, end: *pos }, false)); + result.push((Span::new(start, *pos), false)); } let span_str = &line[pos - global_span_offset..span.end - global_span_offset]; let end = span_str @@ -157,18 +157,12 @@ fn split_span_by_highlight_positions( .next() .map(|c| pos + get_char_length(c)) .unwrap_or(pos + 1); - result.push((Span { start: *pos, end }, true)); + result.push((Span::new(*pos, end), true)); start = end; } } if start < span.end { - result.push(( - Span { - start, - end: span.end, - }, - false, - )); + result.push((Span::new(start, span.end), false)); } result } diff --git a/crates/nu-cli/src/util.rs b/crates/nu-cli/src/util.rs index 26494c61c..a3b3b8532 100644 --- a/crates/nu-cli/src/util.rs +++ b/crates/nu-cli/src/util.rs @@ -291,7 +291,7 @@ fn set_last_exit_code(stack: &mut Stack, exit_code: i64) { "LAST_EXIT_CODE".to_string(), Value::Int { val: exit_code, - span: Span { start: 0, end: 0 }, + span: Span::unknown(), }, ); } diff --git a/crates/nu-cli/tests/support/completions_helpers.rs b/crates/nu-cli/tests/support/completions_helpers.rs index e1c8fd51e..2ef7b648a 100644 --- a/crates/nu-cli/tests/support/completions_helpers.rs +++ b/crates/nu-cli/tests/support/completions_helpers.rs @@ -33,20 +33,14 @@ pub fn new_engine() -> (PathBuf, String, EngineState, Stack) { "PWD".to_string(), Value::String { val: dir_str.clone(), - span: nu_protocol::Span { - start: 0, - end: dir_str.len(), - }, + span: nu_protocol::Span::new(0, dir_str.len()), }, ); stack.add_env_var( "TEST".to_string(), Value::String { val: "NUSHELL".to_string(), - span: nu_protocol::Span { - start: 0, - end: dir_str.len(), - }, + span: nu_protocol::Span::new(0, dir_str.len()), }, ); @@ -112,7 +106,7 @@ pub fn merge_input( &block, PipelineData::Value( Value::Nothing { - span: Span { start: 0, end: 0 }, + span: Span::unknown(), }, None ), diff --git a/crates/nu-command/src/charting/hashable_value.rs b/crates/nu-command/src/charting/hashable_value.rs index 5c81a84f4..e70cd3213 100644 --- a/crates/nu-command/src/charting/hashable_value.rs +++ b/crates/nu-command/src/charting/hashable_value.rs @@ -53,7 +53,7 @@ impl Default for HashableValue { fn default() -> Self { HashableValue::Bool { val: false, - span: Span { start: 0, end: 0 }, + span: Span::unknown(), } } } @@ -214,7 +214,7 @@ mod test { ]; for (val, expect_hashable_val) in values.into_iter() { assert_eq!( - HashableValue::from_value(val, Span { start: 0, end: 0 }).unwrap(), + HashableValue::from_value(val, Span::unknown()).unwrap(), expect_hashable_val ); } @@ -245,7 +245,7 @@ mod test { }, ]; for v in values { - assert!(HashableValue::from_value(v, Span { start: 0, end: 0 }).is_err()) + assert!(HashableValue::from_value(v, Span::unknown()).is_err()) } } @@ -266,7 +266,7 @@ mod test { for val in values.into_iter() { let expected_val = val.clone(); assert_eq!( - HashableValue::from_value(val, Span { start: 0, end: 0 }) + HashableValue::from_value(val, Span::unknown()) .unwrap() .into_value(), expected_val @@ -279,14 +279,11 @@ mod test { assert_eq!( HashableValue::Bool { val: true, - span: Span { start: 0, end: 1 } + span: Span::new(0, 1) }, HashableValue::Bool { val: true, - span: Span { - start: 90, - end: 1000 - } + span: Span::new(90, 1000) } ) } @@ -299,7 +296,7 @@ mod test { assert!(set.contains(&HashableValue::Bool { val: true, span })); // hashable value doesn't care about span. - let diff_span = Span { start: 1, end: 2 }; + let diff_span = Span::new(1, 2); set.insert(HashableValue::Bool { val: true, span: diff_span, diff --git a/crates/nu-command/src/conversions/into/duration.rs b/crates/nu-command/src/conversions/into/duration.rs index c32e453e0..d1c62837b 100644 --- a/crates/nu-command/src/conversions/into/duration.rs +++ b/crates/nu-command/src/conversions/into/duration.rs @@ -502,7 +502,7 @@ mod test { #[test] fn turns_ns_to_duration() { - let span = Span::test_data(); + let span = Span::new(0, 2); let word = Value::test_string("3ns"); let expected = Value::Duration { val: 3, span }; let convert_duration = None; @@ -513,7 +513,7 @@ mod test { #[test] fn turns_us_to_duration() { - let span = Span::test_data(); + let span = Span::new(0, 2); let word = Value::test_string("4us"); let expected = Value::Duration { val: 4 * 1000, @@ -527,7 +527,7 @@ mod test { #[test] fn turns_ms_to_duration() { - let span = Span::test_data(); + let span = Span::new(0, 2); let word = Value::test_string("5ms"); let expected = Value::Duration { val: 5 * 1000 * 1000, @@ -541,7 +541,7 @@ mod test { #[test] fn turns_sec_to_duration() { - let span = Span::test_data(); + let span = Span::new(0, 3); let word = Value::test_string("1sec"); let expected = Value::Duration { val: 1000 * 1000 * 1000, @@ -555,7 +555,7 @@ mod test { #[test] fn turns_min_to_duration() { - let span = Span::test_data(); + let span = Span::new(0, 3); let word = Value::test_string("7min"); let expected = Value::Duration { val: 7 * 60 * 1000 * 1000 * 1000, @@ -569,7 +569,7 @@ mod test { #[test] fn turns_hr_to_duration() { - let span = Span::test_data(); + let span = Span::new(0, 3); let word = Value::test_string("42hr"); let expected = Value::Duration { val: 42 * 60 * 60 * 1000 * 1000 * 1000, @@ -583,7 +583,7 @@ mod test { #[test] fn turns_day_to_duration() { - let span = Span::test_data(); + let span = Span::new(0, 5); let word = Value::test_string("123day"); let expected = Value::Duration { val: 123 * 24 * 60 * 60 * 1000 * 1000 * 1000, @@ -597,7 +597,7 @@ mod test { #[test] fn turns_wk_to_duration() { - let span = Span::test_data(); + let span = Span::new(0, 2); let word = Value::test_string("3wk"); let expected = Value::Duration { val: 3 * 7 * 24 * 60 * 60 * 1000 * 1000 * 1000, diff --git a/crates/nu-command/src/core_commands/error_make.rs b/crates/nu-command/src/core_commands/error_make.rs index a81654003..391a26813 100644 --- a/crates/nu-command/src/core_commands/error_make.rs +++ b/crates/nu-command/src/core_commands/error_make.rs @@ -108,10 +108,7 @@ fn make_error(value: &Value, throw_span: Option) -> Option { ) => Some(ShellError::GenericError( message, label_text, - Some(Span { - start: start as usize, - end: end as usize, - }), + Some(Span::new(start as usize, end as usize)), None, Vec::new(), )), diff --git a/crates/nu-command/src/dataframe/values/nu_dataframe/mod.rs b/crates/nu-command/src/dataframe/values/nu_dataframe/mod.rs index b3b0d949e..2f945d61f 100644 --- a/crates/nu-command/src/dataframe/values/nu_dataframe/mod.rs +++ b/crates/nu-command/src/dataframe/values/nu_dataframe/mod.rs @@ -39,7 +39,7 @@ impl Display for DataFrameValue { impl Default for DataFrameValue { fn default() -> Self { Self(Value::Nothing { - span: Span { start: 0, end: 0 }, + span: Span::unknown(), }) } } diff --git a/crates/nu-command/src/env/config/config_env.rs b/crates/nu-command/src/env/config/config_env.rs index de48bac2e..4c34bb835 100644 --- a/crates/nu-command/src/env/config/config_env.rs +++ b/crates/nu-command/src/env/config/config_env.rs @@ -64,7 +64,7 @@ impl Command for ConfigEnv { let args = vec![Spanned { item: nu_config.to_string_lossy().to_string(), - span: Span { start: 0, end: 0 }, + span: Span::unknown(), }]; let command = ExternalCommand { diff --git a/crates/nu-command/src/env/config/config_nu.rs b/crates/nu-command/src/env/config/config_nu.rs index 0224438c4..01a019305 100644 --- a/crates/nu-command/src/env/config/config_nu.rs +++ b/crates/nu-command/src/env/config/config_nu.rs @@ -64,7 +64,7 @@ impl Command for ConfigNu { let args = vec![Spanned { item: nu_config.to_string_lossy().to_string(), - span: Span { start: 0, end: 0 }, + span: Span::unknown(), }]; let command = ExternalCommand { diff --git a/crates/nu-command/src/filesystem/ls.rs b/crates/nu-command/src/filesystem/ls.rs index debb2d1a4..36fdc82f6 100644 --- a/crates/nu-command/src/filesystem/ls.rs +++ b/crates/nu-command/src/filesystem/ls.rs @@ -518,7 +518,7 @@ pub(crate) fn dir_entry_dict( if md.is_dir() { if du { - let params = DirBuilder::new(Span { start: 0, end: 2 }, None, false, None, false); + let params = DirBuilder::new(Span::new(0, 2), None, false, None, false); let dir_size = DirInfo::new(filename, ¶ms, None, ctrl_c).get_size(); vals.push(Value::Filesize { diff --git a/crates/nu-command/src/filesystem/rm.rs b/crates/nu-command/src/filesystem/rm.rs index b775606bc..28e651c17 100644 --- a/crates/nu-command/src/filesystem/rm.rs +++ b/crates/nu-command/src/filesystem/rm.rs @@ -199,18 +199,18 @@ fn rm( )); } - let targets_span = Span { - start: targets + let targets_span = Span::new( + targets .iter() .map(|x| x.span.start) .min() .expect("targets were empty"), - end: targets + targets .iter() .map(|x| x.span.end) .max() .expect("targets were empty"), - }; + ); let path = current_dir(engine_state, stack)?; diff --git a/crates/nu-command/src/filters/uniq_by.rs b/crates/nu-command/src/filters/uniq_by.rs index 2358c0144..90c3f74ca 100644 --- a/crates/nu-command/src/filters/uniq_by.rs +++ b/crates/nu-command/src/filters/uniq_by.rs @@ -154,7 +154,7 @@ fn item_mapper_by_col(cols: Vec) -> impl Fn(crate::ItemMapperState) -> c let col_vals = Value::List { vals: item_column_values, - span: Span { start: 0, end: 0 }, + span: Span::unknown(), }; crate::ValueCounter::new_vals_to_compare(ms.item, ms.flag_ignore_case, col_vals) diff --git a/crates/nu-command/src/formats/from/json.rs b/crates/nu-command/src/formats/from/json.rs index 5d551c407..a186e25ff 100644 --- a/crates/nu-command/src/formats/from/json.rs +++ b/crates/nu-command/src/formats/from/json.rs @@ -166,19 +166,13 @@ fn convert_row_column_to_span(row: usize, col: usize, contents: &str) -> Span { cur_col = 0; } if cur_row >= row && cur_col >= col { - return Span { - start: offset, - end: offset, - }; + return Span::new(offset, offset); } else { cur_col += 1; } } - Span { - start: contents.len(), - end: contents.len(), - } + Span::new(contents.len(), contents.len()) } fn convert_string_to_value(string_input: String, span: Span) -> Result { diff --git a/crates/nu-command/src/misc/tutor.rs b/crates/nu-command/src/misc/tutor.rs index 2db272d2f..30281d998 100644 --- a/crates/nu-command/src/misc/tutor.rs +++ b/crates/nu-command/src/misc/tutor.rs @@ -420,11 +420,11 @@ fn display(help: &str, engine_state: &EngineState, stack: &mut Stack, span: Span &Call::new(span), Value::String { val: item.to_string(), - span: Span { start: 0, end: 0 }, + span: Span::unknown(), } .into_pipeline_data(), ) { - let result = output.into_value(Span { start: 0, end: 0 }); + let result = output.into_value(Span::unknown()); match result.as_string() { Ok(s) => { build.push_str(&s); diff --git a/crates/nu-command/src/strings/format/command.rs b/crates/nu-command/src/strings/format/command.rs index 34e27ba27..57cd35063 100644 --- a/crates/nu-command/src/strings/format/command.rs +++ b/crates/nu-command/src/strings/format/command.rs @@ -152,18 +152,12 @@ fn extract_formatting_operations(input: String, span_start: usize) -> Vec { - let result = output.into_value(Span { start: 0, end: 0 }); + let result = output.into_value(Span::unknown()); match result.as_string() { Ok(s) => { let _ = write!(long_desc, "\n > {}\n", s); diff --git a/crates/nu-engine/src/eval.rs b/crates/nu-engine/src/eval.rs index 1d331fa55..ff094fc8e 100644 --- a/crates/nu-engine/src/eval.rs +++ b/crates/nu-engine/src/eval.rs @@ -1096,7 +1096,7 @@ pub fn eval_block( } } - input = PipelineData::new(Span { start: 0, end: 0 }) + input = PipelineData::new(Span::unknown()) } } diff --git a/crates/nu-parser/src/flatten.rs b/crates/nu-parser/src/flatten.rs index 4a3d9177f..14464ed42 100644 --- a/crates/nu-parser/src/flatten.rs +++ b/crates/nu-parser/src/flatten.rs @@ -102,10 +102,7 @@ pub fn flatten_expression( } Expr::UnaryNot(inner_expr) => { let mut output = vec![( - Span { - start: expr.span.start, - end: expr.span.start + 3, - }, + Span::new(expr.span.start, expr.span.start + 3), FlatShape::Operator, )]; output.extend(flatten_expression(working_set, inner_expr)); @@ -123,25 +120,13 @@ pub fn flatten_expression( if let Some(first) = flattened.first() { if first.0.start > outer_span.start { - output.push(( - Span { - start: outer_span.start, - end: first.0.start, - }, - FlatShape::Block, - )); + output.push((Span::new(outer_span.start, first.0.start), FlatShape::Block)); } } let last = if let Some(last) = flattened.last() { if last.0.end < outer_span.end { - Some(( - Span { - start: last.0.end, - end: outer_span.end, - }, - FlatShape::Block, - )) + Some((Span::new(last.0.end, outer_span.end), FlatShape::Block)) } else { None } @@ -313,13 +298,7 @@ pub fn flatten_expression( if let Some(first) = flattened.first() { if first.0.start > last_end { - output.push(( - Span { - start: last_end, - end: first.0.start, - }, - FlatShape::List, - )); + output.push((Span::new(last_end, first.0.start), FlatShape::List)); } } @@ -331,13 +310,7 @@ pub fn flatten_expression( } if last_end < outer_span.end { - output.push(( - Span { - start: last_end, - end: outer_span.end, - }, - FlatShape::List, - )); + output.push((Span::new(last_end, outer_span.end), FlatShape::List)); } output } @@ -353,18 +326,12 @@ pub fn flatten_expression( output.insert( 0, ( - Span { - start: expr.span.start, - end: expr.span.start + 2, - }, + Span::new(expr.span.start, expr.span.start + 2), FlatShape::StringInterpolation, ), ); output.push(( - Span { - start: expr.span.end - 1, - end: expr.span.end, - }, + Span::new(expr.span.end - 1, expr.span.end), FlatShape::StringInterpolation, )); } @@ -382,13 +349,7 @@ pub fn flatten_expression( if let Some(first) = flattened_lhs.first() { if first.0.start > last_end { - output.push(( - Span { - start: last_end, - end: first.0.start, - }, - FlatShape::Record, - )); + output.push((Span::new(last_end, first.0.start), FlatShape::Record)); } } if let Some(last) = flattened_lhs.last() { @@ -398,13 +359,7 @@ pub fn flatten_expression( if let Some(first) = flattened_rhs.first() { if first.0.start > last_end { - output.push(( - Span { - start: last_end, - end: first.0.start, - }, - FlatShape::Record, - )); + output.push((Span::new(last_end, first.0.start), FlatShape::Record)); } } if let Some(last) = flattened_rhs.last() { @@ -414,13 +369,7 @@ pub fn flatten_expression( output.extend(flattened_rhs); } if last_end < outer_span.end { - output.push(( - Span { - start: last_end, - end: outer_span.end, - }, - FlatShape::Record, - )); + output.push((Span::new(last_end, outer_span.end), FlatShape::Record)); } output @@ -448,13 +397,7 @@ pub fn flatten_expression( let flattened = flatten_expression(working_set, e); if let Some(first) = flattened.first() { if first.0.start > last_end { - output.push(( - Span { - start: last_end, - end: first.0.start, - }, - FlatShape::Table, - )); + output.push((Span::new(last_end, first.0.start), FlatShape::Table)); } } @@ -469,13 +412,7 @@ pub fn flatten_expression( let flattened = flatten_expression(working_set, expr); if let Some(first) = flattened.first() { if first.0.start > last_end { - output.push(( - Span { - start: last_end, - end: first.0.start, - }, - FlatShape::Table, - )); + output.push((Span::new(last_end, first.0.start), FlatShape::Table)); } } @@ -488,13 +425,7 @@ pub fn flatten_expression( } if last_end < outer_span.end { - output.push(( - Span { - start: last_end, - end: outer_span.end, - }, - FlatShape::Table, - )); + output.push((Span::new(last_end, outer_span.end), FlatShape::Table)); } output diff --git a/crates/nu-parser/src/lex.rs b/crates/nu-parser/src/lex.rs index ed7b6a6e5..fb972dccf 100644 --- a/crates/nu-parser/src/lex.rs +++ b/crates/nu-parser/src/lex.rs @@ -122,10 +122,7 @@ pub fn lex_item( }, Some(ParseError::UnexpectedEof( (start as char).to_string(), - Span { - start: span.end, - end: span.end, - }, + Span::new(span.end, span.end), )), ); } @@ -193,13 +190,8 @@ pub fn lex_item( // If there is still unclosed opening delimiters, remember they were missing if let Some(block) = block_level.last() { let delim = block.closing(); - let cause = ParseError::UnexpectedEof( - (delim as char).to_string(), - Span { - start: span.end, - end: span.end, - }, - ); + let cause = + ParseError::UnexpectedEof((delim as char).to_string(), Span::new(span.end, span.end)); return ( Token { @@ -221,10 +213,7 @@ pub fn lex_item( }, Some(ParseError::UnexpectedEof( (delim as char).to_string(), - Span { - start: span.end, - end: span.end, - }, + Span::new(span.end, span.end), )), ); } diff --git a/crates/nu-parser/src/parse_keywords.rs b/crates/nu-parser/src/parse_keywords.rs index fcc88ac1f..e2a837340 100644 --- a/crates/nu-parser/src/parse_keywords.rs +++ b/crates/nu-parser/src/parse_keywords.rs @@ -1179,10 +1179,7 @@ pub fn parse_export_in_module( error = error.or_else(|| { Some(ParseError::MissingPositional( "def, def-env, alias, or env keyword".into(), // TODO: keep filling more keywords as they come - Span { - start: export_span.end, - end: export_span.end, - }, + Span::new(export_span.end, export_span.end), "'def', `def-env`, `alias`, or 'env' keyword.".to_string(), )) }); @@ -1472,11 +1469,10 @@ pub fn parse_module( if block_bytes.ends_with(b"}") { end -= 1; } else { - error = - error.or_else(|| Some(ParseError::Unclosed("}".into(), Span { start: end, end }))); + error = error.or_else(|| Some(ParseError::Unclosed("}".into(), Span::new(end, end)))); } - let block_span = Span { start, end }; + let block_span = Span::new(start, end); let (block, module, err) = parse_module_block(working_set, block_span, expand_aliases_denylist); diff --git a/crates/nu-parser/src/parser.rs b/crates/nu-parser/src/parser.rs index eda05f163..b58ef0007 100644 --- a/crates/nu-parser/src/parser.rs +++ b/crates/nu-parser/src/parser.rs @@ -173,19 +173,13 @@ pub fn check_call(command: Span, sig: &Signature, call: &Call) -> Option Option { if token_start < end { - let span = Span { - start: token_start, - end, - }; + let span = Span::new(token_start, end); let str_contents = working_set.get_span_contents(span); let str_contents = if double_quote { @@ -1743,10 +1710,7 @@ pub fn parse_string_interpolation( } InterpolationMode::Expression => { if token_start < end { - let span = Span { - start: token_start, - end, - }; + let span = Span::new(token_start, end); let (expr, err) = parse_full_cell_path(working_set, None, span, expand_aliases_denylist); @@ -1923,11 +1887,11 @@ pub fn parse_full_cell_path( if bytes.ends_with(b")") { end -= 1; } else { - error = error - .or_else(|| Some(ParseError::Unclosed(")".into(), Span { start: end, end }))); + error = + error.or_else(|| Some(ParseError::Unclosed(")".into(), Span::new(end, end)))); } - let span = Span { start, end }; + let span = Span::new(start, end); let source = working_set.get_span_contents(span); @@ -2568,19 +2532,13 @@ pub fn unescape_string(bytes: &[u8], span: Span) -> (Vec, Option } err = Some(ParseError::Expected( "unicode hex value".into(), - Span { - start: (span.start + idx), - end: span.end, - }, + Span::new(span.start + idx, span.end), )); } _ => { err = Some(ParseError::Expected( "unicode hex value".into(), - Span { - start: (span.start + idx), - end: span.end, - }, + Span::new(span.start + idx, span.end), )); } } @@ -2589,10 +2547,7 @@ pub fn unescape_string(bytes: &[u8], span: Span) -> (Vec, Option _ => { err = Some(ParseError::Expected( "supported escape character".into(), - Span { - start: (span.start + idx), - end: span.end, - }, + Span::new(span.start + idx, span.end), )); } } @@ -2772,10 +2727,7 @@ pub fn parse_shape_name( let (shape, err) = parse_shape_name( working_set, split[0].as_bytes(), - Span { - start: span.start, - end: span.start + split[0].len(), - }, + Span::new(span.start, span.start + split[0].len()), ); let command_name = trim_quotes(split[1].as_bytes()); @@ -2786,10 +2738,10 @@ pub fn parse_shape_name( } else { return ( shape, - Some(ParseError::UnknownCommand(Span { - start: span.start + split[0].len() + 1, - end: span.end, - })), + Some(ParseError::UnknownCommand(Span::new( + span.start + split[0].len() + 1, + span.end, + ))), ); } } else { @@ -3143,10 +3095,7 @@ pub fn parse_signature( error = error.or_else(|| { Some(ParseError::Expected( "[ or (".into(), - Span { - start, - end: start + 1, - }, + Span::new(start, start + 1), )) }); } @@ -3154,16 +3103,11 @@ pub fn parse_signature( if (has_paren && bytes.ends_with(b")")) || (!has_paren && bytes.ends_with(b"]")) { end -= 1; } else { - error = error.or_else(|| { - Some(ParseError::Unclosed( - "] or )".into(), - Span { start: end, end }, - )) - }); + error = error.or_else(|| Some(ParseError::Unclosed("] or )".into(), Span::new(end, end)))); } let (sig, err) = - parse_signature_helper(working_set, Span { start, end }, expand_aliases_denylist); + parse_signature_helper(working_set, Span::new(start, end), expand_aliases_denylist); error = error.or(err); ( @@ -3631,10 +3575,7 @@ pub fn parse_signature_helper( contents: crate::TokenContents::Comment, span, } => { - let contents = working_set.get_span_contents(Span { - start: span.start + 1, - end: span.end, - }); + let contents = working_set.get_span_contents(Span::new(span.start + 1, span.end)); let mut contents = String::from_utf8_lossy(contents).to_string(); contents = contents.trim().into(); @@ -3724,10 +3665,10 @@ pub fn parse_list_expression( if bytes.ends_with(b"]") { end -= 1; } else { - error = error.or_else(|| Some(ParseError::Unclosed("]".into(), Span { start: end, end }))); + error = error.or_else(|| Some(ParseError::Unclosed("]".into(), Span::new(end, end)))); } - let inner_span = Span { start, end }; + let inner_span = Span::new(start, end); let source = working_set.get_span_contents(inner_span); let (output, err) = lex(source, inner_span.start, &[b'\n', b'\r', b','], &[], true); @@ -3803,10 +3744,10 @@ pub fn parse_table_expression( if bytes.ends_with(b"]") { end -= 1; } else { - error = error.or_else(|| Some(ParseError::Unclosed("]".into(), Span { start: end, end }))); + error = error.or_else(|| Some(ParseError::Unclosed("]".into(), Span::new(end, end)))); } - let inner_span = Span { start, end }; + let inner_span = Span::new(start, end); let source = working_set.get_span_contents(inner_span); @@ -3938,10 +3879,10 @@ pub fn parse_block_expression( if bytes.ends_with(b"}") { end -= 1; } else { - error = error.or_else(|| Some(ParseError::Unclosed("}".into(), Span { start: end, end }))); + error = error.or_else(|| Some(ParseError::Unclosed("}".into(), Span::new(end, end)))); } - let inner_span = Span { start, end }; + let inner_span = Span::new(start, end); let source = working_set.get_span_contents(inner_span); @@ -4069,10 +4010,10 @@ pub fn parse_closure_expression( if bytes.ends_with(b"}") { end -= 1; } else { - error = error.or_else(|| Some(ParseError::Unclosed("}".into(), Span { start: end, end }))); + error = error.or_else(|| Some(ParseError::Unclosed("}".into(), Span::new(end, end)))); } - let inner_span = Span { start, end }; + let inner_span = Span::new(start, end); let source = working_set.get_span_contents(inner_span); @@ -4111,10 +4052,7 @@ pub fn parse_closure_expression( end }; - let signature_span = Span { - start: start_point, - end: end_point, - }; + let signature_span = Span::new(start_point, end_point); let (signature, err) = parse_signature_helper(working_set, signature_span, expand_aliases_denylist); error = error.or(err); @@ -4673,10 +4611,7 @@ pub fn parse_math_expression( garbage(spans[0]), Some(ParseError::Expected( "expression".into(), - Span { - start: spans[0].end, - end: spans[0].end, - }, + Span::new(spans[0].end, spans[0].end), )), ); } @@ -4825,16 +4760,10 @@ pub fn parse_expression( let lhs = parse_string_strict( working_set, - Span { - start: spans[pos].start, - end: spans[pos].start + point - 1, - }, + Span::new(spans[pos].start, spans[pos].start + point - 1), ); let rhs = if spans[pos].start + point < spans[pos].end { - let rhs_span = Span { - start: spans[pos].start + point, - end: spans[pos].end, - }; + let rhs_span = Span::new(spans[pos].start + point, spans[pos].end); if working_set.get_span_contents(rhs_span).starts_with(b"$") { parse_dollar_expr(working_set, rhs_span, expand_aliases_denylist) @@ -4845,7 +4774,7 @@ pub fn parse_expression( ( Expression { expr: Expr::String(String::new()), - span: Span { start: 0, end: 0 }, + span: Span::unknown(), ty: Type::Nothing, custom_completion: None, }, @@ -5124,7 +5053,7 @@ pub fn parse_expression( ]; let expr = Expr::Call(Box::new(Call { - head: Span { start: 0, end: 0 }, + head: Span::unknown(), decl_id, arguments, redirect_stdout: true, @@ -5232,10 +5161,7 @@ pub fn parse_record( error = error.or_else(|| { Some(ParseError::Expected( "{".into(), - Span { - start, - end: start + 1, - }, + Span::new(start, start + 1), )) }); } @@ -5243,10 +5169,10 @@ pub fn parse_record( if bytes.ends_with(b"}") { end -= 1; } else { - error = error.or_else(|| Some(ParseError::Unclosed("}".into(), Span { start: end, end }))); + error = error.or_else(|| Some(ParseError::Unclosed("}".into(), Span::new(end, end)))); } - let inner_span = Span { start, end }; + let inner_span = Span::new(start, end); let source = working_set.get_span_contents(inner_span); let (tokens, err) = lex(source, start, &[b'\n', b'\r', b','], &[b':'], true); diff --git a/crates/nu-parser/tests/test_lex.rs b/crates/nu-parser/tests/test_lex.rs index b96f63cbf..e88eb3d5c 100644 --- a/crates/nu-parser/tests/test_lex.rs +++ b/crates/nu-parser/tests/test_lex.rs @@ -18,7 +18,7 @@ fn lex_newline() { assert!(output.0.contains(&Token { contents: TokenContents::Eol, - span: Span { start: 11, end: 12 } + span: Span::new(11, 12) })); } @@ -43,7 +43,7 @@ fn lex_parenthesis() { output.0.get(3).unwrap(), &Token { contents: TokenContents::Item, - span: Span { start: 8, end: 27 } + span: Span::new(8, 27) } ); } @@ -58,7 +58,7 @@ fn lex_comment() { output.0.get(4).unwrap(), &Token { contents: TokenContents::Comment, - span: Span { start: 12, end: 24 } + span: Span::new(12, 24) } ); } @@ -108,14 +108,14 @@ fn lex_comments() { output.0.get(4).unwrap(), &Token { contents: TokenContents::Comment, - span: Span { start: 10, end: 19 } + span: Span::new(10, 19) } ); assert_eq!( output.0.get(5).unwrap(), &Token { contents: TokenContents::Eol, - span: Span { start: 19, end: 20 } + span: Span::new(19, 20) } ); @@ -125,14 +125,14 @@ fn lex_comments() { output.0.get(10).unwrap(), &Token { contents: TokenContents::Comment, - span: Span { start: 31, end: 40 } + span: Span::new(31, 40) } ); assert_eq!( output.0.get(11).unwrap(), &Token { contents: TokenContents::Eol, - span: Span { start: 40, end: 41 } + span: Span::new(40, 41) } ); } diff --git a/crates/nu-plugin/src/protocol/evaluated_call.rs b/crates/nu-plugin/src/protocol/evaluated_call.rs index 81adbc635..a79e4e144 100644 --- a/crates/nu-plugin/src/protocol/evaluated_call.rs +++ b/crates/nu-plugin/src/protocol/evaluated_call.rs @@ -115,32 +115,32 @@ mod test { #[test] fn call_to_value() { let call = EvaluatedCall { - head: Span { start: 0, end: 10 }, + head: Span::new(0, 10), positional: vec![ Value::Float { val: 1.0, - span: Span { start: 0, end: 10 }, + span: Span::new(0, 10), }, Value::String { val: "something".into(), - span: Span { start: 0, end: 10 }, + span: Span::new(0, 10), }, ], named: vec![ ( Spanned { item: "name".to_string(), - span: Span { start: 0, end: 10 }, + span: Span::new(0, 10), }, Some(Value::Float { val: 1.0, - span: Span { start: 0, end: 10 }, + span: Span::new(0, 10), }), ), ( Spanned { item: "flag".to_string(), - span: Span { start: 0, end: 10 }, + span: Span::new(0, 10), }, None, ), diff --git a/crates/nu-plugin/src/serializers/json.rs b/crates/nu-plugin/src/serializers/json.rs index 6d77e11c1..e422d41df 100644 --- a/crates/nu-plugin/src/serializers/json.rs +++ b/crates/nu-plugin/src/serializers/json.rs @@ -79,29 +79,29 @@ mod tests { let input = Value::Bool { val: false, - span: Span { start: 1, end: 20 }, + span: Span::new(1, 20), }; let call = EvaluatedCall { - head: Span { start: 0, end: 10 }, + head: Span::new(0, 10), positional: vec![ Value::Float { val: 1.0, - span: Span { start: 0, end: 10 }, + span: Span::new(0, 10), }, Value::String { val: "something".into(), - span: Span { start: 0, end: 10 }, + span: Span::new(0, 10), }, ], named: vec![( Spanned { item: "name".to_string(), - span: Span { start: 0, end: 10 }, + span: Span::new(0, 10), }, Some(Value::Float { val: 1.0, - span: Span { start: 0, end: 10 }, + span: Span::new(0, 10), }), )], }; @@ -155,7 +155,7 @@ mod tests { #[test] fn callinfo_round_trip_collapsecustomvalue() { let data = vec![1, 2, 3, 4, 5, 6, 7]; - let span = Span { start: 0, end: 20 }; + let span = Span::new(0, 20); let collapse_custom_value = PluginCall::CollapseCustomValue(PluginData { data: data.clone(), @@ -247,7 +247,7 @@ mod tests { fn response_round_trip_value() { let value = Value::Int { val: 10, - span: Span { start: 2, end: 30 }, + span: Span::new(2, 30), }; let response = PluginResponse::Value(Box::new(value.clone())); @@ -276,7 +276,7 @@ mod tests { let name = "test".to_string(); let data = vec![1, 2, 3, 4, 5]; - let span = Span { start: 2, end: 30 }; + let span = Span::new(2, 30); let response = PluginResponse::PluginData( name.clone(), @@ -312,7 +312,7 @@ mod tests { let error = LabeledError { label: "label".into(), msg: "msg".into(), - span: Some(Span { start: 2, end: 30 }), + span: Some(Span::new(2, 30)), }; let response = PluginResponse::Error(error.clone()); diff --git a/crates/nu-plugin/src/serializers/msgpack.rs b/crates/nu-plugin/src/serializers/msgpack.rs index 20e6df592..5a7d6bbee 100644 --- a/crates/nu-plugin/src/serializers/msgpack.rs +++ b/crates/nu-plugin/src/serializers/msgpack.rs @@ -78,29 +78,29 @@ mod tests { let input = Value::Bool { val: false, - span: Span { start: 1, end: 20 }, + span: Span::new(1, 20), }; let call = EvaluatedCall { - head: Span { start: 0, end: 10 }, + head: Span::new(0, 10), positional: vec![ Value::Float { val: 1.0, - span: Span { start: 0, end: 10 }, + span: Span::new(0, 10), }, Value::String { val: "something".into(), - span: Span { start: 0, end: 10 }, + span: Span::new(0, 10), }, ], named: vec![( Spanned { item: "name".to_string(), - span: Span { start: 0, end: 10 }, + span: Span::new(0, 10), }, Some(Value::Float { val: 1.0, - span: Span { start: 0, end: 10 }, + span: Span::new(0, 10), }), )], }; @@ -154,7 +154,7 @@ mod tests { #[test] fn callinfo_round_trip_collapsecustomvalue() { let data = vec![1, 2, 3, 4, 5, 6, 7]; - let span = Span { start: 0, end: 20 }; + let span = Span::new(0, 20); let collapse_custom_value = PluginCall::CollapseCustomValue(PluginData { data: data.clone(), @@ -246,7 +246,7 @@ mod tests { fn response_round_trip_value() { let value = Value::Int { val: 10, - span: Span { start: 2, end: 30 }, + span: Span::new(2, 30), }; let response = PluginResponse::Value(Box::new(value.clone())); @@ -275,7 +275,7 @@ mod tests { let name = "test".to_string(); let data = vec![1, 2, 3, 4, 5]; - let span = Span { start: 2, end: 30 }; + let span = Span::new(2, 30); let response = PluginResponse::PluginData( name.clone(), @@ -311,7 +311,7 @@ mod tests { let error = LabeledError { label: "label".into(), msg: "msg".into(), - span: Some(Span { start: 2, end: 30 }), + span: Some(Span::new(2, 30)), }; let response = PluginResponse::Error(error.clone()); diff --git a/crates/nu-protocol/src/ast/import_pattern.rs b/crates/nu-protocol/src/ast/import_pattern.rs index 77371624c..1f1fa5712 100644 --- a/crates/nu-protocol/src/ast/import_pattern.rs +++ b/crates/nu-protocol/src/ast/import_pattern.rs @@ -32,7 +32,7 @@ impl ImportPattern { head: ImportPatternHead { name: vec![], id: None, - span: Span { start: 0, end: 0 }, + span: Span::unknown(), }, members: vec![], hidden: HashSet::new(), diff --git a/crates/nu-protocol/src/config.rs b/crates/nu-protocol/src/config.rs index 4278cd297..2dae94e8c 100644 --- a/crates/nu-protocol/src/config.rs +++ b/crates/nu-protocol/src/config.rs @@ -981,7 +981,7 @@ fn create_hooks(value: &Value) -> Result { _ => Err(ShellError::UnsupportedConfigValue( "record for 'hooks' config".into(), "non-record value".into(), - Span { start: 0, end: 0 }, + Span::unknown(), )), }, } diff --git a/crates/nu-protocol/src/engine/engine_state.rs b/crates/nu-protocol/src/engine/engine_state.rs index 876855674..b2fe080ef 100644 --- a/crates/nu-protocol/src/engine/engine_state.rs +++ b/crates/nu-protocol/src/engine/engine_state.rs @@ -755,10 +755,7 @@ impl EngineState { pub fn get_file_source(&self, file_id: usize) -> String { for file in self.files.iter().enumerate() { if file.0 == file_id { - let contents = self.get_span_contents(&Span { - start: file.1 .1, - end: file.1 .2, - }); + let contents = self.get_span_contents(&Span::new(file.1 .1, file.1 .2)); let output = String::from_utf8_lossy(contents).to_string(); return output; @@ -1318,10 +1315,9 @@ impl<'a> StateWorkingSet<'a> { pub fn get_file_source(&self, file_id: usize) -> String { for file in self.files().enumerate() { if file.0 == file_id { - let output = String::from_utf8_lossy(self.get_span_contents(Span { - start: file.1 .1, - end: file.1 .2, - })) + let output = String::from_utf8_lossy( + self.get_span_contents(Span::new(file.1 .1, file.1 .2)), + ) .to_string(); return output; @@ -2041,10 +2037,7 @@ impl<'a> miette::SourceCode for &StateWorkingSet<'a> { let found_file = "Found matching file"; dbg!(found_file); } - let our_span = Span { - start: *start, - end: *end, - }; + let our_span = Span::new(*start, *end); // We need to move to a local span because we're only reading // the specific file contents via self.get_span_contents. let local_span = (span.offset() - *start, span.len()).into(); diff --git a/crates/nu-protocol/src/pipeline_data.rs b/crates/nu-protocol/src/pipeline_data.rs index cc03e1b2c..1389ccfb5 100644 --- a/crates/nu-protocol/src/pipeline_data.rs +++ b/crates/nu-protocol/src/pipeline_data.rs @@ -308,7 +308,7 @@ impl PipelineData { } PipelineData::ListStream(stream, ..) => Ok(stream.map(f).into_pipeline_data(ctrlc)), PipelineData::ExternalStream { stdout: None, .. } => { - Ok(PipelineData::new(Span { start: 0, end: 0 })) + Ok(PipelineData::new(Span::unknown())) } PipelineData::ExternalStream { stdout: Some(stream), @@ -366,7 +366,7 @@ impl PipelineData { Ok(stream.flat_map(f).into_pipeline_data(ctrlc)) } PipelineData::ExternalStream { stdout: None, .. } => { - Ok(PipelineData::new(Span { start: 0, end: 0 })) + Ok(PipelineData::new(Span::unknown())) } PipelineData::ExternalStream { stdout: Some(stream), @@ -419,7 +419,7 @@ impl PipelineData { } PipelineData::ListStream(stream, ..) => Ok(stream.filter(f).into_pipeline_data(ctrlc)), PipelineData::ExternalStream { stdout: None, .. } => { - Ok(PipelineData::new(Span { start: 0, end: 0 })) + Ok(PipelineData::new(Span::unknown())) } PipelineData::ExternalStream { stdout: Some(stream), diff --git a/crates/nu-protocol/src/span.rs b/crates/nu-protocol/src/span.rs index c5ea6cfbb..3daf27213 100644 --- a/crates/nu-protocol/src/span.rs +++ b/crates/nu-protocol/src/span.rs @@ -14,6 +14,7 @@ where /// Spans are a global offset across all seen files, which are cached in the engine's state. The start and /// end offset together make the inclusive start/exclusive end pair for where to underline to highlight /// a given point of interest. +#[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] pub struct Span { pub start: usize, @@ -28,24 +29,28 @@ impl From for SourceSpan { impl Span { pub fn new(start: usize, end: usize) -> Span { + debug_assert!( + end >= start, + "Can't create a Span whose end < start, start={}, end={}", + start, + end + ); + Span { start, end } } - pub fn unknown() -> Self { - Self::new(0, 0) + pub const fn unknown() -> Span { + Span { start: 0, end: 0 } } /// Note: Only use this for test data, *not* live data, as it will point into unknown source /// when used in errors. - pub fn test_data() -> Span { - Span { start: 0, end: 0 } + pub const fn test_data() -> Span { + Self::unknown() } pub fn offset(&self, offset: usize) -> Span { - Span { - start: self.start - offset, - end: self.end - offset, - } + Span::new(self.start - offset, self.end - offset) } pub fn contains(&self, pos: usize) -> bool { @@ -70,15 +75,17 @@ impl Span { pub fn span(spans: &[Span]) -> Span { let length = spans.len(); + //TODO debug_assert!(length > 0, "expect spans > 0"); if length == 0 { - // TODO: do this for now, but we might also want to protect against this case - Span { start: 0, end: 0 } + Span::unknown() } else if length == 1 { spans[0] } else { - Span { - start: spans[0].start, - end: spans[length - 1].end, - } + let end = spans + .iter() + .map(|s| s.end) + .max() + .expect("Must be an end. Length > 0"); + Span::new(spans[0].start, end) } } diff --git a/crates/nu-protocol/src/value/mod.rs b/crates/nu-protocol/src/value/mod.rs index d8b0e1382..210590cbf 100644 --- a/crates/nu-protocol/src/value/mod.rs +++ b/crates/nu-protocol/src/value/mod.rs @@ -1391,7 +1391,7 @@ impl Value { impl Default for Value { fn default() -> Self { Value::Nothing { - span: Span { start: 0, end: 0 }, + span: Span::unknown(), } } }