k3s/vendor/github.com/rancher/wrangler/pkg/schemas/schemas.go

201 lines
4.1 KiB
Go
Raw Normal View History

2020-03-26 21:07:15 +00:00
package schemas
import (
"fmt"
"reflect"
"strings"
"sync"
"github.com/rancher/wrangler/pkg/data/convert"
"github.com/rancher/wrangler/pkg/merr"
"github.com/rancher/wrangler/pkg/name"
)
type SchemasInitFunc func(*Schemas) *Schemas
type MapperFactory func() Mapper
type FieldMapperFactory func(fieldName string, args ...string) Mapper
type Schemas struct {
sync.Mutex
processingTypes map[reflect.Type]*Schema
typeNames map[reflect.Type]string
schemasByID map[string]*Schema
mappers map[string][]Mapper
embedded map[string]*Schema
fieldMappers map[string]FieldMapperFactory
DefaultMapper MapperFactory
DefaultPostMapper MapperFactory
schemas []*Schema
}
func EmptySchemas() *Schemas {
s, _ := NewSchemas()
return s
}
func NewSchemas(schemas ...*Schemas) (*Schemas, error) {
var (
errs []error
)
s := &Schemas{
processingTypes: map[reflect.Type]*Schema{},
typeNames: map[reflect.Type]string{},
schemasByID: map[string]*Schema{},
mappers: map[string][]Mapper{},
embedded: map[string]*Schema{},
}
for _, schemas := range schemas {
if _, err := s.AddSchemas(schemas); err != nil {
errs = append(errs, err)
}
}
return s, merr.NewErrors(errs...)
}
func (s *Schemas) Init(initFunc SchemasInitFunc) *Schemas {
return initFunc(s)
}
func (s *Schemas) MustAddSchemas(schema *Schemas) *Schemas {
s, err := s.AddSchemas(schema)
if err != nil {
panic(err)
}
return s
}
func (s *Schemas) AddSchemas(schema *Schemas) (*Schemas, error) {
var errs []error
for _, schema := range schema.Schemas() {
if err := s.AddSchema(*schema); err != nil {
errs = append(errs, err)
}
}
return s, merr.NewErrors(errs...)
}
func (s *Schemas) RemoveSchema(schema Schema) *Schemas {
s.Lock()
defer s.Unlock()
return s.doRemoveSchema(schema)
}
func (s *Schemas) doRemoveSchema(schema Schema) *Schemas {
delete(s.schemasByID, schema.ID)
return s
}
func (s *Schemas) MustAddSchema(schema Schema) *Schemas {
err := s.AddSchema(schema)
if err != nil {
panic(err)
}
return s
}
func (s *Schemas) AddSchema(schema Schema) error {
s.Lock()
defer s.Unlock()
return s.doAddSchema(schema)
}
func (s *Schemas) doAddSchema(schema Schema) error {
if err := s.setupDefaults(&schema); err != nil {
return err
}
existing, ok := s.schemasByID[schema.ID]
if ok {
*existing = schema
} else {
s.schemasByID[schema.ID] = &schema
s.schemas = append(s.schemas, &schema)
}
return nil
}
func (s *Schemas) setupDefaults(schema *Schema) (err error) {
if schema.ID == "" {
return fmt.Errorf("ID is not set on schema: %v", schema)
}
if schema.PluralName == "" {
schema.PluralName = name.GuessPluralName(schema.ID)
}
if schema.CodeName == "" {
schema.CodeName = convert.Capitalize(schema.ID)
}
if schema.CodeNamePlural == "" {
schema.CodeNamePlural = name.GuessPluralName(schema.CodeName)
}
if err := s.assignMappers(schema); err != nil {
return err
}
return
}
func (s *Schemas) AddFieldMapper(name string, factory FieldMapperFactory) *Schemas {
if s.fieldMappers == nil {
s.fieldMappers = map[string]FieldMapperFactory{}
}
s.fieldMappers[name] = factory
return s
}
func (s *Schemas) AddMapper(schemaID string, mapper Mapper) *Schemas {
s.mappers[schemaID] = append(s.mappers[schemaID], mapper)
return s
}
func (s *Schemas) Schemas() []*Schema {
return s.schemas
}
func (s *Schemas) SchemasByID() map[string]*Schema {
return s.schemasByID
}
func (s *Schemas) mapper(schemaID string) []Mapper {
return s.mappers[schemaID]
}
func (s *Schemas) Schema(name string) *Schema {
return s.doSchema(name, true)
}
func (s *Schemas) doSchema(name string, lock bool) *Schema {
if lock {
s.Lock()
}
schema, ok := s.schemasByID[name]
if lock {
s.Unlock()
}
if ok {
return schema
}
for _, check := range s.schemas {
if strings.EqualFold(check.ID, name) || strings.EqualFold(check.PluralName, name) {
return check
}
}
return nil
}
func (s *Schema) MustCustomizeField(name string, f func(f Field) Field) *Schema {
field, ok := s.ResourceFields[name]
if !ok {
panic("Failed to find field " + name + " on schema " + s.ID)
}
s.ResourceFields[name] = f(field)
return s
}