-
Notifications
You must be signed in to change notification settings - Fork 0
/
ptr.go
81 lines (65 loc) · 1.28 KB
/
ptr.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package buzz
import (
"fmt"
"reflect"
)
type BuzzPtr struct {
name string
field BuzzField
refType reflect.Type
nullable bool
}
func Ptr(field BuzzField) *BuzzPtr {
return &BuzzPtr{
field: field,
refType: reflect.New(field.Type()).Type(),
nullable: true,
}
}
func (p *BuzzPtr) Name() string {
return p.name
}
func (p *BuzzPtr) Type() reflect.Type {
return p.refType
}
func (p *BuzzPtr) Validate(v any) error {
refValue := reflect.ValueOf(v)
refKind := refValue.Kind()
if refKind == reflect.Invalid {
if p.nullable {
return nil
}
return notNullableFieldErr(p.name)
}
if refKind != reflect.Pointer {
return fmt.Errorf(invalidTypeMsg, p.refType, v)
}
if refValue.IsNil() {
if p.nullable {
return nil
}
return notNullableFieldErr(p.name)
}
refValueElem := refValue.Elem()
if refValueElem.Type() != p.field.Type() {
return fmt.Errorf(invalidTypeMsg, p.refType, v)
}
return p.field.Validate(refValueElem.Interface())
}
func (p *BuzzPtr) WithName(name string) BuzzField {
p.name = name
p.field.WithName(name)
return p
}
func (p *BuzzPtr) Clone() BuzzField {
return &BuzzPtr{
name: p.name,
field: p.field,
refType: p.refType,
nullable: p.nullable,
}
}
func (p *BuzzPtr) Nonnil() *BuzzPtr {
p.nullable = false
return p
}