1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
use super::operate; use crate::prelude::*; use nu_engine::WholeStreamCommand; use nu_errors::ShellError; use nu_protocol::{Signature, SyntaxShape, Value}; pub struct SubCommand; impl WholeStreamCommand for SubCommand { fn name(&self) -> &str { "str trim" } fn signature(&self) -> Signature { Signature::build("str trim") .rest( SyntaxShape::ColumnPath, "optionally trim text by column paths", ) .named( "char", SyntaxShape::String, "character to trim (default: whitespace)", Some('c'), ) } fn usage(&self) -> &str { "trims text" } fn run_with_actions(&self, args: CommandArgs) -> Result<ActionStream, ShellError> { operate(args, &trim) } fn examples(&self) -> Vec<Example> { vec![ Example { description: "Trim whitespace", example: "echo 'Nu shell ' | str trim", result: Some(vec![Value::from("Nu shell")]), }, Example { description: "Trim a specific character", example: "echo '=== Nu shell ===' | str trim -c '=' | str trim", result: Some(vec![Value::from("Nu shell")]), }, ] } } fn trim(s: &str, char_: Option<char>) -> String { match char_ { None => String::from(s.trim()), Some(ch) => String::from(s.trim_matches(ch)), } } #[cfg(test)] mod tests { use super::ShellError; use super::{trim, SubCommand}; use crate::commands::strings::str_::trim::{action, ActionMode}; use nu_protocol::row; use nu_source::Tag; use nu_test_support::value::{int, string, table}; #[test] fn examples_work_as_expected() -> Result<(), ShellError> { use crate::examples::test as test_examples; test_examples(SubCommand {}) } #[test] fn trims() { let word = string("andres "); let expected = string("andres"); let actual = action(&word, Tag::unknown(), None, &trim, ActionMode::Local).unwrap(); assert_eq!(actual, expected); } #[test] fn trims_global() { let word = string(" global "); let expected = string("global"); let actual = action(&word, Tag::unknown(), None, &trim, ActionMode::Global).unwrap(); assert_eq!(actual, expected); } #[test] fn global_trim_ignores_numbers() { let number = int(2020); let expected = int(2020); let actual = action(&number, Tag::unknown(), None, &trim, ActionMode::Global).unwrap(); assert_eq!(actual, expected); } #[test] fn global_trim_row() { let row = row!["a".to_string() => string(" c "), " b ".to_string() => string(" d ")]; let expected = row!["a".to_string() => string("c"), " b ".to_string() => string("d")]; let actual = action(&row, Tag::unknown(), None, &trim, ActionMode::Global).unwrap(); assert_eq!(actual, expected); } #[test] fn global_trim_table() { let row = table(&[string(" a "), int(65), string(" d")]); let expected = table(&[string("a"), int(65), string("d")]); let actual = action(&row, Tag::unknown(), None, &trim, ActionMode::Global).unwrap(); assert_eq!(actual, expected); } #[test] fn trims_custom_character_both_ends() { let word = string("!#andres#!"); let expected = string("#andres#"); let actual = action(&word, Tag::unknown(), Some('!'), &trim, ActionMode::Local).unwrap(); assert_eq!(actual, expected); } }