2017-02-07 21:33:23 +00:00
|
|
|
package client
|
|
|
|
|
|
|
|
import (
|
|
|
|
"reflect"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Schemas struct {
|
|
|
|
Collection
|
|
|
|
Data []Schema `json:"data,omitempty"`
|
|
|
|
schemasByName map[string]*Schema
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Schema) CheckField(name string) (Field, bool) {
|
|
|
|
for fieldName := range s.ResourceFields {
|
|
|
|
if fieldName == name {
|
|
|
|
v, ok := s.ResourceFields[fieldName]
|
|
|
|
return v, ok
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return Field{}, false
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Schema) Field(name string) Field {
|
|
|
|
f, _ := s.CheckField(name)
|
|
|
|
return f
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Schemas) CheckSchema(name string) (Schema, bool) {
|
|
|
|
for i := range s.Data {
|
2017-11-05 12:02:03 +00:00
|
|
|
if s.Data[i].Id == name {
|
2017-02-07 21:33:23 +00:00
|
|
|
return s.Data[i], true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return Schema{}, false
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Schemas) Schema(name string) Schema {
|
|
|
|
r, _ := s.CheckSchema(name)
|
|
|
|
return r
|
|
|
|
}
|
|
|
|
|
|
|
|
func typeToFields(t reflect.Type) map[string]Field {
|
|
|
|
result := map[string]Field{}
|
|
|
|
|
|
|
|
for i := 0; i < t.NumField(); i++ {
|
|
|
|
schemaField := Field{}
|
|
|
|
|
|
|
|
typeField := t.Field(i)
|
|
|
|
if typeField.Anonymous && typeField.Type.Kind() == reflect.Struct {
|
|
|
|
parentFields := typeToFields(typeField.Type)
|
|
|
|
for k, v := range result {
|
|
|
|
parentFields[k] = v
|
|
|
|
}
|
|
|
|
result = parentFields
|
|
|
|
continue
|
|
|
|
} else if typeField.Anonymous {
|
|
|
|
continue
|
2017-11-05 12:02:03 +00:00
|
|
|
} else if privateFieldRegex.FindStringIndex(typeField.Name) != nil {
|
|
|
|
continue
|
2017-02-07 21:33:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fieldString := strings.ToLower(typeField.Type.Kind().String())
|
|
|
|
|
|
|
|
switch {
|
|
|
|
case strings.HasPrefix(fieldString, "int") || strings.HasPrefix(fieldString, "uint"):
|
|
|
|
schemaField.Type = "int"
|
|
|
|
case fieldString == "bool":
|
|
|
|
schemaField.Type = fieldString
|
|
|
|
case fieldString == "float32" || fieldString == "float64":
|
|
|
|
schemaField.Type = "float"
|
|
|
|
case fieldString == "string":
|
|
|
|
schemaField.Type = "string"
|
|
|
|
case fieldString == "map":
|
|
|
|
// HACK
|
|
|
|
schemaField.Type = "map[string]"
|
|
|
|
case fieldString == "slice":
|
|
|
|
// HACK
|
|
|
|
schemaField.Type = "array[string]"
|
|
|
|
}
|
|
|
|
|
|
|
|
name := strings.Split(typeField.Tag.Get("json"), ",")[0]
|
|
|
|
if name == "" && len(typeField.Name) > 1 {
|
|
|
|
name = strings.ToLower(typeField.Name[0:1]) + typeField.Name[1:]
|
|
|
|
} else if name == "" {
|
|
|
|
name = typeField.Name
|
|
|
|
}
|
|
|
|
|
|
|
|
if schemaField.Type != "" {
|
|
|
|
result[name] = schemaField
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Schemas) AddType(schemaName string, obj interface{}) *Schema {
|
|
|
|
t := reflect.TypeOf(obj)
|
|
|
|
schema := Schema{
|
|
|
|
Resource: Resource{
|
|
|
|
Id: schemaName,
|
|
|
|
Type: "schema",
|
|
|
|
Links: map[string]string{},
|
|
|
|
},
|
|
|
|
PluralName: guessPluralName(schemaName),
|
|
|
|
ResourceFields: typeToFields(t),
|
|
|
|
CollectionMethods: []string{"GET"},
|
|
|
|
ResourceMethods: []string{"GET"},
|
|
|
|
}
|
|
|
|
|
|
|
|
if s.Data == nil {
|
|
|
|
s.Data = []Schema{}
|
|
|
|
}
|
|
|
|
|
|
|
|
s.Data = append(s.Data, schema)
|
|
|
|
|
|
|
|
return &s.Data[len(s.Data)-1]
|
|
|
|
}
|
|
|
|
|
|
|
|
func guessPluralName(name string) string {
|
|
|
|
if name == "" {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
|
|
|
if strings.HasSuffix(name, "s") ||
|
|
|
|
strings.HasSuffix(name, "ch") ||
|
|
|
|
strings.HasSuffix(name, "x") {
|
|
|
|
return name + "es"
|
|
|
|
}
|
|
|
|
return name + "s"
|
|
|
|
}
|