Skip to content

Commit f8829bd

Browse files
RamazonRasankRam
authored andcommitted
feat: add code generation for discriminator with allOf
1 parent 09919e7 commit f8829bd

File tree

19 files changed

+5116
-7
lines changed

19 files changed

+5116
-7
lines changed

examples/discriminator-allof/api.gen.go

Lines changed: 820 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/discriminator-allof/api.yaml

Lines changed: 534 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package: discriminator
2+
generate:
3+
models: true
4+
output: api.gen.go
5+
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
package discriminator
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
)
7+
8+
// Note: This package demonstrates client-side usage of discriminators with allOf.
9+
// Additional client examples and tests: ./strict-server/client_test.go
10+
// Server-side polymorphism usage: ./strict-server/server_test.go
11+
12+
// ExamplePetDiscriminator demonstrates standard one-level inheritance discriminator usage.
13+
func ExamplePetDiscriminator() {
14+
catJSON := `{"petType": "cat", "name": "Fluffy", "meow": true}`
15+
16+
var pet Pet
17+
if err := json.Unmarshal([]byte(catJSON), &pet); err != nil {
18+
panic(err)
19+
}
20+
21+
fmt.Printf("Pet: %s (type: %s)\n", pet.Name, pet.Discriminator())
22+
23+
// IsCat is here only for clarity. Use only `value, err := pet.AsCat()` for concrete type.
24+
if pet.IsCat() {
25+
cat, _ := pet.AsCat()
26+
fmt.Printf("Cat meows: %v\n", *cat.Meow)
27+
}
28+
}
29+
30+
// ExampleValueByDiscriminator demonstrates ValueByDiscriminator + type switch pattern.
31+
// For client-side processing, Is<Type>()/As<Type>() is often more convenient.
32+
func ExampleValueByDiscriminator() {
33+
catJSON := `{"petType": "cat", "name": "Whiskers", "meow": true}`
34+
35+
var pet Pet
36+
if err := json.Unmarshal([]byte(catJSON), &pet); err != nil {
37+
panic(err)
38+
}
39+
40+
value, err := pet.ValueByDiscriminator()
41+
if err != nil {
42+
panic(err)
43+
}
44+
45+
switch v := value.(type) {
46+
case *Cat:
47+
fmt.Printf("This is a cat: %s (meows: %v)\n", v.Name, *v.Meow)
48+
case *Dog:
49+
fmt.Printf("This is a dog: %s (barks: %v)\n", v.Name, *v.Bark)
50+
default:
51+
fmt.Printf("Unknown pet type: %T\n", v)
52+
}
53+
}
54+
55+
// ExampleNestedDiscriminators demonstrates multi-level discriminator hierarchy.
56+
func ExampleNestedDiscriminators() {
57+
houseCatJSON := `{
58+
"animalType": "domestic",
59+
"domesticType": "housecat",
60+
"name": "Whiskers",
61+
"owner": "John",
62+
"indoor": true
63+
}`
64+
65+
var animal Animal
66+
if err := json.Unmarshal([]byte(houseCatJSON), &animal); err != nil {
67+
panic(err)
68+
}
69+
70+
fmt.Printf("Animal: %s (type: %s)\n", animal.Name, animal.Discriminator())
71+
72+
// Navigate through hierarchy or use `value, err := As<Type>` without Is<Type>.
73+
// The hierarchy navigation is shown for clarity.
74+
if animal.IsDomesticAnimal() {
75+
domestic, _ := animal.AsDomesticAnimal()
76+
fmt.Printf("Domestic type: %s, Owner: %s\n", domestic.Discriminator(), *domestic.Owner)
77+
78+
// Further navigate to concrete type
79+
if domestic.IsHouseCat() {
80+
cat, _ := domestic.AsHouseCat()
81+
fmt.Printf("House cat, Indoor: %v\n", *cat.Indoor)
82+
}
83+
}
84+
85+
// Another example: Lion
86+
lionJSON := `{
87+
"animalType": "wild",
88+
"wildType": "lion",
89+
"name": "Simba",
90+
"habitat": "Savanna",
91+
"maneColor": "golden"
92+
}`
93+
94+
var wildAnimal Animal
95+
if err := json.Unmarshal([]byte(lionJSON), &wildAnimal); err != nil {
96+
panic(err)
97+
}
98+
99+
if wildAnimal.IsWildAnimal() {
100+
wild, _ := wildAnimal.AsWildAnimal()
101+
fmt.Printf("\nWild animal: %s, habitat: %s\n", wild.Name, *wild.Habitat)
102+
103+
if wild.IsLion() {
104+
lion, _ := wild.AsLion()
105+
fmt.Printf("Lion with mane color: %s\n", lion.ManeColor)
106+
}
107+
}
108+
}
109+
110+
// ExampleProcessingArray demonstrates filtering arrays of polymorphic objects.
111+
func ExampleProcessingArray() {
112+
animalsJSON := `[
113+
{"animalType": "domestic", "domesticType": "housecat", "name": "Whiskers", "owner": "Alice", "indoor": true},
114+
{"animalType": "wild", "wildType": "lion", "name": "Simba", "habitat": "Savanna"},
115+
{"animalType": "domestic", "domesticType": "housedog", "name": "Buddy", "owner": "Bob", "trained": true}
116+
]`
117+
118+
var animals []Animal
119+
if err := json.Unmarshal([]byte(animalsJSON), &animals); err != nil {
120+
panic(err)
121+
}
122+
123+
// Select cats
124+
var cats []*HouseCat
125+
for _, animal := range animals {
126+
if animal.IsDomesticAnimal() {
127+
domestic, _ := animal.AsDomesticAnimal()
128+
129+
if domestic.IsHouseCat() {
130+
cat, _ := domestic.AsHouseCat()
131+
cats = append(cats, cat)
132+
}
133+
}
134+
}
135+
fmt.Printf("Found %d cats\n", len(cats))
136+
}
137+
138+
// ExampleMultipleDiscriminators demonstrates handling types with multiple inherited discriminators.
139+
func ExampleMultipleDiscriminators() {
140+
mouseJSON := `{
141+
"petType": "mouse",
142+
"name": "Jerry",
143+
"pestType": "rodent",
144+
"habitat": "house",
145+
"tailLength": 5.5
146+
}`
147+
148+
// Deserialize into Pet (polymorphic base type)
149+
var pet Pet
150+
if err := json.Unmarshal([]byte(mouseJSON), &pet); err != nil {
151+
panic(err)
152+
}
153+
154+
fmt.Printf("Pet: %s (type: %s)\n", pet.Name, pet.Discriminator())
155+
156+
// Convert to Mouse
157+
mouse, _ := pet.AsMouse()
158+
159+
// Mouse has both discriminator properties as regular fields
160+
fmt.Printf("Mouse name: %s\n", mouse.Name)
161+
fmt.Printf("Pet type: %s\n", mouse.PetType)
162+
fmt.Printf("Pest type: %s\n", mouse.PestType)
163+
fmt.Printf("Habitat: %s\n", mouse.Habitat)
164+
if mouse.TailLength != nil {
165+
fmt.Printf("Tail length: %.1f\n", *mouse.TailLength)
166+
}
167+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package discriminator
2+
3+
//go:generate go run ../../cmd/oapi-codegen/oapi-codegen.go --config=cfg.yaml api.yaml
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package: discriminator
2+
generate:
3+
models: true
4+
output: client.gen.go

0 commit comments

Comments
 (0)