lines command

This commit is contained in:
Fernando Herrera 2021-09-23 20:03:08 +01:00
parent 36c32e9832
commit 772f8598dd
3 changed files with 88 additions and 1 deletions

View file

@ -7,7 +7,7 @@ use nu_protocol::{
use crate::{
where_::Where, Alias, Benchmark, BuildString, Def, Do, Each, External, For, Git, GitCheckout,
If, Length, Let, LetEnv, ListGitBranches, Ls, Table,
If, Length, Let, LetEnv, Lines, ListGitBranches, Ls, Table,
};
pub fn create_default_context() -> Rc<RefCell<EngineState>> {
@ -50,6 +50,8 @@ pub fn create_default_context() -> Rc<RefCell<EngineState>> {
working_set.add_decl(Box::new(External));
working_set.add_decl(Box::new(Lines));
// This is a WIP proof of concept
working_set.add_decl(Box::new(ListGitBranches));
working_set.add_decl(Box::new(Git));

View file

@ -12,6 +12,7 @@ mod if_;
mod length;
mod let_;
mod let_env;
mod lines;
mod list_git_branches;
mod ls;
mod run_external;
@ -32,6 +33,7 @@ pub use if_::If;
pub use length::Length;
pub use let_::Let;
pub use let_env::LetEnv;
pub use lines::Lines;
pub use list_git_branches::ListGitBranches;
pub use ls::Ls;
pub use run_external::External;

View file

@ -0,0 +1,83 @@
use std::cell::RefCell;
use std::rc::Rc;
use nu_protocol::ast::Call;
use nu_protocol::engine::{Command, EvaluationContext};
use nu_protocol::{Signature, Span, Value, ValueStream};
pub struct Lines;
const SPLIT_CHAR: char = '\n';
impl Command for Lines {
fn name(&self) -> &str {
"lines"
}
fn usage(&self) -> &str {
"Converts input to lines"
}
fn signature(&self) -> nu_protocol::Signature {
Signature::build("lines")
}
fn run(
&self,
_context: &EvaluationContext,
_call: &Call,
input: Value,
) -> Result<nu_protocol::Value, nu_protocol::ShellError> {
let value = match input {
Value::String { val, span } => {
let iter = val
.split(SPLIT_CHAR)
.map(|s| Value::String {
val: s.into(),
span,
})
.collect::<Vec<Value>>(); // <----- how to avoid collecting?
Value::Stream {
stream: ValueStream(Rc::new(RefCell::new(iter.into_iter()))),
span: Span::unknown(),
}
}
Value::Stream { stream, span: _ } => {
let iter = stream
.into_iter()
.filter_map(|value| {
if let Value::String { val, span } = value {
let inner = val
.split(SPLIT_CHAR)
.filter_map(|s| {
if !s.is_empty() {
Some(Value::String {
val: s.into(),
span,
})
} else {
None
}
})
.collect::<Vec<Value>>();
Some(inner)
} else {
None
}
})
.flatten()
.collect::<Vec<Value>>(); // <----- how to avoid collecting?
Value::Stream {
stream: ValueStream(Rc::new(RefCell::new(iter.into_iter()))),
span: Span::unknown(),
}
}
_ => unimplemented!(),
};
Ok(value)
}
}