github.com/profzone/eden-framework@v1.0.10/pkg/strings/utils.go (about)

     1  package str
     2  
     3  import (
     4  	"github.com/sirupsen/logrus"
     5  	"strings"
     6  	"unicode"
     7  	"unicode/utf8"
     8  )
     9  
    10  // https://github.com/golang/lint/blob/master/lint.go#L720
    11  var commonInitialisms = map[string]bool{
    12  	"ACL":   true,
    13  	"API":   true,
    14  	"ASCII": true,
    15  	"CPU":   true,
    16  	"CSS":   true,
    17  	"DNS":   true,
    18  	"EOF":   true,
    19  	"GUID":  true,
    20  	"HTML":  true,
    21  	"HTTP":  true,
    22  	"HTTPS": true,
    23  	"ID":    true,
    24  	"IP":    true,
    25  	"JSON":  true,
    26  	"LHS":   true,
    27  	"QPS":   true,
    28  	"RAM":   true,
    29  	"RHS":   true,
    30  	"RPC":   true,
    31  	"SLA":   true,
    32  	"SMTP":  true,
    33  	"SQL":   true,
    34  	"SSH":   true,
    35  	"TCP":   true,
    36  	"TLS":   true,
    37  	"TTL":   true,
    38  	"UDP":   true,
    39  	"UI":    true,
    40  	"UID":   true,
    41  	"UUID":  true,
    42  	"URI":   true,
    43  	"URL":   true,
    44  	"UTF8":  true,
    45  	"VM":    true,
    46  	"XML":   true,
    47  	"XMPP":  true,
    48  	"XSRF":  true,
    49  	"XSS":   true,
    50  }
    51  
    52  func SplitToWords(s string) (entries []string) {
    53  	if !utf8.ValidString(s) {
    54  		return []string{s}
    55  	}
    56  	entries = []string{}
    57  	var runes [][]rune
    58  	lastClass := 0
    59  	class := 0
    60  
    61  	// split into fields based on class of unicode character
    62  	for _, r := range s {
    63  		switch true {
    64  		case unicode.IsSpace(r):
    65  			class = 1
    66  		case unicode.IsLower(r):
    67  			class = 2
    68  		case unicode.IsUpper(r):
    69  			class = 3
    70  		case unicode.IsDigit(r):
    71  			class = 4
    72  		default:
    73  			class = 5
    74  		}
    75  		if class == lastClass {
    76  			runes[len(runes)-1] = append(runes[len(runes)-1], r)
    77  		} else {
    78  			runes = append(runes, []rune{r})
    79  		}
    80  		lastClass = class
    81  	}
    82  
    83  	// handle upper case -> lower case sequences, e.g.
    84  	// "PDFL", "oader" -> "PDF", "Loader"
    85  	for i := 0; i < len(runes)-1; i++ {
    86  		if unicode.IsUpper(runes[i][0]) && unicode.IsLower(runes[i+1][0]) {
    87  			runes[i+1] = append([]rune{runes[i][len(runes[i])-1]}, runes[i+1]...)
    88  			runes[i] = runes[i][:len(runes[i])-1]
    89  		}
    90  	}
    91  
    92  	// construct []string from results
    93  	//
    94  	for _, s := range runes {
    95  		if len(s) > 0 && (unicode.IsDigit(s[0]) || unicode.IsLetter(s[0])) {
    96  			entries = append(entries, string(s))
    97  		}
    98  	}
    99  
   100  	return
   101  }
   102  
   103  type RewordsReducer func(result string, word string, index int) string
   104  
   105  func Rewords(s string, reducer RewordsReducer) string {
   106  	words := SplitToWords(s)
   107  
   108  	var result = ""
   109  
   110  	for idx, word := range words {
   111  		result = reducer(result, word, idx)
   112  	}
   113  
   114  	return result
   115  }
   116  
   117  func ToUpperFirst(s string) string {
   118  	runes := []rune(s)
   119  	runes[0] = unicode.ToUpper(runes[0])
   120  	return string(runes)
   121  }
   122  
   123  func ToCamelCase(s string) string {
   124  	upperString := strings.ToUpper(s)
   125  	if commonInitialisms[upperString] {
   126  		return upperString
   127  	}
   128  	return ToUpperFirst(strings.ToLower(upperString))
   129  }
   130  
   131  func ToUpperCamelCase(s string) string {
   132  	return Rewords(s, func(result string, word string, idx int) string {
   133  		return result + ToCamelCase(word)
   134  	})
   135  }
   136  
   137  func ToLowerCamelCase(s string) string {
   138  	return Rewords(s, func(result string, word string, idx int) string {
   139  		if idx == 0 {
   140  			return result + strings.ToLower(word)
   141  		}
   142  		return result + ToCamelCase(word)
   143  	})
   144  }
   145  
   146  func ToUpperSnakeCase(s string) string {
   147  	return Rewords(s, func(result string, word string, idx int) string {
   148  		newWord := strings.ToUpper(word)
   149  		if idx == 0 || (len(newWord) == 1 && unicode.IsDigit(rune(newWord[0]))) {
   150  			return result + newWord
   151  		}
   152  		return result + "_" + newWord
   153  	})
   154  }
   155  
   156  func ToLowerSnakeCase(s string) string {
   157  	return strings.ToLower(ToUpperSnakeCase(s))
   158  }
   159  
   160  func ToLowerLinkCase(s string) string {
   161  	return strings.Replace(ToLowerSnakeCase(s), "_", "-", -1)
   162  }
   163  
   164  func ToLowerSlashCase(s string) string {
   165  	return Rewords(s, func(result string, word string, index int) string {
   166  		return result + "/" + strings.ToLower(word)
   167  	})
   168  }
   169  
   170  func RecursiveJoin(strs [][]string, seps ...string) string {
   171  	if len(seps) == 0 {
   172  		logrus.Panic("seps need at least 1 elements, current is 0")
   173  	}
   174  	if len(seps) == 1 {
   175  		seps = append(seps, seps[0])
   176  	}
   177  	level := make([]string, 0)
   178  	for _, s1 := range strs {
   179  		level = append(level, strings.Join(s1, seps[0]))
   180  	}
   181  	return strings.Join(level, seps[1])
   182  }