forked from extern/nushell
commit
91698b2657
@ -268,6 +268,7 @@ Nu adheres closely to a set of goals that make up its design philosophy. As feat
|
|||||||
| command | description |
|
| command | description |
|
||||||
| ------------- | ------------- |
|
| ------------- | ------------- |
|
||||||
| append row-data | Append a row to the end of the table |
|
| append row-data | Append a row to the end of the table |
|
||||||
|
| compact ...columns | Remove rows where given columns are empty |
|
||||||
| count | Show the total number of rows |
|
| count | Show the total number of rows |
|
||||||
| edit column-or-column-path value | Edit an existing column to have a new value |
|
| edit column-or-column-path value | Edit an existing column to have a new value |
|
||||||
| embed column | Creates a new table of one column with the given name, and places the current table inside of it |
|
| embed column | Creates a new table of one column with the given name, and places the current table inside of it |
|
||||||
@ -286,7 +287,7 @@ Nu adheres closely to a set of goals that make up its design philosophy. As feat
|
|||||||
| reject ...columns | Remove the given columns from the table |
|
| reject ...columns | Remove the given columns from the table |
|
||||||
| reverse | Reverses the table. |
|
| reverse | Reverses the table. |
|
||||||
| skip amount | Skip a number of rows |
|
| skip amount | Skip a number of rows |
|
||||||
| skip-while condition | Skips rows while the condition matches. |
|
| skip-while condition | Skips rows while the condition matches |
|
||||||
| split-by column | Creates a new table with the data from the inner tables splitted by the column given |
|
| split-by column | Creates a new table with the data from the inner tables splitted by the column given |
|
||||||
| sort-by ...columns | Sort by the given columns |
|
| sort-by ...columns | Sort by the given columns |
|
||||||
| str (column) | Apply string function. Optionally use the column of a table |
|
| str (column) | Apply string function. Optionally use the column of a table |
|
||||||
|
@ -309,6 +309,7 @@ pub async fn cli() -> Result<(), Box<dyn Error>> {
|
|||||||
per_item_command(Where),
|
per_item_command(Where),
|
||||||
per_item_command(Echo),
|
per_item_command(Echo),
|
||||||
whole_stream_command(Config),
|
whole_stream_command(Config),
|
||||||
|
whole_stream_command(Compact),
|
||||||
whole_stream_command(SkipWhile),
|
whole_stream_command(SkipWhile),
|
||||||
per_item_command(Enter),
|
per_item_command(Enter),
|
||||||
per_item_command(Help),
|
per_item_command(Help),
|
||||||
|
@ -11,6 +11,7 @@ pub(crate) mod cd;
|
|||||||
pub(crate) mod classified;
|
pub(crate) mod classified;
|
||||||
pub(crate) mod clip;
|
pub(crate) mod clip;
|
||||||
pub(crate) mod command;
|
pub(crate) mod command;
|
||||||
|
pub(crate) mod compact;
|
||||||
pub(crate) mod config;
|
pub(crate) mod config;
|
||||||
pub(crate) mod count;
|
pub(crate) mod count;
|
||||||
pub(crate) mod cp;
|
pub(crate) mod cp;
|
||||||
@ -98,6 +99,7 @@ pub(crate) use command::{
|
|||||||
|
|
||||||
pub(crate) use append::Append;
|
pub(crate) use append::Append;
|
||||||
pub(crate) use classified::ClassifiedCommand;
|
pub(crate) use classified::ClassifiedCommand;
|
||||||
|
pub(crate) use compact::Compact;
|
||||||
pub(crate) use config::Config;
|
pub(crate) use config::Config;
|
||||||
pub(crate) use count::Count;
|
pub(crate) use count::Count;
|
||||||
pub(crate) use cp::Cpy;
|
pub(crate) use cp::Cpy;
|
||||||
|
53
src/commands/compact.rs
Normal file
53
src/commands/compact.rs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
use crate::commands::WholeStreamCommand;
|
||||||
|
use crate::errors::ShellError;
|
||||||
|
use crate::parser::registry::{CommandRegistry, Signature};
|
||||||
|
use crate::prelude::*;
|
||||||
|
use futures::stream::StreamExt;
|
||||||
|
|
||||||
|
pub struct Compact;
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct CompactArgs {
|
||||||
|
rest: Vec<Tagged<String>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WholeStreamCommand for Compact {
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
"compact"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn signature(&self) -> Signature {
|
||||||
|
Signature::build("compact").rest(SyntaxShape::Any, "the columns to compact from the table")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn usage(&self) -> &str {
|
||||||
|
"Creates a table with non-empty rows"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run(
|
||||||
|
&self,
|
||||||
|
args: CommandArgs,
|
||||||
|
registry: &CommandRegistry,
|
||||||
|
) -> Result<OutputStream, ShellError> {
|
||||||
|
args.process(registry, compact)?.run()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn compact(
|
||||||
|
CompactArgs { rest: columns }: CompactArgs,
|
||||||
|
RunnableContext { input, .. }: RunnableContext,
|
||||||
|
) -> Result<OutputStream, ShellError> {
|
||||||
|
let objects = input.values.take_while(move |item| {
|
||||||
|
let keep = if columns.is_empty() {
|
||||||
|
item.is_some()
|
||||||
|
} else {
|
||||||
|
columns
|
||||||
|
.iter()
|
||||||
|
.all(|field| item.get_data(field).borrow().is_some())
|
||||||
|
};
|
||||||
|
|
||||||
|
futures::future::ready(keep)
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(objects.from_input_stream())
|
||||||
|
}
|
@ -498,6 +498,17 @@ impl Value {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn is_some(&self) -> bool {
|
||||||
|
!self.is_none()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn is_none(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
Value::Primitive(Primitive::Nothing) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn is_error(&self) -> bool {
|
pub(crate) fn is_error(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
Value::Error(_err) => true,
|
Value::Error(_err) => true,
|
||||||
|
@ -3,6 +3,54 @@ mod helpers;
|
|||||||
use helpers as h;
|
use helpers as h;
|
||||||
use helpers::{Playground, Stub::*};
|
use helpers::{Playground, Stub::*};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn compact_rows_where_given_column_is_empty() {
|
||||||
|
Playground::setup("compact_test_1", |dirs, sandbox| {
|
||||||
|
sandbox.with_files(vec![FileWithContentToBeTrimmed(
|
||||||
|
"los_tres_amigos.json",
|
||||||
|
r#"
|
||||||
|
{
|
||||||
|
"amigos": [
|
||||||
|
{"name": "Yehuda", "rusty_luck": 1},
|
||||||
|
{"name": "Jonathan", "rusty_luck": 1},
|
||||||
|
{"name": "Andres", "rusty_luck": 1},
|
||||||
|
{"name":"GorbyPuff"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)]);
|
||||||
|
|
||||||
|
let actual = nu!(
|
||||||
|
cwd: dirs.test(), h::pipeline(
|
||||||
|
r#"
|
||||||
|
open los_tres_amigos.json
|
||||||
|
| get amigos
|
||||||
|
| compact rusty_luck
|
||||||
|
| count
|
||||||
|
| echo $it
|
||||||
|
"#
|
||||||
|
));
|
||||||
|
|
||||||
|
assert_eq!(actual, "3");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn compact_empty_rows_by_default() {
|
||||||
|
Playground::setup("compact_test_2", |dirs, _| {
|
||||||
|
let actual = nu!(
|
||||||
|
cwd: dirs.test(), h::pipeline(
|
||||||
|
r#"
|
||||||
|
echo "[1,2,3,14,null]"
|
||||||
|
| from-json
|
||||||
|
| compact
|
||||||
|
| count
|
||||||
|
| echo $it
|
||||||
|
"#
|
||||||
|
));
|
||||||
|
|
||||||
|
assert_eq!(actual, "4");
|
||||||
|
});
|
||||||
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn group_by() {
|
fn group_by() {
|
||||||
Playground::setup("group_by_test_1", |dirs, sandbox| {
|
Playground::setup("group_by_test_1", |dirs, sandbox| {
|
||||||
|
Loading…
Reference in New Issue
Block a user