diff --git a/internal/evaluator/map.go b/internal/evaluator/map.go index 405bf6f..fd3aa46 100644 --- a/internal/evaluator/map.go +++ b/internal/evaluator/map.go @@ -15,6 +15,9 @@ package evaluator import ( + "fmt" + "strconv" + "github.com/bufbuild/protovalidate-go/internal/errors" "google.golang.org/protobuf/reflect/protoreflect" ) @@ -32,7 +35,7 @@ func (m kvPairs) Evaluate(val protoreflect.Value, failFast bool) (err error) { val.Map().Range(func(key protoreflect.MapKey, value protoreflect.Value) bool { evalErr := m.evalPairs(key, value, failFast) if evalErr != nil { - errors.PrefixErrorPaths(evalErr, "[%#v]", key.Interface()) + errors.PrefixErrorPaths(evalErr, "[%s]", m.formatKey(key.Interface())) } ok, err = errors.Merge(err, evalErr, failFast) return ok @@ -57,4 +60,13 @@ func (m kvPairs) Tautology() bool { m.ValueConstraints.Tautology() } +func (m kvPairs) formatKey(key any) string { + switch k := key.(type) { + case string: + return strconv.Quote(k) + default: + return fmt.Sprintf("%v", key) + } +} + var _ evaluator = kvPairs{} diff --git a/internal/evaluator/map_test.go b/internal/evaluator/map_test.go new file mode 100644 index 0000000..da36366 --- /dev/null +++ b/internal/evaluator/map_test.go @@ -0,0 +1,54 @@ +package evaluator + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestFormatKey(t *testing.T) { + t.Parallel() + tests := []struct { + key any + expected string + }{ + { + key: int32(32), + expected: "32", + }, + { + key: int64(64), + expected: "64", + }, + { + key: uint32(32), + expected: "32", + }, + { + key: uint32(64), + expected: "64", + }, + { + key: true, + expected: "true", + }, + { + key: false, + expected: "false", + }, + { + key: `"foobar"`, + expected: `"\"foobar\""`, + }, + } + + kv := kvPairs{} + for _, tc := range tests { + test := tc + t.Run(test.expected, func(t *testing.T) { + t.Parallel() + actual := kv.formatKey(test.key) + assert.Equal(t, test.expected, actual) + }) + } +}