diff --git a/src/commands/lines.rs b/src/commands/lines.rs new file mode 100644 index 0000000000..b1db3feb2f --- /dev/null +++ b/src/commands/lines.rs @@ -0,0 +1,37 @@ +use crate::errors::ShellError; +use crate::object::{Primitive, Value}; +use crate::prelude::*; + +pub fn lines(args: CommandArgs) -> Result { + let input = args.input; + let span = args.name_span; + + let stream = input + .map(move |v| match v { + Value::Primitive(Primitive::String(s)) => { + let split_result: Vec<_> = s.lines().filter(|s| s.trim() != "").collect(); + + let mut result = VecDeque::new(); + for s in split_result { + result.push_back(ReturnValue::Value(Value::Primitive(Primitive::String( + s.to_string(), + )))); + } + result + } + _ => { + let mut result = VecDeque::new(); + result.push_back(ReturnValue::Value(Value::Error(Box::new( + ShellError::maybe_labeled_error( + "Expected string values from pipeline", + "expects strings from pipeline", + span, + ), + )))); + result + } + }) + .flatten(); + + Ok(stream.boxed()) +} diff --git a/src/commands/skip_while.rs b/src/commands/skip_while.rs new file mode 100644 index 0000000000..15cb439812 --- /dev/null +++ b/src/commands/skip_while.rs @@ -0,0 +1,51 @@ +use crate::errors::ShellError; +use crate::parser::registry::PositionalType; +use crate::parser::CommandConfig; +use crate::prelude::*; + +pub struct SkipWhile; + +impl Command for SkipWhile { + fn run(&self, args: CommandArgs) -> Result { + skip_while(args) + } + fn name(&self) -> &str { + "skip-while" + } + + fn config(&self) -> CommandConfig { + CommandConfig { + name: self.name().to_string(), + mandatory_positional: vec![PositionalType::Block("condition".to_string())], + optional_positional: vec![], + rest_positional: false, + named: indexmap::IndexMap::new(), + } + } +} + +pub fn skip_while(args: CommandArgs) -> Result { + if args.positional.len() == 0 { + return Err(ShellError::maybe_labeled_error( + "Where requires a condition", + "needs condition", + args.name_span, + )); + } + + let block = args.positional[0].as_block()?; + let input = args.input; + + let objects = input.skip_while(move |item| { + let result = block.invoke(&item); + + let return_value = match result { + Ok(v) if v.is_true() => true, + _ => false, + }; + + futures::future::ready(return_value) + }); + + Ok(objects.map(|x| ReturnValue::Value(x)).boxed()) +} \ No newline at end of file