fn.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. package spec
  2. import (
  3. "errors"
  4. "regexp"
  5. "strings"
  6. "github.com/tal-tech/go-zero/core/stringx"
  7. "github.com/tal-tech/go-zero/tools/goctl/util"
  8. )
  9. const (
  10. TagKey = "tag"
  11. NameKey = "name"
  12. OptionKey = "option"
  13. BodyTag = "json"
  14. )
  15. var (
  16. TagRe = regexp.MustCompile(`(?P<tag>\w+):"(?P<name>[^,"]+)[,]?(?P<option>[^"]*)"`)
  17. TagSubNames = TagRe.SubexpNames()
  18. definedTags = []string{TagKey, NameKey, OptionKey}
  19. )
  20. type Attribute struct {
  21. Key string
  22. value string
  23. }
  24. func (s Service) Routes() []Route {
  25. var result []Route
  26. for _, group := range s.Groups {
  27. result = append(result, group.Routes...)
  28. }
  29. return result
  30. }
  31. func (m Member) IsOptional() bool {
  32. var option string
  33. matches := TagRe.FindStringSubmatch(m.Tag)
  34. for i := range matches {
  35. name := TagSubNames[i]
  36. if name == OptionKey {
  37. option = matches[i]
  38. }
  39. }
  40. if len(option) == 0 {
  41. return false
  42. }
  43. fields := strings.Split(option, ",")
  44. for _, field := range fields {
  45. if field == "optional" || strings.HasPrefix(field, "default=") {
  46. return true
  47. }
  48. }
  49. return false
  50. }
  51. func (m Member) IsOmitempty() bool {
  52. var option string
  53. matches := TagRe.FindStringSubmatch(m.Tag)
  54. for i := range matches {
  55. name := TagSubNames[i]
  56. if name == OptionKey {
  57. option = matches[i]
  58. }
  59. }
  60. if len(option) == 0 {
  61. return false
  62. }
  63. fields := strings.Split(option, ",")
  64. for _, field := range fields {
  65. if field == "omitempty" {
  66. return true
  67. }
  68. }
  69. return false
  70. }
  71. func (m Member) GetAttributes() []Attribute {
  72. matches := TagRe.FindStringSubmatch(m.Tag)
  73. var result []Attribute
  74. for i := range matches {
  75. name := TagSubNames[i]
  76. if stringx.Contains(definedTags, name) {
  77. result = append(result, Attribute{
  78. Key: name,
  79. value: matches[i],
  80. })
  81. }
  82. }
  83. return result
  84. }
  85. func (m Member) GetPropertyName() (string, error) {
  86. attrs := m.GetAttributes()
  87. for _, attr := range attrs {
  88. if attr.Key == NameKey && len(attr.value) > 0 {
  89. if attr.value == "-" {
  90. return util.Untitle(m.Name), nil
  91. }
  92. return attr.value, nil
  93. }
  94. }
  95. return "", errors.New("json property name not exist, member: " + m.Name)
  96. }
  97. func (m Member) GetComment() string {
  98. return strings.TrimSpace(strings.Join(m.Comments, "; "))
  99. }
  100. func (m Member) IsBodyMember() bool {
  101. if m.IsInline {
  102. return true
  103. }
  104. attrs := m.GetAttributes()
  105. for _, attr := range attrs {
  106. if attr.value == BodyTag {
  107. return true
  108. }
  109. }
  110. return false
  111. }
  112. func (t Type) GetBodyMembers() []Member {
  113. var result []Member
  114. for _, member := range t.Members {
  115. if member.IsBodyMember() {
  116. result = append(result, member)
  117. }
  118. }
  119. return result
  120. }
  121. func (t Type) GetNonBodyMembers() []Member {
  122. var result []Member
  123. for _, member := range t.Members {
  124. if !member.IsBodyMember() {
  125. result = append(result, member)
  126. }
  127. }
  128. return result
  129. }