format.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. package format
  2. import (
  3. "bytes"
  4. "errors"
  5. "fmt"
  6. "io"
  7. "strings"
  8. )
  9. const (
  10. flagGo = "GO"
  11. flagZero = "ZERO"
  12. unknown style = iota
  13. title
  14. lower
  15. upper
  16. )
  17. var ErrNamingFormat = errors.New("unsupported format")
  18. type (
  19. styleFormat struct {
  20. before string
  21. through string
  22. after string
  23. goStyle style
  24. zeroStyle style
  25. }
  26. style int
  27. )
  28. // FileNamingFormat is used to format the file name. You can define the format style
  29. // through the go and zero formatting characters. For example, you can define the snake
  30. // format as go_zero, and the camel case format as goZero. You can even specify the split
  31. // character, such as go#Zero, theoretically any combination can be used, but the prerequisite
  32. // must meet the naming conventions of each operating system file name.
  33. // Note: Formatting is based on snake or camel string
  34. func FileNamingFormat(format, content string) (string, error) {
  35. upperFormat := strings.ToUpper(format)
  36. indexGo := strings.Index(upperFormat, flagGo)
  37. indexZero := strings.Index(upperFormat, flagZero)
  38. if indexGo < 0 || indexZero < 0 || indexGo > indexZero {
  39. return "", ErrNamingFormat
  40. }
  41. var (
  42. before, through, after string
  43. flagGo, flagZero string
  44. goStyle, zeroStyle style
  45. err error
  46. )
  47. before = format[:indexGo]
  48. flagGo = format[indexGo : indexGo+2]
  49. through = format[indexGo+2 : indexZero]
  50. flagZero = format[indexZero : indexZero+4]
  51. after = format[indexZero+4:]
  52. goStyle, err = getStyle(flagGo)
  53. if err != nil {
  54. return "", err
  55. }
  56. zeroStyle, err = getStyle(flagZero)
  57. if err != nil {
  58. return "", err
  59. }
  60. var formatStyle styleFormat
  61. formatStyle.goStyle = goStyle
  62. formatStyle.zeroStyle = zeroStyle
  63. formatStyle.before = before
  64. formatStyle.through = through
  65. formatStyle.after = after
  66. return doFormat(formatStyle, content)
  67. }
  68. func doFormat(f styleFormat, content string) (string, error) {
  69. splits, err := split(content)
  70. if err != nil {
  71. return "", err
  72. }
  73. var join []string
  74. for index, split := range splits {
  75. if index == 0 {
  76. join = append(join, transferTo(split, f.goStyle))
  77. continue
  78. }
  79. join = append(join, transferTo(split, f.zeroStyle))
  80. }
  81. joined := strings.Join(join, f.through)
  82. return f.before + joined + f.after, nil
  83. }
  84. func transferTo(in string, style style) string {
  85. switch style {
  86. case upper:
  87. return strings.ToUpper(in)
  88. case lower:
  89. return strings.ToLower(in)
  90. case title:
  91. return strings.Title(in)
  92. default:
  93. return in
  94. }
  95. }
  96. func split(content string) ([]string, error) {
  97. var (
  98. list []string
  99. reader = strings.NewReader(content)
  100. buffer = bytes.NewBuffer(nil)
  101. )
  102. for {
  103. r, _, err := reader.ReadRune()
  104. if err != nil {
  105. if err == io.EOF {
  106. if buffer.Len() > 0 {
  107. list = append(list, buffer.String())
  108. }
  109. return list, nil
  110. }
  111. return nil, err
  112. }
  113. if r == '_' {
  114. if buffer.Len() > 0 {
  115. list = append(list, buffer.String())
  116. }
  117. buffer.Reset()
  118. continue
  119. }
  120. if r >= 'A' && r <= 'Z' {
  121. if buffer.Len() > 0 {
  122. list = append(list, buffer.String())
  123. }
  124. buffer.Reset()
  125. }
  126. buffer.WriteRune(r)
  127. }
  128. }
  129. func getStyle(flag string) (style, error) {
  130. compare := strings.ToLower(flag)
  131. switch flag {
  132. case strings.ToLower(compare):
  133. return lower, nil
  134. case strings.ToUpper(compare):
  135. return upper, nil
  136. case strings.Title(compare):
  137. return title, nil
  138. default:
  139. return unknown, fmt.Errorf("unexpected format: %s", flag)
  140. }
  141. }