-
Notifications
You must be signed in to change notification settings - Fork 40
Expand file tree
/
Copy pathunion.go
More file actions
90 lines (81 loc) · 2.19 KB
/
Copy pathunion.go
File metadata and controls
90 lines (81 loc) · 2.19 KB
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
82
83
84
85
86
87
88
89
90
package zog
import (
"github.com/Oudwins/zog/conf"
p "github.com/Oudwins/zog/pkgs/internals"
zss "github.com/Oudwins/zog/pkgs/zss/core"
"github.com/Oudwins/zog/zconst"
)
var _ ZogSchema = &UnionSchema{}
type UnionSchema struct {
schemas []ZogSchema
}
func Union(schemas []ZogSchema, options ...SchemaOption) *UnionSchema {
s := &UnionSchema{
schemas: schemas,
}
for _, opt := range options {
opt(s)
}
return s
}
func (u *UnionSchema) Parse(data any, dest any, options ...ExecOption) p.ZogIssueList {
errs := p.NewErrsList()
defer errs.Free()
ctx := p.NewExecCtx(errs, conf.IssueFormatter)
defer ctx.Free()
for _, opt := range options {
opt(ctx)
}
path := p.NewPathBuilder()
defer path.Free()
sctx := ctx.NewSchemaCtx(data, dest, path, u.getType())
defer sctx.Free()
u.process(sctx)
return errs.List
}
func (u *UnionSchema) Validate(dest any, options ...ExecOption) p.ZogIssueList {
errs := p.NewErrsList()
defer errs.Free()
ctx := p.NewExecCtx(errs, conf.IssueFormatter)
defer ctx.Free()
for _, opt := range options {
opt(ctx)
}
path := p.NewPathBuilder()
defer path.Free()
sctx := ctx.NewSchemaCtx(dest, dest, path, u.getType())
defer sctx.Free()
u.validate(sctx)
return errs.List
}
func (u *UnionSchema) process(ctx *p.SchemaCtx) {
// Wrap the context and only go to the next one on fail. Keeping all the errors and appending at the end
listStart := len(ctx.Errors.List)
for _, s := range u.schemas {
numIssues := len(ctx.Errors.List)
s.process(ctx)
if len(ctx.Errors.List) == numIssues {
ctx.Errors.List = ctx.Errors.List[:listStart]
return // success
}
}
}
func (u *UnionSchema) validate(ctx *p.SchemaCtx) {
// Wrap the context and only go to the next one on fail. Keeping all the errors and appending at the end
listStart := len(ctx.Errors.List)
for _, s := range u.schemas {
numIssues := len(ctx.Errors.List)
s.validate(ctx)
if len(ctx.Errors.List) == numIssues {
ctx.Errors.List = ctx.Errors.List[:listStart]
return // success
}
}
}
func (u *UnionSchema) getType() zconst.ZogType {
return zconst.TypeUnion
}
func (u *UnionSchema) setCoercer(c CoercerFunc) {}
func (u *UnionSchema) toZSS(*ZSSSerializeCtx) *zss.ZSSSchema {
return &zss.ZSSSchema{}
}