From 9aed75d58262a9f90c468d2c2d5ba4d5122439b0 Mon Sep 17 00:00:00 2001 From: Xavier L'Heureux <xavier.lheureux@icloud.com> Date: Fri, 15 Feb 2019 09:30:07 -0500 Subject: [PATCH] Increase small heuristic to make the code more compact --- build.rs | 2 +- members/braces/src/lib.rs | 82 +++---- members/builtins/src/conditionals.rs | 16 +- members/builtins/src/echo.rs | 37 ++- members/builtins/src/random.rs | 5 +- members/builtins/src/test.rs | 222 +++++------------- members/lexers/src/arguments.rs | 39 +-- members/lexers/src/assignments/keys.rs | 87 ++----- members/lexers/src/assignments/mod.rs | 41 +--- members/lexers/src/assignments/primitive.rs | 8 +- members/lexers/src/designators.rs | 5 +- members/ranges/src/index.rs | 9 +- members/ranges/src/lib.rs | 174 +++----------- members/ranges/src/parse.rs | 13 +- members/ranges/src/range.rs | 32 +-- members/ranges/src/select.rs | 19 +- members/sys/src/sys/redox/mod.rs | 20 +- members/sys/src/sys/unix/mod.rs | 9 +- members/sys/src/sys/unix/signals.rs | 12 +- rustfmt.toml | 2 + src/lib/ascii_helpers.rs | 5 +- src/lib/builtins/command_info.rs | 5 +- src/lib/builtins/exec.rs | 10 +- src/lib/builtins/exists.rs | 167 +++---------- src/lib/builtins/is.rs | 30 +-- src/lib/builtins/job_control.rs | 26 +- src/lib/builtins/mod.rs | 6 +- src/lib/parser/assignments/actions.rs | 68 ++---- src/lib/parser/assignments/checker.rs | 14 +- src/lib/parser/pipelines/collector.rs | 21 +- src/lib/parser/pipelines/mod.rs | 10 +- src/lib/parser/quotes.rs | 22 +- src/lib/parser/shell_expand/mod.rs | 151 ++++-------- .../shell_expand/words/methods/arrays.rs | 40 +--- .../shell_expand/words/methods/strings.rs | 11 +- src/lib/parser/shell_expand/words/mod.rs | 20 +- src/lib/parser/shell_expand/words/tests.rs | 12 +- src/lib/parser/statement/case.rs | 5 +- src/lib/parser/statement/functions.rs | 20 +- src/lib/parser/statement/parse.rs | 36 +-- src/lib/parser/statement/splitter.rs | 93 ++------ src/lib/shell/assignments.rs | 102 +++----- src/lib/shell/binary/mod.rs | 21 +- src/lib/shell/binary/prompt.rs | 8 +- src/lib/shell/binary/terminate.rs | 5 +- src/lib/shell/colors.rs | 39 +-- src/lib/shell/completer.rs | 29 +-- src/lib/shell/directory_stack.rs | 28 +-- src/lib/shell/flow.rs | 85 ++----- src/lib/shell/flow_control.rs | 44 +--- src/lib/shell/history.rs | 25 +- src/lib/shell/job.rs | 33 +-- src/lib/shell/mod.rs | 27 +-- src/lib/shell/pipe_exec/foreground.rs | 4 +- src/lib/shell/pipe_exec/job_control.rs | 13 +- src/lib/shell/pipe_exec/mod.rs | 93 ++------ src/lib/shell/pipe_exec/pipes.rs | 6 +- src/lib/shell/pipe_exec/streams.rs | 4 +- src/lib/shell/variables/mod.rs | 46 +--- src/main.rs | 5 +- 60 files changed, 536 insertions(+), 1687 deletions(-) diff --git a/build.rs b/build.rs index f5129fe5..9a32b7a2 100644 --- a/build.rs +++ b/build.rs @@ -46,7 +46,7 @@ fn get_git_rev() -> io::Result<String> { String::from_utf8(out.stdout).map_err(|_| { io::Error::new( io::ErrorKind::InvalidData, - format!("git rev-parse master output was not UTF-8"), + "git rev-parse master output was not UTF-8", ) }) }) diff --git a/members/braces/src/lib.rs b/members/braces/src/lib.rs index e7852b1a..8b4b9a09 100644 --- a/members/braces/src/lib.rs +++ b/members/braces/src/lib.rs @@ -76,22 +76,17 @@ impl<'a> Iterator for MultipleBraceExpand<'a> { fn next(&mut self) -> Option<Self::Item> { if self.permutator.next_with_buffer(&mut self.buffer) { let mut strings = self.buffer.iter(); - let small_vec: SmallVec<[u8; 64]> = - self.tokens - .iter() - .fold( - SmallVec::with_capacity(64), - |mut small_vec, token| match *token { - BraceToken::Normal(ref text) => { - escape_string(&mut small_vec, text); - small_vec - } - BraceToken::Expander => { - escape_string(&mut small_vec, strings.next().unwrap()); - small_vec - } + let small_vec = + self.tokens.iter().fold(SmallVec::with_capacity(64), |mut small_vec, token| { + escape_string( + &mut small_vec, + match *token { + BraceToken::Normal(ref text) => text, + BraceToken::Expander => strings.next().unwrap(), }, ); + small_vec + }); Some(unsafe { small::String::from_utf8_unchecked(small_vec.to_vec()) }) } else { None @@ -117,45 +112,34 @@ where fn next(&mut self) -> Option<Self::Item> { match self.loop_count { 0 => { - let small_vec: SmallVec<[u8; 64]> = - self.tokens - .iter() - .fold( - SmallVec::with_capacity(64), - |mut small_vec, token| match *token { - BraceToken::Normal(ref text) => { - escape_string(&mut small_vec, text); - small_vec - } - BraceToken::Expander => { - escape_string(&mut small_vec, self.elements.next().unwrap()); - small_vec - } + let small_vec = + self.tokens.iter().fold(SmallVec::with_capacity(64), |mut small_vec, token| { + escape_string( + &mut small_vec, + match *token { + BraceToken::Normal(ref text) => text, + BraceToken::Expander => self.elements.next().unwrap(), }, ); + small_vec + }); self.loop_count = 1; Some(unsafe { small::String::from_utf8_unchecked(small_vec.to_vec()) }) } - _ => { - if let Some(element) = self.elements.next() { - let small_vec: SmallVec<[u8; 64]> = self.tokens.iter().fold( - SmallVec::with_capacity(64), - |mut small_vec, token| match *token { - BraceToken::Normal(ref text) => { - escape_string(&mut small_vec, text); - small_vec - } - BraceToken::Expander => { - escape_string(&mut small_vec, element); - small_vec - } - }, - ); - Some(unsafe { small::String::from_utf8_unchecked(small_vec.to_vec()) }) - } else { - None - } - } + _ => self.elements.next().and_then(|element| { + let small_vec = + self.tokens.iter().fold(SmallVec::with_capacity(64), |mut small_vec, token| { + escape_string( + &mut small_vec, + match *token { + BraceToken::Normal(ref text) => text, + BraceToken::Expander => element, + }, + ); + small_vec + }); + Some(unsafe { small::String::from_utf8_unchecked(small_vec.to_vec()) }) + }), } } } @@ -199,7 +183,7 @@ mod tests { SingleBraceExpand { elements: elements.iter().map(|element| *element), tokens, - loop_count: 0, + loop_count: 0 } .collect::<Vec<small::String>>(), vec![ diff --git a/members/builtins/src/conditionals.rs b/members/builtins/src/conditionals.rs index a9a0873c..e17ffaa3 100644 --- a/members/builtins/src/conditionals.rs +++ b/members/builtins/src/conditionals.rs @@ -8,20 +8,8 @@ macro_rules! string_function { eprintln!("ion: {}: two arguments must be supplied", args[0]); return 2; } - 3 => { - if args[1].$method(args[2].as_str()) { - 0 - } else { - 1 - } - } - _ => { - if args[2..].iter().any(|arg| args[1].$method(arg.as_str())) { - 0 - } else { - 1 - } - } + 3 => !args[1].$method(args[2].as_str()) as i32, + _ => !args[2..].iter().any(|arg| args[1].$method(arg.as_str())) as i32, } } }; diff --git a/members/builtins/src/echo.rs b/members/builtins/src/echo.rs index d00a93ad..17640708 100644 --- a/members/builtins/src/echo.rs +++ b/members/builtins/src/echo.rs @@ -19,31 +19,30 @@ pub fn echo(args: &[small::String]) -> Result<(), io::Error> { "--escape" => flags |= Flags::ESCAPE, "--no-newline" => flags |= Flags::NO_NEWLINE, "--no-spaces" => flags |= Flags::NO_SPACES, - _ => { - if arg.starts_with('-') { - let mut is_opts = true; - let opts = &arg[1..]; - let mut short_flags = Flags::empty(); - for argopt in opts.chars() { - match argopt { - 'e' => short_flags |= Flags::ESCAPE, - 'n' => short_flags |= Flags::NO_NEWLINE, - 's' => short_flags |= Flags::NO_SPACES, - _ => { - is_opts = false; - break; - } + _ if arg.starts_with('-') => { + let mut is_opts = true; + let opts = &arg[1..]; + let mut short_flags = Flags::empty(); + for argopt in opts.chars() { + match argopt { + 'e' => short_flags |= Flags::ESCAPE, + 'n' => short_flags |= Flags::NO_NEWLINE, + 's' => short_flags |= Flags::NO_SPACES, + _ => { + is_opts = false; + break; } } - if is_opts { - flags |= short_flags; - } else { - data.push(arg); - } + } + if is_opts { + flags |= short_flags; } else { data.push(arg); } } + _ => { + data.push(arg); + } } } diff --git a/members/builtins/src/random.rs b/members/builtins/src/random.rs index 8dc6b0bf..925fc02c 100644 --- a/members/builtins/src/random.rs +++ b/members/builtins/src/random.rs @@ -33,10 +33,7 @@ pub fn random(args: &[small::String]) -> Result<(), small::String> { writeln!(stdout, "{}", rand_num); } 1 => { - writeln!( - stdout, - "Ion Shell does not currently support changing the seed" - ); + writeln!(stdout, "Ion Shell does not currently support changing the seed"); } 2 => { let arg1 = match args[0].parse::<u64>() { diff --git a/members/builtins/src/test.rs b/members/builtins/src/test.rs index e636c383..949c8efd 100644 --- a/members/builtins/src/test.rs +++ b/members/builtins/src/test.rs @@ -144,15 +144,13 @@ fn evaluate_arguments(arguments: &[small::String]) -> Result<bool, small::String } Some(arg) => { // If there is no operator, check if the first argument is non-zero - arguments - .get(1) - .map_or(Ok(string_is_nonzero(arg)), |operator| { - // If there is no right hand argument, a condition was expected - let right_arg = arguments - .get(2) - .ok_or_else(|| small::String::from("parse error: condition expected"))?; - evaluate_expression(arg, operator, right_arg) - }) + arguments.get(1).map_or(Ok(string_is_nonzero(arg)), |operator| { + // If there is no right hand argument, a condition was expected + let right_arg = arguments + .get(2) + .ok_or_else(|| small::String::from("parse error: condition expected"))?; + evaluate_expression(arg, operator, right_arg) + }) } None => { println!("{}", QUICK_GUIDE); @@ -189,7 +187,8 @@ fn files_have_same_device_and_inode_numbers(first: &str, second: &str) -> bool { get_dev_and_inode(first).map_or(false, |left| { // Obtain the device and inode of the second file or return FAILED get_dev_and_inode(second).map_or(false, |right| { - // Compare the device and inodes of the first and second files + // Compare the device and inodes of the + // first and second files left == right }) }) @@ -197,18 +196,19 @@ fn files_have_same_device_and_inode_numbers(first: &str, second: &str) -> bool { /// Obtains the device and inode numbers of the file specified fn get_dev_and_inode(filename: &str) -> Option<(u64, u64)> { - fs::metadata(filename) - .map(|file| (file.dev(), file.ino())) - .ok() + fs::metadata(filename).map(|file| (file.dev(), file.ino())).ok() } /// Exits SUCCESS if the first file is newer than the second file. fn file_is_newer_than(first: &str, second: &str) -> bool { // Obtain the modified file time of the first file or return FAILED get_modified_file_time(first).map_or(false, |left| { - // Obtain the modified file time of the second file or return FAILED + // Obtain the modified file time of the second file or return + // FAILED get_modified_file_time(second).map_or(false, |right| { - // If the first file is newer than the right file, return SUCCESS + // If the first file is newer + // than the right file, + // return SUCCESS left > right }) }) @@ -216,9 +216,7 @@ fn file_is_newer_than(first: &str, second: &str) -> bool { /// Obtain the time the file was last modified as a `SystemTime` type. fn get_modified_file_time(filename: &str) -> Option<SystemTime> { - fs::metadata(filename) - .ok() - .and_then(|file| file.modified().ok()) + fs::metadata(filename).ok().and_then(|file| file.modified().ok()) } /// Attempt to parse a &str as a usize. @@ -272,9 +270,7 @@ fn match_flag_argument(flag: char, argument: &str) -> bool { /// Exits SUCCESS if the file size is greather than zero. fn file_size_is_greater_than_zero(filepath: &str) -> bool { - fs::metadata(filepath) - .ok() - .map_or(false, |metadata| metadata.len() > 0) + fs::metadata(filepath).ok().map_or(false, |metadata| metadata.len() > 0) } /// Exits SUCCESS if the file has read permissions. This function is rather low level because @@ -332,23 +328,17 @@ fn file_has_execute_permission(filepath: &str) -> bool { /// Exits SUCCESS if the file argument is a socket fn file_is_socket(filepath: &str) -> bool { - fs::metadata(filepath) - .ok() - .map_or(false, |metadata| metadata.file_type().is_socket()) + fs::metadata(filepath).ok().map_or(false, |metadata| metadata.file_type().is_socket()) } /// Exits SUCCESS if the file argument is a block device fn file_is_block_device(filepath: &str) -> bool { - fs::metadata(filepath) - .ok() - .map_or(false, |metadata| metadata.file_type().is_block_device()) + fs::metadata(filepath).ok().map_or(false, |metadata| metadata.file_type().is_block_device()) } /// Exits SUCCESS if the file argument is a character device fn file_is_character_device(filepath: &str) -> bool { - fs::metadata(filepath) - .ok() - .map_or(false, |metadata| metadata.file_type().is_char_device()) + fs::metadata(filepath).ok().map_or(false, |metadata| metadata.file_type().is_char_device()) } /// Exits SUCCESS if the file exists @@ -356,23 +346,17 @@ fn file_exists(filepath: &str) -> bool { Path::new(filepath).exists() } /// Exits SUCCESS if the file is a regular file fn file_is_regular(filepath: &str) -> bool { - fs::metadata(filepath) - .ok() - .map_or(false, |metadata| metadata.file_type().is_file()) + fs::metadata(filepath).ok().map_or(false, |metadata| metadata.file_type().is_file()) } /// Exits SUCCESS if the file is a directory fn file_is_directory(filepath: &str) -> bool { - fs::metadata(filepath) - .ok() - .map_or(false, |metadata| metadata.file_type().is_dir()) + fs::metadata(filepath).ok().map_or(false, |metadata| metadata.file_type().is_dir()) } /// Exits SUCCESS if the file is a symbolic link fn file_is_symlink(filepath: &str) -> bool { - fs::symlink_metadata(filepath) - .ok() - .map_or(false, |metadata| metadata.file_type().is_symlink()) + fs::symlink_metadata(filepath).ok().map_or(false, |metadata| metadata.file_type().is_symlink()) } /// Exits SUCCESS if the string is not empty @@ -402,128 +386,44 @@ fn test_integers_arguments() { args.iter().map(|s| (*s).into()).collect() } // Equal To - assert_eq!( - evaluate_arguments(&vec_string(&["10", "-eq", "10"])), - Ok(true) - ); - assert_eq!( - evaluate_arguments(&vec_string(&["10", "-eq", "5"])), - Ok(false) - ); - assert_eq!( - evaluate_arguments(&vec_string(&["-10", "-eq", "-10"])), - Ok(true) - ); - assert_eq!( - evaluate_arguments(&vec_string(&["-10", "-eq", "10"])), - Ok(false) - ); + assert_eq!(evaluate_arguments(&vec_string(&["10", "-eq", "10"])), Ok(true)); + assert_eq!(evaluate_arguments(&vec_string(&["10", "-eq", "5"])), Ok(false)); + assert_eq!(evaluate_arguments(&vec_string(&["-10", "-eq", "-10"])), Ok(true)); + assert_eq!(evaluate_arguments(&vec_string(&["-10", "-eq", "10"])), Ok(false)); // Greater Than or Equal To - assert_eq!( - evaluate_arguments(&vec_string(&["10", "-ge", "10"])), - Ok(true) - ); - assert_eq!( - evaluate_arguments(&vec_string(&["10", "-ge", "5"])), - Ok(true) - ); - assert_eq!( - evaluate_arguments(&vec_string(&["5", "-ge", "10"])), - Ok(false) - ); - assert_eq!( - evaluate_arguments(&vec_string(&["-9", "-ge", "-10"])), - Ok(true) - ); - assert_eq!( - evaluate_arguments(&vec_string(&["-10", "-ge", "-10"])), - Ok(true) - ); - assert_eq!( - evaluate_arguments(&vec_string(&["-10", "-ge", "10"])), - Ok(false) - ); + assert_eq!(evaluate_arguments(&vec_string(&["10", "-ge", "10"])), Ok(true)); + assert_eq!(evaluate_arguments(&vec_string(&["10", "-ge", "5"])), Ok(true)); + assert_eq!(evaluate_arguments(&vec_string(&["5", "-ge", "10"])), Ok(false)); + assert_eq!(evaluate_arguments(&vec_string(&["-9", "-ge", "-10"])), Ok(true)); + assert_eq!(evaluate_arguments(&vec_string(&["-10", "-ge", "-10"])), Ok(true)); + assert_eq!(evaluate_arguments(&vec_string(&["-10", "-ge", "10"])), Ok(false)); // Less Than or Equal To - assert_eq!( - evaluate_arguments(&vec_string(&["5", "-le", "5"])), - Ok(true) - ); - assert_eq!( - evaluate_arguments(&vec_string(&["5", "-le", "10"])), - Ok(true) - ); - assert_eq!( - evaluate_arguments(&vec_string(&["10", "-le", "5"])), - Ok(false) - ); - assert_eq!( - evaluate_arguments(&vec_string(&["-11", "-le", "-10"])), - Ok(true) - ); - assert_eq!( - evaluate_arguments(&vec_string(&["-10", "-le", "-10"])), - Ok(true) - ); - assert_eq!( - evaluate_arguments(&vec_string(&["10", "-le", "-10"])), - Ok(false) - ); + assert_eq!(evaluate_arguments(&vec_string(&["5", "-le", "5"])), Ok(true)); + assert_eq!(evaluate_arguments(&vec_string(&["5", "-le", "10"])), Ok(true)); + assert_eq!(evaluate_arguments(&vec_string(&["10", "-le", "5"])), Ok(false)); + assert_eq!(evaluate_arguments(&vec_string(&["-11", "-le", "-10"])), Ok(true)); + assert_eq!(evaluate_arguments(&vec_string(&["-10", "-le", "-10"])), Ok(true)); + assert_eq!(evaluate_arguments(&vec_string(&["10", "-le", "-10"])), Ok(false)); // Less Than - assert_eq!( - evaluate_arguments(&vec_string(&["5", "-lt", "10"])), - Ok(true) - ); - assert_eq!( - evaluate_arguments(&vec_string(&["10", "-lt", "5"])), - Ok(false) - ); - assert_eq!( - evaluate_arguments(&vec_string(&["-11", "-lt", "-10"])), - Ok(true) - ); - assert_eq!( - evaluate_arguments(&vec_string(&["10", "-lt", "-10"])), - Ok(false) - ); + assert_eq!(evaluate_arguments(&vec_string(&["5", "-lt", "10"])), Ok(true)); + assert_eq!(evaluate_arguments(&vec_string(&["10", "-lt", "5"])), Ok(false)); + assert_eq!(evaluate_arguments(&vec_string(&["-11", "-lt", "-10"])), Ok(true)); + assert_eq!(evaluate_arguments(&vec_string(&["10", "-lt", "-10"])), Ok(false)); // Greater Than - assert_eq!( - evaluate_arguments(&vec_string(&["10", "-gt", "5"])), - Ok(true) - ); - assert_eq!( - evaluate_arguments(&vec_string(&["5", "-gt", "10"])), - Ok(false) - ); - assert_eq!( - evaluate_arguments(&vec_string(&["-9", "-gt", "-10"])), - Ok(true) - ); - assert_eq!( - evaluate_arguments(&vec_string(&["-10", "-gt", "10"])), - Ok(false) - ); + assert_eq!(evaluate_arguments(&vec_string(&["10", "-gt", "5"])), Ok(true)); + assert_eq!(evaluate_arguments(&vec_string(&["5", "-gt", "10"])), Ok(false)); + assert_eq!(evaluate_arguments(&vec_string(&["-9", "-gt", "-10"])), Ok(true)); + assert_eq!(evaluate_arguments(&vec_string(&["-10", "-gt", "10"])), Ok(false)); // Not Equal To - assert_eq!( - evaluate_arguments(&vec_string(&["10", "-ne", "5"])), - Ok(true) - ); - assert_eq!( - evaluate_arguments(&vec_string(&["5", "-ne", "5"])), - Ok(false) - ); - assert_eq!( - evaluate_arguments(&vec_string(&["-10", "-ne", "-10"])), - Ok(false) - ); - assert_eq!( - evaluate_arguments(&vec_string(&["-10", "-ne", "10"])), - Ok(true) - ); + assert_eq!(evaluate_arguments(&vec_string(&["10", "-ne", "5"])), Ok(true)); + assert_eq!(evaluate_arguments(&vec_string(&["5", "-ne", "5"])), Ok(false)); + assert_eq!(evaluate_arguments(&vec_string(&["-10", "-ne", "-10"])), Ok(false)); + assert_eq!(evaluate_arguments(&vec_string(&["-10", "-ne", "10"])), Ok(true)); } #[test] @@ -552,24 +452,12 @@ fn test_file_is_symlink() { #[test] fn test_file_has_execute_permission() { - assert_eq!( - file_has_execute_permission("../../testing/executable_file"), - true - ); - assert_eq!( - file_has_execute_permission("../../testing/empty_file"), - false - ); + assert_eq!(file_has_execute_permission("../../testing/executable_file"), true); + assert_eq!(file_has_execute_permission("../../testing/empty_file"), false); } #[test] fn test_file_size_is_greater_than_zero() { - assert_eq!( - file_size_is_greater_than_zero("../../testing/file_with_text"), - true - ); - assert_eq!( - file_size_is_greater_than_zero("../../testing/empty_file"), - false - ); + assert_eq!(file_size_is_greater_than_zero("../../testing/file_with_text"), true); + assert_eq!(file_size_is_greater_than_zero("../../testing/empty_file"), false); } diff --git a/members/lexers/src/arguments.rs b/members/lexers/src/arguments.rs index ffa72a57..a07b12a2 100644 --- a/members/lexers/src/arguments.rs +++ b/members/lexers/src/arguments.rs @@ -24,11 +24,7 @@ pub struct ArgumentSplitter<'a> { impl<'a> ArgumentSplitter<'a> { pub fn new(data: &'a str) -> ArgumentSplitter<'a> { - ArgumentSplitter { - data, - read: 0, - bitflags: ArgumentFlags::empty(), - } + ArgumentSplitter { data, read: 0, bitflags: ArgumentFlags::empty() } } } @@ -72,16 +68,14 @@ impl<'a> Iterator for ArgumentSplitter<'a> { // Disable COMM_1 and enable COMM_2 + ARRAY. b'@' => { self.bitflags.remove(ArgumentFlags::COMM_1); - self.bitflags - .insert(ArgumentFlags::COMM_2 | ArgumentFlags::ARRAY); + self.bitflags.insert(ArgumentFlags::COMM_2 | ArgumentFlags::ARRAY); self.read += 1; continue; } // Disable COMM_2 and enable COMM_1 + VARIAB. b'$' => { self.bitflags.remove(ArgumentFlags::COMM_2); - self.bitflags - .insert(ArgumentFlags::COMM_1 | ArgumentFlags::VARIAB); + self.bitflags.insert(ArgumentFlags::COMM_1 | ArgumentFlags::VARIAB); self.read += 1; continue; } @@ -96,12 +90,8 @@ impl<'a> Iterator for ArgumentSplitter<'a> { b'(' => { // Disable VARIAB + ARRAY and enable METHOD. // if variab or array are set - if self - .bitflags - .intersects(ArgumentFlags::VARIAB | ArgumentFlags::ARRAY) - { - self.bitflags - .remove(ArgumentFlags::VARIAB | ArgumentFlags::ARRAY); + if self.bitflags.intersects(ArgumentFlags::VARIAB | ArgumentFlags::ARRAY) { + self.bitflags.remove(ArgumentFlags::VARIAB | ArgumentFlags::ARRAY); self.bitflags.insert(ArgumentFlags::METHOD); } level += 1 @@ -125,9 +115,7 @@ impl<'a> Iterator for ArgumentSplitter<'a> { } // Break from the loop once a root-level space is found. b' ' => { - if !self - .bitflags - .intersects(ArgumentFlags::DOUBLE | ArgumentFlags::METHOD) + if !self.bitflags.intersects(ArgumentFlags::DOUBLE | ArgumentFlags::METHOD) && level == 0 && alevel == 0 && blevel == 0 @@ -140,8 +128,7 @@ impl<'a> Iterator for ArgumentSplitter<'a> { self.read += 1; // disable COMM_1 and COMM_2 - self.bitflags - .remove(ArgumentFlags::COMM_1 | ArgumentFlags::COMM_2); + self.bitflags.remove(ArgumentFlags::COMM_1 | ArgumentFlags::COMM_2); } if start == self.read { @@ -181,22 +168,14 @@ mod tests { #[test] fn arrays() { let input = "echo [ one two @[echo three four] five ] [ six seven ]"; - let expected = vec![ - "echo", - "[ one two @[echo three four] five ]", - "[ six seven ]", - ]; + let expected = vec!["echo", "[ one two @[echo three four] five ]", "[ six seven ]"]; compare(input, expected); } #[test] fn quotes() { let input = "echo 'one two \"three four\"' \"five six 'seven eight'\""; - let expected = vec![ - "echo", - "'one two \"three four\"'", - "\"five six 'seven eight'\"", - ]; + let expected = vec!["echo", "'one two \"three four\"'", "\"five six 'seven eight'\""]; compare(input, expected); } } diff --git a/members/lexers/src/assignments/keys.rs b/members/lexers/src/assignments/keys.rs index 14e473f9..cd356474 100644 --- a/members/lexers/src/assignments/keys.rs +++ b/members/lexers/src/assignments/keys.rs @@ -42,12 +42,7 @@ impl<'a> Key<'a> { } impl<'a> From<Key<'a>> for KeyBuf { - fn from(key: Key<'a>) -> KeyBuf { - KeyBuf { - kind: key.kind, - name: key.name.to_owned(), - } - } + fn from(key: Key<'a>) -> KeyBuf { KeyBuf { kind: key.kind, name: key.name.to_owned() } } } /// Quite simply, an iterator that returns keys. @@ -158,10 +153,7 @@ impl<'a> Iterator for KeyIterator<'a> { if start == self.read { None } else { - Some(Ok(Key { - name: &self.data[start..self.read].trim(), - kind: Primitive::Any, - })) + Some(Ok(Key { name: &self.data[start..self.read].trim(), kind: Primitive::Any })) } } } @@ -177,47 +169,14 @@ mod tests { k:hmap[int[]] l:hmap[hmap[bool[]]] m:bmap[] n:bmap[int] o:bmap[float[]] \ p:bmap[hmap[bool]] d:a", ); + assert_eq!(parser.next().unwrap(), Ok(Key { name: "a", kind: Primitive::Integer },)); + assert_eq!(parser.next().unwrap(), Ok(Key { name: "b", kind: Primitive::AnyArray },)); + assert_eq!(parser.next().unwrap(), Ok(Key { name: "c", kind: Primitive::Boolean },)); + assert_eq!(parser.next().unwrap(), Ok(Key { name: "d", kind: Primitive::Any },)); + assert_eq!(parser.next().unwrap(), Ok(Key { name: "e", kind: Primitive::IntegerArray },)); assert_eq!( parser.next().unwrap(), - Ok(Key { - name: "a", - kind: Primitive::Integer, - },) - ); - assert_eq!( - parser.next().unwrap(), - Ok(Key { - name: "b", - kind: Primitive::AnyArray, - },) - ); - assert_eq!( - parser.next().unwrap(), - Ok(Key { - name: "c", - kind: Primitive::Boolean, - },) - ); - assert_eq!( - parser.next().unwrap(), - Ok(Key { - name: "d", - kind: Primitive::Any, - },) - ); - assert_eq!( - parser.next().unwrap(), - Ok(Key { - name: "e", - kind: Primitive::IntegerArray, - },) - ); - assert_eq!( - parser.next().unwrap(), - Ok(Key { - name: "f", - kind: Primitive::Indexed("0".into(), Box::new(Primitive::Any)), - },) + Ok(Key { name: "f", kind: Primitive::Indexed("0".into(), Box::new(Primitive::Any)) },) ); assert_eq!( parser.next().unwrap(), @@ -235,24 +194,15 @@ mod tests { ); assert_eq!( parser.next().unwrap(), - Ok(Key { - name: "i", - kind: Primitive::HashMap(Box::new(Primitive::Any)), - },) + Ok(Key { name: "i", kind: Primitive::HashMap(Box::new(Primitive::Any)) },) ); assert_eq!( parser.next().unwrap(), - Ok(Key { - name: "j", - kind: Primitive::HashMap(Box::new(Primitive::Float)), - },) + Ok(Key { name: "j", kind: Primitive::HashMap(Box::new(Primitive::Float)) },) ); assert_eq!( parser.next().unwrap(), - Ok(Key { - name: "k", - kind: Primitive::HashMap(Box::new(Primitive::IntegerArray)), - },) + Ok(Key { name: "k", kind: Primitive::HashMap(Box::new(Primitive::IntegerArray)) },) ); assert_eq!( parser.next().unwrap(), @@ -265,24 +215,15 @@ mod tests { ); assert_eq!( parser.next().unwrap(), - Ok(Key { - name: "m", - kind: Primitive::BTreeMap(Box::new(Primitive::Any)), - },) + Ok(Key { name: "m", kind: Primitive::BTreeMap(Box::new(Primitive::Any)) },) ); assert_eq!( parser.next().unwrap(), - Ok(Key { - name: "n", - kind: Primitive::BTreeMap(Box::new(Primitive::Integer)), - },) + Ok(Key { name: "n", kind: Primitive::BTreeMap(Box::new(Primitive::Integer)) },) ); assert_eq!( parser.next().unwrap(), - Ok(Key { - name: "o", - kind: Primitive::BTreeMap(Box::new(Primitive::FloatArray)), - },) + Ok(Key { name: "o", kind: Primitive::BTreeMap(Box::new(Primitive::FloatArray)) },) ); assert_eq!( parser.next().unwrap(), diff --git a/members/lexers/src/assignments/mod.rs b/members/lexers/src/assignments/mod.rs index c6dab3d7..0aa783e1 100644 --- a/members/lexers/src/assignments/mod.rs +++ b/members/lexers/src/assignments/mod.rs @@ -77,40 +77,22 @@ mod tests { assert_eq!(assignment_lexer(""), (None, None, None)); assert_eq!(assignment_lexer("abc"), (Some("abc"), None, None)); - assert_eq!( - assignment_lexer("abc+=def"), - (Some("abc"), Some(Operator::Add), Some("def")) - ); + assert_eq!(assignment_lexer("abc+=def"), (Some("abc"), Some(Operator::Add), Some("def"))); - assert_eq!( - assignment_lexer("a+=b"), - (Some("a"), Some(Operator::Add), Some("b")) - ); + assert_eq!(assignment_lexer("a+=b"), (Some("a"), Some(Operator::Add), Some("b"))); - assert_eq!( - assignment_lexer("a=b"), - (Some("a"), Some(Operator::Equal), Some("b")) - ); + assert_eq!(assignment_lexer("a=b"), (Some("a"), Some(Operator::Equal), Some("b"))); - assert_eq!( - assignment_lexer("abc ="), - (Some("abc"), Some(Operator::Equal), None) - ); + assert_eq!(assignment_lexer("abc ="), (Some("abc"), Some(Operator::Equal), None)); - assert_eq!( - assignment_lexer("abc = "), - (Some("abc"), Some(Operator::Equal), None) - ); + assert_eq!(assignment_lexer("abc = "), (Some("abc"), Some(Operator::Equal), None)); assert_eq!( assignment_lexer("abc = def"), (Some("abc"), Some(Operator::Equal), Some("def")) ); - assert_eq!( - assignment_lexer("abc=def"), - (Some("abc"), Some(Operator::Equal), Some("def")) - ); + assert_eq!(assignment_lexer("abc=def"), (Some("abc"), Some(Operator::Equal), Some("def"))); assert_eq!( assignment_lexer("def ghi += 124 523"), @@ -127,11 +109,7 @@ mod tests { assert_eq!( assignment_lexer("abc def ?= 123 456"), - ( - Some("abc def"), - Some(Operator::OptionalEqual), - Some("123 456") - ) + (Some("abc def"), Some(Operator::OptionalEqual), Some("123 456")) ); } @@ -147,10 +125,7 @@ mod tests { (Some("abc"), Some(Operator::Exponent), Some("def")) ); - assert_eq!( - assignment_lexer("abc += def"), - (Some("abc"), Some(Operator::Add), Some("def")) - ); + assert_eq!(assignment_lexer("abc += def"), (Some("abc"), Some(Operator::Add), Some("def"))); assert_eq!( assignment_lexer("abc -= def"), diff --git a/members/lexers/src/assignments/primitive.rs b/members/lexers/src/assignments/primitive.rs index c81fccfc..7d57da5a 100644 --- a/members/lexers/src/assignments/primitive.rs +++ b/members/lexers/src/assignments/primitive.rs @@ -46,14 +46,10 @@ impl Primitive { let res = if kind.starts_with("hmap[") { let kind = &kind[5..]; - kind.rfind(']') - .map(|found| &kind[..found]) - .and_then(parse_inner_hash_map) + kind.rfind(']').map(|found| &kind[..found]).and_then(parse_inner_hash_map) } else if kind.starts_with("bmap[") { let kind = &kind[5..]; - kind.rfind(']') - .map(|found| &kind[..found]) - .and_then(parse_inner_btree_map) + kind.rfind(']').map(|found| &kind[..found]).and_then(parse_inner_btree_map) } else { None }; diff --git a/members/lexers/src/designators.rs b/members/lexers/src/designators.rs index 6f20cd2e..d2229c90 100644 --- a/members/lexers/src/designators.rs +++ b/members/lexers/src/designators.rs @@ -28,10 +28,7 @@ impl<'a> DesignatorLexer<'a> { } pub fn new(data: &'a [u8]) -> DesignatorLexer { - DesignatorLexer { - data, - flags: Flags::empty(), - } + DesignatorLexer { data, flags: Flags::empty() } } } diff --git a/members/ranges/src/index.rs b/members/ranges/src/index.rs index ca8b1a39..79eb448c 100644 --- a/members/ranges/src/index.rs +++ b/members/ranges/src/index.rs @@ -13,13 +13,8 @@ impl Index { pub fn resolve(&self, vector_length: usize) -> Option<usize> { match *self { Index::Forward(n) => Some(n), - Index::Backward(n) => { - if n >= vector_length { - None - } else { - Some(vector_length - (n + 1)) - } - } + Index::Backward(n) if n >= vector_length => None, + Index::Backward(n) => Some(vector_length - (n + 1)), } } diff --git a/members/ranges/src/lib.rs b/members/ranges/src/lib.rs index 27487bca..bf6f020d 100644 --- a/members/ranges/src/lib.rs +++ b/members/ranges/src/lib.rs @@ -24,30 +24,12 @@ mod tests { #[test] fn index_ranges() { let valid_cases = vec![ - ( - Range::exclusive(Index::Forward(0), Index::Forward(3)), - "0..3", - ), - ( - Range::inclusive(Index::Forward(0), Index::Forward(2)), - "0...2", - ), - ( - Range::inclusive(Index::Forward(0), Index::Forward(4)), - "0..=4", - ), - ( - Range::inclusive(Index::Forward(2), Index::Backward(1)), - "2...-2", - ), - ( - Range::inclusive(Index::Forward(0), Index::Backward(0)), - "0...-1", - ), - ( - Range::exclusive(Index::Backward(2), Index::Backward(0)), - "-3..-1", - ), + (Range::exclusive(Index::Forward(0), Index::Forward(3)), "0..3"), + (Range::inclusive(Index::Forward(0), Index::Forward(2)), "0...2"), + (Range::inclusive(Index::Forward(0), Index::Forward(4)), "0..=4"), + (Range::inclusive(Index::Forward(2), Index::Backward(1)), "2...-2"), + (Range::inclusive(Index::Forward(0), Index::Backward(0)), "0...-1"), + (Range::exclusive(Index::Backward(2), Index::Backward(0)), "-3..-1"), (Range::from(Index::Backward(2)), "-3.."), (Range::to(Index::Forward(5)), "..5"), ]; @@ -63,97 +45,39 @@ mod tests { } } - #[test] - fn range_expand() { - if let Some(_) = parse_range("abc") { - panic!("parse_range() failed"); - } - - let actual: Vec<small::String> = parse_range("-3...3").unwrap().collect(); - let expected: Vec<small::String> = vec![ - "-3".into(), - "-2".into(), - "-1".into(), - "0".into(), - "1".into(), - "2".into(), - "3".into(), - ]; - - assert_eq!(actual, expected); - - let actual: Vec<small::String> = parse_range("07...12").unwrap().collect(); - let expected: Vec<small::String> = vec![ - "07".into(), - "08".into(), - "09".into(), - "10".into(), - "11".into(), - "12".into(), - ]; - - assert_eq!(actual, expected); - - let actual: Vec<small::String> = parse_range("-3...10").unwrap().collect(); - let expected: Vec<small::String> = vec![ - "-3".into(), - "-2".into(), - "-1".into(), - "0".into(), - "1".into(), - "2".into(), - "3".into(), - "4".into(), - "5".into(), - "6".into(), - "7".into(), - "8".into(), - "9".into(), - "10".into(), - ]; - - assert_eq!(actual, expected); - - let actual: Vec<small::String> = parse_range("3...-3").unwrap().collect(); - let expected: Vec<small::String> = vec![ - "3".into(), - "2".into(), - "1".into(), - "0".into(), - "-1".into(), - "-2".into(), - "-3".into(), - ]; + fn test_range<T: Iterator<Item = i8>>(range: &str, expected: T) { + let actual: Vec<small::String> = parse_range(range).unwrap().collect(); + let expected: Vec<_> = + expected.map(|i| small::String::from_string(i.to_string())).collect(); assert_eq!(actual, expected); + } - let actual: Vec<small::String> = parse_range("03...-3").unwrap().collect(); - let expected: Vec<small::String> = vec![ - "03".into(), - "02".into(), - "01".into(), - "00".into(), - "-1".into(), - "-2".into(), - "-3".into(), - ]; + fn test_fixed_range<T: Iterator<Item = i8>>(range: &str, expected: T, digits: usize) { + let actual: Vec<small::String> = parse_range(range).unwrap().collect(); + let expected: Vec<_> = + expected.map(|i| small::String::from_string(format!("{:01$}", i, digits))).collect(); assert_eq!(actual, expected); + } - let actual: Vec<small::String> = parse_range("3...-03").unwrap().collect(); - let also: Vec<small::String> = parse_range("3..=-03").unwrap().collect(); - let expected: Vec<small::String> = vec![ - "003".into(), - "002".into(), - "001".into(), - "000".into(), - "-01".into(), - "-02".into(), - "-03".into(), - ]; + #[test] + fn range_expand() { + if let Some(_) = parse_range("abc") { + panic!("parse_range() failed"); + } - assert_eq!(actual, expected); - assert_eq!(also, expected); + test_range("-3...3", -3..=3); + test_fixed_range("07...12", 7..=12, 2); + test_range("-3...10", -3..=10); + test_range("3...-3", (-3..=3).rev()); + test_fixed_range("03...-3", (-3..=3).rev(), 2); + test_fixed_range("3...-03", (-3..=3).rev(), 3); + test_fixed_range("3..=-03", (-3..=3).rev(), 3); + test_range("-3..4", -3..4); + test_range("3..-4", (-3..4).rev()); + test_range("-3...0", -3..=0); + test_range("-3..0", -3..0); let actual: Vec<small::String> = parse_range("a...c").unwrap().collect(); let expected: Vec<small::String> = vec!["a".into(), "b".into(), "c".into()]; @@ -186,39 +110,5 @@ mod tests { let expected: Vec<small::String> = vec!["c".into(), "b".into()]; assert_eq!(actual, expected); - - let actual: Vec<small::String> = parse_range("-3..4").unwrap().collect(); - let expected: Vec<small::String> = vec![ - "-3".into(), - "-2".into(), - "-1".into(), - "0".into(), - "1".into(), - "2".into(), - "3".into(), - ]; - - assert_eq!(actual, expected); - - let actual: Vec<small::String> = parse_range("3..-4").unwrap().collect(); - let expected: Vec<small::String> = vec![ - "3".into(), - "2".into(), - "1".into(), - "0".into(), - "-1".into(), - "-2".into(), - "-3".into(), - ]; - - assert_eq!(actual, expected); - - let actual: Vec<small::String> = parse_range("-3...0").unwrap().collect(); - let expected: Vec<small::String> = vec!["-3".into(), "-2".into(), "-1".into(), "0".into()]; - assert_eq!(actual, expected); - - let actual: Vec<small::String> = parse_range("-3..0").unwrap().collect(); - let expected: Vec<small::String> = vec!["-3".into(), "-2".into(), "-1".into()]; - assert_eq!(actual, expected); } } diff --git a/members/ranges/src/parse.rs b/members/ranges/src/parse.rs index 97bc08e9..6f432ddb 100644 --- a/members/ranges/src/parse.rs +++ b/members/ranges/src/parse.rs @@ -118,9 +118,7 @@ fn char_range<'a>( } stepped_range_chars(start, end, char_step) } else { - Some(Box::new( - Some((start as char).to_string().into()).into_iter(), - )) + Some(Box::new(Some((start as char).to_string().into()).into_iter())) } } @@ -307,15 +305,10 @@ pub fn parse_index_range(input: &str) -> Option<Range> { return if end.is_empty() { None } else { - end.parse::<isize>() - .map(|end| Range::to(Index::new(end))) - .ok() + end.parse::<isize>().map(|end| Range::to(Index::new(end))).ok() }; } else if end.is_empty() { - return first - .parse::<isize>() - .map(|start| Range::from(Index::new(start))) - .ok(); + return first.parse::<isize>().map(|start| Range::from(Index::new(start))).ok(); } return first diff --git a/members/ranges/src/range.rs b/members/ranges/src/range.rs index 5bdb9e8c..8436c2d9 100644 --- a/members/ranges/src/range.rs +++ b/members/ranges/src/range.rs @@ -42,35 +42,11 @@ impl Range { } } - pub fn exclusive(start: Index, end: Index) -> Range { - Range { - start, - end, - inclusive: false, - } - } + pub fn exclusive(start: Index, end: Index) -> Range { Range { start, end, inclusive: false } } - pub fn inclusive(start: Index, end: Index) -> Range { - Range { - start, - end, - inclusive: true, - } - } + pub fn inclusive(start: Index, end: Index) -> Range { Range { start, end, inclusive: true } } - pub fn from(start: Index) -> Range { - Range { - start, - end: Index::new(-1), - inclusive: true, - } - } + pub fn from(start: Index) -> Range { Range { start, end: Index::new(-1), inclusive: true } } - pub fn to(end: Index) -> Range { - Range { - start: Index::new(0), - end, - inclusive: false, - } - } + pub fn to(end: Index) -> Range { Range { start: Index::new(0), end, inclusive: false } } } diff --git a/members/ranges/src/select.rs b/members/ranges/src/select.rs index 8ac46e90..4e33b7f0 100644 --- a/members/ranges/src/select.rs +++ b/members/ranges/src/select.rs @@ -40,19 +40,14 @@ where match s { Select::None => empty().collect(), Select::All => self.collect(), - Select::Index(idx) => idx - .resolve(size) - .and_then(|idx| self.nth(idx)) - .into_iter() - .collect(), - Select::Range(range) => { - if let Some((start, length)) = range.bounds(size) { - self.skip(start).take(length).collect() - } else { - empty().collect() - } + Select::Index(idx) => { + idx.resolve(size).and_then(|idx| self.nth(idx)).into_iter().collect() } - Select::Key(_) => empty().collect(), + Select::Range(range) if range.bounds(size).is_some() => range + .bounds(size) + .map(|(start, length)| self.skip(start).take(length).collect()) + .unwrap(), + _ => empty().collect(), } } } diff --git a/members/sys/src/sys/redox/mod.rs b/members/sys/src/sys/redox/mod.rs index 00de1576..600da97a 100644 --- a/members/sys/src/sys/redox/mod.rs +++ b/members/sys/src/sys/redox/mod.rs @@ -73,10 +73,7 @@ pub fn waitpid(pid: i32, status: &mut i32, options: i32) -> Result<i32, i32> { } pub fn strerror(errno: i32) -> &'static str { - syscall::error::STR_ERROR - .get(errno as usize) - .map(|err| *err) - .unwrap_or("Unknown Error") + syscall::error::STR_ERROR.get(errno as usize).map(|err| *err).unwrap_or("Unknown Error") } pub fn getpid() -> io::Result<u32> { cvt(syscall::getpid()).map(|pid| pid as u32) } @@ -265,10 +262,7 @@ pub fn execve<S: AsRef<str>>(prog: &str, args: &[S], clear_env: bool) -> io::Err } // Push the program name - cvt_args.push([ - prog.as_os_str().as_bytes().as_ptr() as usize, - prog.as_os_str().len(), - ]); + cvt_args.push([prog.as_os_str().as_bytes().as_ptr() as usize, prog.as_os_str().len()]); // Push all arguments for arg in args { @@ -322,10 +316,7 @@ pub fn tcsetpgrp(tty_fd: RawFd, pgid: u32) -> io::Result<()> { let pgid_usize = pgid as usize; let res = syscall::write(fd, unsafe { - slice::from_raw_parts( - &pgid_usize as *const usize as *const u8, - mem::size_of::<usize>(), - ) + slice::from_raw_parts(&pgid_usize as *const usize as *const u8, mem::size_of::<usize>()) }); let _ = syscall::close(fd); @@ -377,10 +368,7 @@ pub mod variables { if unsafe { libc::gethostname(&mut host_name as *mut _ as *mut c_char, host_name.len()) } == 0 { - let len = host_name - .iter() - .position(|i| *i == 0) - .unwrap_or(host_name.len()); + let len = host_name.iter().position(|i| *i == 0).unwrap_or(host_name.len()); Some(unsafe { String::from_utf8_unchecked(host_name[..len].to_owned()) }) } else { diff --git a/members/sys/src/sys/unix/mod.rs b/members/sys/src/sys/unix/mod.rs index f7b3d70a..f7770bd3 100644 --- a/members/sys/src/sys/unix/mod.rs +++ b/members/sys/src/sys/unix/mod.rs @@ -371,10 +371,7 @@ pub mod variables { if unsafe { libc::gethostname(&mut host_name as *mut _ as *mut c_char, host_name.len()) } == 0 { - let len = host_name - .iter() - .position(|i| *i == 0) - .unwrap_or_else(|| host_name.len()); + let len = host_name.iter().position(|i| *i == 0).unwrap_or_else(|| host_name.len()); Some(unsafe { String::from_utf8_unchecked(host_name[..len].to_owned()) }) } else { @@ -395,9 +392,7 @@ pub mod env { }; pub fn home_dir() -> Option<PathBuf> { - return env::var_os("HOME") - .or_else(|| unsafe { fallback() }) - .map(PathBuf::from); + return env::var_os("HOME").or_else(|| unsafe { fallback() }).map(PathBuf::from); #[cfg(any(target_os = "android", target_os = "ios", target_os = "emscripten"))] unsafe fn fallback() -> Option<OsString> { None } diff --git a/members/sys/src/sys/unix/signals.rs b/members/sys/src/sys/unix/signals.rs index ba4166e3..00a80262 100644 --- a/members/sys/src/sys/unix/signals.rs +++ b/members/sys/src/sys/unix/signals.rs @@ -11,11 +11,7 @@ pub fn block() { sigaddset(&mut sigset as *mut sigset_t, SIGTTOU); sigaddset(&mut sigset as *mut sigset_t, SIGTTIN); sigaddset(&mut sigset as *mut sigset_t, SIGCHLD); - sigprocmask( - SIG_BLOCK, - &sigset as *const sigset_t, - ptr::null_mut() as *mut sigset_t, - ); + sigprocmask(SIG_BLOCK, &sigset as *const sigset_t, ptr::null_mut() as *mut sigset_t); } } @@ -30,10 +26,6 @@ pub fn unblock() { sigaddset(&mut sigset as *mut sigset_t, SIGTTOU); sigaddset(&mut sigset as *mut sigset_t, SIGTTIN); sigaddset(&mut sigset as *mut sigset_t, SIGCHLD); - sigprocmask( - SIG_UNBLOCK, - &sigset as *const sigset_t, - ptr::null_mut() as *mut sigset_t, - ); + sigprocmask(SIG_UNBLOCK, &sigset as *const sigset_t, ptr::null_mut() as *mut sigset_t); } } diff --git a/rustfmt.toml b/rustfmt.toml index d6df6d66..44c3d285 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -13,3 +13,5 @@ struct_field_align_threshold = 30 use_field_init_shorthand = true wrap_comments = true merge_imports = true +force_multiline_blocks = false +use_small_heuristics = "Max" diff --git a/src/lib/ascii_helpers.rs b/src/lib/ascii_helpers.rs index b612c289..e40d1d80 100644 --- a/src/lib/ascii_helpers.rs +++ b/src/lib/ascii_helpers.rs @@ -22,10 +22,7 @@ impl AsciiReplaceInPlace for str { // I tried replacing these `assert!` calls with `debug_assert!` but it looks // like they get const-folded away anyway since it doesn't affect the speed fn ascii_replace_in_place(&mut self, needle: char, haystack: char) { - assert!( - needle.is_ascii(), - "AsciiReplace functions can only be used for ascii characters" - ); + assert!(needle.is_ascii(), "AsciiReplace functions can only be used for ascii characters"); assert!( haystack.is_ascii(), "AsciiReplace functions can only be used for ascii characters" diff --git a/src/lib/builtins/command_info.rs b/src/lib/builtins/command_info.rs index 8ef3eda1..992c12b6 100644 --- a/src/lib/builtins/command_info.rs +++ b/src/lib/builtins/command_info.rs @@ -73,9 +73,8 @@ pub(crate) fn get_command_info<'a>(command: &str, shell: &mut Shell) -> Result<C } else if shell.builtins.contains_key(command) { return Ok("builtin".into()); } else { - for path in env::var("PATH") - .unwrap_or_else(|_| String::from("/bin")) - .split(sys::PATH_SEPARATOR) + for path in + env::var("PATH").unwrap_or_else(|_| String::from("/bin")).split(sys::PATH_SEPARATOR) { let executable = Path::new(path).join(command); if executable.is_file() { diff --git a/src/lib/builtins/exec.rs b/src/lib/builtins/exec.rs index 29fe57eb..100c9d8a 100644 --- a/src/lib/builtins/exec.rs +++ b/src/lib/builtins/exec.rs @@ -23,15 +23,9 @@ pub(crate) fn exec(shell: &mut Shell, args: &[small::String]) -> Result<(), smal match args.get(idx) { Some(argument) => { - let args = if args.len() > idx + 1 { - &args[idx + 1..] - } else { - &[] - }; + let args = if args.len() > idx + 1 { &args[idx + 1..] } else { &[] }; shell.prep_for_exit(); - Err(execve(argument, args, (flags & CLEAR_ENV) == 1) - .description() - .into()) + Err(execve(argument, args, (flags & CLEAR_ENV) == 1).description().into()) } None => Err("no command provided".into()), } diff --git a/src/lib/builtins/exists.rs b/src/lib/builtins/exists.rs index 5d0ee870..e3b82572 100644 --- a/src/lib/builtins/exists.rs +++ b/src/lib/builtins/exists.rs @@ -65,16 +65,12 @@ fn match_option_argument(option: &str, argument: &str, shell: &Shell) -> bool { /// Returns true if the file is a regular file fn path_is_file(filepath: &str) -> bool { - fs::metadata(filepath) - .ok() - .map_or(false, |metadata| metadata.file_type().is_file()) + fs::metadata(filepath).ok().map_or(false, |metadata| metadata.file_type().is_file()) } /// Returns true if the file is a directory fn path_is_directory(filepath: &str) -> bool { - fs::metadata(filepath) - .ok() - .map_or(false, |metadata| metadata.file_type().is_dir()) + fs::metadata(filepath).ok().map_or(false, |metadata| metadata.file_type().is_dir()) } /// Returns true if the binary is found in path (and is executable) @@ -150,65 +146,36 @@ fn test_evaluate_arguments() { assert_eq!(evaluate_arguments(&[], &shell), Ok(false)); // multiple arguments // ignores all but the first argument - assert_eq!( - evaluate_arguments(&["foo".into(), "bar".into()], &shell), - Ok(true) - ); + assert_eq!(evaluate_arguments(&["foo".into(), "bar".into()], &shell), Ok(true)); // check `exists STRING` assert_eq!(evaluate_arguments(&["".into()], &shell), Ok(false)); assert_eq!(evaluate_arguments(&["string".into()], &shell), Ok(true)); - assert_eq!( - evaluate_arguments(&["string with space".into()], &shell), - Ok(true) - ); - assert_eq!( - evaluate_arguments(&["-startswithdash".into()], &shell), - Ok(true) - ); + assert_eq!(evaluate_arguments(&["string with space".into()], &shell), Ok(true)); + assert_eq!(evaluate_arguments(&["-startswithdash".into()], &shell), Ok(true)); // check `exists -a` // no argument means we treat it as a string assert_eq!(evaluate_arguments(&["-a".into()], &shell), Ok(true)); shell.variables.set("emptyarray", types::Array::new()); - assert_eq!( - evaluate_arguments(&["-a".into(), "emptyarray".into()], &shell), - Ok(false) - ); + assert_eq!(evaluate_arguments(&["-a".into(), "emptyarray".into()], &shell), Ok(false)); let mut array = types::Array::new(); array.push("element".into()); shell.variables.set("array", array); - assert_eq!( - evaluate_arguments(&["-a".into(), "array".into()], &shell), - Ok(true) - ); + assert_eq!(evaluate_arguments(&["-a".into(), "array".into()], &shell), Ok(true)); shell.variables.remove_variable("array"); - assert_eq!( - evaluate_arguments(&["-a".into(), "array".into()], &shell), - Ok(false) - ); + assert_eq!(evaluate_arguments(&["-a".into(), "array".into()], &shell), Ok(false)); // check `exists -b` // TODO: see test_binary_is_in_path() // no argument means we treat it as a string assert_eq!(evaluate_arguments(&["-b".into()], &shell), Ok(true)); - let oldpath = shell - .get::<types::Str>("PATH") - .unwrap_or_else(|| "/usr/bin".into()); + let oldpath = shell.get::<types::Str>("PATH").unwrap_or_else(|| "/usr/bin".into()); shell.set("PATH", "testing/"); - assert_eq!( - evaluate_arguments(&["-b".into(), "executable_file".into()], &shell), - Ok(true) - ); - assert_eq!( - evaluate_arguments(&["-b".into(), "empty_file".into()], &shell), - Ok(false) - ); - assert_eq!( - evaluate_arguments(&["-b".into(), "file_does_not_exist".into()], &shell), - Ok(false) - ); + assert_eq!(evaluate_arguments(&["-b".into(), "executable_file".into()], &shell), Ok(true)); + assert_eq!(evaluate_arguments(&["-b".into(), "empty_file".into()], &shell), Ok(false)); + assert_eq!(evaluate_arguments(&["-b".into(), "file_does_not_exist".into()], &shell), Ok(false)); // restore original PATH. Not necessary for the currently defined test cases // but this might change in the future? Better safe than sorry! @@ -217,89 +184,47 @@ fn test_evaluate_arguments() { // check `exists -d` // no argument means we treat it as a string assert_eq!(evaluate_arguments(&["-d".into()], &shell), Ok(true)); - assert_eq!( - evaluate_arguments(&["-d".into(), "testing/".into()], &shell), - Ok(true) - ); - assert_eq!( - evaluate_arguments(&["-d".into(), "testing/empty_file".into()], &shell), - Ok(false) - ); - assert_eq!( - evaluate_arguments(&["-d".into(), "does/not/exist/".into()], &shell), - Ok(false) - ); + assert_eq!(evaluate_arguments(&["-d".into(), "testing/".into()], &shell), Ok(true)); + assert_eq!(evaluate_arguments(&["-d".into(), "testing/empty_file".into()], &shell), Ok(false)); + assert_eq!(evaluate_arguments(&["-d".into(), "does/not/exist/".into()], &shell), Ok(false)); // check `exists -f` // no argument means we treat it as a string assert_eq!(evaluate_arguments(&["-f".into()], &shell), Ok(true)); - assert_eq!( - evaluate_arguments(&["-f".into(), "testing/".into()], &shell), - Ok(false) - ); - assert_eq!( - evaluate_arguments(&["-f".into(), "testing/empty_file".into()], &shell), - Ok(true) - ); - assert_eq!( - evaluate_arguments(&["-f".into(), "does-not-exist".into()], &shell), - Ok(false) - ); + assert_eq!(evaluate_arguments(&["-f".into(), "testing/".into()], &shell), Ok(false)); + assert_eq!(evaluate_arguments(&["-f".into(), "testing/empty_file".into()], &shell), Ok(true)); + assert_eq!(evaluate_arguments(&["-f".into(), "does-not-exist".into()], &shell), Ok(false)); // check `exists -s` // no argument means we treat it as a string assert_eq!(evaluate_arguments(&["-s".into()], &shell), Ok(true)); shell.set("emptyvar", "".to_string()); - assert_eq!( - evaluate_arguments(&["-s".into(), "emptyvar".into()], &shell), - Ok(false) - ); + assert_eq!(evaluate_arguments(&["-s".into(), "emptyvar".into()], &shell), Ok(false)); shell.set("testvar", "foobar".to_string()); - assert_eq!( - evaluate_arguments(&["-s".into(), "testvar".into()], &shell), - Ok(true) - ); + assert_eq!(evaluate_arguments(&["-s".into(), "testvar".into()], &shell), Ok(true)); shell.variables.remove_variable("testvar"); - assert_eq!( - evaluate_arguments(&["-s".into(), "testvar".into()], &shell), - Ok(false) - ); + assert_eq!(evaluate_arguments(&["-s".into(), "testvar".into()], &shell), Ok(false)); // also check that it doesn't trigger on arrays let mut array = types::Array::new(); array.push("element".into()); shell.variables.remove_variable("array"); shell.variables.set("array", array); - assert_eq!( - evaluate_arguments(&["-s".into(), "array".into()], &shell), - Ok(false) - ); + assert_eq!(evaluate_arguments(&["-s".into(), "array".into()], &shell), Ok(false)); // check `exists --fn` let name_str = "test_function"; let name = small::String::from(name_str); let mut args = Vec::new(); - args.push(KeyBuf { - name: "testy".into(), - kind: Primitive::Any, - }); + args.push(KeyBuf { name: "testy".into(), kind: Primitive::Any }); let mut statements = Vec::new(); statements.push(Statement::End); let description: small::String = "description".into(); - shell.variables.set( - &name, - Function::new(Some(description), name.clone(), args, statements), - ); + shell.variables.set(&name, Function::new(Some(description), name.clone(), args, statements)); - assert_eq!( - evaluate_arguments(&["--fn".into(), name_str.into()], &shell), - Ok(true) - ); + assert_eq!(evaluate_arguments(&["--fn".into(), name_str.into()], &shell), Ok(true)); shell.variables.remove_variable(name_str); - assert_eq!( - evaluate_arguments(&["--fn".into(), name_str.into()], &shell), - Ok(false) - ); + assert_eq!(evaluate_arguments(&["--fn".into(), name_str.into()], &shell), Ok(false)); // check invalid flags / parameters (should all be treated as strings and // therefore succeed) @@ -313,26 +238,11 @@ fn test_match_flag_argument() { // we don't really care about the passed values, as long as both sited return // the same value - assert_eq!( - match_flag_argument('a', "ARRAY", &shell), - array_var_is_not_empty("ARRAY", &shell) - ); - assert_eq!( - match_flag_argument('b', "binary", &shell), - binary_is_in_path("binary", &shell) - ); - assert_eq!( - match_flag_argument('d', "path", &shell), - path_is_directory("path") - ); - assert_eq!( - match_flag_argument('f', "file", &shell), - path_is_file("file") - ); - assert_eq!( - match_flag_argument('s', "STR", &shell), - string_var_is_not_empty("STR", &shell) - ); + assert_eq!(match_flag_argument('a', "ARRAY", &shell), array_var_is_not_empty("ARRAY", &shell)); + assert_eq!(match_flag_argument('b', "binary", &shell), binary_is_in_path("binary", &shell)); + assert_eq!(match_flag_argument('d', "path", &shell), path_is_directory("path")); + assert_eq!(match_flag_argument('f', "file", &shell), path_is_file("file")); + assert_eq!(match_flag_argument('s', "STR", &shell), string_var_is_not_empty("STR", &shell)); // Any flag which is not implemented assert_eq!(match_flag_argument('x', "ARG", &shell), false); @@ -344,10 +254,7 @@ fn test_match_option_argument() { // we don't really care about the passed values, as long as both sited return // the same value - assert_eq!( - match_option_argument("fn", "FUN", &shell), - array_var_is_not_empty("FUN", &shell) - ); + assert_eq!(match_option_argument("fn", "FUN", &shell), array_var_is_not_empty("FUN", &shell)); // Any option which is not implemented assert_eq!(match_option_argument("foo", "ARG", &shell), false); @@ -448,18 +355,12 @@ fn test_function_is_defined() { let name_str = "test_function"; let name: small::String = name_str.into(); let mut args = Vec::new(); - args.push(KeyBuf { - name: "testy".into(), - kind: Primitive::Any, - }); + args.push(KeyBuf { name: "testy".into(), kind: Primitive::Any }); let mut statements = Vec::new(); statements.push(Statement::End); let description: small::String = "description".into(); - shell.variables.set( - &name, - Function::new(Some(description), name.clone(), args, statements), - ); + shell.variables.set(&name, Function::new(Some(description), name.clone(), args, statements)); assert_eq!(function_is_defined(name_str, &shell), true); shell.variables.remove_variable(name_str); diff --git a/src/lib/builtins/is.rs b/src/lib/builtins/is.rs index 6ffe7eae..680826fa 100644 --- a/src/lib/builtins/is.rs +++ b/src/lib/builtins/is.rs @@ -57,32 +57,14 @@ fn test_is() { is(&vec_string(&["is", " ", " ", " "]), &mut shell), Err("Expected 'not' instead found ' '\n".to_string()) ); - assert_eq!( - is(&vec_string(&["is", "not", " ", " "]), &mut shell), - Err("".to_string()) - ); - assert_eq!( - is(&vec_string(&["is", "not", "$x", "$x"]), &mut shell), - Err("".to_string()) - ); - assert_eq!( - is(&vec_string(&["is", "not", "2", "1"]), &mut shell), - Ok(()) - ); - assert_eq!( - is(&vec_string(&["is", "not", "$x", "$y"]), &mut shell), - Ok(()) - ); + assert_eq!(is(&vec_string(&["is", "not", " ", " "]), &mut shell), Err("".to_string())); + assert_eq!(is(&vec_string(&["is", "not", "$x", "$x"]), &mut shell), Err("".to_string())); + assert_eq!(is(&vec_string(&["is", "not", "2", "1"]), &mut shell), Ok(())); + assert_eq!(is(&vec_string(&["is", "not", "$x", "$y"]), &mut shell), Ok(())); // Three arguments - assert_eq!( - is(&vec_string(&["is", "1", "2"]), &mut shell), - Err("".to_string()) - ); - assert_eq!( - is(&vec_string(&["is", "$x", "$y"]), &mut shell), - Err("".to_string()) - ); + assert_eq!(is(&vec_string(&["is", "1", "2"]), &mut shell), Err("".to_string())); + assert_eq!(is(&vec_string(&["is", "$x", "$y"]), &mut shell), Err("".to_string())); assert_eq!(is(&vec_string(&["is", " ", " "]), &mut shell), Ok(())); assert_eq!(is(&vec_string(&["is", "$x", "$x"]), &mut shell), Ok(())); diff --git a/src/lib/builtins/job_control.rs b/src/lib/builtins/job_control.rs index 8825d746..0fa7425c 100644 --- a/src/lib/builtins/job_control.rs +++ b/src/lib/builtins/job_control.rs @@ -30,9 +30,8 @@ pub(crate) fn disown(shell: &mut Shell, args: &[small::String]) -> Result<(), St "-h" => flags |= NO_SIGHUP, "-r" => flags |= RUN_JOBS, _ => { - let jobspec = arg - .parse::<u32>() - .map_err(|_| format!("invalid jobspec: '{}'", arg))?; + let jobspec = + arg.parse::<u32>().map_err(|_| format!("invalid jobspec: '{}'", arg))?; collected_jobs.push(jobspec); } } @@ -48,13 +47,9 @@ pub(crate) fn disown(shell: &mut Shell, args: &[small::String]) -> Result<(), St let mut process_table = shell.background.lock().unwrap(); if collected_jobs.is_empty() && flags & ALL_JOBS != 0 { if flags & NO_SIGHUP != 0 { - process_table - .iter_mut() - .for_each(|process| process.ignore_sighup = true); + process_table.iter_mut().for_each(|process| process.ignore_sighup = true); } else { - process_table - .iter_mut() - .for_each(|process| process.state = ProcessState::Empty); + process_table.iter_mut().for_each(|process| process.state = ProcessState::Empty); } } else { collected_jobs.sort(); @@ -90,10 +85,7 @@ pub(crate) fn disown(shell: &mut Shell, args: &[small::String]) -> Result<(), St pub(crate) fn jobs(shell: &mut Shell) { for (id, process) in shell.background.lock().unwrap().iter().enumerate() { if process.state != ProcessState::Empty { - eprintln!( - "[{}] {} {}\t{}", - id, process.pid, process.state, process.name - ); + eprintln!("[{}] {} {}\t{}", id, process.pid, process.state, process.name); } } } @@ -152,13 +144,7 @@ pub(crate) fn fg(shell: &mut Shell, args: &[small::String]) -> i32 { /// Resumes a stopped background process, if it was stopped. pub(crate) fn bg(shell: &mut Shell, args: &[small::String]) -> i32 { fn bg_job(shell: &mut Shell, njob: u32) -> bool { - if let Some(job) = shell - .background - .lock() - .unwrap() - .iter_mut() - .nth(njob as usize) - { + if let Some(job) = shell.background.lock().unwrap().iter_mut().nth(njob as usize) { match job.state { ProcessState::Running => { eprintln!("ion: bg: job {} is already running", njob); diff --git a/src/lib/builtins/mod.rs b/src/lib/builtins/mod.rs index c6390e12..1989df67 100644 --- a/src/lib/builtins/mod.rs +++ b/src/lib/builtins/mod.rs @@ -503,11 +503,7 @@ fn builtin_exit(args: &[small::String], shell: &mut Shell) -> i32 { } } let previous_status = shell.previous_status; - shell.exit( - args.get(1) - .and_then(|status| status.parse::<i32>().ok()) - .unwrap_or(previous_status), - ) + shell.exit(args.get(1).and_then(|status| status.parse::<i32>().ok()).unwrap_or(previous_status)) } fn builtin_exec(args: &[small::String], shell: &mut Shell) -> i32 { diff --git a/src/lib/parser/assignments/actions.rs b/src/lib/parser/assignments/actions.rs index 6552f75e..5c386413 100644 --- a/src/lib/parser/assignments/actions.rs +++ b/src/lib/parser/assignments/actions.rs @@ -37,11 +37,9 @@ impl<'a> Display for AssignmentError<'a> { "repeated assignment to same key, and thus ignored. Repeated key: '{}'", repkey ), - AssignmentError::NoKey(ref lone_val) => write!( - f, - "no key to assign value, thus ignored. Value: '{}'", - lone_val - ), + AssignmentError::NoKey(ref lone_val) => { + write!(f, "no key to assign value, thus ignored. Value: '{}'", lone_val) + } } } } @@ -169,10 +167,7 @@ mod tests { assert_eq!( actions[0], Ok(Action::UpdateString( - Key { - name: "abc", - kind: Primitive::Any, - }, + Key { name: "abc", kind: Primitive::Any }, Operator::Equal, "123", )) @@ -180,10 +175,7 @@ mod tests { assert_eq!( actions[1], Ok(Action::UpdateString( - Key { - name: "def", - kind: Primitive::Any, - }, + Key { name: "def", kind: Primitive::Any }, Operator::Equal, "456", )) @@ -195,10 +187,7 @@ mod tests { assert_eq!( actions[0], Ok(Action::UpdateString( - Key { - name: "ab", - kind: Primitive::Integer, - }, + Key { name: "ab", kind: Primitive::Integer }, Operator::Multiply, "3", )) @@ -210,10 +199,7 @@ mod tests { assert_eq!( actions[0], Ok(Action::UpdateString( - Key { - name: "a", - kind: Primitive::Any, - }, + Key { name: "a", kind: Primitive::Any }, Operator::Equal, "one", )) @@ -221,10 +207,7 @@ mod tests { assert_eq!( actions[1], Ok(Action::UpdateArray( - Key { - name: "b", - kind: Primitive::AnyArray, - }, + Key { name: "b", kind: Primitive::AnyArray }, Operator::Equal, "[two three]", )) @@ -232,10 +215,7 @@ mod tests { assert_eq!( actions[2], Ok(Action::UpdateArray( - Key { - name: "c", - kind: Primitive::IntegerArray, - }, + Key { name: "c", kind: Primitive::IntegerArray }, Operator::Equal, "[4 5 6]", )) @@ -247,10 +227,7 @@ mod tests { assert_eq!( actions[0], Ok(Action::UpdateArray( - Key { - name: "a", - kind: Primitive::AnyArray, - }, + Key { name: "a", kind: Primitive::AnyArray }, Operator::Equal, "[one two]", )) @@ -258,10 +235,7 @@ mod tests { assert_eq!( actions[1], Ok(Action::UpdateString( - Key { - name: "b", - kind: Primitive::Any, - }, + Key { name: "b", kind: Primitive::Any }, Operator::Equal, "three", )) @@ -269,10 +243,7 @@ mod tests { assert_eq!( actions[2], Ok(Action::UpdateArray( - Key { - name: "c", - kind: Primitive::AnyArray, - }, + Key { name: "c", kind: Primitive::AnyArray }, Operator::Equal, "[four five]", )) @@ -283,10 +254,7 @@ mod tests { assert_eq!( actions[0], Ok(Action::UpdateArray( - Key { - name: "array", - kind: Primitive::Any, - }, + Key { name: "array", kind: Primitive::Any }, Operator::Concatenate, "[one two three four five]", )) @@ -297,10 +265,7 @@ mod tests { assert_eq!( actions[0], Ok(Action::UpdateArray( - Key { - name: "array", - kind: Primitive::Any, - }, + Key { name: "array", kind: Primitive::Any }, Operator::ConcatenateHead, "[1 2 3 4 5]", )) @@ -311,10 +276,7 @@ mod tests { assert_eq!( actions[0], Ok(Action::UpdateArray( - Key { - name: "array", - kind: Primitive::Any, - }, + Key { name: "array", kind: Primitive::Any }, Operator::Filter, "[foo bar baz]", )) diff --git a/src/lib/parser/assignments/checker.rs b/src/lib/parser/assignments/checker.rs index 243a8ad2..7165bb18 100644 --- a/src/lib/parser/assignments/checker.rs +++ b/src/lib/parser/assignments/checker.rs @@ -143,9 +143,7 @@ fn is_float_array(value: VariableType) -> Result<VariableType, ()> { } fn get_string<E: Expander>(shell: &E, value: &str) -> VariableType { - VariableType::Str(types::Str::from( - expand_string(value, shell, false).join(" "), - )) + VariableType::Str(types::Str::from(expand_string(value, shell, false).join(" "))) } fn get_array<E: Expander>(shell: &E, value: &str) -> VariableType { @@ -306,13 +304,7 @@ mod test { #[test] fn is_integer_array_() { let expected = Ok(VariableType::Array(array!["1", "2", "3"])); - assert_eq!( - is_integer_array(VariableType::Array(array!["1", "2", "3"])), - expected - ); - assert_eq!( - is_integer_array(VariableType::Array(array!["1", "2", "three"])), - Err(()) - ); + assert_eq!(is_integer_array(VariableType::Array(array!["1", "2", "3"])), expected); + assert_eq!(is_integer_array(VariableType::Array(array!["1", "2", "three"])), Err(())); } } diff --git a/src/lib/parser/pipelines/collector.rs b/src/lib/parser/pipelines/collector.rs index fe40dee5..a1c28c6f 100644 --- a/src/lib/parser/pipelines/collector.rs +++ b/src/lib/parser/pipelines/collector.rs @@ -83,11 +83,7 @@ impl<'a> Collector<'a> { match arg { Some(file) => { if let Some(o) = outputs.as_mut() { - o.push(Redirection { - from, - file: file.into(), - append, - }); + o.push(Redirection { from, file: file.into(), append }); } Ok(()) @@ -513,10 +509,7 @@ mod tests { if let Statement::Pipeline(pipeline) = parse("echo $(echo one $(echo two) three)") { let items = pipeline.items; assert_eq!("echo", items[0].job.args[0].as_str()); - assert_eq!( - "$(echo one $(echo two) three)", - items[0].job.args[1].as_str() - ); + assert_eq!("$(echo one $(echo two) three)", items[0].job.args[1].as_str()); } else { assert!(false); } @@ -527,10 +520,7 @@ mod tests { if let Statement::Pipeline(pipeline) = parse("echo @(echo one @(echo two) three)") { let items = pipeline.items; assert_eq!("echo", items[0].job.args[0].as_str()); - assert_eq!( - "@(echo one @(echo two) three)", - items[0].job.args[1].as_str() - ); + assert_eq!("@(echo one @(echo two) three)", items[0].job.args[1].as_str()); } else { assert!(false); } @@ -1031,10 +1021,7 @@ mod tests { assert_eq!("awk", pipeline.clone().items[0].job.args[0].as_str()); assert_eq!("-v", pipeline.clone().items[0].job.args[1].as_str()); assert_eq!("x=$x", pipeline.clone().items[0].job.args[2].as_str()); - assert_eq!( - "'{ if (1) print $1 }'", - pipeline.clone().items[0].job.args[3].as_str() - ); + assert_eq!("'{ if (1) print $1 }'", pipeline.clone().items[0].job.args[3].as_str()); assert_eq!("myfile", pipeline.clone().items[0].job.args[4].as_str()); } else { assert!(false); diff --git a/src/lib/parser/pipelines/mod.rs b/src/lib/parser/pipelines/mod.rs index 6d26d717..72f0aec0 100644 --- a/src/lib/parser/pipelines/mod.rs +++ b/src/lib/parser/pipelines/mod.rs @@ -87,18 +87,12 @@ impl PipeItem { } for output in &mut self.outputs { - output.file = expand_string(output.file.as_str(), shell, false) - .join(" ") - .into(); + output.file = expand_string(output.file.as_str(), shell, false).join(" ").into(); } } pub(crate) fn new(job: Job, outputs: Vec<Redirection>, inputs: Vec<Input>) -> Self { - PipeItem { - job, - outputs, - inputs, - } + PipeItem { job, outputs, inputs } } } diff --git a/src/lib/parser/quotes.rs b/src/lib/parser/quotes.rs index 43773b60..8fd68b79 100644 --- a/src/lib/parser/quotes.rs +++ b/src/lib/parser/quotes.rs @@ -95,21 +95,19 @@ impl Terminator { .bytes() .enumerate() .skip(self.read) - .coalesce(|prev, next| { - if prev.1 == b'\\' { - Ok((next.0, 0)) - } else { - Err((prev, next)) - } - }) + .coalesce( + |prev, next| { + if prev.1 == b'\\' { + Ok((next.0, 0)) + } else { + Err((prev, next)) + } + }, + ) .filter(|&(_, c)| c != 0) .peekable(); - let mut bytes = RearPeekable { - iter: bytes, - now: None, - last: None, - }; + let mut bytes = RearPeekable { iter: bytes, now: None, last: None }; while let Some((i, character)) = bytes.next() { self.read = i + 1; diff --git a/src/lib/parser/shell_expand/mod.rs b/src/lib/parser/shell_expand/mod.rs index 54c36e79..1ed5af95 100644 --- a/src/lib/parser/shell_expand/mod.rs +++ b/src/lib/parser/shell_expand/mod.rs @@ -55,11 +55,8 @@ fn expand_process<E: Expander>( if output.is_empty() { return; } else if quoted { - let output: &str = if let Some(pos) = output.rfind(|x| x != '\n') { - &output[..=pos] - } else { - &output - }; + let output: &str = + if let Some(pos) = output.rfind(|x| x != '\n') { &output[..=pos] } else { &output }; slice(current, output, selection) } else { // If we ever do something with UTF-8, this won't work @@ -103,9 +100,8 @@ fn expand_brace<E: Expander>( reverse_quoting: bool, ) { let mut temp = Vec::new(); - for word in nodes - .iter() - .flat_map(|node| expand_string_no_glob(node, expand_func, reverse_quoting)) + for word in + nodes.iter().flat_map(|node| expand_string_no_glob(node, expand_func, reverse_quoting)) { match parse_range(&word) { Some(elements) => { @@ -135,22 +131,15 @@ fn array_expand<E: Expander>( ) -> types::Array { match selection { Select::None => types::Array::new(), - Select::All => elements - .iter() - .flat_map(|e| expand_string(e, expand_func, false)) - .collect(), - Select::Index(index) => array_nth(elements, expand_func, index) - .into_iter() - .collect(), + Select::All => elements.iter().flat_map(|e| expand_string(e, expand_func, false)).collect(), + Select::Index(index) => array_nth(elements, expand_func, index).into_iter().collect(), Select::Range(range) => array_range(elements, expand_func, range), Select::Key(_) => types::Array::new(), } } fn array_nth<E: Expander>(elements: &[&str], expand_func: &E, index: Index) -> Option<types::Str> { - let mut expanded = elements - .iter() - .flat_map(|e| expand_string(e, expand_func, false)); + let mut expanded = elements.iter().flat_map(|e| expand_string(e, expand_func, false)); match index { Index::Forward(n) => expanded.nth(n), Index::Backward(n) => expanded.rev().nth(n), @@ -181,9 +170,8 @@ fn slice<S: AsRef<str>>(output: &mut small::String, expanded: S, selection: Sele } } Select::Index(Index::Backward(id)) => { - if let Some(character) = UnicodeSegmentation::graphemes(expanded.as_ref(), true) - .rev() - .nth(id) + if let Some(character) = + UnicodeSegmentation::graphemes(expanded.as_ref(), true).rev().nth(id) { output.push_str(character); } @@ -191,11 +179,7 @@ fn slice<S: AsRef<str>>(output: &mut small::String, expanded: S, selection: Sele Select::Range(range) => { let graphemes = UnicodeSegmentation::graphemes(expanded.as_ref(), true); if let Some((start, length)) = range.bounds(graphemes.clone().count()) { - let substring = graphemes - .skip(start) - .take(length) - .collect::<Vec<&str>>() - .join(""); + let substring = graphemes.skip(start).take(length).collect::<Vec<&str>>().join(""); output.push_str(&substring); } } @@ -334,11 +318,8 @@ fn expand_braces<E: Expander>( expand_process(&mut temp, command, Select::All, expand_func, false); let len = temp.split_whitespace().count(); if let Some((start, length)) = range.bounds(len) { - let res = temp - .split_whitespace() - .skip(start) - .take(length) - .collect::<Vec<&str>>(); + let res = + temp.split_whitespace().skip(start).take(length).collect::<Vec<&str>>(); output.push_str(&res.join(" ")); } } @@ -373,14 +354,7 @@ fn expand_braces<E: Expander>( slice(&mut output, expanded, index.clone()); } WordToken::Normal(ref text, _, tilde) => { - expand( - &mut output, - &mut expanded_words, - expand_func, - text.as_ref(), - false, - tilde, - ); + expand(&mut output, &mut expanded_words, expand_func, text.as_ref(), false, tilde); } WordToken::Arithmetic(s) => expand_arithmetic(&mut output, s, expand_func), } @@ -401,34 +375,32 @@ fn expand_braces<E: Expander>( } } - expanded_words - .into_iter() - .fold(types::Array::new(), |mut array, word| { - if word.find('*').is_some() { - if let Ok(mut paths) = glob(&word) { - if let Some(path) = paths.next() { - if let Ok(path_buf) = path { - array.push((*path_buf.to_string_lossy()).into()); - } else { - array.push("".into()); - } + expanded_words.into_iter().fold(types::Array::new(), |mut array, word| { + if word.find('*').is_some() { + if let Ok(mut paths) = glob(&word) { + if let Some(path) = paths.next() { + if let Ok(path_buf) = path { + array.push((*path_buf.to_string_lossy()).into()); + } else { + array.push("".into()); } - for path in paths { - if let Ok(path_buf) = path { - array.push((*path_buf.to_string_lossy()).into()); - } else { - array.push("".into()); - } + } + for path in paths { + if let Ok(path_buf) = path { + array.push((*path_buf.to_string_lossy()).into()); + } else { + array.push("".into()); } - } else { - array.push(word); } - array } else { array.push(word); - array } - }) + array + } else { + array.push(word); + array + } + }) } fn expand_single_array_token<E: Expander>( @@ -453,35 +425,15 @@ fn expand_single_array_token<E: Expander>( Select::None => Some(types::Array::new()), Select::All => { expand_process(&mut output, command, Select::All, expand_func, false); - Some( - output - .split_whitespace() - .map(From::from) - .collect::<types::Array>(), - ) + Some(output.split_whitespace().map(From::from).collect::<types::Array>()) } Select::Index(Index::Forward(id)) => { expand_process(&mut output, command, Select::All, expand_func, false); - Some( - output - .split_whitespace() - .nth(id) - .map(Into::into) - .into_iter() - .collect(), - ) + Some(output.split_whitespace().nth(id).map(Into::into).into_iter().collect()) } Select::Index(Index::Backward(id)) => { expand_process(&mut output, command, Select::All, expand_func, false); - Some( - output - .split_whitespace() - .rev() - .nth(id) - .map(Into::into) - .into_iter() - .collect(), - ) + Some(output.split_whitespace().rev().nth(id).map(Into::into).into_iter().collect()) } Select::Range(range) => { expand_process(&mut output, command, Select::All, expand_func, false); @@ -516,14 +468,7 @@ fn expand_single_string_token<E: Expander>( match *token { WordToken::StringMethod(ref method) => method.handle(&mut output, expand_func), WordToken::Normal(ref text, do_glob, tilde) => { - expand( - &mut output, - &mut expanded_words, - expand_func, - text.as_ref(), - do_glob, - tilde, - ); + expand(&mut output, &mut expanded_words, expand_func, text.as_ref(), do_glob, tilde); } WordToken::Whitespace(text) => output.push_str(text), WordToken::Process(command, quoted, ref index) => { @@ -730,11 +675,7 @@ pub(crate) fn expand_tokens<E: Expander>( /// if `x=5` and `y=7` fn expand_arithmetic<E: Expander>(output: &mut small::String, input: &str, expander: &E) { // small::String cannot be created with a capacity of 0 without causing a panic - let len = if input.as_bytes().is_empty() { - input.as_bytes().len() - } else { - 1 - }; + let len = if input.as_bytes().is_empty() { input.as_bytes().len() } else { 1 }; let mut intermediate = small::String::with_capacity(len); let mut varbuf = small::String::new(); let flush = |var: &mut small::String, out: &mut small::String| { @@ -829,10 +770,7 @@ mod test { prospective projections"; let expanded = expand_string(line, &VariableExpander, false); assert_eq!( - expected - .split_whitespace() - .map(|x| x.into()) - .collect::<types::Array>(), + expected.split_whitespace().map(|x| x.into()).collect::<types::Array>(), expanded ); } @@ -843,10 +781,7 @@ mod test { let expected = "Itemized Itemize Italicized Italicize Iterated Iterate"; let expanded = expand_string(line, &VariableExpander, false); assert_eq!( - expected - .split_whitespace() - .map(|x| x.into()) - .collect::<types::Array>(), + expected.split_whitespace().map(|x| x.into()).collect::<types::Array>(), expanded ); } @@ -933,10 +868,8 @@ mod test { #[test] fn inline_expression() { - let cases = vec![ - (array!["5"], "$len([0 1 2 3 4])"), - (array!["FxOxO"], "$join(@chars('FOO') 'x')"), - ]; + let cases = + vec![(array!["5"], "$len([0 1 2 3 4])"), (array!["FxOxO"], "$join(@chars('FOO') 'x')")]; for (expected, input) in cases { assert_eq!(expected, expand_string(input, &VariableExpander, false)); } diff --git a/src/lib/parser/shell_expand/words/methods/arrays.rs b/src/lib/parser/shell_expand/words/methods/arrays.rs index ecd1e097..e86bc577 100644 --- a/src/lib/parser/shell_expand/words/methods/arrays.rs +++ b/src/lib/parser/shell_expand/words/methods/arrays.rs @@ -66,9 +66,8 @@ impl<'a> ArrayMethod<'a> { fn graphemes<E: Expander>(&self, expand_func: &E) -> Result<Array, &'static str> { let variable = self.resolve_var(expand_func); - let graphemes: Vec<types::Str> = UnicodeSegmentation::graphemes(variable.as_str(), true) - .map(From::from) - .collect(); + let graphemes: Vec<types::Str> = + UnicodeSegmentation::graphemes(variable.as_str(), true).map(From::from).collect(); let len = graphemes.len(); Ok(graphemes.into_iter().select(self.selection.clone(), len)) } @@ -77,9 +76,8 @@ impl<'a> ArrayMethod<'a> { let variable = self.resolve_var(expand_func); match self.pattern { Pattern::StringPattern(string) => { - if let Ok(value) = expand_string(string, expand_func, false) - .join(" ") - .parse::<usize>() + if let Ok(value) = + expand_string(string, expand_func, false).join(" ").parse::<usize>() { if value < variable.len() { let (l, r) = variable.split_at(value); @@ -144,10 +142,7 @@ impl<'a> ArrayMethod<'a> { } } (&Pattern::Whitespace, Select::Range(range)) => { - let len = variable - .split(char::is_whitespace) - .filter(|x| !x.is_empty()) - .count(); + let len = variable.split(char::is_whitespace).filter(|x| !x.is_empty()).count(); if let Some((start, length)) = range.bounds(len) { variable .split(char::is_whitespace) @@ -416,10 +411,7 @@ mod test { pattern: Pattern::StringPattern("3"), selection: Select::All, }; - assert_eq!( - method.handle_as_array(&VariableExpander), - array!["FOO", "BAR"] - ); + assert_eq!(method.handle_as_array(&VariableExpander), array!["FOO", "BAR"]); } #[test] @@ -430,10 +422,7 @@ mod test { pattern: Pattern::StringPattern("3"), selection: Select::All, }; - assert_eq!( - method.handle_as_array(&VariableExpander), - array!["F", "O", "O", "B", "A", "R"] - ); + assert_eq!(method.handle_as_array(&VariableExpander), array!["F", "O", "O", "B", "A", "R"]); } #[test] @@ -458,10 +447,7 @@ mod test { pattern: Pattern::StringPattern("3"), selection: Select::All, }; - assert_eq!( - method.handle_as_array(&VariableExpander), - array!["F", "O", "O", "B", "A", "R"] - ); + assert_eq!(method.handle_as_array(&VariableExpander), array!["F", "O", "O", "B", "A", "R"]); } #[test] @@ -472,10 +458,7 @@ mod test { pattern: Pattern::StringPattern("3"), selection: Select::All, }; - assert_eq!( - method.handle_as_array(&VariableExpander), - array!["FOO", "BAR"] - ); + assert_eq!(method.handle_as_array(&VariableExpander), array!["FOO", "BAR"]); } #[test] @@ -486,9 +469,6 @@ mod test { pattern: Pattern::StringPattern("3"), selection: Select::All, }; - assert_eq!( - method.handle_as_array(&VariableExpander), - array!["c", "b", "a"] - ); + assert_eq!(method.handle_as_array(&VariableExpander), array!["c", "b", "a"]); } } diff --git a/src/lib/parser/shell_expand/words/methods/strings.rs b/src/lib/parser/shell_expand/words/methods/strings.rs index bab41cf1..48b30fe3 100644 --- a/src/lib/parser/shell_expand/words/methods/strings.rs +++ b/src/lib/parser/shell_expand/words/methods/strings.rs @@ -106,9 +106,7 @@ impl<'a> StringMethod<'a> { let is_true = if let Some(value) = expand.string($variable, false) { value.$method(pattern.as_str()) } else if is_expression($variable) { - expand_string($variable, expand, false) - .join(" ") - .$method(pattern.as_str()) + expand_string($variable, expand, false).join(" ").$method(pattern.as_str()) } else { false }; @@ -317,11 +315,8 @@ impl<'a> StringMethod<'a> { small::String::new() }; let second_array = pattern.array(); - let first_maybe: Option<String> = if first_str != "" { - Some(first_str.to_string()) - } else { - None - }; + let first_maybe: Option<String> = + if first_str != "" { Some(first_str.to_string()) } else { None }; match first_maybe { Some(first) => output.push_str(&first), None => { diff --git a/src/lib/parser/shell_expand/words/mod.rs b/src/lib/parser/shell_expand/words/mod.rs index c60650ab..a3e37fc0 100644 --- a/src/lib/parser/shell_expand/words/mod.rs +++ b/src/lib/parser/shell_expand/words/mod.rs @@ -617,11 +617,7 @@ impl<'a, E: Expander + 'a> WordIterator<'a, E> { self.read += 1; } - WordToken::Variable( - &self.data[start..], - self.flags.contains(Flags::DQUOTE), - Select::All, - ) + WordToken::Variable(&self.data[start..], self.flags.contains(Flags::DQUOTE), Select::All) } // Contains the logic for parsing braced variables @@ -661,13 +657,7 @@ impl<'a, E: Expander + 'a> WordIterator<'a, E> { } pub(crate) fn new(data: &'a str, expanders: &'a E, do_glob: bool) -> WordIterator<'a, E> { - WordIterator { - data, - read: 0, - flags: Flags::empty(), - expanders, - do_glob, - } + WordIterator { data, read: 0, flags: Flags::empty(), expanders, do_glob } } } @@ -885,11 +875,7 @@ impl<'a, E: Expander + 'a> Iterator for WordIterator<'a, E> { if start == self.read { None } else { - Some(WordToken::Normal( - unescape(&self.data[start..]), - glob, - tilde, - )) + Some(WordToken::Normal(unescape(&self.data[start..]), glob, tilde)) } } } diff --git a/src/lib/parser/shell_expand/words/tests.rs b/src/lib/parser/shell_expand/words/tests.rs index 723958e3..d5ffbd21 100644 --- a/src/lib/parser/shell_expand/words/tests.rs +++ b/src/lib/parser/shell_expand/words/tests.rs @@ -157,11 +157,7 @@ fn words_process_with_quotes() { let expected = vec![ WordToken::Normal("echo".into(), false, false), WordToken::Whitespace(" "), - WordToken::Process( - "git branch | rg '[*]' | awk '{print $2}'", - false, - Select::All, - ), + WordToken::Process("git branch | rg '[*]' | awk '{print $2}'", false, Select::All), ]; compare(input, expected); @@ -169,11 +165,7 @@ fn words_process_with_quotes() { let expected = vec![ WordToken::Normal("echo".into(), false, false), WordToken::Whitespace(" "), - WordToken::Process( - "git branch | rg \"[*]\" | awk '{print $2}'", - false, - Select::All, - ), + WordToken::Process("git branch | rg \"[*]\" | awk '{print $2}'", false, Select::All), ]; compare(input, expected); } diff --git a/src/lib/parser/statement/case.rs b/src/lib/parser/statement/case.rs index db294751..dbbe4b8f 100644 --- a/src/lib/parser/statement/case.rs +++ b/src/lib/parser/statement/case.rs @@ -92,10 +92,7 @@ mod tests { Ok((Some("test"), Some("test"), Some("exists".into()))), parse_case("test @ test if exists") ); - assert_eq!( - Ok((Some("test"), Some("test"), None)), - parse_case("test @ test") - ); + assert_eq!(Ok((Some("test"), Some("test"), None)), parse_case("test @ test")); assert_eq!(Ok((Some("test"), None, None)), parse_case("test")); } } diff --git a/src/lib/parser/statement/functions.rs b/src/lib/parser/statement/functions.rs index e07f5f12..cdf3fac8 100644 --- a/src/lib/parser/statement/functions.rs +++ b/src/lib/parser/statement/functions.rs @@ -61,22 +61,10 @@ mod tests { assert_eq!( args, Ok(vec![ - KeyBuf { - name: "a".into(), - kind: Primitive::Integer, - }, - KeyBuf { - name: "b".into(), - kind: Primitive::Boolean, - }, - KeyBuf { - name: "c".into(), - kind: Primitive::AnyArray, - }, - KeyBuf { - name: "d".into(), - kind: Primitive::Any, - }, + KeyBuf { name: "a".into(), kind: Primitive::Integer }, + KeyBuf { name: "b".into(), kind: Primitive::Boolean }, + KeyBuf { name: "c".into(), kind: Primitive::AnyArray }, + KeyBuf { name: "d".into(), kind: Primitive::Any }, ]) ); assert_eq!(description, Some("description")) diff --git a/src/lib/parser/statement/parse.rs b/src/lib/parser/statement/parse.rs index e9dcf995..59b1fa42 100644 --- a/src/lib/parser/statement/parse.rs +++ b/src/lib/parser/statement/parse.rs @@ -131,9 +131,7 @@ pub(crate) fn parse(code: &str) -> Statement { return match variables { Some(variables) => Statement::For { variables, - values: ArgumentSplitter::new(cmd) - .map(small::String::from) - .collect(), + values: ArgumentSplitter::new(cmd).map(small::String::from).collect(), statements: Vec::new(), }, None => { @@ -162,12 +160,7 @@ pub(crate) fn parse(code: &str) -> Statement { } }; - return Statement::Case(Case { - value, - binding, - conditional, - statements: Vec::new(), - }); + return Statement::Case(Case { value, binding, conditional, statements: Vec::new() }); } _ if cmd.starts_with("match ") => { return Statement::Match { @@ -260,10 +253,7 @@ mod tests { parse("for x in {1..=10} {1..=10}"), Statement::For { variables: vec!["x"].into_iter().map(Into::into).collect(), - values: vec!["{1..=10}", "{1..=10}"] - .into_iter() - .map(Into::into) - .collect(), + values: vec!["{1..=10}", "{1..=10}"].into_iter().map(Into::into).collect(), statements: Vec::new(), } ); @@ -358,14 +348,8 @@ mod tests { description: None, name: "bob".into(), args: vec![ - KeyBuf { - name: "a".into(), - kind: Primitive::Any, - }, - KeyBuf { - name: "b".into(), - kind: Primitive::Any, - }, + KeyBuf { name: "a".into(), kind: Primitive::Any }, + KeyBuf { name: "b".into(), kind: Primitive::Any }, ], statements: Default::default(), }; @@ -380,14 +364,8 @@ mod tests { description: Some("bob is a nice function".into()), name: "bob".into(), args: vec![ - KeyBuf { - name: "a".into(), - kind: Primitive::Any, - }, - KeyBuf { - name: "b".into(), - kind: Primitive::Any, - }, + KeyBuf { name: "a".into(), kind: Primitive::Any }, + KeyBuf { name: "b".into(), kind: Primitive::Any }, ], statements: vec![], }; diff --git a/src/lib/parser/statement/splitter.rs b/src/lib/parser/statement/splitter.rs index f810cc28..72fe15de 100644 --- a/src/lib/parser/statement/splitter.rs +++ b/src/lib/parser/statement/splitter.rs @@ -172,10 +172,7 @@ impl<'a> Iterator for StatementSplitter<'a> { { // If we are just ending the braced section continue as normal if error.is_none() { - error = Some(StatementError::InvalidCharacter( - character as char, - self.read, - )) + error = Some(StatementError::InvalidCharacter(character as char, self.read)) } } b'\'' if !self.flags.contains(Flags::DQUOTE) => { @@ -201,10 +198,8 @@ impl<'a> Iterator for StatementSplitter<'a> { b'}' if !self.flags.contains(Flags::DQUOTE) => { if self.brace_level == 0 { if error.is_none() { - error = Some(StatementError::InvalidCharacter( - character as char, - self.read, - )) + error = + Some(StatementError::InvalidCharacter(character as char, self.read)) } } else { self.brace_level -= 1; @@ -213,15 +208,9 @@ impl<'a> Iterator for StatementSplitter<'a> { b'(' if self.flags.contains(Flags::MATHEXPR) => { self.math_paren_level += 1; } - b'(' if !self - .flags - .intersects(Flags::COMM_1 | Flags::VARIAB | Flags::ARRAY) => - { + b'(' if !self.flags.intersects(Flags::COMM_1 | Flags::VARIAB | Flags::ARRAY) => { if error.is_none() && !self.flags.contains(Flags::DQUOTE) { - error = Some(StatementError::InvalidCharacter( - character as char, - self.read, - )) + error = Some(StatementError::InvalidCharacter(character as char, self.read)) } } b'(' if self.flags.intersects(Flags::COMM_1 | Flags::METHOD) => { @@ -266,10 +255,7 @@ impl<'a> Iterator for StatementSplitter<'a> { } b')' if self.paren_level == 0 => { if error.is_none() && !self.flags.contains(Flags::DQUOTE) { - error = Some(StatementError::InvalidCharacter( - character as char, - self.read, - )) + error = Some(StatementError::InvalidCharacter(character as char, self.read)) } } b')' => self.paren_level -= 1, @@ -381,9 +367,9 @@ impl<'a> Iterator for StatementSplitter<'a> { } b'|' => Some(Err(StatementError::ExpectedCommandButFound("pipe"))), b'&' => Some(Err(StatementError::ExpectedCommandButFound("&"))), - b'*' | b'%' | b'?' | b'{' | b'}' => Some(Err( - StatementError::IllegalCommandName(String::from(output)), - )), + b'*' | b'%' | b'?' | b'{' | b'}' => { + Some(Err(StatementError::IllegalCommandName(String::from(output)))) + } _ => Some(Ok(self.get_statement_from(output))), } } @@ -404,10 +390,7 @@ fn syntax_errors() { let command = ">echo"; let results = StatementSplitter::new(command).collect::<Vec<_>>(); - assert_eq!( - results[0], - Err(StatementError::ExpectedCommandButFound("redirection")) - ); + assert_eq!(results[0], Err(StatementError::ExpectedCommandButFound("redirection"))); assert_eq!(results.len(), 1); let command = "echo $((foo bar baz)"; @@ -420,14 +403,8 @@ fn syntax_errors() { fn methods() { let command = "echo $join(array, ', '); echo @join(var, ', ')"; let statements = StatementSplitter::new(command).collect::<Vec<_>>(); - assert_eq!( - statements[0], - Ok(StatementVariant::Default("echo $join(array, ', ')")) - ); - assert_eq!( - statements[1], - Ok(StatementVariant::Default("echo @join(var, ', ')")) - ); + assert_eq!(statements[0], Ok(StatementVariant::Default("echo $join(array, ', ')"))); + assert_eq!(statements[1], Ok(StatementVariant::Default("echo @join(var, ', ')"))); assert_eq!(statements.len(), 2); } @@ -443,10 +420,7 @@ fn processes() { fn array_processes() { let command = "echo @(echo one; sleep 1); echo @(echo one; sleep 1)"; for statement in StatementSplitter::new(command) { - assert_eq!( - statement, - Ok(StatementVariant::Default("echo @(echo one; sleep 1)")) - ); + assert_eq!(statement, Ok(StatementVariant::Default("echo @(echo one; sleep 1)"))); } } @@ -463,14 +437,8 @@ fn quotes() { let command = "echo \"This ;'is a test\"; echo 'This ;\" is also a test'"; let results = StatementSplitter::new(command).collect::<Vec<_>>(); assert_eq!(results.len(), 2); - assert_eq!( - results[0], - Ok(StatementVariant::Default("echo \"This ;'is a test\"")) - ); - assert_eq!( - results[1], - Ok(StatementVariant::Default("echo 'This ;\" is also a test'")) - ); + assert_eq!(results[0], Ok(StatementVariant::Default("echo \"This ;'is a test\""))); + assert_eq!(results[1], Ok(StatementVariant::Default("echo 'This ;\" is also a test'"))); } #[test] @@ -478,10 +446,7 @@ fn comments() { let command = "echo $(echo one # two); echo three # four"; let results = StatementSplitter::new(command).collect::<Vec<_>>(); assert_eq!(results.len(), 2); - assert_eq!( - results[0], - Ok(StatementVariant::Default("echo $(echo one # two)")) - ); + assert_eq!(results[0], Ok(StatementVariant::Default("echo $(echo one # two)"))); assert_eq!(results[1], Ok(StatementVariant::Default("echo three"))); } @@ -524,28 +489,12 @@ fn variants() { let command = r#"echo "Hello!"; echo "How are you doing?" && echo "I'm just an ordinary test." || echo "Helping by making sure your code works right."; echo "Have a good day!""#; let results = StatementSplitter::new(command).collect::<Vec<_>>(); assert_eq!(results.len(), 5); - assert_eq!( - results[0], - Ok(StatementVariant::Default(r#"echo "Hello!""#)) - ); - assert_eq!( - results[1], - Ok(StatementVariant::Default(r#"echo "How are you doing?""#)) - ); - assert_eq!( - results[2], - Ok(StatementVariant::And( - r#"echo "I'm just an ordinary test.""# - )) - ); + assert_eq!(results[0], Ok(StatementVariant::Default(r#"echo "Hello!""#))); + assert_eq!(results[1], Ok(StatementVariant::Default(r#"echo "How are you doing?""#))); + assert_eq!(results[2], Ok(StatementVariant::And(r#"echo "I'm just an ordinary test.""#))); assert_eq!( results[3], - Ok(StatementVariant::Or( - r#"echo "Helping by making sure your code works right.""# - )) - ); - assert_eq!( - results[4], - Ok(StatementVariant::Default(r#"echo "Have a good day!""#)) + Ok(StatementVariant::Or(r#"echo "Helping by making sure your code works right.""#)) ); + assert_eq!(results[4], Ok(StatementVariant::Default(r#"echo "Have a good day!""#))); } diff --git a/src/lib/shell/assignments.rs b/src/lib/shell/assignments.rs index d532ffce..cc2e1e90 100644 --- a/src/lib/shell/assignments.rs +++ b/src/lib/shell/assignments.rs @@ -170,10 +170,9 @@ impl VariableStore for Shell { list_vars(&self); return SUCCESS; } - LocalAction::Assign(ref keys, op, ref vals) => ( - AssignmentActions::new(keys, op, vals), - AssignmentActions::new(keys, op, vals), - ), + LocalAction::Assign(ref keys, op, ref vals) => { + (AssignmentActions::new(keys, op, vals), AssignmentActions::new(keys, op, vals)) + } }; for action in actions_step1 { match action { @@ -473,39 +472,34 @@ impl VariableStore for Shell { Some(VariableType::Str(value)) => { if let Primitive::Indexed(ref index_value, ref index_kind) = key.kind { match value_check(self, index_value, index_kind) { - Ok(VariableType::Str(ref index)) => { - match self.variables.get_mut(key.name) { - Some(VariableType::HashMap(hmap)) => { - hmap.insert( - index.clone(), - VariableType::Str(value), - ); - } - Some(VariableType::BTreeMap(bmap)) => { - bmap.insert( - index.clone(), - VariableType::Str(value), - ); - } - Some(VariableType::Array(array)) => { - let index_num = match index.parse::<usize>() { - Ok(num) => num, - Err(_) => { - eprintln!( - "ion: index variable does not contain \ - a numeric value: {}", - index - ); - return FAILURE; - } - }; - if let Some(val) = array.get_mut(index_num) { - *val = value; + Ok(VariableType::Str(ref index)) => match self + .variables + .get_mut(key.name) + { + Some(VariableType::HashMap(hmap)) => { + hmap.insert(index.clone(), VariableType::Str(value)); + } + Some(VariableType::BTreeMap(bmap)) => { + bmap.insert(index.clone(), VariableType::Str(value)); + } + Some(VariableType::Array(array)) => { + let index_num = match index.parse::<usize>() { + Ok(num) => num, + Err(_) => { + eprintln!( + "ion: index variable does not contain a \ + numeric value: {}", + index + ); + return FAILURE; } + }; + if let Some(val) = array.get_mut(index_num) { + *val = value; } - _ => (), } - } + _ => (), + }, Ok(VariableType::Array(_)) => { eprintln!("ion: index variable cannot be an array"); return FAILURE; @@ -573,13 +567,9 @@ impl Display for MathError { } fn parse_f64<F: Fn(f64, f64) -> f64>(lhs: &str, rhs: &str, operation: F) -> Result<f64, MathError> { - lhs.parse::<f64>() - .map_err(|_| MathError::LHS) - .and_then(|lhs| { - rhs.parse::<f64>() - .map_err(|_| MathError::RHS) - .map(|rhs| operation(lhs, rhs)) - }) + lhs.parse::<f64>().map_err(|_| MathError::LHS).and_then(|lhs| { + rhs.parse::<f64>().map_err(|_| MathError::RHS).map(|rhs| operation(lhs, rhs)) + }) } fn parse_i64<F: Fn(i64, i64) -> Option<i64>>( @@ -627,11 +617,7 @@ fn math<'a, F: FnMut(&[u8])>( match operator { Operator::Add => { if Primitive::Any == *key || Primitive::Float == *key { - writefn( - parse_f64(lhs, value, |lhs, rhs| lhs + rhs)? - .to_string() - .as_bytes(), - ); + writefn(parse_f64(lhs, value, |lhs, rhs| lhs + rhs)?.to_string().as_bytes()); } else if let Primitive::Integer = key { write_integer(parse_i64(lhs, value, |lhs, rhs| Some(lhs + rhs))?, writefn); } else { @@ -640,11 +626,7 @@ fn math<'a, F: FnMut(&[u8])>( } Operator::Divide => { if Primitive::Any == *key || Primitive::Float == *key || Primitive::Integer == *key { - writefn( - parse_f64(lhs, value, |lhs, rhs| lhs / rhs)? - .to_string() - .as_bytes(), - ); + writefn(parse_f64(lhs, value, |lhs, rhs| lhs / rhs)?.to_string().as_bytes()); } else { return Err(MathError::Unsupported); } @@ -668,11 +650,7 @@ fn math<'a, F: FnMut(&[u8])>( } Operator::Subtract => { if Primitive::Any == *key || Primitive::Float == *key { - writefn( - parse_f64(lhs, value, |lhs, rhs| lhs - rhs)? - .to_string() - .as_bytes(), - ); + writefn(parse_f64(lhs, value, |lhs, rhs| lhs - rhs)?.to_string().as_bytes()); } else if let Primitive::Integer = key { write_integer(parse_i64(lhs, value, |lhs, rhs| Some(lhs - rhs))?, writefn); } else { @@ -681,11 +659,7 @@ fn math<'a, F: FnMut(&[u8])>( } Operator::Multiply => { if Primitive::Any == *key || Primitive::Float == *key { - writefn( - parse_f64(lhs, value, |lhs, rhs| lhs * rhs)? - .to_string() - .as_bytes(), - ); + writefn(parse_f64(lhs, value, |lhs, rhs| lhs * rhs)?.to_string().as_bytes()); } else if let Primitive::Integer = key { write_integer(parse_i64(lhs, value, |lhs, rhs| Some(lhs * rhs))?, writefn); } else { @@ -694,11 +668,7 @@ fn math<'a, F: FnMut(&[u8])>( } Operator::Exponent => { if Primitive::Any == *key || Primitive::Float == *key { - writefn( - parse_f64(lhs, value, |lhs, rhs| lhs.powf(rhs))? - .to_string() - .as_bytes(), - ); + writefn(parse_f64(lhs, value, |lhs, rhs| lhs.powf(rhs))?.to_string().as_bytes()); } else if let Primitive::Integer = key { write_integer( parse_i64(lhs, value, |lhs, rhs| Some(lhs.pow(rhs as u32)))?, diff --git a/src/lib/shell/binary/mod.rs b/src/lib/shell/binary/mod.rs index eb1bf75f..41370c47 100644 --- a/src/lib/shell/binary/mod.rs +++ b/src/lib/shell/binary/mod.rs @@ -95,25 +95,19 @@ impl Binary for Shell { let mut context = Context::new(); context.word_divider_fn = Box::new(word_divide); if "1" == self.get_str_or_empty("HISTFILE_ENABLED") { - let path = self - .get::<types::Str>("HISTFILE") - .expect("shell didn't set HISTFILE"); + let path = self.get::<types::Str>("HISTFILE").expect("shell didn't set HISTFILE"); if !Path::new(path.as_str()).exists() { eprintln!("ion: creating history file at \"{}\"", path); } - let _ = context - .history - .set_file_name_and_load_history(path.as_str()); + let _ = context.history.set_file_name_and_load_history(path.as_str()); } context }); self.evaluate_init_file(); - self.variables.set( - "args", - iter::once(env::args().next().unwrap().into()).collect::<types::Array>(), - ); + self.variables + .set("args", iter::once(env::args().next().unwrap().into()).collect::<types::Array>()); loop { if let Some(command) = self.readln() { @@ -235,10 +229,5 @@ where fn word_divide(buf: &Buffer) -> Vec<(usize, usize)> { // -> impl Iterator<Item = (usize, usize)> + 'a - WordDivide { - iter: buf.chars().cloned().enumerate(), - count: 0, - word_start: None, - } - .collect() // TODO: return iterator directly :D + WordDivide { iter: buf.chars().cloned().enumerate(), count: 0, word_start: None }.collect() // TODO: return iterator directly :D } diff --git a/src/lib/shell/binary/prompt.rs b/src/lib/shell/binary/prompt.rs index 918679ab..f8e1023b 100644 --- a/src/lib/shell/binary/prompt.rs +++ b/src/lib/shell/binary/prompt.rs @@ -4,12 +4,8 @@ use std::{io::Read, process}; use sys; pub(crate) fn prompt(shell: &mut Shell) -> String { - let blocks = shell.flow_control.block.len() - + if shell.flags & UNTERMINATED != 0 { - 1 - } else { - 0 - }; + let blocks = + shell.flow_control.block.len() + if shell.flags & UNTERMINATED != 0 { 1 } else { 0 }; if blocks == 0 { match prompt_fn(shell) { diff --git a/src/lib/shell/binary/terminate.rs b/src/lib/shell/binary/terminate.rs index 0b2900c3..6e527253 100644 --- a/src/lib/shell/binary/terminate.rs +++ b/src/lib/shell/binary/terminate.rs @@ -20,10 +20,7 @@ pub(crate) fn terminate_script_quotes<I: Iterator<Item = String>>( if shell.flow_control.unclosed_block() { let open_block = shell.flow_control.block.last().unwrap(); - eprintln!( - "ion: unexpected end of script: expected end block for `{}`", - open_block.short(), - ); + eprintln!("ion: unexpected end of script: expected end block for `{}`", open_block.short(),); return FAILURE; } diff --git a/src/lib/shell/colors.rs b/src/lib/shell/colors.rs index 176fa775..f7cde1c9 100644 --- a/src/lib/shell/colors.rs +++ b/src/lib/shell/colors.rs @@ -6,10 +6,7 @@ struct StaticMap { impl StaticMap { fn get(&self, key: &str) -> Option<&'static str> { - self.keys - .binary_search(&key) - .ok() - .map(|pos| unsafe { *self.values.get_unchecked(pos) }) + self.keys.binary_search(&key).ok().map(|pos| unsafe { *self.values.get_unchecked(pos) }) } } @@ -204,18 +201,10 @@ impl Colors { /// transformation into ANSI code parameters, which may be obtained by calling the /// `into_string()` method on the newly-created `Colors` structure. pub(crate) fn collect(input: &str) -> Colors { - let mut colors = Colors { - foreground: None, - background: None, - attributes: None, - }; + let mut colors = Colors { foreground: None, background: None, attributes: None }; for variable in input.split(',') { if variable == "reset" { - return Colors { - foreground: None, - background: None, - attributes: Some(vec!["0"]), - }; + return Colors { foreground: None, background: None, attributes: Some(vec!["0"]) }; } else if let Some(attribute) = ATTRIBUTES.get(&variable) { colors.append_attribute(attribute); } else if let Some(color) = COLORS.get(&variable) { @@ -259,11 +248,8 @@ mod test { #[test] fn set_multiple_color_attributes() { - let expected = Colors { - attributes: Some(vec!["1", "4", "5"]), - background: None, - foreground: None, - }; + let expected = + Colors { attributes: Some(vec!["1", "4", "5"]), background: None, foreground: None }; let actual = Colors::collect("bold,underlined,blink"); assert_eq!(actual, expected); assert_eq!(Some("\x1b[1;4;5m".to_owned()), actual.into_string()); @@ -290,10 +276,7 @@ mod test { }; let actual = Colors::collect("0x4b,0x4dbg"); assert_eq!(actual, expected); - assert_eq!( - Some("\x1b[38;5;75;48;5;77m".to_owned()), - actual.into_string() - ) + assert_eq!(Some("\x1b[38;5;75;48;5;77m".to_owned()), actual.into_string()) } #[test] @@ -305,10 +288,7 @@ mod test { }; let actual = Colors::collect("78bg,32"); assert_eq!(actual, expected); - assert_eq!( - Some("\x1b[38;5;32;48;5;78m".to_owned()), - actual.into_string() - ) + assert_eq!(Some("\x1b[38;5;32;48;5;78m".to_owned()), actual.into_string()) } #[test] @@ -320,10 +300,7 @@ mod test { }; let actual = Colors::collect("0x000,0xFFFbg"); assert_eq!(expected, actual); - assert_eq!( - Some("\x1b[38;2;0;0;0;48;2;255;255;255m".to_owned()), - actual.into_string() - ); + assert_eq!(Some("\x1b[38;2;0;0;0;48;2;255;255;255m".to_owned()), actual.into_string()); } #[test] diff --git a/src/lib/shell/completer.rs b/src/lib/shell/completer.rs index c2bf3a93..ea4cee21 100644 --- a/src/lib/shell/completer.rs +++ b/src/lib/shell/completer.rs @@ -26,11 +26,7 @@ impl IonFileCompleter { dir_stack: *const DirectoryStack, vars: *const Variables, ) -> IonFileCompleter { - IonFileCompleter { - inner: FilenameCompleter::new(path), - dir_stack, - vars, - } + IonFileCompleter { inner: FilenameCompleter::new(path), dir_stack, vars } } } @@ -137,10 +133,8 @@ where let string = unsafe { &str::from_utf8_unchecked(&string) }; let globs = glob(string).ok().and_then(|completions| { - let mut completions = completions - .filter_map(Result::ok) - .map(|x| x.to_string_lossy().into_owned()) - .peekable(); + let mut completions = + completions.filter_map(Result::ok).map(|x| x.to_string_lossy().into_owned()).peekable(); if completions.peek().is_some() { Some(completions) @@ -156,11 +150,8 @@ where // Use Liner::Completer as well, to preserve the previous behaviour // around single-directory completions - iter_inner_glob.flat_map(move |path| { - liner_complete(&path) - .into_iter() - .map(|x| escape(x.as_str())) - }) + iter_inner_glob + .flat_map(move |path| liner_complete(&path).into_iter().map(|x| escape(x.as_str()))) } /// A completer that combines suggestions from multiple completers. @@ -211,16 +202,10 @@ mod tests { &Variables::default(), ); assert_eq!(completer.completions("testing"), vec!["testing/"]); - assert_eq!( - completer.completions("testing/file"), - vec!["testing/file_with_text"] - ); + assert_eq!(completer.completions("testing/file"), vec!["testing/file_with_text"]); assert_eq!(completer.completions("~"), vec!["~/"]); - assert_eq!( - completer.completions("tes/fil"), - vec!["testing/file_with_text"] - ); + assert_eq!(completer.completions("tes/fil"), vec!["testing/file_with_text"]); } } diff --git a/src/lib/shell/directory_stack.rs b/src/lib/shell/directory_stack.rs index 2d43c6d7..e64ae506 100644 --- a/src/lib/shell/directory_stack.rs +++ b/src/lib/shell/directory_stack.rs @@ -76,10 +76,7 @@ impl DirectoryStack { caller: &str, ) -> Result<(), Cow<'static, str>> { let dir = self.dirs.get(index).ok_or_else(|| { - Cow::Owned(format!( - "ion: {}: {}: directory stack out of range", - caller, index - )) + Cow::Owned(format!("ion: {}: {}: directory stack out of range", caller, index)) })?; set_current_dir_ion(dir) @@ -153,11 +150,8 @@ impl DirectoryStack { None => return FAILURE, }; } else { - let folder: fn(String, Cow<str>) -> String = if dirs_args & MULTILINE > 0 { - |x, y| x + "\n" + &y - } else { - |x, y| x + " " + &y - }; + let folder: fn(String, Cow<str>) -> String = + if dirs_args & MULTILINE > 0 { |x, y| x + "\n" + &y } else { |x, y| x + " " + &y }; let first = match iter.next() { Some(x) => x.to_string(), @@ -228,9 +222,7 @@ impl DirectoryStack { Err(Cow::Borrowed("ion: failed to get home directory")), |home| { home.to_str().map_or( - Err(Cow::Borrowed( - "ion: failed to convert home directory to str", - )), + Err(Cow::Borrowed("ion: failed to convert home directory to str")), |home| self.change_and_push_dir(home, variables), ) }, @@ -395,10 +387,7 @@ impl DirectoryStack { /// variable, /// else it will return a default value of 1000. fn get_size(variables: &Variables) -> usize { - variables - .get_str_or_empty("DIRECTORY_STACK_SIZE") - .parse::<usize>() - .unwrap_or(1000) + variables.get_str_or_empty("DIRECTORY_STACK_SIZE").parse::<usize>().unwrap_or(1000) } /// Create a new `DirectoryStack` containing the current working directory, @@ -433,10 +422,5 @@ fn parse_numeric_arg(arg: &str) -> Option<(bool, usize)> { // converts pbuf to an absolute path if possible fn try_abs_path(pbuf: &PathBuf) -> Cow<str> { - Cow::Owned( - pbuf.canonicalize() - .unwrap_or_else(|_| pbuf.clone()) - .to_string_lossy() - .to_string(), - ) + Cow::Owned(pbuf.canonicalize().unwrap_or_else(|_| pbuf.clone()).to_string_lossy().to_string()) } diff --git a/src/lib/shell/flow.rs b/src/lib/shell/flow.rs index 14261b34..b9d0c4de 100644 --- a/src/lib/shell/flow.rs +++ b/src/lib/shell/flow.rs @@ -94,9 +94,7 @@ impl FlowLogic for Shell { } // Try to execute else_if branches - let else_if_conditions = else_if - .into_iter() - .map(|cond| (cond.expression, cond.success)); + let else_if_conditions = else_if.into_iter().map(|cond| (cond.expression, cond.success)); for (condition, statements) in else_if_conditions { if let Condition::SigInt = self.execute_statements(condition) { @@ -119,10 +117,7 @@ impl FlowLogic for Shell { ) -> Condition { macro_rules! set_vars_then_exec { ($chunk:expr, $def:expr) => { - for (key, value) in variables - .iter() - .zip($chunk.chain(::std::iter::repeat($def))) - { + for (key, value) in variables.iter().zip($chunk.chain(::std::iter::repeat($def))) { if key != "_" { self.set(key, value.clone()); } @@ -194,45 +189,27 @@ impl FlowLogic for Shell { self.previous_status = self.export(action); self.variables.set("?", self.previous_status.to_string()); } - Statement::While { - expression, - statements, - } => { + Statement::While { expression, statements } => { if let Condition::SigInt = self.execute_while(expression, statements) { return Condition::SigInt; } } - Statement::For { - variables, - values, - statements, - } => { + Statement::For { variables, values, statements } => { if let Condition::SigInt = self.execute_for(&variables, &values, statements) { return Condition::SigInt; } } - Statement::If { - expression, - success, - else_if, - failure, - .. - } => match self.execute_if(expression, success, else_if, failure) { - Condition::Break => return Condition::Break, - Condition::Continue => return Condition::Continue, - Condition::NoOp => (), - Condition::SigInt => return Condition::SigInt, - }, - Statement::Function { - name, - args, - statements, - description, - } => { - self.variables.set( - &name, - Function::new(description, name.clone(), args, statements), - ); + Statement::If { expression, success, else_if, failure, .. } => { + match self.execute_if(expression, success, else_if, failure) { + Condition::Break => return Condition::Break, + Condition::Continue => return Condition::Continue, + Condition::NoOp => (), + Condition::SigInt => return Condition::SigInt, + } + } + Statement::Function { name, args, statements, description } => { + self.variables + .set(&name, Function::new(description, name.clone(), args, statements)); } Statement::Pipeline(pipeline) => match expand_pipeline(&self, pipeline) { Ok((mut pipeline, statements)) => { @@ -389,16 +366,12 @@ impl FlowLogic for Shell { let mut previous_bind = None; if let Some(ref bind) = case.binding { if is_array { - previous_bind = self - .variables - .get::<types::Array>(bind) - .map(VariableType::Array); + previous_bind = + self.variables.get::<types::Array>(bind).map(VariableType::Array); self.variables.set(&bind, value.clone()); } else { - previous_bind = self - .variables - .get::<types::Str>(bind) - .map(VariableType::Str); + previous_bind = + self.variables.get::<types::Str>(bind).map(VariableType::Str); self.set(&bind, value.join(" ")); } } @@ -435,16 +408,12 @@ impl FlowLogic for Shell { let mut previous_bind = None; if let Some(ref bind) = case.binding { if is_array { - previous_bind = self - .variables - .get::<types::Array>(bind) - .map(VariableType::Array); + previous_bind = + self.variables.get::<types::Array>(bind).map(VariableType::Array); self.variables.set(&bind, value.clone()); } else { - previous_bind = self - .variables - .get::<types::Str>(bind) - .map(VariableType::Str); + previous_bind = + self.variables.get::<types::Str>(bind).map(VariableType::Str); self.set(&bind, value.join(" ")); } } @@ -517,13 +486,9 @@ fn expand_pipeline( let mut statements = Vec::new(); while let Some(item) = item_iter.next() { - let possible_alias = shell - .variables - .get::<types::Alias>(item.job.command.as_ref()); + let possible_alias = shell.variables.get::<types::Alias>(item.job.command.as_ref()); if let Some(alias) = possible_alias { - statements = StatementSplitter::new(alias.0.as_str()) - .map(parse_and_validate) - .collect(); + statements = StatementSplitter::new(alias.0.as_str()).map(parse_and_validate).collect(); // First item in the alias should be a pipeline item, otherwise it cannot // be placed into a pipeline! diff --git a/src/lib/shell/flow_control.rs b/src/lib/shell/flow_control.rs index b941c64a..e114555c 100644 --- a/src/lib/shell/flow_control.rs +++ b/src/lib/shell/flow_control.rs @@ -161,11 +161,7 @@ impl FlowControl { } impl Default for FlowControl { - fn default() -> FlowControl { - FlowControl { - block: Vec::with_capacity(5), - } - } + fn default() -> FlowControl { FlowControl { block: Vec::with_capacity(5) } } } pub(crate) fn insert_statement( @@ -249,10 +245,7 @@ pub(crate) fn insert_statement( } _ => pushed = false, }, - Statement::While { - ref mut expression, - ref statements, - } => { + Statement::While { ref mut expression, ref statements } => { if statements.is_empty() { expression.push(statement.clone()); } else { @@ -307,20 +300,14 @@ fn insert_into_block(block: &mut Vec<Statement>, statement: Statement) -> Result }; match block { - Statement::Function { - ref mut statements, .. - } => statements.push(statement), - Statement::For { - ref mut statements, .. - } => statements.push(statement), - Statement::While { - ref mut statements, .. - } => statements.push(statement), + Statement::Function { ref mut statements, .. } => statements.push(statement), + Statement::For { ref mut statements, .. } => statements.push(statement), + Statement::While { ref mut statements, .. } => statements.push(statement), Statement::Match { ref mut cases, .. } => match statement { Statement::Case(case) => cases.push(case), _ => { return Err( - "ion: error: statement found outside of Case { .. } block in Match { .. }", + "ion: error: statement found outside of Case { .. } block in Match { .. }" ); } }, @@ -445,12 +432,7 @@ impl Function { args: Vec<KeyBuf>, statements: Vec<Statement>, ) -> Function { - Function { - description, - name, - args, - statements, - } + Function { description, name, args, statements } } } @@ -459,10 +441,7 @@ mod tests { use super::*; fn new_match() -> Statement { - Statement::Match { - expression: small::String::from(""), - cases: Vec::new(), - } + Statement::Match { expression: small::String::from(""), cases: Vec::new() } } fn new_if() -> Statement { Statement::If { @@ -550,12 +529,7 @@ mod tests { assert_eq!(Ok(Some(ok)), res); } - let errs = vec![ - Statement::Else, - Statement::End, - Statement::Break, - Statement::Continue, - ]; + let errs = vec![Statement::Else, Statement::End, Statement::Break, Statement::Continue]; for err in errs { let res = insert_statement(&mut flow_control, err); if res.is_ok() { diff --git a/src/lib/shell/history.rs b/src/lib/shell/history.rs index 2ce118e8..7f39d003 100644 --- a/src/lib/shell/history.rs +++ b/src/lib/shell/history.rs @@ -33,10 +33,7 @@ pub(crate) struct IgnoreSetting { impl IgnoreSetting { pub(crate) fn default() -> IgnoreSetting { - IgnoreSetting { - flags: IgnoreFlags::empty(), - regexes: None, - } + IgnoreSetting { flags: IgnoreFlags::empty(), regexes: None } } } @@ -87,31 +84,19 @@ impl ShellHistory for Shell { } self.ignore_setting.flags = flags; - self.ignore_setting.regexes = if !regexes.is_empty() { - Some(regexes) - } else { - None - } + self.ignore_setting.regexes = if !regexes.is_empty() { Some(regexes) } else { None } } fn save_command_in_history(&mut self, command: &str) { if self.should_save_command(command) { if self.variables.get_str_or_empty("HISTORY_TIMESTAMP") == "1" { // Get current time stamp - let since_unix_epoch = SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap() - .as_secs(); + let since_unix_epoch = + SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(); let cur_time_sys = ["#", &since_unix_epoch.to_owned().to_string()].concat(); // Push current time to history - if let Err(err) = self - .context - .as_mut() - .unwrap() - .history - .push(cur_time_sys.into()) - { + if let Err(err) = self.context.as_mut().unwrap().history.push(cur_time_sys.into()) { eprintln!("ion: {}", err) } } diff --git a/src/lib/shell/job.rs b/src/lib/shell/job.rs index e5891d5f..7ba29f7b 100644 --- a/src/lib/shell/job.rs +++ b/src/lib/shell/job.rs @@ -34,12 +34,7 @@ impl Job { pub(crate) fn new(args: types::Array, kind: JobKind) -> Self { let command = args[0].clone(); let builtin = BUILTINS.get(command.as_ref()).map(|b| b.main); - Job { - command, - args, - kind, - builtin, - } + Job { command, args, kind, builtin } } } @@ -80,20 +75,11 @@ pub struct RefinedJob { pub enum JobVariant { /// An external program that is executed by this shell - External { - name: types::Str, - args: types::Array, - }, + External { name: types::Str, args: types::Array }, /// A procedure embedded into Ion - Builtin { - main: BuiltinFunction, - args: types::Array, - }, + Builtin { main: BuiltinFunction, args: types::Array }, /// Functions can act as commands too! - Function { - name: types::Str, - args: types::Array, - }, + Function { name: types::Str, args: types::Array }, /// Represents redirection into stdin from more than one source Cat { sources: Vec<File> }, Tee { @@ -229,19 +215,12 @@ impl RefinedJob { stdin: None, stdout: None, stderr: None, - var: JobVariant::Tee { - items: (tee_out, tee_err), - }, + var: JobVariant::Tee { items: (tee_out, tee_err) }, } } pub(crate) fn cat(sources: Vec<File>) -> Self { - RefinedJob { - stdin: None, - stdout: None, - stderr: None, - var: JobVariant::Cat { sources }, - } + RefinedJob { stdin: None, stdout: None, stderr: None, var: JobVariant::Cat { sources } } } pub(crate) fn function(name: types::Str, args: types::Array) -> Self { diff --git a/src/lib/shell/mod.rs b/src/lib/shell/mod.rs index a79ba0d8..58b8fdec 100644 --- a/src/lib/shell/mod.rs +++ b/src/lib/shell/mod.rs @@ -199,15 +199,12 @@ impl Shell { name: &str, args: &[S], ) -> Result<i32, IonError> { - self.variables - .get::<Function>(name) - .ok_or(IonError::DoesNotExist) - .and_then(|function| { - function - .execute(self, args) - .map(|_| self.previous_status) - .map_err(|err| IonError::Function { why: err }) - }) + self.variables.get::<Function>(name).ok_or(IonError::DoesNotExist).and_then(|function| { + function + .execute(self, args) + .map(|_| self.previous_status) + .map_err(|err| IonError::Function { why: err }) + }) } /// A method for executing scripts in the Ion shell without capturing. Given a `Path`, this @@ -281,9 +278,8 @@ impl Shell { Some(self.execute_pipeline(pipeline)) } // Branch else if -> input == shell function and set the exit_status - } else if let Some(function) = self - .variables - .get::<Function>(&pipeline.items[0].job.command) + } else if let Some(function) = + self.variables.get::<Function>(&pipeline.items[0].job.command) { if !pipeline.requires_piping() { let args = pipeline.items[0].job.args.deref(); @@ -416,9 +412,7 @@ impl<'a> Expander for Shell { /// Uses a subshell to expand a given command. fn command(&self, command: &str) -> Option<types::Str> { let mut output = None; - match self.fork(Capture::StdoutThenIgnoreStderr, move |shell| { - shell.on_command(command) - }) { + match self.fork(Capture::StdoutThenIgnoreStderr, move |shell| shell.on_command(command)) { Ok(result) => { let mut string = String::with_capacity(1024); match result.stdout.unwrap().read_to_string(&mut string) { @@ -446,8 +440,7 @@ impl<'a> Expander for Shell { } else if quoted { self.get::<types::Str>(name) } else { - self.get::<types::Str>(name) - .map(|x| x.ascii_replace('\n', ' ')) + self.get::<types::Str>(name).map(|x| x.ascii_replace('\n', ' ')) } } diff --git a/src/lib/shell/pipe_exec/foreground.rs b/src/lib/shell/pipe_exec/foreground.rs index ea7dc969..451b2348 100644 --- a/src/lib/shell/pipe_exec/foreground.rs +++ b/src/lib/shell/pipe_exec/foreground.rs @@ -34,9 +34,7 @@ impl ForegroundSignals { if reply & ERRORED != 0 { Some(BackgroundResult::Errored) } else if reply & REPLIED != 0 { - Some(BackgroundResult::Status( - self.status.load(Ordering::SeqCst) as u8 - )) + Some(BackgroundResult::Status(self.status.load(Ordering::SeqCst) as u8)) } else { None } diff --git a/src/lib/shell/pipe_exec/job_control.rs b/src/lib/shell/pipe_exec/job_control.rs index 7b8aea40..016d9cca 100644 --- a/src/lib/shell/pipe_exec/job_control.rs +++ b/src/lib/shell/pipe_exec/job_control.rs @@ -59,17 +59,10 @@ pub(crate) fn add_to_background( command: String, ) -> u32 { let mut processes = processes.lock().unwrap(); - match (*processes) - .iter() - .position(|x| x.state == ProcessState::Empty) - { + match (*processes).iter().position(|x| x.state == ProcessState::Empty) { Some(id) => { - (*processes)[id] = BackgroundProcess { - pid, - ignore_sighup: false, - state, - name: command, - }; + (*processes)[id] = + BackgroundProcess { pid, ignore_sighup: false, state, name: command }; id as u32 } None => { diff --git a/src/lib/shell/pipe_exec/mod.rs b/src/lib/shell/pipe_exec/mod.rs index efe71b42..8f4a7103 100644 --- a/src/lib/shell/pipe_exec/mod.rs +++ b/src/lib/shell/pipe_exec/mod.rs @@ -164,10 +164,7 @@ fn do_redirection( macro_rules! set_one_tee { ($new:ident, $outputs:ident, $job:ident, $kind:ident, $teed:ident, $other:ident) => {{ - let mut tee = TeeItem { - sinks: Vec::new(), - source: None, - }; + let mut tee = TeeItem { sinks: Vec::new(), source: None }; for output in $outputs { match if output.append { OpenOptions::new() @@ -231,10 +228,7 @@ fn do_redirection( (0, _) => {} (1, JobKind::Pipe(_)) => { let sources = vec![inputs[0].get_infile()?]; - new_commands.push(( - RefinedJob::cat(sources), - JobKind::Pipe(RedirectFrom::Stdout), - )); + new_commands.push((RefinedJob::cat(sources), JobKind::Pipe(RedirectFrom::Stdout))); } (1, _) => job.stdin(inputs[0].get_infile()?), _ => { @@ -246,10 +240,7 @@ fn do_redirection( return None; }); } - new_commands.push(( - RefinedJob::cat(sources), - JobKind::Pipe(RedirectFrom::Stdout), - )); + new_commands.push((RefinedJob::cat(sources), JobKind::Pipe(RedirectFrom::Stdout))); } } prev_kind = kind; @@ -269,14 +260,8 @@ fn do_redirection( (true, false) => set_one_tee!(new_commands, outputs, job, kind, Stdout, Stderr), // tee both (true, true) => { - let mut tee_out = TeeItem { - sinks: Vec::new(), - source: None, - }; - let mut tee_err = TeeItem { - sinks: Vec::new(), - source: None, - }; + let mut tee_out = TeeItem { sinks: Vec::new(), source: None }; + let mut tee_err = TeeItem { sinks: Vec::new(), source: None }; for output in outputs { match if output.append { OpenOptions::new() @@ -424,21 +409,9 @@ impl PipelineExecution for Shell { let result = sys::fork_and_exec( name, args, - if let Some(ref f) = *stdin { - Some(f.as_raw_fd()) - } else { - None - }, - if let Some(ref f) = *stdout { - Some(f.as_raw_fd()) - } else { - None - }, - if let Some(ref f) = *stderr { - Some(f.as_raw_fd()) - } else { - None - }, + if let Some(ref f) = *stdin { Some(f.as_raw_fd()) } else { None }, + if let Some(ref f) = *stdout { Some(f.as_raw_fd()) } else { None }, + if let Some(ref f) = *stderr { Some(f.as_raw_fd()) } else { None }, false, || prepare_child(true, 0), ); @@ -616,10 +589,7 @@ impl PipelineExecution for Shell { return code; } - eprintln!( - "ion: failed to `dup` STDOUT, STDIN, or STDERR: not running '{}'", - long - ); + eprintln!("ion: failed to `dup` STDOUT, STDIN, or STDERR: not running '{}'", long); COULD_NOT_EXEC } @@ -632,11 +602,7 @@ impl PipelineExecution for Shell { // This doesn't allocate String::new() } else { - commands - .iter() - .map(RefinedJob::long) - .collect::<Vec<String>>() - .join(" | ") + commands.iter().map(RefinedJob::long).collect::<Vec<String>>().join(" | ") }; // Watch the foreground group, dropping all commands that exit as they exit. @@ -649,22 +615,14 @@ impl PipelineExecution for Shell { ) -> Result<SmallVec<[RefinedItem; 16]>, i32> { let mut results: SmallVec<[RefinedItem; 16]> = SmallVec::new(); for item in pipeline.items.drain(..) { - let PipeItem { - mut job, - outputs, - inputs, - } = item; + let PipeItem { mut job, outputs, inputs } = item; let refined = { if is_implicit_cd(&job.args[0]) { RefinedJob::builtin( builtins::builtin_cd, iter::once("cd".into()).chain(job.args.drain()).collect(), ) - } else if self - .variables - .get::<Function>(job.args[0].as_str()) - .is_some() - { + } else if self.variables.get::<Function>(job.args[0].as_str()).is_some() { RefinedJob::function(job.args[0].clone(), job.args.drain().collect()) } else if let Some(builtin) = job.builtin { RefinedJob::builtin(builtin, job.args.drain().collect()) @@ -706,11 +664,7 @@ impl PipelineExecution for Shell { self, piped_commands, command_name, - if disown { - ProcessState::Empty - } else { - ProcessState::Running - }, + if disown { ProcessState::Empty } else { ProcessState::Running }, ), None => { // While active, the SIGTTOU signal will be ignored. @@ -754,11 +708,8 @@ pub(crate) fn pipe( // If parent is a RefindJob::External, then we need to keep track of the // output pipes, so we can properly close them after the job has been // spawned. - let is_external = if let JobVariant::External { .. } = parent.var { - true - } else { - false - }; + let is_external = + if let JobVariant::External { .. } = parent.var { true } else { false }; // TODO: Refactor this part // If we need to tee both stdout and stderr, we directly connect pipes to @@ -881,10 +832,7 @@ fn spawn_proc( let stdout = &mut cmd.stdout; let stderr = &mut cmd.stderr; match cmd.var { - JobVariant::External { - ref mut name, - ref mut args, - } => { + JobVariant::External { ref mut name, ref mut args } => { let args: Vec<&str> = args.iter().skip(1).map(|x| x as &str).collect(); let mut result = sys::fork_and_exec( name, @@ -923,10 +871,7 @@ fn spawn_proc( |stdout, stderr, stdin| shell.exec_builtin(main, args, stdout, stderr, stdin), ); } - JobVariant::Function { - ref mut name, - ref mut args, - } => { + JobVariant::Function { ref mut name, ref mut args } => { fork_exec_internal( stdout, stderr, @@ -1052,7 +997,5 @@ pub fn pipe_fail(why: io::Error) { } pub fn append_external_stdio_pipe(pipes: &mut Option<Vec<File>>, file: RawFd) { - pipes - .get_or_insert_with(|| Vec::with_capacity(4)) - .push(unsafe { File::from_raw_fd(file) }); + pipes.get_or_insert_with(|| Vec::with_capacity(4)).push(unsafe { File::from_raw_fd(file) }); } diff --git a/src/lib/shell/pipe_exec/pipes.rs b/src/lib/shell/pipe_exec/pipes.rs index 2506cbc2..fecc3a8f 100644 --- a/src/lib/shell/pipe_exec/pipes.rs +++ b/src/lib/shell/pipe_exec/pipes.rs @@ -18,11 +18,7 @@ impl<'a> TeePipe<'a> { ext_stdio_pipes: &'a mut Option<Vec<File>>, is_external: bool, ) -> TeePipe<'a> { - TeePipe { - parent, - ext_stdio_pipes, - is_external, - } + TeePipe { parent, ext_stdio_pipes, is_external } } fn inner_connect<F>(&mut self, tee: &mut TeeItem, mut action: F) diff --git a/src/lib/shell/pipe_exec/streams.rs b/src/lib/shell/pipe_exec/streams.rs index c820ab12..43a16795 100644 --- a/src/lib/shell/pipe_exec/streams.rs +++ b/src/lib/shell/pipe_exec/streams.rs @@ -17,9 +17,7 @@ pub(crate) fn redir(old: RawFd, new: RawFd) { /// when dropped. pub(crate) fn duplicate_streams() -> io::Result<(Option<File>, File, File)> { // STDIN may have been closed for a background shell, so it is ok if it cannot be duplicated. - let stdin = sys::dup(sys::STDIN_FILENO) - .ok() - .map(|fd| unsafe { File::from_raw_fd(fd) }); + let stdin = sys::dup(sys::STDIN_FILENO).ok().map(|fd| unsafe { File::from_raw_fd(fd) }); sys::dup(sys::STDOUT_FILENO) .map(|fd| unsafe { File::from_raw_fd(fd) }) diff --git a/src/lib/shell/variables/mod.rs b/src/lib/shell/variables/mod.rs index 5b8d8526..c038f34b 100644 --- a/src/lib/shell/variables/mod.rs +++ b/src/lib/shell/variables/mod.rs @@ -175,10 +175,7 @@ pub struct Variables { impl Default for Variables { fn default() -> Self { let mut map: HashMap<types::Str, VariableType> = HashMap::with_capacity(64); - map.insert( - "DIRECTORY_STACK_SIZE".into(), - VariableType::Str("1000".into()), - ); + map.insert("DIRECTORY_STACK_SIZE".into(), VariableType::Str("1000".into())); map.insert("HISTORY_SIZE".into(), VariableType::Str("1000".into())); map.insert("HISTFILE_SIZE".into(), VariableType::Str("100000".into())); map.insert( @@ -202,11 +199,7 @@ impl Default for Variables { ); map.insert( "EUID".into(), - VariableType::Str( - geteuid() - .ok() - .map_or("?".into(), |id| id.to_string().into()), - ), + VariableType::Str(geteuid().ok().map_or("?".into(), |id| id.to_string().into())), ); // Initialize the HISTFILE variable @@ -235,19 +228,9 @@ impl Default for Variables { ); // Initialize the HOST variable - env::set_var( - "HOST", - &self_sys::get_host_name().unwrap_or_else(|| "?".to_owned()), - ); + env::set_var("HOST", &self_sys::get_host_name().unwrap_or_else(|| "?".to_owned())); - Variables { - flags: 0, - scopes: vec![Scope { - vars: map, - namespace: false, - }], - current: 0, - } + Variables { flags: 0, scopes: vec![Scope { vars: map, namespace: false }], current: 0 } } } @@ -255,10 +238,7 @@ impl Variables { pub fn new_scope(&mut self, namespace: bool) { self.current += 1; if self.current >= self.scopes.len() { - self.scopes.push(Scope { - vars: HashMap::with_capacity(64), - namespace, - }); + self.scopes.push(Scope { vars: HashMap::with_capacity(64), namespace }); } else { self.scopes[self.current].namespace = namespace; } @@ -488,19 +468,16 @@ impl Variables { } } } - Some(("env", variable)) => env::var(variable) - .map(Into::into) - .ok() - .map(|s| T::from(VariableType::Str(s))), + Some(("env", variable)) => { + env::var(variable).map(Into::into).ok().map(|s| T::from(VariableType::Str(s))) + } Some(("super", _)) | Some(("global", _)) | None => { // Otherwise, it's just a simple variable name. match self.get_ref(name) { Some(VariableType::Str(val)) => { Some(T::from(VariableType::Str(val.clone()))) } - _ => env::var(name) - .ok() - .map(|s| T::from(VariableType::Str(s.into()))), + _ => env::var(name).ok().map(|s| T::from(VariableType::Str(s.into()))), } } Some((..)) => { @@ -683,10 +660,7 @@ impl Variables { // Temporarily borrow the `swd` variable while we attempt to assemble a minimal // variant of the directory path. If that is not possible, we will cancel the // borrow and return `swd` itself as the minified path. - let elements = swd - .split('/') - .filter(|s| !s.is_empty()) - .collect::<Vec<&str>>(); + let elements = swd.split('/').filter(|s| !s.is_empty()).collect::<Vec<&str>>(); if elements.len() > 2 { let mut output = types::Str::new(); for element in &elements[..elements.len() - 1] { diff --git a/src/main.rs b/src/main.rs index 541e1981..4bf8830c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -37,10 +37,7 @@ fn main() { "-h" | "--help" => { let stdout = stdout(); let mut stdout = stdout.lock(); - match stdout - .write_all(MAN_ION.as_bytes()) - .and_then(|_| stdout.flush()) - { + match stdout.write_all(MAN_ION.as_bytes()).and_then(|_| stdout.flush()) { Ok(_) => return, Err(err) => panic!("{}", err.description().to_owned()), } -- GitLab