├── .travis.yml ├── LICENSE ├── blank.go ├── README.md └── blank_test.go /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | sudo: false 3 | go: 4 | - tip 5 | before_install: 6 | - go get github.com/mattn/goveralls 7 | script: 8 | - $GOPATH/bin/goveralls -service=travis-ci -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Henry Sarabia 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /blank.go: -------------------------------------------------------------------------------- 1 | package blank 2 | 3 | import ( 4 | "unicode" 5 | ) 6 | 7 | // Remove returns the provided string with all whitespace removed. 8 | // This includes spaces, tabs, newlines, returns, form feeds and other 9 | // space-like characters. 10 | // 11 | // For more information on what is considered whitespace, visit: 12 | // https://golang.org/pkg/unicode/#IsSpace 13 | func Remove(str string) string { 14 | var out []rune 15 | for _, r := range str { 16 | if !unicode.IsSpace(r) { 17 | out = append(out, r) 18 | } 19 | } 20 | 21 | return string(out) 22 | } 23 | 24 | // Is returns true if the provided string is empty or consists only of 25 | // whitespace. Returns false otherwise. 26 | func Is(str string) bool { 27 | if Remove(str) == "" { 28 | return true 29 | } 30 | 31 | return false 32 | } 33 | 34 | // Has returns true if any of the strings in the provided slice is empty 35 | // or consists of only whitespace. If the slice is nil, returns true as well. 36 | // Returns false otherwise. 37 | func Has(slice []string) bool { 38 | if len(slice) <= 0 { 39 | return true 40 | } 41 | 42 | for _, s := range slice { 43 | if Is(s) { 44 | return true 45 | } 46 | } 47 | 48 | return false 49 | } 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # blank 2 | 3 | [![GoDoc](https://godoc.org/github.com/Henry-Sarabia/blank?status.svg)](https://godoc.org/github.com/Henry-Sarabia/blank) 4 | [![Build Status](https://travis-ci.com/Henry-Sarabia/blank.svg?branch=master)](https://travis-ci.com/Henry-Sarabia/blank) 5 | [![Go Report Card](https://goreportcard.com/badge/github.com/Henry-Sarabia/blank)](https://goreportcard.com/report/github.com/Henry-Sarabia/blank) 6 | [![Coverage Status](https://coveralls.io/repos/github/Henry-Sarabia/blank/badge.svg?branch=master)](https://coveralls.io/github/Henry-Sarabia/blank?branch=master) 7 | 8 | The **Blank** package offers two main functionalities. 9 | 10 | **Blank** can remove whitespace from a string. 11 | The package defines whitepsace as a character that is not typically visible. 12 | These characters range anywhere from the ordinary space to a less common vertical tab. 13 | 14 | **Blank** can check if a string is blank. 15 | The package considers a string to be blank if it is comprised solely of whitespace. 16 | 17 | 18 | ## Installation 19 | 20 | If you do not have Go installed yet, you can find installation instructions 21 | [here](https://golang.org/doc/install). 22 | 23 | To pull the most recent version of **Blank**, use `go get`. 24 | 25 | ``` 26 | go get -u github.com/Henry-Sarabia/blank 27 | ``` 28 | 29 | Then import the package into your project. 30 | 31 | ```go 32 | import "github.com/Henry-Sarabia/blank" 33 | ``` 34 | 35 | ## Usage 36 | 37 | ### Whitespace Removal 38 | 39 | The package considers whitespace to be any character that is not typically visible. 40 | The most common of these characters are: space, tab, newline, return, formfeed, nonbreaking space, and vertical tab. 41 | For more information, visit the [unicode package](https://golang.org/pkg/unicode/#IsSpace) and the [unicode seperator category](http://www.fileformat.info/info/unicode/category/Zs/list.htm). 42 | 43 | To remove the whitespace from a string, use the `Remove` function. 44 | 45 | ```go 46 | phrase := "this is a phrase" 47 | 48 | str := blank.Remove(phrase) 49 | 50 | fmt.Println(str) 51 | // output: "thisisaphrase" 52 | ``` 53 | 54 | ### Blank Detection 55 | 56 | The package considers a string to be blank if it is comprised solely of whitespace. 57 | 58 | For example, assume we are creating a search function that takes a string as a search query. 59 | We want to avoid searching for blank queries. 60 | Blank queries can be detected using the `Is` function. 61 | 62 | ```go 63 | func search(qry string) error { 64 | if blank.Is(qry) { 65 | // return error 66 | } 67 | 68 | // rest of code 69 | } 70 | ``` 71 | 72 | Similarly, the `Has` function can process an entire slice of strings; it will check if any of the strings are blank. 73 | 74 | Let's slightly alter our example. 75 | Assume the search function takes a slice of strings as a list of queries. 76 | We still want to avoid seraching for blank queries. 77 | Blank queries can be detected using the `Has` function. 78 | 79 | ```go 80 | func search(qrs []string) error { 81 | if blank.Has(qrs) { 82 | // return error 83 | } 84 | 85 | // rest of code 86 | } 87 | ``` 88 | 89 | ## Contributions 90 | 91 | If you would like to contribute to this project, please adhere to the following guidelines. 92 | 93 | * Submit an issue describing the problem. 94 | * Fork the repo and add your contribution. 95 | * Add appropriate tests. 96 | * Run go fmt, go vet, and golint. 97 | * Prefer idiomatic Go over non-idiomatic code. 98 | * Follow the basic Go conventions found [here](https://github.com/golang/go/wiki/CodeReviewComments). 99 | * If in doubt, try to match your code to the current codebase. 100 | * Create a pull request with a description of your changes. 101 | 102 | I'll review pull requests as they come in and merge them if everything checks out. 103 | 104 | Any and all contributions are greatly appreciated. Thank you! -------------------------------------------------------------------------------- /blank_test.go: -------------------------------------------------------------------------------- 1 | package blank 2 | 3 | import "testing" 4 | 5 | func TestRemove(t *testing.T) { 6 | tests := []struct { 7 | name string 8 | input string 9 | want string 10 | }{ 11 | {"Empty", "", ""}, 12 | {"Space", " ", ""}, 13 | {"Nonbreaking space", "\u00a0", ""}, 14 | {"Tab", "\t", ""}, 15 | {"Vertical tab", "\v", ""}, 16 | {"Newline", "\n", ""}, 17 | {"Return", "\r", ""}, 18 | {"Mixed", " \t\n\r", ""}, 19 | {"Non-blank with space", "one two", "onetwo"}, 20 | {"Non-blank with tab", "one \t two", "onetwo"}, 21 | {"Non-blank with newline", "one\ntwo", "onetwo"}, 22 | {"Non-blank with return", "one\rtwo", "onetwo"}, 23 | {"Non-blank with mixed", "one \t\n\r two", "onetwo"}, 24 | {"Non-blank with surrounding space", " onetwo ", "onetwo"}, 25 | {"Non-blank with surrounding tab", "\t one\ttwo \t", "onetwo"}, 26 | {"Non-blank with surrounding newline", "\none\ntwo\n", "onetwo"}, 27 | {"Non-blank with surrounding return", "\rone\rtwo\r", "onetwo"}, 28 | {"Non-blank with surrounding mixed", "\t\n\r onetwo \t\n\r", "onetwo"}, 29 | } 30 | for _, test := range tests { 31 | t.Run(test.name, func(t *testing.T) { 32 | s := Remove(test.input) 33 | 34 | if s != test.want { 35 | t.Errorf("got: <%v>, want: <%v>", s, test.want) 36 | } 37 | }) 38 | } 39 | } 40 | 41 | func TestIs(t *testing.T) { 42 | tests := []struct { 43 | name string 44 | input string 45 | want bool 46 | }{ 47 | {"Empty", "", true}, 48 | {"Space", " ", true}, 49 | {"Nonbreaking space", "\u00a0", true}, 50 | {"Tab", "\t", true}, 51 | {"Vertical tab", "\v", true}, 52 | {"Newline", "\n", true}, 53 | {"Return", "\r", true}, 54 | {"Mixed", " \t\n\r\v\u00a0", true}, 55 | {"Non-blank with space", "one two", false}, 56 | {"Non-blank with nonbreaking space", "one\u00a0two", false}, 57 | {"Non-blank with tab", "one \t two", false}, 58 | {"Non-blank with vertical tab", "one \v two", false}, 59 | {"Non-blank with newline", "one\ntwo", false}, 60 | {"Non-blank with return", "one\rtwo", false}, 61 | {"Non-blank with mixed", "one \t\n\r two", false}, 62 | {"Non-blank with surrounding space", " onetwo ", false}, 63 | {"Non-blank with surrounding nonbreaking space", "\u00a0onet\u00a0wo\u00a0", false}, 64 | {"Non-blank with surrounding tab", "\tone\ttwo\t", false}, 65 | {"Non-blank with surrounding vertical tab", "\vone\vtwo\v", false}, 66 | {"Non-blank with surrounding newline", "\none\ntwo\n", false}, 67 | {"Non-blank with surrounding return", "\rone\rtwo\r", false}, 68 | {"Non-blank with surrounding mixed", "\t\n\r\v\u00a0 onetwo \t\n\r\v\u00a0", false}, 69 | } 70 | for _, test := range tests { 71 | t.Run(test.name, func(t *testing.T) { 72 | b := Is(test.input) 73 | 74 | if b != test.want { 75 | t.Errorf("got: <%v>, want: <%v>", b, test.want) 76 | } 77 | }) 78 | } 79 | } 80 | 81 | func TestHas(t *testing.T) { 82 | tests := []struct { 83 | name string 84 | input []string 85 | want bool 86 | }{ 87 | {"Empty slice", nil, true}, 88 | {"Single empty string", []string{""}, true}, 89 | {"Multiple empty strings", []string{"", "", ""}, true}, 90 | {"Single space string", []string{" "}, true}, 91 | {"Multiple space strings", []string{" ", " ", " "}, true}, 92 | {"Single nonbreaking space string", []string{"\u00a0"}, true}, 93 | {"Multiple nonbreaking space strings", []string{"\u00a0", "\u00a0", "\u00a0"}, true}, 94 | {"Single tab string", []string{"\t"}, true}, 95 | {"Multiple tab strings", []string{"\t", "\t", "\t"}, true}, 96 | {"Single vertical tab string", []string{"\v"}, true}, 97 | {"Multiple vertical tab strings", []string{"\v", "\v", "\v"}, true}, 98 | {"Single newline string", []string{"\n"}, true}, 99 | {"Multiple newline strings", []string{"\n", "\n", "\n"}, true}, 100 | {"Single return string", []string{"\r"}, true}, 101 | {"Multiple return strings", []string{"\r", "\r", "\r"}, true}, 102 | {"Single mixed string", []string{" \t\n\r"}, true}, 103 | {"Multiple mixed strings", []string{" \t\n", "\r\n", "\t\n ", "\t\n\r "}, true}, 104 | {"Non-blank with single empty string", []string{"123", ""}, true}, 105 | {"Non-blank with multiple empty strings", []string{"", "123", ""}, true}, 106 | {"Non-blank with single space string", []string{" ", "123 "}, true}, 107 | {"Non-blank with multiple space strings", []string{" ", " ", " 123"}, true}, 108 | {"Non-blank with single nonbreaking space string", []string{"\u00a0", "123\u00a0"}, true}, 109 | {"Non-blank with multiple nonbreaking space strings", []string{"\u00a0", "\u00a0", "\u00a0123"}, true}, 110 | {"Non-blank with single tab string", []string{"\t123", "\t"}, true}, 111 | {"Non-blank with multiple tab strings", []string{"\t", "\t123", "\t"}, true}, 112 | {"Non-blank with single vertical tab string", []string{"\v123", "\v"}, true}, 113 | {"Non-blank with multiple vertical tab strings", []string{"\v", "\v123", "\v"}, true}, 114 | {"Non-blank with single newline string", []string{"123\n", "\n"}, true}, 115 | {"Non-blank with multiple newline strings", []string{"\n", "\n", "\n123"}, true}, 116 | {"Non-blank with single return string", []string{"\r123", "\r"}, true}, 117 | {"Non-blank with multiple return strings", []string{"123\r", "\r", "\r"}, true}, 118 | {"Non-blank with single mixed string", []string{"\t\n\r", " \t\n 123 \r"}, true}, 119 | {"Non-blank with multiple mixed strings", []string{" 123\t\n\v", "\r\n\u00a0", "\t\n\u00a0 ", "123\t\n\r\v\u00a0 "}, true}, 120 | {"Single non-blank string", []string{"123"}, false}, 121 | {"Multiple non-blank strings", []string{"123", "456", "789"}, false}, 122 | } 123 | for _, test := range tests { 124 | t.Run(test.name, func(t *testing.T) { 125 | b := Has(test.input) 126 | 127 | if b != test.want { 128 | t.Errorf("got: <%v>, want: <%v>", b, test.want) 129 | } 130 | }) 131 | } 132 | } 133 | --------------------------------------------------------------------------------