github.com/morlay/goqcloud@v0.0.0-20181123023149-b00e0b0b9afc/generator/type_schema.go (about) 1 package generator 2 3 import ( 4 "sort" 5 "strings" 6 7 "github.com/go-courier/codegen" 8 ) 9 10 type TypeSchema struct { 11 ImportPath string 12 Name string 13 Desc string 14 Type *BasicType 15 Items *TypeSchema 16 AdditionalProp *TypeSchema 17 AllOf []*TypeSchema 18 Props map[string]*TypeSchema 19 Required bool 20 Tag string 21 } 22 23 func (s *TypeSchema) IsRef() bool { 24 return s.Type == nil && !s.IsArray() && !s.IsMap() && !s.IsObject() 25 } 26 27 func (s *TypeSchema) IsArray() bool { 28 return s.Items != nil 29 } 30 31 func (s *TypeSchema) IsObject() bool { 32 return s.Props != nil || len(s.AllOf) > 0 33 } 34 35 func (s *TypeSchema) IsMap() bool { 36 return s.AdditionalProp != nil 37 } 38 39 func (s *TypeSchema) Write(file *codegen.File) { 40 file.WriteBlock( 41 codegen.Comments(s.Desc), 42 codegen.DeclType( 43 codegen.Var(s.SnippetType(file), s.Name), 44 ), 45 ) 46 } 47 48 func (s *TypeSchema) SnippetType(file *codegen.File) codegen.SnippetType { 49 if s.IsArray() { 50 return codegen.Slice(s.Items.SnippetType(file)) 51 } 52 53 if s.IsObject() { 54 fields := make([]*codegen.SnippetField, 0) 55 56 for _, embedType := range s.AllOf { 57 fields = append(fields, codegen.Var(embedType.SnippetType(file))) 58 } 59 60 names := make([]string, 0) 61 for name := range s.Props { 62 names = append(names, name) 63 } 64 sort.Strings(names) 65 66 for _, name := range names { 67 prop := s.Props[name] 68 69 tags := map[string][]string{} 70 tag := s.Tag 71 if tag == "" { 72 tag = "json" 73 } 74 tags[tag] = append(tags[tag], name) 75 if !prop.Required { 76 tags[tag] = append(tags[tag], "omitempty") 77 } 78 79 fields = append(fields, codegen.Var(prop.SnippetType(file), name).WithTags(tags).WithComments(prop.Desc)) 80 } 81 82 return codegen.Struct(fields...) 83 } 84 85 maybeStarType := func(tpe codegen.SnippetType) codegen.SnippetType { 86 if !s.Required { 87 return codegen.Star(tpe) 88 } 89 return tpe 90 } 91 92 if s.Name != "" { 93 if s.ImportPath != "" { 94 return maybeStarType(codegen.Type(file.Use(s.ImportPath, s.Name))) 95 } 96 return maybeStarType(codegen.Type(s.Name)) 97 98 } 99 100 if s.Type != nil { 101 switch *s.Type { 102 case BasicTypeBoolean: 103 return maybeStarType(codegen.Bool) 104 case BasicTypeString: 105 return maybeStarType(codegen.String) 106 case BasicTypeInteger: 107 return maybeStarType(codegen.Int64) 108 case BasicTypeFloat: 109 return maybeStarType(codegen.Float64) 110 case BasicTypeTimestamp, BasicTypeDate: 111 return maybeStarType(codegen.Type(file.Use("time", "Time"))) 112 } 113 } 114 115 return codegen.Interface() 116 } 117 118 func (s *TypeSchema) AddProp(name string, propSchema *TypeSchema) { 119 if s.Props == nil { 120 s.Props = map[string]*TypeSchema{} 121 } 122 if s.Props[name] == nil { 123 s.Props[name] = propSchema 124 } 125 } 126 127 type BasicType string 128 129 const ( 130 BasicTypeDate BasicType = "Date" 131 BasicTypeTimestamp BasicType = "Timestamp" 132 BasicTypeString BasicType = "String" 133 BasicTypeInteger BasicType = "Integer" 134 BasicTypeBoolean BasicType = "Boolean" 135 BasicTypeFloat BasicType = "Float" 136 ) 137 138 const arrayPrefix = "Array of " 139 140 func IsArrayType(tpe string) bool { 141 return strings.HasPrefix(tpe, arrayPrefix) 142 } 143 144 func IndirectType(tpe string) (basicType *BasicType) { 145 t := BasicType(strings.TrimLeft(tpe, arrayPrefix)) 146 return &t 147 }