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 }