• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Oudwins / zog / 27600447079

16 Jun 2026 07:07AM UTC coverage: 76.816% (-1.8%) from 78.597%
27600447079

push

github

web-flow
feat!: removing field key and invalid type schema panics as this is required change to support union schema (#229)

* wp

* refactor!: remove panics from invalid types

* feat: add zog skill to repo

* fix: review

60 of 161 new or added lines in 12 files covered. (37.27%)

16 existing lines in 9 files now uncovered.

2929 of 3813 relevant lines covered (76.82%)

69.13 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

85.84
/pointers.go
1
package zog
2

3
import (
4
        "reflect"
5

6
        "github.com/Oudwins/zog/conf"
7
        p "github.com/Oudwins/zog/pkgs/internals"
8
        "github.com/Oudwins/zog/zconst"
9
)
10

11
var _ ComplexZogSchema = &PointerSchema{}
12

13
type PointerSchema struct {
14
        schema   ZogSchema
15
        required *p.Test[any]
16
        // postTransforms []PostTransform
17
        // defaultVal     *any
18
        // catch          *any
19
}
20

21
func (v *PointerSchema) getType() zconst.ZogType {
202✔
22
        // return zconst.TypePtr
202✔
23
        return v.schema.getType()
202✔
24
}
202✔
25

26
func (v *PointerSchema) setCoercer(c conf.CoercerFunc) {
2✔
27
        v.schema.setCoercer(c)
2✔
28
}
2✔
29

30
// Ptr creates a pointer ZogSchema
31
func Ptr(schema ZogSchema) *PointerSchema {
107✔
32
        return &PointerSchema{
107✔
33
                schema: schema,
107✔
34
        }
107✔
35
}
107✔
36

37
// Parse the data into the destination pointer
38
func (v *PointerSchema) Parse(data any, dest any, options ...ExecOption) ZogIssueList {
52✔
39
        errs := p.NewErrsList()
52✔
40
        defer errs.Free()
52✔
41
        ctx := p.NewExecCtx(errs, conf.IssueFormatter)
52✔
42
        defer ctx.Free()
52✔
43
        for _, opt := range options {
54✔
44
                opt(ctx)
2✔
45
        }
2✔
46
        path := p.NewPathBuilder()
52✔
47
        defer path.Free()
52✔
48
        sctx := ctx.NewSchemaCtx(data, dest, path, v.getType())
52✔
49
        defer sctx.Free()
52✔
50
        v.process(sctx)
52✔
51

52✔
52
        return errs.List
52✔
53
}
54

55
func (v *PointerSchema) process(ctx *p.SchemaCtx) {
143✔
56

143✔
57
        // TODO this is a mess. But couldn't figure out a simple way to support top level optional structs without doing this.
143✔
58
        // Companion code to this codde is in struct.go > process
143✔
59
        subCtx := ctx.NewSchemaCtx(ctx.Data, ctx.ValPtr, ctx.Path, v.schema.getType())
143✔
60
        defer subCtx.Free()
143✔
61
        if fn, ok := ctx.Data.(p.DpFactory); ok {
143✔
62
                val, err := fn()
×
63
                if err != nil {
×
64
                        ctx.AddIssue(subCtx.IssueFromUnknownError(err))
×
65
                        return
×
66
                }
×
67
                ctx.Data = val
×
68
        }
69
        _, isEmptyStruct := ctx.Data.(*p.EmptyDataProvider)
143✔
70
        // End of messy code
143✔
71

143✔
72
        isZero := p.IsParseZeroValue(ctx.Data, ctx) || isEmptyStruct
143✔
73
        if isZero {
184✔
74
                if v.required != nil {
50✔
75
                        // We set the destination type to the schema type because pointer doesn't have any issue messages. They pass through to the schema type
9✔
76
                        ctx.AddIssue(ctx.IssueFromTest(v.required, ctx.Data).SetDType(v.schema.getType()))
9✔
77
                }
9✔
78
                return
41✔
79
        }
80
        rv := reflect.ValueOf(ctx.ValPtr)
102✔
81
        if !rv.IsValid() || rv.Kind() != reflect.Pointer {
102✔
NEW
82
                // We have to go directly to the exec context as that is what formats. We cannot use ctx because it will try to catch the issue and this is an uncatchable issue
×
NEW
83
                // since we cannot set the value as its not a pointer
×
NEW
84
                ctx.ExecCtx.AddIssue(ctx.IssueFromInvalidType("pointer", ctx.ValPtr, "processing a pointer schema"))
×
NEW
85
                return
×
NEW
86
        }
×
87
        destPtr := rv.Elem()
102✔
88
        if !destPtr.IsValid() || destPtr.Kind() != reflect.Pointer {
102✔
NEW
89
                // We have to go directly to the exec context as that is what formats. We cannot use ctx because it will try to catch the issue and this is an uncatchable issue
×
NEW
90
                // since we cannot set the value as its not a pointer
×
NEW
91
                ctx.ExecCtx.AddIssue(ctx.IssueFromInvalidType("pointer", ctx.ValPtr, "processing a pointer schema"))
×
NEW
92
                return
×
NEW
93
        }
×
94
        if destPtr.IsNil() {
199✔
95
                // this sets the primitive also
97✔
96
                newVal := reflect.New(destPtr.Type().Elem())
97✔
97
                // this generates a new nil pointer
97✔
98
                //newVal := reflect.Zero(destPtr.Type())
97✔
99
                destPtr.Set(newVal)
97✔
100
        }
97✔
101
        di := destPtr.Interface()
102✔
102
        subCtx.ValPtr = di
102✔
103
        v.schema.process(subCtx)
102✔
104
}
105

106
// Validates a pointer pointer
107
func (v *PointerSchema) Validate(data any, options ...ExecOption) ZogIssueList {
16✔
108
        errs := p.NewErrsList()
16✔
109
        defer errs.Free()
16✔
110
        ctx := p.NewExecCtx(errs, conf.IssueFormatter)
16✔
111
        defer ctx.Free()
16✔
112
        for _, opt := range options {
18✔
113
                opt(ctx)
2✔
114
        }
2✔
115
        path := p.NewPathBuilder()
16✔
116
        defer path.Free()
16✔
117
        v.validate(ctx.NewValidateSchemaCtx(data, path, v.getType()))
16✔
118
        return errs.List
16✔
119
}
120

121
func (v *PointerSchema) validate(ctx *p.SchemaCtx) {
60✔
122
        rv := reflect.ValueOf(ctx.ValPtr)
60✔
123
        if !rv.IsValid() || rv.Kind() != reflect.Pointer {
61✔
124
                // We have to go directly to the exec context as that is what formats. We cannot use ctx because it will try to catch the issue and this is an uncatchable issue
1✔
125
                // since we cannot set the value as its not a pointer
1✔
126
                ctx.ExecCtx.AddIssue(ctx.IssueFromInvalidType("pointer", ctx.ValPtr, "validating a pointer schema"))
1✔
127
                return
1✔
128
        }
1✔
129
        destPtr := rv.Elem()
59✔
130
        if !destPtr.IsValid() || destPtr.IsNil() {
76✔
131
                if v.required != nil {
22✔
132
                        // We set the destination type to the schema type because pointer doesn't have any issue messages. They pass through to the schema type
5✔
133
                        ctx.AddIssue(ctx.IssueFromTest(v.required, ctx.Data).SetDType(v.schema.getType()))
5✔
134
                }
5✔
135
                return
17✔
136
        }
137
        di := destPtr.Interface()
42✔
138
        ctx.ValPtr = di
42✔
139
        v.schema.validate(ctx.NewValidateSchemaCtx(di, ctx.Path, v.schema.getType()))
42✔
140
}
141

142
// Validate Existing Pointer
143

144
func (v *PointerSchema) NotNil(options ...TestOption) *PointerSchema {
13✔
145
        r := p.Test[any]{
13✔
146
                IssueCode: zconst.IssueCodeNotNil,
13✔
147
        }
13✔
148
        for _, opt := range options {
17✔
149
                opt(&r)
4✔
150
        }
4✔
151
        v.required = &r
13✔
152
        return v
13✔
153
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc