-
Notifications
You must be signed in to change notification settings - Fork 34
Expand file tree
/
Copy pathstruct_helpers.go
More file actions
119 lines (109 loc) · 3.24 KB
/
struct_helpers.go
File metadata and controls
119 lines (109 loc) · 3.24 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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package zog
import (
"maps"
p "github.com/Oudwins/zog/pkgs/internals"
)
// Merge combines two or more schemas into a new schema.
// It performs a shallow merge, meaning:
// - Fields with the same key from later schemas override earlier ones
// - Modifying nested schemas may affect the original schemas
//
// Parameters:
// - other: The first schema to merge with
// - others: Additional schemas to merge
//
// Returns a new schema containing the merged fields and transforms
func (v *StructSchema) Merge(other *StructSchema, others ...*StructSchema) *StructSchema {
totalProcessors := len(v.processors) + len(other.processors)
for _, o := range others {
totalProcessors += len(o.processors)
}
new := &StructSchema{
processors: make([]p.ZProcessor[any], 0, totalProcessors),
required: other.required,
schema: Shape{},
}
// processors
new.processors = append(new.processors, v.processors...)
new.processors = append(new.processors, other.processors...)
for _, s := range others {
new.processors = append(new.processors, s.processors...)
}
maps.Copy(new.schema, v.schema)
maps.Copy(new.schema, other.schema)
for _, s := range others {
maps.Copy(new.schema, s.schema)
}
return new
}
// cloneShallow creates a shallow copy of the schema.
// The new schema shares references to the transforms, tests and inner schema.
func (v *StructSchema) cloneShallow() *StructSchema {
new := &StructSchema{
processors: v.processors,
required: v.required,
schema: v.schema,
}
return new
}
// Omit creates a new schema with specified fields removed.
// It accepts either strings or map[string]bool as arguments:
// - Strings directly specify fields to omit
// - For maps, fields are omitted when their boolean value is true
//
// Returns a new schema with the specified fields removed
func (v *StructSchema) Omit(vals ...any) *StructSchema {
new := v.cloneShallow()
new.schema = Shape{}
maps.Copy(new.schema, v.schema)
for _, k := range vals {
switch k := k.(type) {
case string:
delete(new.schema, k)
case map[string]bool:
for key, val := range k {
if val {
delete(new.schema, key)
}
}
}
}
return new
}
// Pick creates a new schema keeping only the specified fields.
// It accepts either strings or map[string]bool as arguments:
// - Strings directly specify fields to keep
// - For maps, fields are kept when their boolean value is true
//
// Returns a new schema containing only the specified fields
func (v *StructSchema) Pick(picks ...any) *StructSchema {
new := v.cloneShallow()
new.schema = Shape{}
for _, pick := range picks {
switch pick := pick.(type) {
case string:
new.schema[pick] = v.schema[pick]
case map[string]bool:
for k, pick := range pick {
if pick {
new.schema[k] = v.schema[k]
}
}
}
}
return new
}
// Extend creates a new schema by adding additional fields from the provided schema.
// Fields in the provided schema override any existing fields with the same key.
//
// Parameters:
// - schema: The schema containing fields to add
//
// Returns a new schema with the additional fields
func (v *StructSchema) Extend(schema Shape) *StructSchema {
new := v.cloneShallow()
new.schema = Shape{}
maps.Copy(new.schema, v.schema)
maps.Copy(new.schema, schema)
return new
}