mirror of
https://github.com/nushell/nushell.git
synced 2025-03-26 07:19:55 +01:00
str plugin can capitalize and trim strings. (#1652)
* Str plugin can capitalize. * Str plugin can trim.
This commit is contained in:
parent
716c4def03
commit
10768b6ecf
@ -15,9 +15,11 @@ impl Plugin for Str {
|
|||||||
fn config(&mut self) -> Result<Signature, ShellError> {
|
fn config(&mut self) -> Result<Signature, ShellError> {
|
||||||
Ok(Signature::build("str")
|
Ok(Signature::build("str")
|
||||||
.desc("Apply string function. Optional use the column of a table")
|
.desc("Apply string function. Optional use the column of a table")
|
||||||
|
.switch("capitalize", "capitalizes the string", Some('c'))
|
||||||
.switch("downcase", "convert string to lowercase", Some('d'))
|
.switch("downcase", "convert string to lowercase", Some('d'))
|
||||||
.switch("upcase", "convert string to uppercase", Some('U'))
|
.switch("upcase", "convert string to uppercase", Some('U'))
|
||||||
.switch("to-int", "convert string to integer", Some('i'))
|
.switch("to-int", "convert string to integer", Some('i'))
|
||||||
|
.switch("trim", "trims the string", Some('t'))
|
||||||
.named(
|
.named(
|
||||||
"replace",
|
"replace",
|
||||||
SyntaxShape::String,
|
SyntaxShape::String,
|
||||||
@ -49,6 +51,12 @@ impl Plugin for Str {
|
|||||||
fn begin_filter(&mut self, call_info: CallInfo) -> Result<Vec<ReturnValue>, ShellError> {
|
fn begin_filter(&mut self, call_info: CallInfo) -> Result<Vec<ReturnValue>, ShellError> {
|
||||||
let args = call_info.args;
|
let args = call_info.args;
|
||||||
|
|
||||||
|
if args.has("trim") {
|
||||||
|
self.for_trim();
|
||||||
|
}
|
||||||
|
if args.has("capitalize") {
|
||||||
|
self.for_capitalize();
|
||||||
|
}
|
||||||
if args.has("downcase") {
|
if args.has("downcase") {
|
||||||
self.for_downcase();
|
self.for_downcase();
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,20 @@ mod integration {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn picks_up_trim_flag() {
|
||||||
|
plugin(&mut Str::new())
|
||||||
|
.args(CallStub::new().with_long_flag("trim").create())
|
||||||
|
.setup(|plugin, _| plugin.expect_action(Action::Trim));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn picks_up_capitalize_flag() {
|
||||||
|
plugin(&mut Str::new())
|
||||||
|
.args(CallStub::new().with_long_flag("capitalize").create())
|
||||||
|
.setup(|plugin, _| plugin.expect_action(Action::Capitalize));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn picks_up_downcase_flag() {
|
fn picks_up_downcase_flag() {
|
||||||
plugin(&mut Str::new())
|
plugin(&mut Str::new())
|
||||||
@ -169,6 +183,44 @@ mod integration {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn trims_the_input_using_the_field_passed_as_parameter() -> Result<(), ShellError> {
|
||||||
|
let run = plugin(&mut Str::new())
|
||||||
|
.args(
|
||||||
|
CallStub::new()
|
||||||
|
.with_long_flag("trim")
|
||||||
|
.with_parameter("name")?
|
||||||
|
.create(),
|
||||||
|
)
|
||||||
|
.input(structured_sample_record("name", "andres "))
|
||||||
|
.setup(|_, _| {})
|
||||||
|
.test();
|
||||||
|
|
||||||
|
let actual = expect_return_value_at(run, 0);
|
||||||
|
|
||||||
|
assert_eq!(get_data(actual, "name"), string("andres"));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn capitalizes_the_input_using_the_field_passed_as_parameter() -> Result<(), ShellError> {
|
||||||
|
let run = plugin(&mut Str::new())
|
||||||
|
.args(
|
||||||
|
CallStub::new()
|
||||||
|
.with_long_flag("capitalize")
|
||||||
|
.with_parameter("name")?
|
||||||
|
.create(),
|
||||||
|
)
|
||||||
|
.input(structured_sample_record("name", "andres"))
|
||||||
|
.setup(|_, _| {})
|
||||||
|
.test();
|
||||||
|
|
||||||
|
let actual = expect_return_value_at(run, 0);
|
||||||
|
|
||||||
|
assert_eq!(get_data(actual, "name"), string("Andres"));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn downcases_the_input_using_the_field_passed_as_parameter() -> Result<(), ShellError> {
|
fn downcases_the_input_using_the_field_passed_as_parameter() -> Result<(), ShellError> {
|
||||||
let run = plugin(&mut Str::new())
|
let run = plugin(&mut Str::new())
|
||||||
@ -261,6 +313,30 @@ mod integration {
|
|||||||
assert_eq!(actual, string("JOANDREHUDA"));
|
assert_eq!(actual, string("JOANDREHUDA"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn trims_the_input() {
|
||||||
|
let run = plugin(&mut Str::new())
|
||||||
|
.args(CallStub::new().with_long_flag("trim").create())
|
||||||
|
.input(unstructured_sample_record("andres "))
|
||||||
|
.setup(|_, _| {})
|
||||||
|
.test();
|
||||||
|
|
||||||
|
let actual = expect_return_value_at(run, 0);
|
||||||
|
assert_eq!(actual, string("andres"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn capitalizes_the_input() {
|
||||||
|
let run = plugin(&mut Str::new())
|
||||||
|
.args(CallStub::new().with_long_flag("capitalize").create())
|
||||||
|
.input(unstructured_sample_record("andres"))
|
||||||
|
.setup(|_, _| {})
|
||||||
|
.test();
|
||||||
|
|
||||||
|
let actual = expect_return_value_at(run, 0);
|
||||||
|
assert_eq!(actual, string("Andres"));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn downcases_the_input() {
|
fn downcases_the_input() {
|
||||||
let run = plugin(&mut Str::new())
|
let run = plugin(&mut Str::new())
|
||||||
|
@ -10,12 +10,14 @@ use std::cmp;
|
|||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub enum Action {
|
pub enum Action {
|
||||||
|
Capitalize,
|
||||||
Downcase,
|
Downcase,
|
||||||
Upcase,
|
Upcase,
|
||||||
ToInteger,
|
ToInteger,
|
||||||
Substring(usize, usize),
|
Substring(usize, usize),
|
||||||
Replace(ReplaceAction),
|
Replace(ReplaceAction),
|
||||||
ToDateTime(String),
|
ToDateTime(String),
|
||||||
|
Trim,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
@ -38,6 +40,22 @@ impl Str {
|
|||||||
|
|
||||||
fn apply(&self, input: &str) -> Result<UntaggedValue, ShellError> {
|
fn apply(&self, input: &str) -> Result<UntaggedValue, ShellError> {
|
||||||
let applied = match self.action.as_ref() {
|
let applied = match self.action.as_ref() {
|
||||||
|
Some(Action::Trim) => UntaggedValue::string(input.trim()),
|
||||||
|
Some(Action::Capitalize) => {
|
||||||
|
let mut capitalized = String::new();
|
||||||
|
|
||||||
|
for (idx, character) in input.chars().enumerate() {
|
||||||
|
let out = if idx == 0 {
|
||||||
|
character.to_uppercase().to_string()
|
||||||
|
} else {
|
||||||
|
character.to_lowercase().to_string()
|
||||||
|
};
|
||||||
|
|
||||||
|
capitalized.push_str(&out);
|
||||||
|
}
|
||||||
|
|
||||||
|
UntaggedValue::string(capitalized)
|
||||||
|
}
|
||||||
Some(Action::Downcase) => UntaggedValue::string(input.to_ascii_lowercase()),
|
Some(Action::Downcase) => UntaggedValue::string(input.to_ascii_lowercase()),
|
||||||
Some(Action::Upcase) => UntaggedValue::string(input.to_ascii_uppercase()),
|
Some(Action::Upcase) => UntaggedValue::string(input.to_ascii_uppercase()),
|
||||||
Some(Action::Substring(s, e)) => {
|
Some(Action::Substring(s, e)) => {
|
||||||
@ -101,6 +119,14 @@ impl Str {
|
|||||||
self.add_action(Action::ToInteger);
|
self.add_action(Action::ToInteger);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn for_capitalize(&mut self) {
|
||||||
|
self.add_action(Action::Capitalize);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn for_trim(&mut self) {
|
||||||
|
self.add_action(Action::Trim);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn for_downcase(&mut self) {
|
pub fn for_downcase(&mut self) {
|
||||||
self.add_action(Action::Downcase);
|
self.add_action(Action::Downcase);
|
||||||
}
|
}
|
||||||
@ -151,7 +177,7 @@ impl Str {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn usage() -> &'static str {
|
pub fn usage() -> &'static str {
|
||||||
"Usage: str field [--downcase|--upcase|--to-int|--substring \"start,end\"|--replace|--find-replace [pattern replacement]]]"
|
"Usage: str field [--capitalize|--downcase|--upcase|--to-int|--substring \"start,end\"|--replace|--find-replace [pattern replacement]|to-date-time|--trim]"
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn strutils(&self, value: Value) -> Result<Value, ShellError> {
|
pub fn strutils(&self, value: Value) -> Result<Value, ShellError> {
|
||||||
@ -216,6 +242,22 @@ pub mod tests {
|
|||||||
use super::Str;
|
use super::Str;
|
||||||
use nu_plugin::test_helpers::value::{int, string};
|
use nu_plugin::test_helpers::value::{int, string};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn trim() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let mut strutils = Str::new();
|
||||||
|
strutils.for_trim();
|
||||||
|
assert_eq!(strutils.apply("andres ")?, string("andres").value);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn capitalize() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let mut strutils = Str::new();
|
||||||
|
strutils.for_capitalize();
|
||||||
|
assert_eq!(strutils.apply("andres")?, string("Andres").value);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn downcases() -> Result<(), Box<dyn std::error::Error>> {
|
fn downcases() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let mut strutils = Str::new();
|
let mut strutils = Str::new();
|
||||||
|
@ -47,4 +47,18 @@ Consumes either a single value or a table and converts the provided data to a st
|
|||||||
─────────
|
─────────
|
||||||
6
|
6
|
||||||
━━━━━━━━━
|
━━━━━━━━━
|
||||||
```
|
|
||||||
|
> echo "nu" | str --capitalize
|
||||||
|
━━━━━━━━━
|
||||||
|
<value>
|
||||||
|
─────────
|
||||||
|
Nu
|
||||||
|
━━━━━━━━━
|
||||||
|
|
||||||
|
> echo "Nu " | str --trim
|
||||||
|
━━━━━━━━━
|
||||||
|
<value>
|
||||||
|
─────────
|
||||||
|
Nu
|
||||||
|
━━━━━━━━━
|
||||||
|
```
|
@ -9,7 +9,7 @@ fn can_only_apply_one() {
|
|||||||
"open caco3_plastics.csv | first 1 | str origin --downcase --upcase"
|
"open caco3_plastics.csv | first 1 | str origin --downcase --upcase"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert!(actual.contains(r#"--downcase|--upcase|--to-int|--substring "start,end"|--replace|--find-replace [pattern replacement]]"#));
|
assert!(actual.contains(r#"--capitalize|--downcase|--upcase|--to-int|--substring "start,end"|--replace|--find-replace [pattern replacement]|to-date-time|--trim]"#));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -34,8 +34,48 @@ fn acts_without_passing_field() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn downcases() {
|
fn trims() {
|
||||||
Playground::setup("plugin_str_test_2", |dirs, sandbox| {
|
Playground::setup("plugin_str_test_2", |dirs, sandbox| {
|
||||||
|
sandbox.with_files(vec![FileWithContent(
|
||||||
|
"sample.toml",
|
||||||
|
r#"
|
||||||
|
[dependency]
|
||||||
|
name = "nu "
|
||||||
|
"#,
|
||||||
|
)]);
|
||||||
|
|
||||||
|
let actual = nu!(
|
||||||
|
cwd: dirs.test(),
|
||||||
|
"open sample.toml | str dependency.name --trim | get dependency.name | echo $it"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(actual, "nu");
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn capitalizes() {
|
||||||
|
Playground::setup("plugin_str_test_3", |dirs, sandbox| {
|
||||||
|
sandbox.with_files(vec![FileWithContent(
|
||||||
|
"sample.toml",
|
||||||
|
r#"
|
||||||
|
[dependency]
|
||||||
|
name = "nu"
|
||||||
|
"#,
|
||||||
|
)]);
|
||||||
|
|
||||||
|
let actual = nu!(
|
||||||
|
cwd: dirs.test(),
|
||||||
|
"open sample.toml | str dependency.name --capitalize | get dependency.name | echo $it"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(actual, "Nu");
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn downcases() {
|
||||||
|
Playground::setup("plugin_str_test_4", |dirs, sandbox| {
|
||||||
sandbox.with_files(vec![FileWithContent(
|
sandbox.with_files(vec![FileWithContent(
|
||||||
"sample.toml",
|
"sample.toml",
|
||||||
r#"
|
r#"
|
||||||
@ -55,7 +95,7 @@ fn downcases() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn upcases() {
|
fn upcases() {
|
||||||
Playground::setup("plugin_str_test_3", |dirs, sandbox| {
|
Playground::setup("plugin_str_test_5", |dirs, sandbox| {
|
||||||
sandbox.with_files(vec![FileWithContent(
|
sandbox.with_files(vec![FileWithContent(
|
||||||
"sample.toml",
|
"sample.toml",
|
||||||
r#"
|
r#"
|
||||||
@ -93,7 +133,7 @@ fn converts_to_int() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn replaces() {
|
fn replaces() {
|
||||||
Playground::setup("plugin_str_test_4", |dirs, sandbox| {
|
Playground::setup("plugin_str_test_5", |dirs, sandbox| {
|
||||||
sandbox.with_files(vec![FileWithContent(
|
sandbox.with_files(vec![FileWithContent(
|
||||||
"sample.toml",
|
"sample.toml",
|
||||||
r#"
|
r#"
|
||||||
@ -118,7 +158,7 @@ fn replaces() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn find_and_replaces() {
|
fn find_and_replaces() {
|
||||||
Playground::setup("plugin_str_test_5", |dirs, sandbox| {
|
Playground::setup("plugin_str_test_6", |dirs, sandbox| {
|
||||||
sandbox.with_files(vec![FileWithContent(
|
sandbox.with_files(vec![FileWithContent(
|
||||||
"sample.toml",
|
"sample.toml",
|
||||||
r#"
|
r#"
|
||||||
@ -143,7 +183,7 @@ fn find_and_replaces() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn find_and_replaces_without_passing_field() {
|
fn find_and_replaces_without_passing_field() {
|
||||||
Playground::setup("plugin_str_test_6", |dirs, sandbox| {
|
Playground::setup("plugin_str_test_7", |dirs, sandbox| {
|
||||||
sandbox.with_files(vec![FileWithContent(
|
sandbox.with_files(vec![FileWithContent(
|
||||||
"sample.toml",
|
"sample.toml",
|
||||||
r#"
|
r#"
|
||||||
|
Loading…
Reference in New Issue
Block a user