61 lines
1.4 KiB
Go
61 lines
1.4 KiB
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
"strings"
|
|
)
|
|
|
|
type publishingPolicy interface {
|
|
defaultStatus() string
|
|
isAllowedStatus(status string) bool
|
|
invalidStatusMessage() string
|
|
validate(payload Doc, existing Doc) error
|
|
}
|
|
|
|
func applyPublishingPolicy(payload Doc, partial bool, existing Doc, policy publishingPolicy) error {
|
|
status, hasStatus, err := getOptionalString(payload, "status")
|
|
if err != nil {
|
|
return errors.New("status must be a string")
|
|
}
|
|
if !hasStatus && !partial {
|
|
status = policy.defaultStatus()
|
|
hasStatus = true
|
|
}
|
|
if hasStatus {
|
|
normalizedStatus := strings.TrimSpace(strings.ToLower(status))
|
|
if !policy.isAllowedStatus(normalizedStatus) {
|
|
return errors.New(policy.invalidStatusMessage())
|
|
}
|
|
payload["status"] = normalizedStatus
|
|
}
|
|
|
|
return policy.validate(payload, existing)
|
|
}
|
|
|
|
func mergedPublishingValue(payload Doc, existing Doc, field string) (any, bool) {
|
|
if value, ok := payload[field]; ok {
|
|
return value, true
|
|
}
|
|
if existing == nil {
|
|
return nil, false
|
|
}
|
|
value, ok := existing[field]
|
|
return value, ok
|
|
}
|
|
|
|
func mergedPublishingString(payload Doc, existing Doc, field string) (string, bool) {
|
|
value, ok := mergedPublishingValue(payload, existing, field)
|
|
if !ok {
|
|
return "", false
|
|
}
|
|
text, ok := value.(string)
|
|
if !ok {
|
|
return "", false
|
|
}
|
|
trimmed := strings.TrimSpace(text)
|
|
if trimmed == "" {
|
|
return "", false
|
|
}
|
|
return strings.ToLower(trimmed), true
|
|
}
|