From 8a06ea133b1cfb58362b360c6cc6146ab94a0e12 Mon Sep 17 00:00:00 2001 From: Fernando Herrera Date: Sat, 4 Dec 2021 12:38:21 +0000 Subject: [PATCH] removed unwraps (#430) --- .github/workflows/ci.yml | 2 +- crates/nu-command/src/conversions/into/int.rs | 12 +++-- .../nu-command/src/conversions/into/string.rs | 14 +++--- crates/nu-command/src/filesystem/cp.rs | 34 ++++++++++++-- crates/nu-command/src/filesystem/ls.rs | 8 +++- crates/nu-command/src/filesystem/mv.rs | 44 ++++++++++++----- crates/nu-command/src/filesystem/rm.rs | 46 +++++++++--------- crates/nu-command/src/filters/drop/command.rs | 3 +- crates/nu-command/src/filters/first.rs | 12 ++++- crates/nu-command/src/filters/last.rs | 5 +- crates/nu-command/src/math/median.rs | 6 ++- crates/nu-command/src/math/mode.rs | 15 +++--- crates/nu-command/src/platform/kill.rs | 21 ++++++++- .../nu-command/src/strings/format/command.rs | 6 +-- crates/nu-command/src/strings/str_/lpad.rs | 2 +- crates/nu-command/src/strings/str_/rpad.rs | 2 +- .../src/strings/str_/trim/command.rs | 2 +- crates/nu-command/src/system/run_external.rs | 25 +++++----- crates/nu-command/src/viewers/griddle.rs | 37 ++++++++------- crates/nu-command/src/viewers/icons.rs | 41 ++++++++++++---- crates/nu-protocol/src/config.rs | 2 +- crates/nu-protocol/src/engine/engine_state.rs | 47 +++---------------- crates/nu-table/src/table.rs | 2 +- src/main.rs | 4 +- 24 files changed, 233 insertions(+), 159 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6ff109e74a..12ed146404 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,4 +39,4 @@ jobs: - uses: actions-rs/cargo@v1 with: command: clippy - args: -- -D warnings + args: -- -D warnings -D clippy::unwrap_used -A clippy::needless_collect diff --git a/crates/nu-command/src/conversions/into/int.rs b/crates/nu-command/src/conversions/into/int.rs index c7dba5590e..0c78d64e5b 100644 --- a/crates/nu-command/src/conversions/into/int.rs +++ b/crates/nu-command/src/conversions/into/int.rs @@ -114,11 +114,13 @@ fn into_int( None => 10, }; - if !(2..=36).contains(&radix) { - return Err(ShellError::UnsupportedInput( - "Radix must lie in the range [2, 36]".to_string(), - options.radix.unwrap().span().unwrap(), - )); + if let Some(val) = &options.radix { + if !(2..=36).contains(&radix) { + return Err(ShellError::UnsupportedInput( + "Radix must lie in the range [2, 36]".to_string(), + val.span()?, + )); + } } input.map( diff --git a/crates/nu-command/src/conversions/into/string.rs b/crates/nu-command/src/conversions/into/string.rs index 842edc6daa..c751e48117 100644 --- a/crates/nu-command/src/conversions/into/string.rs +++ b/crates/nu-command/src/conversions/into/string.rs @@ -139,11 +139,13 @@ fn string_helper( let column_paths: Vec = call.rest(engine_state, stack, 0)?; let config = stack.get_config()?; - if decimals && decimals_value.is_some() && decimals_value.unwrap().is_negative() { - return Err(ShellError::UnsupportedInput( - "Cannot accept negative integers for decimals arguments".to_string(), - head, - )); + if let Some(decimal_val) = decimals_value { + if decimals && decimal_val.is_negative() { + return Err(ShellError::UnsupportedInput( + "Cannot accept negative integers for decimals arguments".to_string(), + head, + )); + } } input.map( @@ -192,7 +194,7 @@ pub fn action( } Value::Float { val, .. } => { if decimals { - let decimal_value = digits.unwrap() as usize; + let decimal_value = digits.unwrap_or(2) as usize; Value::String { val: format!("{:.*}", decimal_value, val), span, diff --git a/crates/nu-command/src/filesystem/cp.rs b/crates/nu-command/src/filesystem/cp.rs index 6f6b4f7d4f..83bb601969 100644 --- a/crates/nu-command/src/filesystem/cp.rs +++ b/crates/nu-command/src/filesystem/cp.rs @@ -49,7 +49,7 @@ impl Command for Cp { let interactive = call.has_flag("interactive"); let force = call.has_flag("force"); - let path: PathBuf = current_dir().unwrap(); + let path = current_dir()?; let source = path.join(source.as_str()); let destination = path.join(destination.as_str()); @@ -83,12 +83,36 @@ impl Command for Cp { let prompt = format!( "Are you shure that you want to copy {} to {}?", file.as_ref() - .unwrap() + .map_err(|err| ShellError::LabeledError( + "Reference error".into(), + err.to_string(), + call.head + ))? .file_name() - .unwrap() + .ok_or_else(|| ShellError::LabeledError( + "File name error".into(), + "Unable to get file name".into(), + call.head + ))? .to_str() - .unwrap(), - destination.file_name().unwrap().to_str().unwrap() + .ok_or_else(|| ShellError::LabeledError( + "Unable to get str error".into(), + "Unable to convert to str file name".into(), + call.head + ))?, + destination + .file_name() + .ok_or_else(|| ShellError::LabeledError( + "File name error".into(), + "Unable to get file name".into(), + call.head + ))? + .to_str() + .ok_or_else(|| ShellError::LabeledError( + "Unable to get str error".into(), + "Unable to convert to str file name".into(), + call.head + ))?, ); let input = get_interactive_confirmation(prompt)?; diff --git a/crates/nu-command/src/filesystem/ls.rs b/crates/nu-command/src/filesystem/ls.rs index 4dc8416e0a..bb3d5f08d9 100644 --- a/crates/nu-command/src/filesystem/ls.rs +++ b/crates/nu-command/src/filesystem/ls.rs @@ -55,7 +55,13 @@ impl Command for Ls { }; let call_span = call.head; - let glob = glob::glob(&pattern).unwrap(); + let glob = glob::glob(&pattern).map_err(|err| { + nu_protocol::ShellError::LabeledError( + "Error extracting glob pattern".into(), + err.to_string(), + call.head, + ) + })?; Ok(glob .into_iter() diff --git a/crates/nu-command/src/filesystem/mv.rs b/crates/nu-command/src/filesystem/mv.rs index 777ac231bb..f24063a91e 100644 --- a/crates/nu-command/src/filesystem/mv.rs +++ b/crates/nu-command/src/filesystem/mv.rs @@ -5,7 +5,7 @@ use super::util::get_interactive_confirmation; use nu_engine::CallExt; use nu_protocol::ast::Call; use nu_protocol::engine::{Command, EngineState, Stack}; -use nu_protocol::{Category, PipelineData, ShellError, Signature, SyntaxShape}; +use nu_protocol::{Category, PipelineData, ShellError, Signature, Spanned, SyntaxShape}; #[derive(Clone)] pub struct Mv; @@ -45,22 +45,20 @@ impl Command for Mv { _input: PipelineData, ) -> Result { // TODO: handle invalid directory or insufficient permissions when moving - let source: String = call.req(engine_state, stack, 0)?; + let spanned_source: Spanned = call.req(engine_state, stack, 0)?; let destination: String = call.req(engine_state, stack, 1)?; let interactive = call.has_flag("interactive"); let force = call.has_flag("force"); - let path: PathBuf = current_dir().unwrap(); - let source = path.join(source.as_str()); + let path: PathBuf = current_dir()?; + let source = path.join(spanned_source.item.as_str()); let destination = path.join(destination.as_str()); let mut sources = glob::glob(&source.to_string_lossy()).map_or_else(|_| Vec::new(), Iterator::collect); if sources.is_empty() { - return Err(ShellError::FileNotFound( - call.positional.first().unwrap().span, - )); + return Err(ShellError::FileNotFound(spanned_source.span)); } if interactive && !force { @@ -69,12 +67,36 @@ impl Command for Mv { let prompt = format!( "Are you shure that you want to move {} to {}?", file.as_ref() - .unwrap() + .map_err(|err| ShellError::LabeledError( + "Reference error".into(), + err.to_string(), + call.head + ))? .file_name() - .unwrap() + .ok_or_else(|| ShellError::LabeledError( + "File name error".into(), + "Unable to get file name".into(), + call.head + ))? .to_str() - .unwrap(), - destination.file_name().unwrap().to_str().unwrap() + .ok_or_else(|| ShellError::LabeledError( + "Unable to get str error".into(), + "Unable to convert to str file name".into(), + call.head + ))?, + destination + .file_name() + .ok_or_else(|| ShellError::LabeledError( + "File name error".into(), + "Unable to get file name".into(), + call.head + ))? + .to_str() + .ok_or_else(|| ShellError::LabeledError( + "Unable to get str error".into(), + "Unable to convert to str file name".into(), + call.head + ))?, ); let input = get_interactive_confirmation(prompt)?; diff --git a/crates/nu-command/src/filesystem/rm.rs b/crates/nu-command/src/filesystem/rm.rs index faea33e586..51b32a8980 100644 --- a/crates/nu-command/src/filesystem/rm.rs +++ b/crates/nu-command/src/filesystem/rm.rs @@ -84,23 +84,6 @@ fn rm( "Can't use \"--trash\" with \"--permanent\"".to_string(), call.head, )); - - // let trash_span = call.get_flag_expr("trash").unwrap().span; - // let perm_span = call.get_flag_expr("permanent").unwrap().span; - - // let left_message = "cannot use".to_string(); - // let right_message = "with".to_string(); - // let (left_span, right_span) = match trash_span.start < perm_span.start { - // true => (trash_span, perm_span), - // false => (perm_span, trash_span), - // }; - - // return Err(ShellError::IncompatibleParameters { - // left_message, - // left_span, - // right_message, - // right_span, - // }); } let current_path = current_dir()?; @@ -141,7 +124,19 @@ fn rm( for (index, file) in targets.iter().enumerate() { let prompt: String = format!( "Are you sure that you what to delete {}?", - file.1.file_name().unwrap().to_str().unwrap() + file.1 + .file_name() + .ok_or_else(|| ShellError::LabeledError( + "File name error".into(), + "Unable to get file name".into(), + call.head + ))? + .to_str() + .ok_or_else(|| ShellError::LabeledError( + "Unable to get str error".into(), + "Unable to convert to str file name".into(), + call.head + ))?, ); let input = get_interactive_confirmation(prompt)?; @@ -192,9 +187,18 @@ fn rm_helper(call: &Call, args: RmArgs) -> Vec { #[cfg(not(feature = "trash-support"))] { if trash { - return vec![Value::Error { - error: ShellError::FeatureNotEnabled(call.get_flag_expr("trash").unwrap().span), - }]; + let error = match call.get_flag_expr("trash").ok_or_else(|| { + ShellError::LabeledError( + "Flag not found".into(), + "trash flag not found".into(), + call.head, + ) + }) { + Ok(expr) => ShellError::FeatureNotEnabled(expr.span), + Err(err) => err, + }; + + return vec![Value::Error { error }]; } } diff --git a/crates/nu-command/src/filters/drop/command.rs b/crates/nu-command/src/filters/drop/command.rs index 78b4515f59..aac7efea6b 100644 --- a/crates/nu-command/src/filters/drop/command.rs +++ b/crates/nu-command/src/filters/drop/command.rs @@ -6,7 +6,6 @@ use nu_protocol::{ Category, Example, IntoInterruptiblePipelineData, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, }; -use std::convert::TryInto; #[derive(Clone)] pub struct Drop; @@ -90,7 +89,7 @@ impl Command for Drop { vlen - rows_to_drop }; - let iter = v.into_iter().take(k.try_into().unwrap()); + let iter = v.into_iter().take(k as usize); Ok(iter.into_pipeline_data(engine_state.ctrlc.clone())) } } diff --git a/crates/nu-command/src/filters/first.rs b/crates/nu-command/src/filters/first.rs index d3358ff9db..9c9ba61809 100644 --- a/crates/nu-command/src/filters/first.rs +++ b/crates/nu-command/src/filters/first.rs @@ -72,7 +72,17 @@ fn first_helper( let mut input_peek = input.into_iter().peekable(); if input_peek.peek().is_some() { - match input_peek.peek().unwrap().get_type() { + match input_peek + .peek() + .ok_or_else(|| { + ShellError::LabeledError( + "Error in first".into(), + "unable to pick on next value".into(), + call.head, + ) + })? + .get_type() + { Type::Binary => { match &mut input_peek.next() { Some(v) => match &v { diff --git a/crates/nu-command/src/filters/last.rs b/crates/nu-command/src/filters/last.rs index 5dd93e16ed..8c1871e74a 100644 --- a/crates/nu-command/src/filters/last.rs +++ b/crates/nu-command/src/filters/last.rs @@ -6,7 +6,6 @@ use nu_protocol::{ Category, Example, IntoInterruptiblePipelineData, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, }; -use std::convert::TryInto; #[derive(Clone)] pub struct Last; @@ -53,9 +52,7 @@ impl Command for Last { let vlen: i64 = v.len() as i64; let beginning_rows_to_skip = rows_to_skip(vlen, rows); - let iter = v - .into_iter() - .skip(beginning_rows_to_skip.try_into().unwrap()); + let iter = v.into_iter().skip(beginning_rows_to_skip as usize); Ok(iter.into_pipeline_data(engine_state.ctrlc.clone())) } diff --git a/crates/nu-command/src/math/median.rs b/crates/nu-command/src/math/median.rs index 080c4fc044..a5b91cf505 100644 --- a/crates/nu-command/src/math/median.rs +++ b/crates/nu-command/src/math/median.rs @@ -1,3 +1,5 @@ +use std::cmp::Ordering; + use crate::math::avg::average; use crate::math::utils::run_with_function; use nu_protocol::ast::Call; @@ -72,14 +74,14 @@ pub fn median(values: &[Value], head: &Span) -> Result { rhs_span: elem[1].span()?, }); } - Ok(elem[0].partial_cmp(&elem[1]).unwrap()) + Ok(elem[0].partial_cmp(&elem[1]).unwrap_or(Ordering::Equal)) }) .find(|elem| elem.is_err()) { return Err(values); } - sorted.sort_by(|a, b| a.partial_cmp(b).unwrap()); + sorted.sort_by(|a, b| a.partial_cmp(b).unwrap_or(Ordering::Equal)); match take { Pick::Median => { diff --git a/crates/nu-command/src/math/mode.rs b/crates/nu-command/src/math/mode.rs index 619a02aeca..03f3e3e222 100644 --- a/crates/nu-command/src/math/mode.rs +++ b/crates/nu-command/src/math/mode.rs @@ -78,7 +78,7 @@ pub fn mode(values: &[Value], head: &Span) -> Result { rhs_span: elem[1].span()?, }); } - Ok(elem[0].partial_cmp(&elem[1]).unwrap()) + Ok(elem[0].partial_cmp(&elem[1]).unwrap_or(Ordering::Equal)) }) .find(|elem| elem.is_err()) { @@ -87,7 +87,7 @@ pub fn mode(values: &[Value], head: &Span) -> Result { //In e-q, Value doesn't implement Hash or Eq, so we have to get the values inside // But f64 doesn't implement Hash, so we get the binary representation to use as // key in the HashMap - let hashable_values: Result, ShellError> = values + let hashable_values = values .iter() .map(|val| match val { Value::Int { val, .. } => Ok(HashableType::new(val.to_ne_bytes(), NumberTypes::Int)), @@ -102,16 +102,13 @@ pub fn mode(values: &[Value], head: &Span) -> Result { } other => Err(ShellError::UnsupportedInput( "Unable to give a result with this input".to_string(), - other.span().unwrap(), + other.span()?, )), }) - .collect::, ShellError>>(); - if let Err(not_hashable) = hashable_values { - return Err(not_hashable); - } + .collect::, ShellError>>()?; let mut frequency_map = std::collections::HashMap::new(); - for v in hashable_values.unwrap() { + for v in hashable_values { let counter = frequency_map.entry(v).or_insert(0); *counter += 1; } @@ -132,7 +129,7 @@ pub fn mode(values: &[Value], head: &Span) -> Result { } } - modes.sort_by(|a, b| a.partial_cmp(b).unwrap()); + modes.sort_by(|a, b| a.partial_cmp(b).unwrap_or(Ordering::Equal)); Ok(Value::List { vals: modes, span: *head, diff --git a/crates/nu-command/src/platform/kill.rs b/crates/nu-command/src/platform/kill.rs index 9ab4f07409..b7da74ab84 100644 --- a/crates/nu-command/src/platform/kill.rs +++ b/crates/nu-command/src/platform/kill.rs @@ -84,10 +84,27 @@ impl Command for Kill { { return Err(ShellError::IncompatibleParameters { left_message: "force".to_string(), - left_span: call.get_named_arg("force").unwrap().span, + left_span: call + .get_named_arg("force") + .ok_or_else(|| { + ShellError::LabeledError( + "Flag error".into(), + "flag force not found".into(), + call.head, + ) + })? + .span, right_message: "signal".to_string(), right_span: span(&[ - call.get_named_arg("signal").unwrap().span, + call.get_named_arg("signal") + .ok_or_else(|| { + ShellError::LabeledError( + "Flag error".into(), + "flag signal not found".into(), + call.head, + ) + })? + .span, signal_span, ]), }); diff --git a/crates/nu-command/src/strings/format/command.rs b/crates/nu-command/src/strings/format/command.rs index 548a51fd19..28efcd003f 100644 --- a/crates/nu-command/src/strings/format/command.rs +++ b/crates/nu-command/src/strings/format/command.rs @@ -38,7 +38,7 @@ impl Command for Format { match specified_pattern { Err(e) => Err(e), Ok(pattern) => { - let string_pattern = pattern.as_string().unwrap(); + let string_pattern = pattern.as_string()?; let ops = extract_formatting_operations(string_pattern); format(input, &ops, call.head) } @@ -184,9 +184,7 @@ fn format_record( val: col_name.clone(), span: Span::unknown(), }]) { - Ok(value_at_column) => { - output.push_str(value_at_column.as_string().unwrap().as_str()) - } + Ok(value_at_column) => output.push_str(value_at_column.as_string()?.as_str()), Err(se) => return Err(se), } } diff --git a/crates/nu-command/src/strings/str_/lpad.rs b/crates/nu-command/src/strings/str_/lpad.rs index 3ca04d2a80..a20ae4d32b 100644 --- a/crates/nu-command/src/strings/str_/lpad.rs +++ b/crates/nu-command/src/strings/str_/lpad.rs @@ -142,7 +142,7 @@ fn action( span: head, } } else { - let c = character.as_ref().unwrap(); // we already know this flag needs to exist because the command is type checked before we call the action function + let c = character.as_ref().expect("we already know this flag needs to exist because the command is type checked before we call the action function"); let mut res = c.repeat(s - val.chars().count()); res += val; Value::String { diff --git a/crates/nu-command/src/strings/str_/rpad.rs b/crates/nu-command/src/strings/str_/rpad.rs index 181489cee0..8f7126e0a0 100644 --- a/crates/nu-command/src/strings/str_/rpad.rs +++ b/crates/nu-command/src/strings/str_/rpad.rs @@ -143,7 +143,7 @@ fn action( } } else { let mut res = val.to_string(); - res += &character.as_ref().unwrap().repeat(s - val.chars().count()); + res += &character.as_ref().expect("we already know this flag needs to exist because the command is type checked before we call the action function").repeat(s - val.chars().count()); Value::String { val: res, span: head, diff --git a/crates/nu-command/src/strings/str_/trim/command.rs b/crates/nu-command/src/strings/str_/trim/command.rs index d969231225..98ed9fd558 100644 --- a/crates/nu-command/src/strings/str_/trim/command.rs +++ b/crates/nu-command/src/strings/str_/trim/command.rs @@ -143,7 +143,7 @@ where input, ); let to_trim = match options.character.as_ref() { - Some(v) => v.as_string().unwrap().chars().next(), + Some(v) => v.as_string()?.chars().next(), None => None, }; diff --git a/crates/nu-command/src/system/run_external.rs b/crates/nu-command/src/system/run_external.rs index 4e117dddc7..cd9ed82a8a 100644 --- a/crates/nu-command/src/system/run_external.rs +++ b/crates/nu-command/src/system/run_external.rs @@ -59,19 +59,21 @@ impl Command for External { args, last_expression, env_vars, + call, }; command.run_with_input(engine_state, input, config) } } -pub struct ExternalCommand { +pub struct ExternalCommand<'call> { pub name: Spanned, pub args: Vec, pub last_expression: bool, pub env_vars: HashMap, + pub call: &'call Call, } -impl ExternalCommand { +impl<'call> ExternalCommand<'call> { pub fn run_with_input( &self, engine_state: &EngineState, @@ -84,7 +86,8 @@ impl ExternalCommand { // TODO. We don't have a way to know the current directory // This should be information from the EvaluationContex or EngineState - let path = env::current_dir().unwrap(); + let path = env::current_dir()?; + process.current_dir(path); process.envs(&self.env_vars); @@ -145,16 +148,12 @@ impl ExternalCommand { // If this external is not the last expression, then its output is piped to a channel // and we create a ValueStream that can be consumed if !last_expression { - let stdout = child - .stdout - .take() - .ok_or_else(|| { - ShellError::ExternalCommand( - "Error taking stdout from external".to_string(), - span, - ) - }) - .unwrap(); + let stdout = child.stdout.take().ok_or_else(|| { + ShellError::ExternalCommand( + "Error taking stdout from external".to_string(), + span, + ) + })?; // Stdout is read using the Buffer reader. It will do so until there is an // error or there are no more bytes to read diff --git a/crates/nu-command/src/viewers/griddle.rs b/crates/nu-command/src/viewers/griddle.rs index 585a6ca247..8489f0fa3c 100644 --- a/crates/nu-command/src/viewers/griddle.rs +++ b/crates/nu-command/src/viewers/griddle.rs @@ -5,7 +5,8 @@ use nu_engine::CallExt; use nu_protocol::{ ast::{Call, PathMember}, engine::{Command, EngineState, Stack}, - Category, Config, IntoPipelineData, PipelineData, Signature, Span, SyntaxShape, Value, + Category, Config, IntoPipelineData, PipelineData, ShellError, Signature, Span, SyntaxShape, + Value, }; use nu_term_grid::grid::{Alignment, Cell, Direction, Filling, Grid, GridOptions}; use terminal_size::{Height, Width}; @@ -76,7 +77,7 @@ prints out the list properly."# separator_param, env_str, use_grid_icons, - )) + )?) } else { Ok(PipelineData::new(call.head)) } @@ -93,7 +94,7 @@ prints out the list properly."# separator_param, env_str, use_grid_icons, - )) + )?) } else { // dbg!(data); Ok(PipelineData::new(call.head)) @@ -115,7 +116,7 @@ prints out the list properly."# separator_param, env_str, use_grid_icons, - )) + )?) } x => { // dbg!("other value"); @@ -142,7 +143,7 @@ fn create_grid_output( separator_param: Option, env_str: Option, use_grid_icons: bool, -) -> PipelineData { +) -> Result { let ls_colors = match env_str { Some(s) => LsColors::from_string(&s), None => LsColors::default(), @@ -173,7 +174,7 @@ fn create_grid_output( if use_grid_icons { let no_ansi = strip_ansi(&value); let path = std::path::Path::new(&no_ansi); - let icon = icon_for_file(path); + let icon = icon_for_file(path)?; let ls_colors_style = ls_colors.style_for_path(path); // eprintln!("ls_colors_style: {:?}", &ls_colors_style); @@ -212,18 +213,20 @@ fn create_grid_output( } } - if let Some(grid_display) = grid.fit_into_width(cols as usize) { - Value::String { - val: grid_display.to_string(), - span: call.head, + Ok( + if let Some(grid_display) = grid.fit_into_width(cols as usize) { + Value::String { + val: grid_display.to_string(), + span: call.head, + } + } else { + Value::String { + val: format!("Couldn't fit grid into {} columns!", cols), + span: call.head, + } } - } else { - Value::String { - val: format!("Couldn't fit grid into {} columns!", cols), - span: call.head, - } - } - .into_pipeline_data() + .into_pipeline_data(), + ) } fn convert_to_list( diff --git a/crates/nu-command/src/viewers/icons.rs b/crates/nu-command/src/viewers/icons.rs index e504e10741..5fd35c3b67 100644 --- a/crates/nu-command/src/viewers/icons.rs +++ b/crates/nu-command/src/viewers/icons.rs @@ -1,4 +1,5 @@ use lazy_static::lazy_static; +use nu_protocol::{ShellError, Span}; use std::collections::HashMap; use std::path::Path; @@ -129,23 +130,47 @@ lazy_static! { }; } -pub fn icon_for_file(file_path: &Path) -> char { +pub fn icon_for_file(file_path: &Path) -> Result { let extensions = Box::new(FileExtensions); let fp = format!("{}", file_path.display()); if let Some(icon) = MAP_BY_NAME.get(&fp[..]) { - *icon + Ok(*icon) } else if file_path.is_dir() { - match file_path.file_name().unwrap().to_str().unwrap() { + let str = file_path + .file_name() + .ok_or_else(|| { + ShellError::LabeledError( + "File name error".into(), + "Unable to get file name".into(), + Span::unknown(), + ) + })? + .to_str() + .ok_or_else(|| { + ShellError::LabeledError( + "Unable to get str error".into(), + "Unable to convert to str file name".into(), + Span::unknown(), + ) + })?; + Ok(match str { "bin" => '\u{e5fc}', //  ".git" => '\u{f1d3}', //  ".idea" => '\u{e7b5}', //  _ => '\u{f115}', //  - } + }) } else if let Some(icon) = extensions.icon_file(file_path) { - icon + Ok(icon) } else if let Some(ext) = file_path.extension().as_ref() { - match ext.to_str().unwrap() { + let str = ext.to_str().ok_or_else(|| { + ShellError::LabeledError( + "Unable to get str error".into(), + "Unable to convert to str file name".into(), + Span::unknown(), + ) + })?; + Ok(match str { "ai" => '\u{e7b4}', //  "android" => '\u{e70e}', //  "apk" => '\u{e70e}', //  @@ -372,9 +397,9 @@ pub fn icon_for_file(file_path: &Path) -> char { "zsh-theme" => '\u{f489}', //  "zshrc" => '\u{f489}', //  _ => '\u{f15b}', //  - } + }) } else { - '\u{f016}' + Ok('\u{f016}') } } diff --git a/crates/nu-protocol/src/config.rs b/crates/nu-protocol/src/config.rs index 4221e65383..241c35a9d7 100644 --- a/crates/nu-protocol/src/config.rs +++ b/crates/nu-protocol/src/config.rs @@ -62,7 +62,7 @@ impl Value { let (cols, vals) = value.as_record()?; let mut hm = HashMap::new(); for (k, v) in cols.iter().zip(vals) { - hm.insert(k.to_string(), v.as_string().unwrap()); + hm.insert(k.to_string(), v.as_string()?); } config.color_config = hm; } diff --git a/crates/nu-protocol/src/engine/engine_state.rs b/crates/nu-protocol/src/engine/engine_state.rs index 2429671af4..629f263cee 100644 --- a/crates/nu-protocol/src/engine/engine_state.rs +++ b/crates/nu-protocol/src/engine/engine_state.rs @@ -227,13 +227,14 @@ impl EngineState { let path = decl.is_plugin().expect("plugin should have file name"); let file_name = path.to_str().expect("path should be a str"); - let line = serde_json::to_string_pretty(&decl.signature()) + serde_json::to_string_pretty(&decl.signature()) .map(|signature| format!("register {} {}\n\n", file_name, signature)) - .map_err(|err| ShellError::PluginFailedToLoad(err.to_string()))?; - - plugin_file - .write_all(line.as_bytes()) - .map_err(|err| ShellError::PluginFailedToLoad(err.to_string()))?; + .map_err(|err| ShellError::PluginFailedToLoad(err.to_string())) + .and_then(|line| { + plugin_file + .write_all(line.as_bytes()) + .map_err(|err| ShellError::PluginFailedToLoad(err.to_string())) + })?; } Ok(()) } else { @@ -248,40 +249,6 @@ impl EngineState { } } - #[cfg(feature = "plugin")] - pub fn update_plugin_file_1(&self) -> Result<(), ShellError> { - use std::io::Write; - - // Updating the signatures plugin file with the added signatures - if let Some(plugin_path) = &self.plugin_signatures { - // Always creating the file which will erase previous signatures - let mut plugin_file = std::fs::File::create(plugin_path.as_path()) - .map_err(|err| ShellError::PluginFailedToLoad(err.to_string()))?; - - // Plugin definitions with parsed signature - for decl in self.plugin_decls() { - // A successful plugin registration already includes the plugin filename - // No need to check the None option - let path = decl.is_plugin().expect("plugin should have file name"); - let file_name = path.to_str().expect("path should be a str"); - - let line = serde_json::to_string_pretty(&decl.signature()) - .map(|signature| format!("register {} {}\n\n", file_name, signature)) - .map_err(|err| ShellError::PluginFailedToLoad(err.to_string()))?; - - plugin_file - .write_all(line.as_bytes()) - .map_err(|err| ShellError::PluginFailedToLoad(err.to_string()))?; - } - - Ok(()) - } else { - Err(ShellError::PluginFailedToLoad( - "Plugin file not found".into(), - )) - } - } - pub fn num_files(&self) -> usize { self.files.len() } diff --git a/crates/nu-table/src/table.rs b/crates/nu-table/src/table.rs index e3132f394b..e73f24e587 100644 --- a/crates/nu-table/src/table.rs +++ b/crates/nu-table/src/table.rs @@ -875,7 +875,7 @@ impl WrappedTable { break; } - writeln!(&mut total_output, "{}", output).unwrap(); + writeln!(&mut total_output, "{}", output).expect("writing should be done to buffer"); } total_output } diff --git a/src/main.rs b/src/main.rs index 467fe48656..8fc847e34a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -64,7 +64,7 @@ impl CompletionActionHandler for FuzzyCompletion { .default(0) .items(&selections[..]) .interact_on_opt(&Term::stdout()) - .unwrap(); + .expect("Fuzzy completion interact on operation"); let _ = crossterm::terminal::enable_raw_mode(); if let Some(result) = result { @@ -85,7 +85,7 @@ fn main() -> Result<()> { // miette::set_panic_hook(); let miette_hook = std::panic::take_hook(); std::panic::set_hook(Box::new(move |x| { - crossterm::terminal::disable_raw_mode().unwrap(); + crossterm::terminal::disable_raw_mode().expect("unable to disable raw mode"); miette_hook(x); }));