diff --git a/README.adoc b/README.adoc index 48234d2..92899d5 100644 --- a/README.adoc +++ b/README.adoc @@ -857,8 +857,10 @@ The executable is at: /bin/just - `lowercase(s)` - Convert `s` to lowercase. - `replace(s, from, to)` - Replace all occurrences of `from` in `s` to `to`. - `trim(s)` - Remove leading and trailing whitespace from `s`. +- `trim_end(s)` - Remove trailing whitespace from `s`. - `trim_end_match(s, pat)` - Remove suffix of `s` matching `pat`. - `trim_end_matches(s, pat)` - Repeatedly remove suffixes of `s` matching `pat`. +- `trim_start(s)` - Remove leading whitespace from `s`. - `trim_start_match(s, pat)` - Remove prefix of `s` matching `pat`. - `trim_start_matches(s, pat)` - Repeatedly remove prefixes of `s` matching `pat`. - `uppercase(s)` - Convert `s` to uppercase. diff --git a/src/function.rs b/src/function.rs index 178fcc4..2e88eb5 100644 --- a/src/function.rs +++ b/src/function.rs @@ -28,8 +28,10 @@ lazy_static! { ("parent_directory", Unary(parent_directory)), ("replace", Ternary(replace)), ("trim", Unary(trim)), + ("trim_end", Unary(trim_end)), ("trim_end_match", Binary(trim_end_match)), ("trim_end_matches", Binary(trim_end_matches)), + ("trim_start", Unary(trim_start)), ("trim_start_match", Binary(trim_start_match)), ("trim_start_matches", Binary(trim_start_matches)), ("uppercase", Unary(uppercase)), @@ -201,6 +203,10 @@ fn trim(_context: &FunctionContext, s: &str) -> Result { Ok(s.trim().to_owned()) } +fn trim_end(_context: &FunctionContext, s: &str) -> Result { + Ok(s.trim_end().to_owned()) +} + fn trim_end_match(_context: &FunctionContext, s: &str, pat: &str) -> Result { Ok(s.strip_suffix(pat).unwrap_or(s).to_owned()) } @@ -209,6 +215,10 @@ fn trim_end_matches(_context: &FunctionContext, s: &str, pat: &str) -> Result Result { + Ok(s.trim_start().to_owned()) +} + fn trim_start_match(_context: &FunctionContext, s: &str, pat: &str) -> Result { Ok(s.strip_prefix(pat).unwrap_or(s).to_owned()) } diff --git a/tests/functions.rs b/tests/functions.rs index ee5a77f..8e7aff2 100644 --- a/tests/functions.rs +++ b/tests/functions.rs @@ -308,6 +308,7 @@ fn assert_eval_eq(expression: &str, result: &str) { .justfile(format!("x := {}", expression)) .args(&["--evaluate", "x"]) .stdout(result) + .unindent_stdout(false) .run(); } @@ -336,3 +337,13 @@ fn trim_start_match() { assert_eval_eq("trim_start_match('oof', 'o')", "of"); assert_eval_eq("trim_start_match('ababf', 'ab')", "abf"); } + +#[test] +fn trim_start() { + assert_eval_eq("trim_start(' f ')", "f "); +} + +#[test] +fn trim_end() { + assert_eval_eq("trim_end(' f ')", " f"); +} diff --git a/tests/test.rs b/tests/test.rs index 31cee0d..8f8d31e 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -47,6 +47,7 @@ pub(crate) struct Test { pub(crate) stdout: String, pub(crate) suppress_dotenv_load_warning: bool, pub(crate) tempdir: TempDir, + pub(crate) unindent_stdout: bool, } impl Test { @@ -68,6 +69,7 @@ impl Test { stdout: String::new(), suppress_dotenv_load_warning: true, tempdir, + unindent_stdout: true, } } @@ -147,6 +149,11 @@ impl Test { tree.instantiate(&self.tempdir.path()).unwrap(); self } + + pub(crate) fn unindent_stdout(mut self, unindent_stdout: bool) -> Self { + self.unindent_stdout = unindent_stdout; + self + } } impl Test { @@ -156,7 +163,11 @@ impl Test { fs::write(self.justfile_path(), justfile).unwrap(); } - let stdout = unindent(&self.stdout); + let stdout = if self.unindent_stdout { + unindent(&self.stdout) + } else { + self.stdout + }; let stderr = unindent(&self.stderr); let mut dotenv_path = self.tempdir.path().to_path_buf();