package contract import ( "strings" "unicode" "unicode/utf8" "github.com/gogf/gf/v2/errors/gerror" ) // Implementations wrap these errors so callers can use errors.Is without // inspecting error text. HTTP adapters choose the response envelope themselves. var ( ErrNotFound = gerror.New("full-sync resource not found") ErrConflict = gerror.New("full-sync conflict") ErrInvalidArgument = gerror.New("invalid full-sync argument") ErrFailureDetailsUnavailable = gerror.New("live failure details unavailable") ErrLeaseLost = gerror.New("full-sync lease lost") ErrBusy = gerror.New("full-sync resource busy") ) func invalid(format string, args ...any) error { return gerror.Wrapf(ErrInvalidArgument, format, args...) } // ValidateID checks new resource identifiers used both as Redis hash tags and // HTTP path segments. It does not rewrite historical identifiers during decode. func ValidateID(id string) error { if id == "" || strings.TrimSpace(id) != id || !utf8.ValidString(id) || strings.ContainsAny(id, "{}/\\") || strings.ContainsFunc(id, unicode.IsControl) { return invalid("invalid resource identifier") } return nil } func nonnegative(values ...int64) error { for _, value := range values { if value < 0 { return invalid("counts must be nonnegative") } } return nil }