Skip to content

Commit 6288d84

Browse files
committed
feat: add to zss
1 parent 0fa94d3 commit 6288d84

7 files changed

Lines changed: 76 additions & 2 deletions

File tree

pkgs/zss/core/zss_structures.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ type ZSSSchema struct {
6363
Element *ZSSSchema `json:"element,omitempty"` // ptr, slice, preprocess, boxed
6464
Key *ZSSSchema `json:"key,omitempty"` // map only
6565
Value *ZSSSchema `json:"value,omitempty"` // map only
66+
Children []*ZSSSchema `json:"children,omitempty"` // union only
6667
Required *ZSSTest `json:"required,omitempty"`
6768
DefaultValue any `json:"defaultValue,omitempty"`
6869
CatchValue any `json:"catchValue,omitempty"`

pkgs/zss/jsonschema/draft2020_12/jsonschema.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ func (c converter) convertSchema(schema *zsscore.ZSSSchema) (Schema, error) {
9191
out, err = c.convertStruct(schema)
9292
case zconst.TypePtr:
9393
out, err = c.convertPtr(schema)
94+
case zconst.TypeUnion:
95+
out, err = c.convertUnion(schema)
9496
case zconst.TypePreprocess, zconst.TypeBoxed:
9597
out, err = c.convertSchema(schema.Element)
9698
case zconst.TypeAny, zconst.TypeCustom:
@@ -187,6 +189,18 @@ func (c converter) convertPtr(schema *zsscore.ZSSSchema) (Schema, error) {
187189
return nullable(inner), nil
188190
}
189191

192+
func (c converter) convertUnion(schema *zsscore.ZSSSchema) (Schema, error) {
193+
children := make([]any, 0, len(schema.Children))
194+
for i, child := range schema.Children {
195+
converted, err := c.convertSchema(child)
196+
if err != nil {
197+
return nil, fmt.Errorf("convert union child %d: %w", i, err)
198+
}
199+
children = append(children, converted)
200+
}
201+
return Schema{"anyOf": children}, nil
202+
}
203+
190204
func nullable(schema Schema) Schema {
191205
typeValue, ok := schema["type"]
192206
if !ok {

pkgs/zss/jsonschema/jsonschema_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,25 @@ func TestFromZSSConvertsContainers(t *testing.T) {
8484
}, schema)
8585
}
8686

87+
func TestFromZSSConvertsUnion(t *testing.T) {
88+
doc := zsscore.ZSSDocument{Root: &zsscore.ZSSSchema{Kind: zconst.TypeUnion, Children: []*zsscore.ZSSSchema{
89+
{Kind: zconst.TypeString},
90+
{Kind: zconst.TypeNumber},
91+
}}}
92+
93+
schema, err := zjsonschema.FromZSS(doc, zjsonschema.Options{})
94+
require.NoError(t, err)
95+
requireValidJSONSchema(t, schema)
96+
97+
assert.Equal(t, zjsonschema.Schema{
98+
"$schema": string(zjsonschema.Draft2020_12),
99+
"anyOf": []any{
100+
zjsonschema.Schema{"type": "string"},
101+
zjsonschema.Schema{"type": "number"},
102+
},
103+
}, schema)
104+
}
105+
87106
func TestFromZSSConvertsPointerNullability(t *testing.T) {
88107
optional, err := zjsonschema.FromZSS(zsscore.ZSSDocument{Root: &zsscore.ZSSSchema{Kind: zconst.TypePtr, Element: &zsscore.ZSSSchema{Kind: zconst.TypeString}}}, zjsonschema.Options{})
89108
require.NoError(t, err)

pkgs/zss/schema/zss_document_schema.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ var ZSSSchemaSchema = z.EXPERIMENTAL_RECURSIVE(func(self z.RecursiveSchema[*z.St
5858
"element": z.Ptr(self()),
5959
"key": z.Ptr(self()),
6060
"value": z.Ptr(self()),
61+
"children": z.Slice(z.Ptr(self())),
6162
"required": z.Ptr(ZSSTestSchema),
6263
"defaultValue": z.EXPERIMENTAL_ANY(),
6364
"catchValue": z.EXPERIMENTAL_ANY(),

pkgs/zss/toZSS_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ func stripGoTypes(schema *zss.ZSSSchema) {
4545
stripGoTypes(schema.Element)
4646
stripGoTypes(schema.Key)
4747
stripGoTypes(schema.Value)
48+
for _, child := range schema.Children {
49+
stripGoTypes(child)
50+
}
4851
}
4952

5053
func TestToJsonString(t *testing.T) {
@@ -212,6 +215,32 @@ func TestToJsonBool(t *testing.T) {
212215
assert.Equal(t, normalize(expected), normalize(string(serialized)))
213216
}
214217

218+
func TestToJsonUnion(t *testing.T) {
219+
s := zog.Union([]zog.ZogSchema{
220+
zog.String(),
221+
zog.Int(),
222+
})
223+
d := zog.EXPERIMENTAL_TO_ZSS[any](s)
224+
serialized, err := json.Marshal(withoutGoTypes(d))
225+
assert.Nil(t, err)
226+
assert.NotNil(t, serialized)
227+
228+
expected := baseZSSJson(`{
229+
"kind": "union",
230+
"children": [
231+
{
232+
"kind": "string"
233+
},
234+
{
235+
"kind": "number"
236+
}
237+
]
238+
}`)
239+
240+
assert.Equal(t, normalize(expected), normalize(string(serialized)))
241+
assert.Nil(t, zssschema.ZSSDocumentSchema.Validate(&d))
242+
}
243+
215244
func TestToJsonTime(t *testing.T) {
216245
s := zog.Time().Required()
217246
d := zog.EXPERIMENTAL_TO_ZSS[time.Time](s)

union.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,15 @@ func (u *UnionSchema) getType() zconst.ZogType {
8585
return zconst.TypeUnion
8686
}
8787
func (u *UnionSchema) setCoercer(c CoercerFunc) {}
88-
func (u *UnionSchema) toZSS(*ZSSSerializeCtx) *zss.ZSSSchema {
89-
return &zss.ZSSSchema{}
88+
89+
func (u *UnionSchema) toZSS(ctx *ZSSSerializeCtx) *zss.ZSSSchema {
90+
children := make([]*zss.ZSSSchema, 0, len(u.schemas))
91+
for _, schema := range u.schemas {
92+
children = append(children, schema.toZSS(ctx))
93+
}
94+
95+
return &zss.ZSSSchema{
96+
Kind: zconst.TypeUnion,
97+
Children: children,
98+
}
9099
}

zconst/consts.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ var ZogTypeValues = []ZogType{
5151
TypePreprocess,
5252
TypeBoxed,
5353
TypeAny,
54+
TypeUnion,
5455
}
5556

5657
// Deprecated: This will be removed in the future. Use z.ZogIssueCode instead

0 commit comments

Comments
 (0)