diff --git a/internal/ast/compiler/disjunctions.go b/internal/ast/compiler/disjunctions.go index 5cc64ec20..93672cd07 100644 --- a/internal/ast/compiler/disjunctions.go +++ b/internal/ast/compiler/disjunctions.go @@ -110,7 +110,8 @@ func (pass *DisjunctionToType) processDisjunction(visitor *Visitor, schema *ast. processedBranch := branch processedBranch.Nullable = true - fields = append(fields, ast.NewStructField(ast.TypeName(processedBranch), processedBranch)) + structField := ast.NewStructField(ast.TypeName(processedBranch), processedBranch) + fields = append(fields, structField) } structType := ast.NewStruct(fields...) @@ -130,6 +131,8 @@ func (pass *DisjunctionToType) processDisjunction(visitor *Visitor, schema *ast. structType.Hints[ast.HintDiscriminatedDisjunctionOfRefs] = disjunction } + structType.Default = def.Default + newObject := ast.NewObject(schema.Package, newTypeName, structType) newObject.AddToPassesTrail("DisjunctionToType[created]") diff --git a/internal/ast/compiler/disjunctions_infer_mapping.go b/internal/ast/compiler/disjunctions_infer_mapping.go index 03c30de5f..43a482395 100644 --- a/internal/ast/compiler/disjunctions_infer_mapping.go +++ b/internal/ast/compiler/disjunctions_infer_mapping.go @@ -37,6 +37,7 @@ func (pass *DisjunctionInferMapping) processDisjunction(_ *Visitor, schema *ast. return def, nil } + def.Default = pass.parseDefault(def) return def, nil } @@ -150,6 +151,10 @@ func (pass *DisjunctionInferMapping) buildDiscriminatorMapping(schema *ast.Schem return nil, fmt.Errorf("could not resolve reference '%s'", branch.AsRef().String()) } + if !referredType.IsStruct() { + continue + } + structType := referredType.AsStruct() field, found := structType.FieldByName(def.Discriminator) @@ -176,3 +181,23 @@ func (pass *DisjunctionInferMapping) buildDiscriminatorMapping(schema *ast.Schem return mapping, nil } + +func (pass *DisjunctionInferMapping) parseDefault(t ast.Type) any { + if t.Default == nil { + return nil + } + + disjunction := t.Disjunction + + defs := t.Default.(map[string]interface{}) + for _, value := range defs { + if _, ok := value.(string); !ok { + continue + } + if referenceName, ok := disjunction.DiscriminatorMapping[value.(string)]; ok { + return referenceName + } + } + + return t.Default +} diff --git a/internal/jennies/golang/rawtypes.go b/internal/jennies/golang/rawtypes.go index f98c65c95..002ee1fcf 100644 --- a/internal/jennies/golang/rawtypes.go +++ b/internal/jennies/golang/rawtypes.go @@ -252,7 +252,8 @@ func (jenny RawTypes) defaultsForStruct(context languages.Context, objectRef ast (field.Required && field.Type.IsArray()) || (field.Required && field.Type.IsMap()) || field.Type.IsConcreteScalar() || - field.Type.IsConstantRef() + field.Type.IsConstantRef() || + (objectType.Default != nil && field.Name == objectType.Default) if !needsExplicitDefault { continue } @@ -295,6 +296,8 @@ func (jenny RawTypes) defaultsForStruct(context languages.Context, objectRef ast defaultValue = formatScalar(field.Type.Default) defaultValue = jenny.maybeValueAsPointer(defaultValue, field.Type.Nullable, resolvedFieldType) + } else if objectType.Default != nil && objectType.IsRef() { + defaultValue = fmt.Sprintf("New%s()", field.Name) } else if field.Type.IsRef() && resolvedFieldType.IsStruct() && field.Type.Default != nil { defaultValue = jenny.defaultsForStruct(context, *field.Type.Ref, resolvedFieldType, field.Type.Default) if field.Type.Nullable { diff --git a/internal/jennies/typescript/jennies.go b/internal/jennies/typescript/jennies.go index 2708624d9..66fe6783a 100644 --- a/internal/jennies/typescript/jennies.go +++ b/internal/jennies/typescript/jennies.go @@ -147,6 +147,7 @@ func (language *Language) Jennies(globalConfig languages.Config) *codejen.JennyL func (language *Language) CompilerPasses() compiler.Passes { return compiler.Passes{ &compiler.RenameNumericEnumValues{}, + &compiler.DisjunctionInferMapping{}, } } diff --git a/internal/jennies/typescript/rawtypes.go b/internal/jennies/typescript/rawtypes.go index 84c6e4316..2301c09cc 100644 --- a/internal/jennies/typescript/rawtypes.go +++ b/internal/jennies/typescript/rawtypes.go @@ -145,6 +145,14 @@ func (jenny RawTypes) defaultValueForObject(object ast.Object, packageMapper pac } return raw(jenny.typeFormatter.enums.formatValue(object, defaultValue)) + case ast.KindDisjunction: + if object.Type.Default != nil { + if object.Type.AsDisjunction().Branches[0].IsRef() { + return raw(fmt.Sprintf("default%s()", object.Type.Default)) + } + return object.Type.Default + } + fallthrough default: return jenny.defaultValueForType(object.Type, packageMapper) } diff --git a/internal/simplecue/generator.go b/internal/simplecue/generator.go index 9ddac3dee..a05be9cde 100644 --- a/internal/simplecue/generator.go +++ b/internal/simplecue/generator.go @@ -548,27 +548,7 @@ func (g *generator) declareDisjunction(v cue.Value, hints ast.JenniesHints, defa return g.declareAnonymousEnum(v, defaultValue, hints) } - _, disjunctionBranchesWithPossibleDefault := v.Expr() - defaultAsCueValue, hasDefault := v.Default() - - disjunctionBranches := make([]cue.Value, 0, len(disjunctionBranchesWithPossibleDefault)) - for _, branch := range disjunctionBranchesWithPossibleDefault { - if hasDefault && branch.Equals(defaultAsCueValue) { - _, bPath := branch.ReferencePath() - _, dPath := defaultAsCueValue.ReferencePath() - - if bPath.String() == dPath.String() { - continue - } - } - - disjunctionBranches = append(disjunctionBranches, branch) - } - - // not a disjunction anymore - if len(disjunctionBranchesWithPossibleDefault) != len(disjunctionBranches) && len(disjunctionBranches) == 1 { - return g.declareNode(disjunctionBranches[0]) - } + _, disjunctionBranches := v.Expr() // We must be looking at a disjunction then (2) branches := make([]ast.Type, 0, len(disjunctionBranches)) diff --git a/testdata/jennies/rawtypes/default_disjunction_value/GoRawTypes/default_disjunction_value/types_gen.go b/testdata/jennies/rawtypes/default_disjunction_value/GoRawTypes/default_disjunction_value/types_gen.go new file mode 100644 index 000000000..0bfdb4428 --- /dev/null +++ b/testdata/jennies/rawtypes/default_disjunction_value/GoRawTypes/default_disjunction_value/types_gen.go @@ -0,0 +1,837 @@ +package default_disjunction_value + +import ( + "encoding/json" + cog "github.com/grafana/cog/generated/cog" + "errors" + "fmt" +) + +type DisjunctionClasses = ValueAOrValueBOrValueC + +// NewDisjunctionClasses creates a new DisjunctionClasses object. +func NewDisjunctionClasses() *DisjunctionClasses { + return NewValueAOrValueBOrValueC() +} +type ValueA struct { + Type string `json:"type"` + AnArray []string `json:"anArray"` + OtherRef ValueB `json:"otherRef"` +} + +// NewValueA creates a new ValueA object. +func NewValueA() *ValueA { + return &ValueA{ + Type: "A", + OtherRef: *NewValueB(), +} +} +// UnmarshalJSONStrict implements a custom JSON unmarshalling logic to decode `ValueA` from JSON. +// Note: the unmarshalling done by this function is strict. It will fail over required fields being absent from the input, fields having an incorrect type, unexpected fields being present, … +func (resource *ValueA) UnmarshalJSONStrict(raw []byte) error { + if raw == nil { + return nil + } + var errs cog.BuildErrors + + fields := make(map[string]json.RawMessage) + if err := json.Unmarshal(raw, &fields); err != nil { + return err + } + // Field "type" + if fields["type"] != nil { + if string(fields["type"]) != "null" { + if err := json.Unmarshal(fields["type"], &resource.Type); err != nil { + errs = append(errs, cog.MakeBuildErrors("type", err)...) + } + } else {errs = append(errs, cog.MakeBuildErrors("type", errors.New("required field is null"))...) + + } + delete(fields, "type") + } else {errs = append(errs, cog.MakeBuildErrors("type", errors.New("required field is missing from input"))...) + } + // Field "anArray" + if fields["anArray"] != nil { + if string(fields["anArray"]) != "null" { + + if err := json.Unmarshal(fields["anArray"], &resource.AnArray); err != nil { + errs = append(errs, cog.MakeBuildErrors("anArray", err)...) + } + } else {errs = append(errs, cog.MakeBuildErrors("anArray", errors.New("required field is null"))...) + + } + delete(fields, "anArray") + } else {errs = append(errs, cog.MakeBuildErrors("anArray", errors.New("required field is missing from input"))...) + } + // Field "otherRef" + if fields["otherRef"] != nil { + if string(fields["otherRef"]) != "null" { + + resource.OtherRef = ValueB{} + if err := resource.OtherRef.UnmarshalJSONStrict(fields["otherRef"]); err != nil { + errs = append(errs, cog.MakeBuildErrors("otherRef", err)...) + } + } else {errs = append(errs, cog.MakeBuildErrors("otherRef", errors.New("required field is null"))...) + + } + delete(fields, "otherRef") + } else {errs = append(errs, cog.MakeBuildErrors("otherRef", errors.New("required field is missing from input"))...) + } + + for field := range fields { + errs = append(errs, cog.MakeBuildErrors("ValueA", fmt.Errorf("unexpected field '%s'", field))...) + } + + if len(errs) == 0 { + return nil + } + + return errs +} + + +// Equals tests the equality of two `ValueA` objects. +func (resource ValueA) Equals(other ValueA) bool { + if resource.Type != other.Type { + return false + } + + if len(resource.AnArray) != len(other.AnArray) { + return false + } + + for i1 := range resource.AnArray { + if resource.AnArray[i1] != other.AnArray[i1] { + return false + } + } + if !resource.OtherRef.Equals(other.OtherRef) { + return false + } + + return true +} + + +// Validate checks all the validation constraints that may be defined on `ValueA` fields for violations and returns them. +func (resource ValueA) Validate() error { + var errs cog.BuildErrors + if err := resource.OtherRef.Validate(); err != nil { + errs = append(errs, cog.MakeBuildErrors("otherRef", err)...) + } + + if len(errs) == 0 { + return nil + } + + return errs +} + + +type ValueB struct { + Type string `json:"type"` + AMap map[string]int64 `json:"aMap"` + Def Int64OrStringOrBool `json:"def"` +} + +// NewValueB creates a new ValueB object. +func NewValueB() *ValueB { + return &ValueB{ + Type: "B", + Def: *NewInt64OrStringOrBool(), +} +} +// UnmarshalJSONStrict implements a custom JSON unmarshalling logic to decode `ValueB` from JSON. +// Note: the unmarshalling done by this function is strict. It will fail over required fields being absent from the input, fields having an incorrect type, unexpected fields being present, … +func (resource *ValueB) UnmarshalJSONStrict(raw []byte) error { + if raw == nil { + return nil + } + var errs cog.BuildErrors + + fields := make(map[string]json.RawMessage) + if err := json.Unmarshal(raw, &fields); err != nil { + return err + } + // Field "type" + if fields["type"] != nil { + if string(fields["type"]) != "null" { + if err := json.Unmarshal(fields["type"], &resource.Type); err != nil { + errs = append(errs, cog.MakeBuildErrors("type", err)...) + } + } else {errs = append(errs, cog.MakeBuildErrors("type", errors.New("required field is null"))...) + + } + delete(fields, "type") + } else {errs = append(errs, cog.MakeBuildErrors("type", errors.New("required field is missing from input"))...) + } + // Field "aMap" + if fields["aMap"] != nil { + if string(fields["aMap"]) != "null" { + + if err := json.Unmarshal(fields["aMap"], &resource.AMap); err != nil { + errs = append(errs, cog.MakeBuildErrors("aMap", err)...) + } + } else {errs = append(errs, cog.MakeBuildErrors("aMap", errors.New("required field is null"))...) + + } + delete(fields, "aMap") + } else {errs = append(errs, cog.MakeBuildErrors("aMap", errors.New("required field is missing from input"))...) + } + // Field "def" + if fields["def"] != nil { + if string(fields["def"]) != "null" { + + resource.Def = Int64OrStringOrBool{} + if err := resource.Def.UnmarshalJSONStrict(fields["def"]); err != nil { + errs = append(errs, cog.MakeBuildErrors("def", err)...) + } + } else {errs = append(errs, cog.MakeBuildErrors("def", errors.New("required field is null"))...) + + } + delete(fields, "def") + } else {errs = append(errs, cog.MakeBuildErrors("def", errors.New("required field is missing from input"))...) + } + + for field := range fields { + errs = append(errs, cog.MakeBuildErrors("ValueB", fmt.Errorf("unexpected field '%s'", field))...) + } + + if len(errs) == 0 { + return nil + } + + return errs +} + + +// Equals tests the equality of two `ValueB` objects. +func (resource ValueB) Equals(other ValueB) bool { + if resource.Type != other.Type { + return false + } + + if len(resource.AMap) != len(other.AMap) { + return false + } + + for key1 := range resource.AMap { + if resource.AMap[key1] != other.AMap[key1] { + return false + } + } + if !resource.Def.Equals(other.Def) { + return false + } + + return true +} + + +// Validate checks all the validation constraints that may be defined on `ValueB` fields for violations and returns them. +func (resource ValueB) Validate() error { + var errs cog.BuildErrors + if err := resource.Def.Validate(); err != nil { + errs = append(errs, cog.MakeBuildErrors("def", err)...) + } + + if len(errs) == 0 { + return nil + } + + return errs +} + + +type ValueC struct { + Type string `json:"type"` + Other float32 `json:"other"` +} + +// NewValueC creates a new ValueC object. +func NewValueC() *ValueC { + return &ValueC{ + Type: "C", +} +} +// UnmarshalJSONStrict implements a custom JSON unmarshalling logic to decode `ValueC` from JSON. +// Note: the unmarshalling done by this function is strict. It will fail over required fields being absent from the input, fields having an incorrect type, unexpected fields being present, … +func (resource *ValueC) UnmarshalJSONStrict(raw []byte) error { + if raw == nil { + return nil + } + var errs cog.BuildErrors + + fields := make(map[string]json.RawMessage) + if err := json.Unmarshal(raw, &fields); err != nil { + return err + } + // Field "type" + if fields["type"] != nil { + if string(fields["type"]) != "null" { + if err := json.Unmarshal(fields["type"], &resource.Type); err != nil { + errs = append(errs, cog.MakeBuildErrors("type", err)...) + } + } else {errs = append(errs, cog.MakeBuildErrors("type", errors.New("required field is null"))...) + + } + delete(fields, "type") + } else {errs = append(errs, cog.MakeBuildErrors("type", errors.New("required field is missing from input"))...) + } + // Field "other" + if fields["other"] != nil { + if string(fields["other"]) != "null" { + if err := json.Unmarshal(fields["other"], &resource.Other); err != nil { + errs = append(errs, cog.MakeBuildErrors("other", err)...) + } + } else {errs = append(errs, cog.MakeBuildErrors("other", errors.New("required field is null"))...) + + } + delete(fields, "other") + } else {errs = append(errs, cog.MakeBuildErrors("other", errors.New("required field is missing from input"))...) + } + + for field := range fields { + errs = append(errs, cog.MakeBuildErrors("ValueC", fmt.Errorf("unexpected field '%s'", field))...) + } + + if len(errs) == 0 { + return nil + } + + return errs +} + + +// Equals tests the equality of two `ValueC` objects. +func (resource ValueC) Equals(other ValueC) bool { + if resource.Type != other.Type { + return false + } + if resource.Other != other.Other { + return false + } + + return true +} + + +// Validate checks all the validation constraints that may be defined on `ValueC` fields for violations and returns them. +func (resource ValueC) Validate() error { + return nil +} + + +type DisjunctionConstants = StringOrInt64OrBool + +// NewDisjunctionConstants creates a new DisjunctionConstants object. +func NewDisjunctionConstants() *DisjunctionConstants { + return NewStringOrInt64OrBool() +} +type ValueAOrValueBOrValueC struct { + ValueA *ValueA `json:"ValueA,omitempty"` + ValueB *ValueB `json:"ValueB,omitempty"` + ValueC *ValueC `json:"ValueC,omitempty"` +} + +// NewValueAOrValueBOrValueC creates a new ValueAOrValueBOrValueC object. +func NewValueAOrValueBOrValueC() *ValueAOrValueBOrValueC { + return &ValueAOrValueBOrValueC{ + ValueA: NewValueA(), +} +} +// MarshalJSON implements a custom JSON marshalling logic to encode `ValueAOrValueBOrValueC` as JSON. +func (resource ValueAOrValueBOrValueC) MarshalJSON() ([]byte, error) { + if resource.ValueA != nil { + return json.Marshal(resource.ValueA) + } + if resource.ValueB != nil { + return json.Marshal(resource.ValueB) + } + if resource.ValueC != nil { + return json.Marshal(resource.ValueC) + } + return nil, fmt.Errorf("no value for disjunction of refs") +} + +// UnmarshalJSON implements a custom JSON unmarshalling logic to decode `ValueAOrValueBOrValueC` from JSON. +func (resource *ValueAOrValueBOrValueC) UnmarshalJSON(raw []byte) error { + if raw == nil { + return nil + } + + // FIXME: this is wasteful, we need to find a more efficient way to unmarshal this. + parsedAsMap := make(map[string]any) + if err := json.Unmarshal(raw, &parsedAsMap); err != nil { + return err + } + + discriminator, found := parsedAsMap["type"] + if !found { + return errors.New("discriminator field 'type' not found in payload") + } + + switch discriminator { + case "A": + var valueA ValueA + if err := json.Unmarshal(raw, &valueA); err != nil { + return err + } + + resource.ValueA = &valueA + return nil + case "B": + var valueB ValueB + if err := json.Unmarshal(raw, &valueB); err != nil { + return err + } + + resource.ValueB = &valueB + return nil + case "C": + var valueC ValueC + if err := json.Unmarshal(raw, &valueC); err != nil { + return err + } + + resource.ValueC = &valueC + return nil + } + + return fmt.Errorf("could not unmarshal resource with `type = %v`", discriminator) +} + + +// UnmarshalJSONStrict implements a custom JSON unmarshalling logic to decode `ValueAOrValueBOrValueC` from JSON. +// Note: the unmarshalling done by this function is strict. It will fail over required fields being absent from the input, fields having an incorrect type, unexpected fields being present, … +func (resource *ValueAOrValueBOrValueC) UnmarshalJSONStrict(raw []byte) error { + if raw == nil { + return nil + } + // FIXME: this is wasteful, we need to find a more efficient way to unmarshal this. + parsedAsMap := make(map[string]any) + if err := json.Unmarshal(raw, &parsedAsMap); err != nil { + return err + } + + discriminator, found := parsedAsMap["type"] + if !found { + return fmt.Errorf("discriminator field 'type' not found in payload") + } + + switch discriminator { + case "A": + valueA := &ValueA{} + if err := valueA.UnmarshalJSONStrict(raw); err != nil { + return err + } + + resource.ValueA = valueA + return nil + case "B": + valueB := &ValueB{} + if err := valueB.UnmarshalJSONStrict(raw); err != nil { + return err + } + + resource.ValueB = valueB + return nil + case "C": + valueC := &ValueC{} + if err := valueC.UnmarshalJSONStrict(raw); err != nil { + return err + } + + resource.ValueC = valueC + return nil + } + + return fmt.Errorf("could not unmarshal resource with `type = %v`", discriminator) +} + +// Equals tests the equality of two `ValueAOrValueBOrValueC` objects. +func (resource ValueAOrValueBOrValueC) Equals(other ValueAOrValueBOrValueC) bool { + if resource.ValueA == nil && other.ValueA != nil || resource.ValueA != nil && other.ValueA == nil { + return false + } + + if resource.ValueA != nil { + if !resource.ValueA.Equals(*other.ValueA) { + return false + } + } + if resource.ValueB == nil && other.ValueB != nil || resource.ValueB != nil && other.ValueB == nil { + return false + } + + if resource.ValueB != nil { + if !resource.ValueB.Equals(*other.ValueB) { + return false + } + } + if resource.ValueC == nil && other.ValueC != nil || resource.ValueC != nil && other.ValueC == nil { + return false + } + + if resource.ValueC != nil { + if !resource.ValueC.Equals(*other.ValueC) { + return false + } + } + + return true +} + + +// Validate checks all the validation constraints that may be defined on `ValueAOrValueBOrValueC` fields for violations and returns them. +func (resource ValueAOrValueBOrValueC) Validate() error { + var errs cog.BuildErrors + if resource.ValueA != nil { + if err := resource.ValueA.Validate(); err != nil { + errs = append(errs, cog.MakeBuildErrors("ValueA", err)...) + } + } + if resource.ValueB != nil { + if err := resource.ValueB.Validate(); err != nil { + errs = append(errs, cog.MakeBuildErrors("ValueB", err)...) + } + } + if resource.ValueC != nil { + if err := resource.ValueC.Validate(); err != nil { + errs = append(errs, cog.MakeBuildErrors("ValueC", err)...) + } + } + + if len(errs) == 0 { + return nil + } + + return errs +} + + +type Int64OrStringOrBool struct { + Int64 *int64 `json:"Int64,omitempty"` + String *string `json:"String,omitempty"` + Bool *bool `json:"Bool,omitempty"` +} + +// NewInt64OrStringOrBool creates a new Int64OrStringOrBool object. +func NewInt64OrStringOrBool() *Int64OrStringOrBool { + return &Int64OrStringOrBool{ + Int64: (func (input int64) *int64 { return &input })(1), + String: (func (input string) *string { return &input })("a"), +} +} +// MarshalJSON implements a custom JSON marshalling logic to encode `Int64OrStringOrBool` as JSON. +func (resource Int64OrStringOrBool) MarshalJSON() ([]byte, error) { + if resource.Int64 != nil { + return json.Marshal(resource.Int64) + } + + if resource.String != nil { + return json.Marshal(resource.String) + } + + if resource.Bool != nil { + return json.Marshal(resource.Bool) + } + + return nil, fmt.Errorf("no value for disjunction of scalars") +} + +// UnmarshalJSON implements a custom JSON unmarshalling logic to decode `Int64OrStringOrBool` from JSON. +func (resource *Int64OrStringOrBool) UnmarshalJSON(raw []byte) error { + if raw == nil { + return nil + } + + var errList []error + + // Int64 + var Int64 int64 + if err := json.Unmarshal(raw, &Int64); err != nil { + errList = append(errList, err) + resource.Int64 = nil + } else { + resource.Int64 = &Int64 + return nil + } + + // String + var String string + if err := json.Unmarshal(raw, &String); err != nil { + errList = append(errList, err) + resource.String = nil + } else { + resource.String = &String + return nil + } + + // Bool + var Bool bool + if err := json.Unmarshal(raw, &Bool); err != nil { + errList = append(errList, err) + resource.Bool = nil + } else { + resource.Bool = &Bool + return nil + } + + return errors.Join(errList...) +} + + +// UnmarshalJSONStrict implements a custom JSON unmarshalling logic to decode `Int64OrStringOrBool` from JSON. +// Note: the unmarshalling done by this function is strict. It will fail over required fields being absent from the input, fields having an incorrect type, unexpected fields being present, … +func (resource *Int64OrStringOrBool) UnmarshalJSONStrict(raw []byte) error { + if raw == nil { + return nil + } + var errs cog.BuildErrors + var errList []error + + // Int64 + var Int64 int64 + + if err := json.Unmarshal(raw, &Int64); err != nil { + errList = append(errList, err) + } else { + resource.Int64 = &Int64 + return nil + } + + // String + var String string + + if err := json.Unmarshal(raw, &String); err != nil { + errList = append(errList, err) + } else { + resource.String = &String + return nil + } + + // Bool + var Bool bool + + if err := json.Unmarshal(raw, &Bool); err != nil { + errList = append(errList, err) + } else { + resource.Bool = &Bool + return nil + } + + + if len(errList) != 0 { + errs = append(errs, cog.MakeBuildErrors("Int64OrStringOrBool", errors.Join(errList...))...) + } + + if len(errs) == 0 { + return nil + } + + return errs +} + +// Equals tests the equality of two `Int64OrStringOrBool` objects. +func (resource Int64OrStringOrBool) Equals(other Int64OrStringOrBool) bool { + if resource.Int64 == nil && other.Int64 != nil || resource.Int64 != nil && other.Int64 == nil { + return false + } + + if resource.Int64 != nil { + if *resource.Int64 != *other.Int64 { + return false + } + } + if resource.String == nil && other.String != nil || resource.String != nil && other.String == nil { + return false + } + + if resource.String != nil { + if *resource.String != *other.String { + return false + } + } + if resource.Bool == nil && other.Bool != nil || resource.Bool != nil && other.Bool == nil { + return false + } + + if resource.Bool != nil { + if *resource.Bool != *other.Bool { + return false + } + } + + return true +} + + +// Validate checks all the validation constraints that may be defined on `Int64OrStringOrBool` fields for violations and returns them. +func (resource Int64OrStringOrBool) Validate() error { + return nil +} + + +type StringOrInt64OrBool struct { + String *string `json:"String,omitempty"` + Int64 *int64 `json:"Int64,omitempty"` + Bool *bool `json:"Bool,omitempty"` +} + +// NewStringOrInt64OrBool creates a new StringOrInt64OrBool object. +func NewStringOrInt64OrBool() *StringOrInt64OrBool { + return &StringOrInt64OrBool{ + String: (func (input string) *string { return &input })("abc"), + Int64: (func (input int64) *int64 { return &input })(1), + Bool: (func (input bool) *bool { return &input })(true), +} +} +// MarshalJSON implements a custom JSON marshalling logic to encode `StringOrInt64OrBool` as JSON. +func (resource StringOrInt64OrBool) MarshalJSON() ([]byte, error) { + if resource.String != nil { + return json.Marshal(resource.String) + } + + if resource.Int64 != nil { + return json.Marshal(resource.Int64) + } + + if resource.Bool != nil { + return json.Marshal(resource.Bool) + } + + return nil, fmt.Errorf("no value for disjunction of scalars") +} + +// UnmarshalJSON implements a custom JSON unmarshalling logic to decode `StringOrInt64OrBool` from JSON. +func (resource *StringOrInt64OrBool) UnmarshalJSON(raw []byte) error { + if raw == nil { + return nil + } + + var errList []error + + // String + var String string + if err := json.Unmarshal(raw, &String); err != nil { + errList = append(errList, err) + resource.String = nil + } else { + resource.String = &String + return nil + } + + // Int64 + var Int64 int64 + if err := json.Unmarshal(raw, &Int64); err != nil { + errList = append(errList, err) + resource.Int64 = nil + } else { + resource.Int64 = &Int64 + return nil + } + + // Bool + var Bool bool + if err := json.Unmarshal(raw, &Bool); err != nil { + errList = append(errList, err) + resource.Bool = nil + } else { + resource.Bool = &Bool + return nil + } + + return errors.Join(errList...) +} + + +// UnmarshalJSONStrict implements a custom JSON unmarshalling logic to decode `StringOrInt64OrBool` from JSON. +// Note: the unmarshalling done by this function is strict. It will fail over required fields being absent from the input, fields having an incorrect type, unexpected fields being present, … +func (resource *StringOrInt64OrBool) UnmarshalJSONStrict(raw []byte) error { + if raw == nil { + return nil + } + var errs cog.BuildErrors + var errList []error + + // String + var String string + + if err := json.Unmarshal(raw, &String); err != nil { + errList = append(errList, err) + } else { + resource.String = &String + return nil + } + + // Int64 + var Int64 int64 + + if err := json.Unmarshal(raw, &Int64); err != nil { + errList = append(errList, err) + } else { + resource.Int64 = &Int64 + return nil + } + + // Bool + var Bool bool + + if err := json.Unmarshal(raw, &Bool); err != nil { + errList = append(errList, err) + } else { + resource.Bool = &Bool + return nil + } + + + if len(errList) != 0 { + errs = append(errs, cog.MakeBuildErrors("StringOrInt64OrBool", errors.Join(errList...))...) + } + + if len(errs) == 0 { + return nil + } + + return errs +} + +// Equals tests the equality of two `StringOrInt64OrBool` objects. +func (resource StringOrInt64OrBool) Equals(other StringOrInt64OrBool) bool { + if resource.String == nil && other.String != nil || resource.String != nil && other.String == nil { + return false + } + + if resource.String != nil { + if *resource.String != *other.String { + return false + } + } + if resource.Int64 == nil && other.Int64 != nil || resource.Int64 != nil && other.Int64 == nil { + return false + } + + if resource.Int64 != nil { + if *resource.Int64 != *other.Int64 { + return false + } + } + if resource.Bool == nil && other.Bool != nil || resource.Bool != nil && other.Bool == nil { + return false + } + + if resource.Bool != nil { + if *resource.Bool != *other.Bool { + return false + } + } + + return true +} + + +// Validate checks all the validation constraints that may be defined on `StringOrInt64OrBool` fields for violations and returns them. +func (resource StringOrInt64OrBool) Validate() error { + return nil +} diff --git a/testdata/jennies/rawtypes/default_disjunction_value/JSONSchema/default_disjunction_value.jsonschema.json b/testdata/jennies/rawtypes/default_disjunction_value/JSONSchema/default_disjunction_value.jsonschema.json new file mode 100644 index 000000000..795cc47cf --- /dev/null +++ b/testdata/jennies/rawtypes/default_disjunction_value/JSONSchema/default_disjunction_value.jsonschema.json @@ -0,0 +1,112 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "definitions": { + "DisjunctionClasses": { + "anyOf": [ + { + "$ref": "#/definitions/ValueA" + }, + { + "$ref": "#/definitions/ValueB" + }, + { + "$ref": "#/definitions/ValueC" + } + ] + }, + "ValueA": { + "type": "object", + "additionalProperties": false, + "required": [ + "type", + "anArray", + "otherRef" + ], + "properties": { + "type": { + "type": "string", + "const": "A" + }, + "anArray": { + "type": "array", + "items": { + "type": "string" + } + }, + "otherRef": { + "$ref": "#/definitions/ValueB" + } + } + }, + "ValueB": { + "type": "object", + "additionalProperties": false, + "required": [ + "type", + "aMap", + "def" + ], + "properties": { + "type": { + "type": "string", + "const": "B" + }, + "aMap": { + "type": "object", + "additionalProperties": { + "type": "integer" + } + }, + "def": { + "anyOf": [ + { + "type": "integer", + "const": 1 + }, + { + "type": "string", + "const": "a" + }, + { + "type": "boolean" + } + ], + "default": 1 + } + } + }, + "ValueC": { + "type": "object", + "additionalProperties": false, + "required": [ + "type", + "other" + ], + "properties": { + "type": { + "type": "string", + "const": "C" + }, + "other": { + "type": "number" + } + } + }, + "DisjunctionConstants": { + "anyOf": [ + { + "type": "string", + "const": "abc" + }, + { + "type": "integer", + "const": 1 + }, + { + "type": "boolean", + "const": true + } + ] + } + } +} diff --git a/testdata/jennies/rawtypes/default_disjunction_value/JavaRawTypes/default_disjunction_value/DisjunctionClasses.java b/testdata/jennies/rawtypes/default_disjunction_value/JavaRawTypes/default_disjunction_value/DisjunctionClasses.java new file mode 100644 index 000000000..0c738f6d3 --- /dev/null +++ b/testdata/jennies/rawtypes/default_disjunction_value/JavaRawTypes/default_disjunction_value/DisjunctionClasses.java @@ -0,0 +1,24 @@ +package default_disjunction_value; + + +public class DisjunctionClasses { + protected ValueA valueA; + protected ValueB valueB; + protected ValueC valueC; + protected DisjunctionClasses() {} + public static DisjunctionClasses createValueA(ValueA valueA) { + DisjunctionClasses disjunctionClasses = new DisjunctionClasses(); + disjunctionClasses.valueA = valueA; + return disjunctionClasses; + } + public static DisjunctionClasses createValueB(ValueB valueB) { + DisjunctionClasses disjunctionClasses = new DisjunctionClasses(); + disjunctionClasses.valueB = valueB; + return disjunctionClasses; + } + public static DisjunctionClasses createValueC(ValueC valueC) { + DisjunctionClasses disjunctionClasses = new DisjunctionClasses(); + disjunctionClasses.valueC = valueC; + return disjunctionClasses; + } +} diff --git a/testdata/jennies/rawtypes/default_disjunction_value/JavaRawTypes/default_disjunction_value/DisjunctionConstants.java b/testdata/jennies/rawtypes/default_disjunction_value/JavaRawTypes/default_disjunction_value/DisjunctionConstants.java new file mode 100644 index 000000000..229a57f06 --- /dev/null +++ b/testdata/jennies/rawtypes/default_disjunction_value/JavaRawTypes/default_disjunction_value/DisjunctionConstants.java @@ -0,0 +1,24 @@ +package default_disjunction_value; + + +public class DisjunctionConstants { + protected String string; + protected Long int64; + protected Boolean bool; + protected DisjunctionConstants() {} + public static DisjunctionConstants createString(String string) { + DisjunctionConstants disjunctionConstants = new DisjunctionConstants(); + disjunctionConstants.string = string; + return disjunctionConstants; + } + public static DisjunctionConstants createInt64(Long int64) { + DisjunctionConstants disjunctionConstants = new DisjunctionConstants(); + disjunctionConstants.int64 = int64; + return disjunctionConstants; + } + public static DisjunctionConstants createBool(Boolean bool) { + DisjunctionConstants disjunctionConstants = new DisjunctionConstants(); + disjunctionConstants.bool = bool; + return disjunctionConstants; + } +} diff --git a/testdata/jennies/rawtypes/default_disjunction_value/JavaRawTypes/default_disjunction_value/Int64OrStringOrBool.java b/testdata/jennies/rawtypes/default_disjunction_value/JavaRawTypes/default_disjunction_value/Int64OrStringOrBool.java new file mode 100644 index 000000000..f39918f78 --- /dev/null +++ b/testdata/jennies/rawtypes/default_disjunction_value/JavaRawTypes/default_disjunction_value/Int64OrStringOrBool.java @@ -0,0 +1,24 @@ +package default_disjunction_value; + + +public class Int64OrStringOrBool { + protected Long int64; + protected String string; + protected Boolean bool; + protected Int64OrStringOrBool() {} + public static Int64OrStringOrBool createInt64(Long int64) { + Int64OrStringOrBool int64OrStringOrBool = new Int64OrStringOrBool(); + int64OrStringOrBool.int64 = int64; + return int64OrStringOrBool; + } + public static Int64OrStringOrBool createString(String string) { + Int64OrStringOrBool int64OrStringOrBool = new Int64OrStringOrBool(); + int64OrStringOrBool.string = string; + return int64OrStringOrBool; + } + public static Int64OrStringOrBool createBool(Boolean bool) { + Int64OrStringOrBool int64OrStringOrBool = new Int64OrStringOrBool(); + int64OrStringOrBool.bool = bool; + return int64OrStringOrBool; + } +} diff --git a/testdata/jennies/rawtypes/default_disjunction_value/JavaRawTypes/default_disjunction_value/ValueA.java b/testdata/jennies/rawtypes/default_disjunction_value/JavaRawTypes/default_disjunction_value/ValueA.java new file mode 100644 index 000000000..990981bec --- /dev/null +++ b/testdata/jennies/rawtypes/default_disjunction_value/JavaRawTypes/default_disjunction_value/ValueA.java @@ -0,0 +1,16 @@ +package default_disjunction_value; + +import java.util.List; + +public class ValueA { + public String type; + public List anArray; + public ValueB otherRef; + public ValueA() { + } + public ValueA(String type,List anArray,ValueB otherRef) { + this.type = type; + this.anArray = anArray; + this.otherRef = otherRef; + } +} diff --git a/testdata/jennies/rawtypes/default_disjunction_value/JavaRawTypes/default_disjunction_value/ValueB.java b/testdata/jennies/rawtypes/default_disjunction_value/JavaRawTypes/default_disjunction_value/ValueB.java new file mode 100644 index 000000000..29d010b2a --- /dev/null +++ b/testdata/jennies/rawtypes/default_disjunction_value/JavaRawTypes/default_disjunction_value/ValueB.java @@ -0,0 +1,16 @@ +package default_disjunction_value; + +import java.util.Map; + +public class ValueB { + public String type; + public Map aMap; + public Int64OrStringOrBool def; + public ValueB() { + } + public ValueB(String type,Map aMap,Int64OrStringOrBool def) { + this.type = type; + this.aMap = aMap; + this.def = def; + } +} diff --git a/testdata/jennies/rawtypes/default_disjunction_value/JavaRawTypes/default_disjunction_value/ValueC.java b/testdata/jennies/rawtypes/default_disjunction_value/JavaRawTypes/default_disjunction_value/ValueC.java new file mode 100644 index 000000000..2c9db3f84 --- /dev/null +++ b/testdata/jennies/rawtypes/default_disjunction_value/JavaRawTypes/default_disjunction_value/ValueC.java @@ -0,0 +1,13 @@ +package default_disjunction_value; + + +public class ValueC { + public String type; + public Float other; + public ValueC() { + } + public ValueC(String type,Float other) { + this.type = type; + this.other = other; + } +} diff --git a/testdata/jennies/rawtypes/default_disjunction_value/OpenAPI/default_disjunction_value.openapi.json b/testdata/jennies/rawtypes/default_disjunction_value/OpenAPI/default_disjunction_value.openapi.json new file mode 100644 index 000000000..b28794640 --- /dev/null +++ b/testdata/jennies/rawtypes/default_disjunction_value/OpenAPI/default_disjunction_value.openapi.json @@ -0,0 +1,121 @@ +{ + "openapi": "3.0.0", + "info": { + "title": "default_disjunction_value", + "version": "0.0.0", + "x-schema-identifier": "", + "x-schema-kind": "" + }, + "paths": {}, + "components": { + "schemas": { + "DisjunctionClasses": { + "anyOf": [ + { + "$ref": "#/components/schemas/ValueA" + }, + { + "$ref": "#/components/schemas/ValueB" + }, + { + "$ref": "#/components/schemas/ValueC" + } + ] + }, + "ValueA": { + "type": "object", + "additionalProperties": false, + "required": [ + "type", + "anArray", + "otherRef" + ], + "properties": { + "type": { + "type": "string", + "const": "A" + }, + "anArray": { + "type": "array", + "items": { + "type": "string" + } + }, + "otherRef": { + "$ref": "#/components/schemas/ValueB" + } + } + }, + "ValueB": { + "type": "object", + "additionalProperties": false, + "required": [ + "type", + "aMap", + "def" + ], + "properties": { + "type": { + "type": "string", + "const": "B" + }, + "aMap": { + "type": "object", + "additionalProperties": { + "type": "integer" + } + }, + "def": { + "anyOf": [ + { + "type": "integer", + "const": 1 + }, + { + "type": "string", + "const": "a" + }, + { + "type": "boolean" + } + ], + "default": 1 + } + } + }, + "ValueC": { + "type": "object", + "additionalProperties": false, + "required": [ + "type", + "other" + ], + "properties": { + "type": { + "type": "string", + "const": "C" + }, + "other": { + "type": "number" + } + } + }, + "DisjunctionConstants": { + "anyOf": [ + { + "type": "string", + "const": "abc" + }, + { + "type": "integer", + "const": 1 + }, + { + "type": "boolean", + "const": true + } + ] + } + } + } +} diff --git a/testdata/jennies/rawtypes/default_disjunction_value/PHPRawTypes/src/DefaultDisjunctionValue/ValueA.php b/testdata/jennies/rawtypes/default_disjunction_value/PHPRawTypes/src/DefaultDisjunctionValue/ValueA.php new file mode 100644 index 000000000..4c8fa669a --- /dev/null +++ b/testdata/jennies/rawtypes/default_disjunction_value/PHPRawTypes/src/DefaultDisjunctionValue/ValueA.php @@ -0,0 +1,57 @@ + + */ + public array $anArray; + + public \Grafana\Foundation\DefaultDisjunctionValue\ValueB $otherRef; + + /** + * @param array|null $anArray + * @param \Grafana\Foundation\DefaultDisjunctionValue\ValueB|null $otherRef + */ + public function __construct(?array $anArray = null, ?\Grafana\Foundation\DefaultDisjunctionValue\ValueB $otherRef = null) + { + $this->type = "A"; + + $this->anArray = $anArray ?: []; + $this->otherRef = $otherRef ?: new \Grafana\Foundation\DefaultDisjunctionValue\ValueB(); + } + + /** + * @param array $inputData + */ + public static function fromArray(array $inputData): self + { + /** @var array{type?: string, anArray?: array, otherRef?: mixed} $inputData */ + $data = $inputData; + return new self( + anArray: $data["anArray"] ?? null, + otherRef: isset($data["otherRef"]) ? (function($input) { + /** @var array{type?: string, aMap?: array, def?: int|string|bool} */ + $val = $input; + return \Grafana\Foundation\DefaultDisjunctionValue\ValueB::fromArray($val); + })($data["otherRef"]) : null, + ); + } + + /** + * @return array + */ + public function jsonSerialize(): array + { + $data = [ + "type" => $this->type, + "anArray" => $this->anArray, + "otherRef" => $this->otherRef, + ]; + return $data; + } +} diff --git a/testdata/jennies/rawtypes/default_disjunction_value/PHPRawTypes/src/DefaultDisjunctionValue/ValueB.php b/testdata/jennies/rawtypes/default_disjunction_value/PHPRawTypes/src/DefaultDisjunctionValue/ValueB.php new file mode 100644 index 000000000..0a57832cd --- /dev/null +++ b/testdata/jennies/rawtypes/default_disjunction_value/PHPRawTypes/src/DefaultDisjunctionValue/ValueB.php @@ -0,0 +1,67 @@ + + */ + public array $aMap; + + /** + * @var int|string|bool + */ + public $def; + + /** + * @param array|null $aMap + * @param int|string|bool|null $def + */ + public function __construct(?array $aMap = null, $def = null) + { + $this->type = "B"; + + $this->aMap = $aMap ?: []; + $this->def = $def ?: 1; + } + + /** + * @param array $inputData + */ + public static function fromArray(array $inputData): self + { + /** @var array{type?: string, aMap?: array, def?: int|string|bool} $inputData */ + $data = $inputData; + return new self( + aMap: $data["aMap"] ?? null, + def: isset($data["def"]) ? (function($input) { + switch (true) { + case is_int($input): + return $input; + case is_string($input): + return $input; + case is_bool($input): + return $input; + default: + throw new \ValueError('incorrect value for disjunction'); + } + })($data["def"]) : null, + ); + } + + /** + * @return array + */ + public function jsonSerialize(): array + { + $data = [ + "type" => $this->type, + "aMap" => $this->aMap, + "def" => $this->def, + ]; + return $data; + } +} diff --git a/testdata/jennies/rawtypes/default_disjunction_value/PHPRawTypes/src/DefaultDisjunctionValue/ValueC.php b/testdata/jennies/rawtypes/default_disjunction_value/PHPRawTypes/src/DefaultDisjunctionValue/ValueC.php new file mode 100644 index 000000000..75dd8e5a0 --- /dev/null +++ b/testdata/jennies/rawtypes/default_disjunction_value/PHPRawTypes/src/DefaultDisjunctionValue/ValueC.php @@ -0,0 +1,44 @@ +type = "C"; + + $this->other = $other ?: 0; + } + + /** + * @param array $inputData + */ + public static function fromArray(array $inputData): self + { + /** @var array{type?: string, other?: float} $inputData */ + $data = $inputData; + return new self( + other: $data["other"] ?? null, + ); + } + + /** + * @return array + */ + public function jsonSerialize(): array + { + $data = [ + "type" => $this->type, + "other" => $this->other, + ]; + return $data; + } +} diff --git a/testdata/jennies/rawtypes/default_disjunction_value/PythonRawTypes/models/default_disjunction_value.py b/testdata/jennies/rawtypes/default_disjunction_value/PythonRawTypes/models/default_disjunction_value.py new file mode 100644 index 000000000..53cf39d49 --- /dev/null +++ b/testdata/jennies/rawtypes/default_disjunction_value/PythonRawTypes/models/default_disjunction_value.py @@ -0,0 +1,92 @@ +import typing + + +DisjunctionClasses: typing.TypeAlias = typing.Union['ValueA', 'ValueB', 'ValueC'] + + +class ValueA: + type_val: typing.Literal["A"] + an_array: list[str] + other_ref: 'ValueB' + + def __init__(self, an_array: typing.Optional[list[str]] = None, other_ref: typing.Optional['ValueB'] = None): + self.type_val = "A" + self.an_array = an_array if an_array is not None else [] + self.other_ref = other_ref if other_ref is not None else ValueB() + + def to_json(self) -> dict[str, object]: + payload: dict[str, object] = { + "type": self.type_val, + "anArray": self.an_array, + "otherRef": self.other_ref, + } + return payload + + @classmethod + def from_json(cls, data: dict[str, typing.Any]) -> typing.Self: + args: dict[str, typing.Any] = {} + + if "anArray" in data: + args["an_array"] = data["anArray"] + if "otherRef" in data: + args["other_ref"] = ValueB.from_json(data["otherRef"]) + + return cls(**args) + + +class ValueB: + type_val: typing.Literal["B"] + a_map: dict[str, int] + def_val: typing.Union[typing.Literal[1], typing.Literal["a"], bool] + + def __init__(self, a_map: typing.Optional[dict[str, int]] = None, def_val: typing.Optional[typing.Union[typing.Literal[1], typing.Literal["a"], bool]] = None): + self.type_val = "B" + self.a_map = a_map if a_map is not None else {} + self.def_val = def_val if def_val is not None else 1 + + def to_json(self) -> dict[str, object]: + payload: dict[str, object] = { + "type": self.type_val, + "aMap": self.a_map, + "def": self.def_val, + } + return payload + + @classmethod + def from_json(cls, data: dict[str, typing.Any]) -> typing.Self: + args: dict[str, typing.Any] = {} + + if "aMap" in data: + args["a_map"] = data["aMap"] + if "def" in data: + args["def_val"] = data["def"] + + return cls(**args) + + +class ValueC: + type_val: typing.Literal["C"] + other: float + + def __init__(self, other: float = 0): + self.type_val = "C" + self.other = other + + def to_json(self) -> dict[str, object]: + payload: dict[str, object] = { + "type": self.type_val, + "other": self.other, + } + return payload + + @classmethod + def from_json(cls, data: dict[str, typing.Any]) -> typing.Self: + args: dict[str, typing.Any] = {} + + if "other" in data: + args["other"] = data["other"] + + return cls(**args) + + +DisjunctionConstants: typing.TypeAlias = typing.Union[typing.Literal["abc"], typing.Literal[1], typing.Literal[True]] diff --git a/testdata/jennies/rawtypes/default_disjunction_value/TypescriptRawTypes/src/defaultDisjunctionValue/types.gen.ts b/testdata/jennies/rawtypes/default_disjunction_value/TypescriptRawTypes/src/defaultDisjunctionValue/types.gen.ts new file mode 100644 index 000000000..9b1febba9 --- /dev/null +++ b/testdata/jennies/rawtypes/default_disjunction_value/TypescriptRawTypes/src/defaultDisjunctionValue/types.gen.ts @@ -0,0 +1,41 @@ +export type DisjunctionClasses = ValueA | ValueB | ValueC; + +export const defaultDisjunctionClasses = (): DisjunctionClasses => (defaultValueA()); + +export interface ValueA { + type: "A"; + anArray: string[]; + otherRef: ValueB; +} + +export const defaultValueA = (): ValueA => ({ + type: "A", + anArray: [], + otherRef: defaultValueB(), +}); + +export interface ValueB { + type: "B"; + aMap: Record; + def: 1 | "a" | boolean; +} + +export const defaultValueB = (): ValueB => ({ + type: "B", + aMap: {}, + def: 1, +}); + +export interface ValueC { + type: "C"; + other: number; +} + +export const defaultValueC = (): ValueC => ({ + type: "C", + other: 0, +}); + +export type DisjunctionConstants = "abc" | 1 | true; + +export const defaultDisjunctionConstants = (): DisjunctionConstants => (1); diff --git a/testdata/jennies/rawtypes/default_disjunction_value/ir.json b/testdata/jennies/rawtypes/default_disjunction_value/ir.json new file mode 100644 index 000000000..815fb1bf5 --- /dev/null +++ b/testdata/jennies/rawtypes/default_disjunction_value/ir.json @@ -0,0 +1,279 @@ +{ + "Package": "default_disjunction_value", + "Metadata": {}, + "EntryPointType": { + "Kind": "", + "Nullable": false + }, + "Objects": { + "DisjunctionClasses": { + "Name": "DisjunctionClasses", + "Type": { + "Kind": "disjunction", + "Nullable": false, + "Default": { + "anArray": null, + "otherRef": { + "aMap": null, + "def": 1, + "type": "B" + }, + "type": "A" + }, + "Disjunction": { + "Branches": [ + { + "Kind": "ref", + "Nullable": false, + "Ref": { + "ReferredPkg": "default_disjunction_value", + "ReferredType": "ValueA" + } + }, + { + "Kind": "ref", + "Nullable": false, + "Ref": { + "ReferredPkg": "default_disjunction_value", + "ReferredType": "ValueB" + } + }, + { + "Kind": "ref", + "Nullable": false, + "Ref": { + "ReferredPkg": "default_disjunction_value", + "ReferredType": "ValueC" + } + } + ] + } + }, + "SelfRef": { + "ReferredPkg": "default_disjunction_value", + "ReferredType": "DisjunctionClasses" + } + }, + "ValueA": { + "Name": "ValueA", + "Type": { + "Kind": "struct", + "Nullable": false, + "Struct": { + "Fields": [ + { + "Name": "type", + "Type": { + "Kind": "scalar", + "Nullable": false, + "Scalar": { + "ScalarKind": "string", + "Value": "A" + } + }, + "Required": true + }, + { + "Name": "anArray", + "Type": { + "Kind": "array", + "Nullable": false, + "Array": { + "ValueType": { + "Kind": "scalar", + "Nullable": false, + "Scalar": { + "ScalarKind": "string" + } + } + } + }, + "Required": true + }, + { + "Name": "otherRef", + "Type": { + "Kind": "ref", + "Nullable": false, + "Ref": { + "ReferredPkg": "default_disjunction_value", + "ReferredType": "ValueB" + } + }, + "Required": true + } + ] + } + }, + "SelfRef": { + "ReferredPkg": "default_disjunction_value", + "ReferredType": "ValueA" + } + }, + "ValueB": { + "Name": "ValueB", + "Type": { + "Kind": "struct", + "Nullable": false, + "Struct": { + "Fields": [ + { + "Name": "type", + "Type": { + "Kind": "scalar", + "Nullable": false, + "Scalar": { + "ScalarKind": "string", + "Value": "B" + } + }, + "Required": true + }, + { + "Name": "aMap", + "Type": { + "Kind": "map", + "Nullable": false, + "Map": { + "IndexType": { + "Kind": "scalar", + "Nullable": false, + "Scalar": { + "ScalarKind": "string" + } + }, + "ValueType": { + "Kind": "scalar", + "Nullable": false, + "Scalar": { + "ScalarKind": "int64" + } + } + } + }, + "Required": true + }, + { + "Name": "def", + "Type": { + "Kind": "disjunction", + "Nullable": false, + "Default": 1, + "Disjunction": { + "Branches": [ + { + "Kind": "scalar", + "Nullable": false, + "Scalar": { + "ScalarKind": "int64", + "Value": 1 + } + }, + { + "Kind": "scalar", + "Nullable": false, + "Scalar": { + "ScalarKind": "string", + "Value": "a" + } + }, + { + "Kind": "scalar", + "Nullable": false, + "Scalar": { + "ScalarKind": "bool" + } + } + ] + } + }, + "Required": true + } + ] + } + }, + "SelfRef": { + "ReferredPkg": "default_disjunction_value", + "ReferredType": "ValueB" + } + }, + "ValueC": { + "Name": "ValueC", + "Type": { + "Kind": "struct", + "Nullable": false, + "Struct": { + "Fields": [ + { + "Name": "type", + "Type": { + "Kind": "scalar", + "Nullable": false, + "Scalar": { + "ScalarKind": "string", + "Value": "C" + } + }, + "Required": true + }, + { + "Name": "other", + "Type": { + "Kind": "scalar", + "Nullable": false, + "Scalar": { + "ScalarKind": "float32" + } + }, + "Required": true + } + ] + } + }, + "SelfRef": { + "ReferredPkg": "default_disjunction_value", + "ReferredType": "ValueC" + } + }, + "DisjunctionConstants": { + "Name": "DisjunctionConstants", + "Type": { + "Kind": "disjunction", + "Nullable": false, + "Default": 1, + "Disjunction": { + "Branches": [ + { + "Kind": "scalar", + "Nullable": false, + "Scalar": { + "ScalarKind": "string", + "Value": "abc" + } + }, + { + "Kind": "scalar", + "Nullable": false, + "Scalar": { + "ScalarKind": "int64", + "Value": 1 + } + }, + { + "Kind": "scalar", + "Nullable": false, + "Scalar": { + "ScalarKind": "bool", + "Value": true + } + } + ] + } + }, + "SelfRef": { + "ReferredPkg": "default_disjunction_value", + "ReferredType": "DisjunctionConstants" + } + } + } +} diff --git a/testdata/jennies/rawtypes/default_disjunction_value/schema.cue b/testdata/jennies/rawtypes/default_disjunction_value/schema.cue new file mode 100644 index 000000000..f08900063 --- /dev/null +++ b/testdata/jennies/rawtypes/default_disjunction_value/schema.cue @@ -0,0 +1,21 @@ +package default_disjunction_value + +DisjunctionClasses: *ValueA | ValueB | ValueC +DisjunctionConstants: "abc" | *1 | true + +ValueA: { + type: "A" + anArray: [...string] + otherRef: ValueB +} + +ValueB: { + type: "B" + aMap: [string]: int64 + def: *1 | "a" | bool +} + +ValueC: { + type: "C" + other: float32 +}