github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/ss/s.go (about)

     1  package ss
     2  
     3  import (
     4  	"strings"
     5  )
     6  
     7  // Left returns the left n runes of s at most.
     8  func Left(s string, n int) string {
     9  	if n <= len(s) {
    10  		return s[:n]
    11  	}
    12  
    13  	return s
    14  }
    15  
    16  func IsDigits(s string) bool {
    17  	for _, c := range s {
    18  		if c < '0' || c > '9' {
    19  			return false
    20  		}
    21  	}
    22  	return true
    23  }
    24  
    25  // Repeat repeats s with separator seq for n times.
    26  func Repeat(s, sep string, n int) string {
    27  	result := ""
    28  	for i := 0; i < n; i++ {
    29  		if i == 0 {
    30  			result = s
    31  		} else {
    32  			result += sep + s
    33  		}
    34  	}
    35  
    36  	return result
    37  }
    38  
    39  // FirstWord returns the first word of the SQL statement s.
    40  func FirstWord(s string) string {
    41  	if v := FieldsN(strings.TrimSpace(s), 2); len(v) > 0 {
    42  		return v[0]
    43  	}
    44  
    45  	return ""
    46  }
    47  
    48  func RemoveAll(s, old string) string { return strings.ReplaceAll(s, old, "") }
    49  
    50  func Ori(a, b int) int {
    51  	if a == 0 {
    52  		return b
    53  	}
    54  
    55  	return a
    56  }
    57  
    58  func Or(a, b string) string {
    59  	if a == "" {
    60  		return b
    61  	}
    62  
    63  	return a
    64  }
    65  
    66  func Ifi(b bool, s1, s2 int) int {
    67  	if b {
    68  		return s1
    69  	}
    70  
    71  	return s2
    72  }
    73  
    74  func If(b bool, s1, s2 string) string {
    75  	if b {
    76  		return s1
    77  	}
    78  
    79  	return s2
    80  }
    81  
    82  func ContainsFold(s string, ss ...string) bool {
    83  	s = strings.ToLower(s)
    84  	for _, of := range ss {
    85  		of = strings.ToLower(of)
    86  		if strings.Contains(s, of) {
    87  			return true
    88  		}
    89  	}
    90  	return false
    91  }
    92  
    93  func Contains(s string, ss ...string) bool {
    94  	for _, of := range ss {
    95  		if strings.Contains(s, of) {
    96  			return true
    97  		}
    98  	}
    99  	return false
   100  }
   101  
   102  func AnyOf(s string, ss ...string) bool {
   103  	for _, of := range ss {
   104  		if s == of {
   105  			return true
   106  		}
   107  	}
   108  	return false
   109  }
   110  
   111  func AnyOfFold(s string, ss ...string) bool {
   112  	s = strings.ToLower(s)
   113  	for _, of := range ss {
   114  		if s == strings.ToLower(of) {
   115  			return true
   116  		}
   117  	}
   118  	return false
   119  }
   120  
   121  func HasPrefix(s string, ss ...string) bool {
   122  	for _, one := range ss {
   123  		if strings.HasPrefix(s, one) {
   124  			return true
   125  		}
   126  	}
   127  	return false
   128  }
   129  
   130  func HasSuffix(s string, ss ...string) bool {
   131  	for _, one := range ss {
   132  		if strings.HasSuffix(s, one) {
   133  			return true
   134  		}
   135  	}
   136  	return false
   137  }
   138  
   139  //func Jsonify(v interface{}) string {
   140  //	b := &bytes.Buffer{}
   141  //	encoder := json.NewEncoder(b)
   142  //	encoder.SetEscapeHTML(false)
   143  //	if err := encoder.Encode(v); err != nil {
   144  //		return err.Error()
   145  //	}
   146  //
   147  //	return b.String()
   148  //}
   149  
   150  func ToSet(v []string) map[string]bool {
   151  	m := make(map[string]bool)
   152  	for _, s := range v {
   153  		m[s] = true
   154  	}
   155  	return m
   156  }
   157  
   158  type Case int
   159  
   160  const (
   161  	CaseUnchanged Case = iota
   162  	CaseLower
   163  	CaseUpper
   164  )
   165  
   166  type SplitConfig struct {
   167  	Separators  string
   168  	IgnoreEmpty bool
   169  	TrimSpace   bool
   170  	Case        Case
   171  	N           int
   172  }
   173  
   174  type SplitOption func(*SplitConfig)
   175  
   176  func WithConfig(v SplitConfig) SplitOption { return func(c *SplitConfig) { *c = v } }
   177  func WithSeps(v string) SplitOption        { return func(c *SplitConfig) { c.Separators = v } }
   178  func WithN(v int) SplitOption              { return func(c *SplitConfig) { c.N = v } }
   179  func WithIgnoreEmpty(v bool) SplitOption   { return func(c *SplitConfig) { c.IgnoreEmpty = v } }
   180  func WithTrimSpace(v bool) SplitOption     { return func(c *SplitConfig) { c.TrimSpace = v } }
   181  func WithCase(v Case) SplitOption          { return func(c *SplitConfig) { c.Case = v } }
   182  
   183  func Split(s string, options ...SplitOption) []string {
   184  	v := make([]string, 0)
   185  	c := createConfig(options)
   186  
   187  	ff := FieldsFuncN(s, c.N, func(r rune) bool {
   188  		return strings.ContainsRune(c.Separators, r)
   189  	})
   190  
   191  	for _, f := range ff {
   192  		if c.TrimSpace {
   193  			f = strings.TrimSpace(f)
   194  		}
   195  		if c.IgnoreEmpty && f == "" {
   196  			continue
   197  		}
   198  		switch c.Case {
   199  		case CaseLower:
   200  			f = strings.ToLower(f)
   201  		case CaseUpper:
   202  			f = strings.ToUpper(f)
   203  		}
   204  
   205  		v = append(v, f)
   206  	}
   207  
   208  	return v
   209  }
   210  
   211  func createConfig(options []SplitOption) *SplitConfig {
   212  	c := &SplitConfig{TrimSpace: true, IgnoreEmpty: true}
   213  	for _, o := range options {
   214  		o(c)
   215  	}
   216  
   217  	if c.Separators == "" {
   218  		c.Separators = ", "
   219  	}
   220  
   221  	return c
   222  }
   223  
   224  func ToLowerKebab(name string) string {
   225  	var sb strings.Builder
   226  
   227  	isUpper := func(c uint8) bool { return 'A' <= c && c <= 'Z' }
   228  
   229  	for i := 0; i < len(name); i++ {
   230  		c := name[i]
   231  		if isUpper(c) {
   232  			if sb.Len() > 0 {
   233  				if i+1 < len(name) && (!(i-1 >= 0 && isUpper(name[i-1])) || !isUpper(name[i+1])) {
   234  					sb.WriteByte('-')
   235  				}
   236  			}
   237  			sb.WriteByte(c - 'A' + 'a')
   238  		} else {
   239  			sb.WriteByte(c)
   240  		}
   241  	}
   242  
   243  	return sb.String()
   244  }