format.go 3.4 KB

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