From c4805eaa48b977a137610351b7b593d186a2bc4e Mon Sep 17 00:00:00 2001
From: Grant Cooksey <cooksey.grant@gmail.com>
Date: Sat, 1 Sep 2018 13:20:09 +0000
Subject: [PATCH] Trim methods for strings #802

---
 examples/methods.ion                          |  8 ++
 examples/methods.out                          |  6 ++
 .../shell_expand/words/methods/strings.rs     | 92 +++++++++++++++++++
 3 files changed, 106 insertions(+)

diff --git a/examples/methods.ion b/examples/methods.ion
index 1c628347..be868a2d 100644
--- a/examples/methods.ion
+++ b/examples/methods.ion
@@ -46,3 +46,11 @@ echo $regex_replace("one two onemy anemy town", "\ o|\ a" "\ e")
 
 echo $unescape('one two\"\tone')
 echo $escape("'one two'")
+
+let spacey = "  Spacey "
+echo $trim(" So Space  ")!
+echo $trim($spacey)!
+echo $trim_right(" So Space  ")!
+echo $trim_right($spacey)!
+echo $trim_left(" So Space  ")!
+echo $trim_left($spacey)!
diff --git a/examples/methods.out b/examples/methods.out
index 030f7746..af19529f 100644
--- a/examples/methods.out
+++ b/examples/methods.out
@@ -72,3 +72,9 @@ sauce
 one two enemy enemy town
 one two"	one
 \'one two\'
+So Space!
+Spacey!
+ So Space!
+  Spacey!
+So Space  !
+Spacey !
diff --git a/src/lib/parser/shell_expand/words/methods/strings.rs b/src/lib/parser/shell_expand/words/methods/strings.rs
index f2e38ac9..09c4a64b 100644
--- a/src/lib/parser/shell_expand/words/methods/strings.rs
+++ b/src/lib/parser/shell_expand/words/methods/strings.rs
@@ -165,6 +165,18 @@ impl<'a> StringMethod<'a> {
             "parent" => path_eval!(parent),
             "to_lowercase" => string_case!(to_lowercase),
             "to_uppercase" => string_case!(to_uppercase),
+            "trim" => {
+                let word = get_var!();
+                output.push_str(word.trim());
+            },
+            "trim_right" => {
+                let word = get_var!();
+                output.push_str(word.trim_right());
+            },
+            "trim_left" => {
+                let word = get_var!();
+                output.push_str(word.trim_left());
+            },
             "repeat" => match pattern.join(" ").parse::<usize>() {
                 Ok(repeat) => output.push_str(&get_var!().repeat(repeat)),
                 Err(_) => {
@@ -350,6 +362,7 @@ mod test {
         fn string(&self, variable: &str, _: bool) -> Option<types::Str> {
             match variable {
                 "FOO" => Some("FOOBAR".into()),
+                "BAZ" => Some("  BARBAZ   ".into()),
                 "EMPTY" => Some("".into()),
                 _ => None,
             }
@@ -526,6 +539,85 @@ mod test {
         assert_eq!(&*output, "FORD PREFECT");
     }
 
+
+    #[test]
+    fn test_trim_with_string() {
+        let mut output = small::String::new();
+        let method = StringMethod {
+            method:    "trim",
+            variable:  "\"  Foo Bar \"",
+            pattern:   "",
+            selection: Select::All,
+        };
+        method.handle(&mut output, &VariableExpander);
+        assert_eq!(&*output, "Foo Bar");
+    }
+
+    #[test]
+    fn test_trim_with_variable() {
+        let mut output = small::String::new();
+        let method = StringMethod {
+            method:    "trim",
+            variable:  "$BAZ",
+            pattern:   "",
+            selection: Select::All,
+        };
+        method.handle(&mut output, &VariableExpander);
+        assert_eq!(&*output, "BARBAZ");
+    }
+
+    #[test]
+    fn test_trim_right_with_string() {
+        let mut output = small::String::new();
+        let method = StringMethod {
+            method:    "trim_right",
+            variable:  "\"  Foo Bar \"",
+            pattern:   "",
+            selection: Select::All,
+        };
+        method.handle(&mut output, &VariableExpander);
+        assert_eq!(&*output, "  Foo Bar");
+    }
+
+    #[test]
+    fn test_trim_right_with_variable() {
+        let mut output = small::String::new();
+        let method = StringMethod {
+            method:    "trim_right",
+            variable:  "$BAZ",
+            pattern:   "",
+            selection: Select::All,
+        };
+        method.handle(&mut output, &VariableExpander);
+        assert_eq!(&*output, "  BARBAZ");
+    }
+
+    #[test]
+    fn test_trim_left_with_string() {
+        let mut output = small::String::new();
+        let method = StringMethod {
+            method:    "trim_left",
+            variable:  "\"  Foo Bar \"",
+            pattern:   "",
+            selection: Select::All,
+        };
+        method.handle(&mut output, &VariableExpander);
+        assert_eq!(&*output, "Foo Bar ");
+    }
+
+    #[test]
+    fn test_trim_left_with_variable() {
+        let mut output = small::String::new();
+        let method = StringMethod {
+            method:    "trim_left",
+            variable:  "$BAZ",
+            pattern:   "",
+            selection: Select::All,
+        };
+        method.handle(&mut output, &VariableExpander);
+        assert_eq!(&*output, "BARBAZ   ");
+    }
+
     #[test]
     fn test_repeat_succeeding() {
         let mut output = small::String::new();
-- 
GitLab