From ace07de2126a56c37cb257cce6b756862f6dd658 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy <mmstickman@gmail.com> Date: Thu, 12 Oct 2017 23:20:10 -0400 Subject: [PATCH] Additional words module refactoring --- .../shell_expand/words/methods/arrays.rs | 7 +- src/parser/shell_expand/words/methods/mod.rs | 70 +------------------ .../shell_expand/words/methods/strings.rs | 6 +- src/parser/shell_expand/words/mod.rs | 4 +- src/parser/shell_expand/words/select.rs | 69 ++++++++++++++++++ 5 files changed, 80 insertions(+), 76 deletions(-) create mode 100644 src/parser/shell_expand/words/select.rs diff --git a/src/parser/shell_expand/words/methods/arrays.rs b/src/parser/shell_expand/words/methods/arrays.rs index f699ae28..73baf2fa 100644 --- a/src/parser/shell_expand/words/methods/arrays.rs +++ b/src/parser/shell_expand/words/methods/arrays.rs @@ -1,8 +1,7 @@ -use super::{Pattern, Select, SelectWithSize}; +use super::Pattern; use super::pattern::unescape; -use super::super::Index; -use super::super::super::{expand_string, Expander}; -use super::super::super::is_expression; +use super::super::{Index, Select, SelectWithSize}; +use super::super::super::{expand_string, Expander, is_expression}; use smallstring::SmallString; use std::char; use std::io::{self, Write}; diff --git a/src/parser/shell_expand/words/methods/mod.rs b/src/parser/shell_expand/words/methods/mod.rs index af15a9b6..efede944 100644 --- a/src/parser/shell_expand/words/methods/mod.rs +++ b/src/parser/shell_expand/words/methods/mod.rs @@ -6,16 +6,13 @@ pub(crate) use self::arrays::ArrayMethod; pub(crate) use self::pattern::Pattern; pub(crate) use self::strings::StringMethod; -use super::{Index, Range, Expander, expand_string}; -use super::super::ranges::parse_index_range; +use super::{Expander, expand_string}; use super::super::super::ArgumentSplitter; -use std::iter::{empty, FromIterator}; -use std::str::FromStr; use self::pattern::unescape; #[derive(Debug, PartialEq, Clone)] pub(crate) struct Key { - key: ::types::Key, + pub(crate) key: ::types::Key, } impl Key { @@ -24,69 +21,6 @@ impl Key { pub(crate) fn get(&self) -> &::types::Key { return &self.key; } } -/// Represents a filter on a vector-like object -#[derive(Debug, PartialEq, Clone)] -pub(crate) enum Select { - /// Select no elements - None, - /// Select all elements - All, - /// Select a single element based on its index - Index(Index), - /// Select a range of elements - Range(Range), - /// Select an element by mapped key - Key(Key), -} - -pub(crate) trait SelectWithSize { - type Item; - fn select<O>(&mut self, Select, usize) -> O - where O: FromIterator<Self::Item>; -} - -impl<I, T> SelectWithSize for I - where I: Iterator<Item = T> -{ - type Item = T; - fn select<O>(&mut self, s: Select, size: usize) -> O - where O: FromIterator<Self::Item> - { - 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::Key(_) => empty().collect(), - } - } -} - -impl FromStr for Select { - type Err = (); - fn from_str(data: &str) -> Result<Select, ()> { - if ".." == data { - return Ok(Select::All); - } - - if let Ok(index) = data.parse::<isize>() { - return Ok(Select::Index(Index::new(index))); - } - - if let Some(range) = parse_index_range(data) { - return Ok(Select::Range(range)); - } - - Ok(Select::Key(Key { key: data.into() })) - } -} - pub(crate) struct MethodArgs<'a, 'b, E: 'b + Expander> { args: &'a str, expand: &'b E, diff --git a/src/parser/shell_expand/words/methods/strings.rs b/src/parser/shell_expand/words/methods/strings.rs index 3c19ae22..7f819677 100644 --- a/src/parser/shell_expand/words/methods/strings.rs +++ b/src/parser/shell_expand/words/methods/strings.rs @@ -1,6 +1,6 @@ -use super::{Select, MethodArgs}; -use super::super::super::{expand_string, Expander}; -use super::super::super::{is_expression, slice}; +use super::MethodArgs; +use super::super::Select; +use super::super::super::{expand_string, Expander, is_expression, slice}; use parser::assignments::is_array; use shell::plugins::methods::{self, MethodArguments, StringMethodPlugins}; use std::path::Path; diff --git a/src/parser/shell_expand/words/mod.rs b/src/parser/shell_expand/words/mod.rs index d1dc3323..2176f773 100644 --- a/src/parser/shell_expand/words/mod.rs +++ b/src/parser/shell_expand/words/mod.rs @@ -3,12 +3,14 @@ mod tests; mod index; mod methods; mod range; +mod select; pub(crate) use self::index::Index; -pub(crate) use self::methods::{ArrayMethod, Pattern, Select, StringMethod}; +pub(crate) use self::methods::{ArrayMethod, Pattern, StringMethod}; #[cfg(test)] pub(crate) use self::methods::Key; pub(crate) use self::range::Range; +pub(crate) use self::select::{Select, SelectWithSize}; use super::{expand_string, Expander}; use super::super::ArgumentSplitter; diff --git a/src/parser/shell_expand/words/select.rs b/src/parser/shell_expand/words/select.rs new file mode 100644 index 00000000..6ca210dc --- /dev/null +++ b/src/parser/shell_expand/words/select.rs @@ -0,0 +1,69 @@ +use super::super::ranges::parse_index_range; +use super::{Index, Range}; +use std::iter::{empty, FromIterator}; +use super::methods::Key; +use std::str::FromStr; + + +/// Represents a filter on a vector-like object +#[derive(Debug, PartialEq, Clone)] +pub(crate) enum Select { + /// Select no elements + None, + /// Select all elements + All, + /// Select a single element based on its index + Index(Index), + /// Select a range of elements + Range(Range), + /// Select an element by mapped key + Key(Key), +} + +pub(crate) trait SelectWithSize { + type Item; + fn select<O>(&mut self, Select, usize) -> O + where O: FromIterator<Self::Item>; +} + +impl<I, T> SelectWithSize for I + where I: Iterator<Item = T> +{ + type Item = T; + fn select<O>(&mut self, s: Select, size: usize) -> O + where O: FromIterator<Self::Item> + { + 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::Key(_) => empty().collect(), + } + } +} + +impl FromStr for Select { + type Err = (); + fn from_str(data: &str) -> Result<Select, ()> { + if ".." == data { + return Ok(Select::All); + } + + if let Ok(index) = data.parse::<isize>() { + return Ok(Select::Index(Index::new(index))); + } + + if let Some(range) = parse_index_range(data) { + return Ok(Select::Range(range)); + } + + Ok(Select::Key(Key { key: data.into() })) + } +} \ No newline at end of file -- GitLab