91 lines
2.0 KiB
Go
91 lines
2.0 KiB
Go
package entry
|
|
|
|
import (
|
|
"RenewCMS/internal/domain/contenttype"
|
|
"reflect"
|
|
"sort"
|
|
)
|
|
|
|
func SameValue(left any, right any) bool {
|
|
return reflect.DeepEqual(left, right)
|
|
}
|
|
|
|
type UniqueValue struct {
|
|
Key string
|
|
Value any
|
|
}
|
|
|
|
func ApplyDefaults(fields []contenttype.Field, data map[string]any) map[string]any {
|
|
filled := make(map[string]any, len(data))
|
|
for key, value := range data {
|
|
filled[key] = value
|
|
}
|
|
for _, field := range fields {
|
|
if _, present := filled[field.Key]; !present && field.Default != nil {
|
|
filled[field.Key] = field.Default
|
|
}
|
|
}
|
|
return filled
|
|
}
|
|
|
|
func Project(fields []contenttype.Field, data map[string]any) map[string]any {
|
|
projected := make(map[string]any, len(data))
|
|
for _, field := range fields {
|
|
if value, present := data[field.Key]; present {
|
|
projected[field.Key] = value
|
|
}
|
|
}
|
|
return projected
|
|
}
|
|
|
|
func Validate(fields []contenttype.Field, data map[string]any) error {
|
|
for _, field := range fields {
|
|
if err := validateField(field, data); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return firstUnknownField(fields, data)
|
|
}
|
|
|
|
func validateField(field contenttype.Field, data map[string]any) error {
|
|
value := data[field.Key]
|
|
if value == nil {
|
|
if field.Required {
|
|
return invalidField(field.Key, RuleRequired)
|
|
}
|
|
return nil
|
|
}
|
|
if rule := field.Violation(value); rule != "" {
|
|
return invalidField(field.Key, rule)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func firstUnknownField(fields []contenttype.Field, data map[string]any) error {
|
|
known := make(map[string]bool, len(fields))
|
|
for _, field := range fields {
|
|
known[field.Key] = true
|
|
}
|
|
var unknown []string
|
|
for key := range data {
|
|
if !known[key] {
|
|
unknown = append(unknown, key)
|
|
}
|
|
}
|
|
if len(unknown) == 0 {
|
|
return nil
|
|
}
|
|
sort.Strings(unknown)
|
|
return invalidField(unknown[0], RuleUnknownField)
|
|
}
|
|
|
|
func UniqueValues(fields []contenttype.Field, data map[string]any) []UniqueValue {
|
|
var values []UniqueValue
|
|
for _, field := range fields {
|
|
if value := data[field.Key]; field.Unique && value != nil {
|
|
values = append(values, UniqueValue{Key: field.Key, Value: value})
|
|
}
|
|
}
|
|
return values
|
|
}
|