...
1 package validation
2
3 import (
4 "errors"
5 "fmt"
6 "strings"
7
8 "google.golang.org/genproto/googleapis/rpc/errdetails"
9 )
10
11
12 type MessageValidator struct {
13 parentField string
14 fieldViolations []*errdetails.BadRequest_FieldViolation
15 }
16
17
18 func (m *MessageValidator) SetParentField(parentField string) {
19 m.parentField = parentField
20 }
21
22
23 func (m *MessageValidator) AddFieldViolation(field, description string, formatArgs ...interface{}) {
24 if m.parentField != "" {
25 field = makeFieldWithParent(m.parentField, field)
26 }
27 if len(formatArgs) > 0 {
28 description = fmt.Sprintf(description, formatArgs...)
29 }
30 m.fieldViolations = append(m.fieldViolations, &errdetails.BadRequest_FieldViolation{
31 Field: field,
32 Description: description,
33 })
34 }
35
36
37
38 func (m *MessageValidator) AddFieldError(field string, err error) {
39 var errValidation *Error
40 if errors.As(err, &errValidation) {
41
42 originalParentField := m.parentField
43 m.parentField = makeFieldWithParent(m.parentField, field)
44 for _, fieldViolation := range errValidation.fieldViolations {
45 m.AddFieldViolation(fieldViolation.GetField(), fieldViolation.GetDescription())
46 }
47 m.parentField = originalParentField
48 } else {
49 m.AddFieldViolation(field, err.Error())
50 }
51 }
52
53
54 func (m *MessageValidator) Err() error {
55 if len(m.fieldViolations) > 0 {
56 return NewError(m.fieldViolations)
57 }
58 return nil
59 }
60
61 func makeFieldWithParent(parentField, field string) string {
62 if parentField == "" {
63 return field
64 }
65 var result strings.Builder
66 result.Grow(len(parentField) + 1 + len(field))
67 _, _ = result.WriteString(parentField)
68 _ = result.WriteByte('.')
69 _, _ = result.WriteString(field)
70 return result.String()
71 }
72
View as plain text