string.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. package stringx
  2. import (
  3. "bytes"
  4. "strings"
  5. "unicode"
  6. )
  7. // String provides for coverting the source text into other spell case,like lower,snake,camel
  8. type String struct {
  9. source string
  10. }
  11. // From converts the input text to String and returns it
  12. func From(data string) String {
  13. return String{source: data}
  14. }
  15. // IsEmptyOrSpace returns true if the length of the string value is 0 after call strings.TrimSpace, or else returns false
  16. func (s String) IsEmptyOrSpace() bool {
  17. if len(s.source) == 0 {
  18. return true
  19. }
  20. if strings.TrimSpace(s.source) == "" {
  21. return true
  22. }
  23. return false
  24. }
  25. // Lower calls the strings.ToLower
  26. func (s String) Lower() string {
  27. return strings.ToLower(s.source)
  28. }
  29. // ReplaceAll calls the strings.ReplaceAll
  30. func (s String) ReplaceAll(old, new string) string {
  31. return strings.ReplaceAll(s.source, old, new)
  32. }
  33. //Source returns the source string value
  34. func (s String) Source() string {
  35. return s.source
  36. }
  37. // Title calls the strings.Title
  38. func (s String) Title() string {
  39. if s.IsEmptyOrSpace() {
  40. return s.source
  41. }
  42. return strings.Title(s.source)
  43. }
  44. // ToCamel converts the input text into camel case
  45. func (s String) ToCamel() string {
  46. list := s.splitBy(func(r rune) bool {
  47. return r == '_'
  48. }, true)
  49. var target []string
  50. for _, item := range list {
  51. target = append(target, From(item).Title())
  52. }
  53. return strings.Join(target, "")
  54. }
  55. // ToSnake converts the input text into snake case
  56. func (s String) ToSnake() string {
  57. list := s.splitBy(unicode.IsUpper, false)
  58. var target []string
  59. for _, item := range list {
  60. target = append(target, From(item).Lower())
  61. }
  62. return strings.Join(target, "_")
  63. }
  64. // Untitle return the original string if rune is not letter at index 0
  65. func (s String) Untitle() string {
  66. if s.IsEmptyOrSpace() {
  67. return s.source
  68. }
  69. r := rune(s.source[0])
  70. if !unicode.IsUpper(r) && !unicode.IsLower(r) {
  71. return s.source
  72. }
  73. return string(unicode.ToLower(r)) + s.source[1:]
  74. }
  75. // it will not ignore spaces
  76. func (s String) splitBy(fn func(r rune) bool, remove bool) []string {
  77. if s.IsEmptyOrSpace() {
  78. return nil
  79. }
  80. var list []string
  81. buffer := new(bytes.Buffer)
  82. for _, r := range s.source {
  83. if fn(r) {
  84. if buffer.Len() != 0 {
  85. list = append(list, buffer.String())
  86. buffer.Reset()
  87. }
  88. if !remove {
  89. buffer.WriteRune(r)
  90. }
  91. continue
  92. }
  93. buffer.WriteRune(r)
  94. }
  95. if buffer.Len() != 0 {
  96. list = append(list, buffer.String())
  97. }
  98. return list
  99. }