func (n *Node) setType(ctx context.Context, t *system.Type) error { if t == nil { n.Type = nil n.JsonType = system.J_NULL n.UnderlyingRule = nil n.UnderlyingInnerType = nil return nil } if t.Interface { return kerr.New("VHOSYBMDQL", "Can't set type to an interface - must be concrete type.") } n.Type = t n.JsonType = t.NativeJsonType(ctx) if t.Alias != nil { rw := system.WrapRule(ctx, t.Alias) n.UnderlyingRule = rw uit := rw.InnerType(ctx) for uit.Alias != nil { uit = system.WrapRule(ctx, uit.Alias).InnerType(ctx) } n.UnderlyingInnerType = uit } else { n.UnderlyingRule = system.WrapEmptyRule(ctx, t) n.UnderlyingInnerType = t } return nil }
// TypeDefinition returns the Go source for the definition of the type // [optional pointer][collection prefix][optional pointer][type name] func TypeDefinition(ctx context.Context, field system.RuleInterface, path string, getAlias func(string) string) (string, error) { outer := system.WrapRule(ctx, field) outerPointer := outer.PassedAsPointerString(ctx) // if the rule is a complex collection, with possibly several maps and // arrays, this iterates over the rule and returns the go collection prefix // - e.g. []map[string] for an array of maps. It also returns the inner rule. prefix, inner, err := collectionPrefixInnerRule(ctx, "", outer) if err != nil { return "", kerr.Wrap("SOGEFOPJHB", err) } innerPointer := "" // if we have a prefix we should also work out the innerPointer if prefix != "" && inner.PassedAsPointer(ctx) { innerPointer = "*" } var n string if inner.Struct.Interface { n = system.GoInterfaceName(inner.Parent.Id.Name) } else { n = system.GoName(inner.Parent.Id.Name) } name := Reference(inner.Parent.Id.Package, n, path, getAlias) return fmt.Sprint(outerPointer, prefix, innerPointer, name), nil }
func extractFields(ctx context.Context, fields map[string]*system.Field, t *system.Type) error { for t.Alias != nil { t = system.WrapRule(ctx, t.Alias).Parent } if !t.Basic && !t.Interface { // All types apart from Basic types embed system:object ob, ok := system.GetTypeFromCache(ctx, "kego.io/system", "object") if !ok { return kerr.New("YRFWOTIGFT", "Type system:object not found in sys ctx") } if err := extractFields(ctx, fields, ob); err != nil { return kerr.Wrap("DTQEFALIMM", err) } } for _, embedRef := range t.Embed { embed, ok := system.GetTypeFromCache(ctx, embedRef.Package, embedRef.Name) if !ok { return kerr.New("SLIRILCARQ", "Type %s not found in sys ctx", embedRef) } if err := extractFields(ctx, fields, embed); err != nil { return kerr.Wrap("JWAPCVIYBJ", err) } } for name, rule := range t.Fields { if _, ok := fields[name]; ok { return kerr.New("BARXPFXQNB", "Duplicate field %s", name) } fields[name] = &system.Field{Name: name, Rule: rule, Origin: t.Id} } return nil }
func (n *Node) initialiseCollectionItem(ctx context.Context, parent *Node, key string, index int) error { n.resetAllValues() n.Parent = parent n.Index = index n.Key = key n.Missing = false var collectionRule *system.RuleWrapper if n.Parent.Type.Alias != nil { collectionRule = system.WrapRule(ctx, n.Parent.Type.Alias) } else { collectionRule = parent.Rule } rule, err := collectionRule.ItemsRule() if err != nil { return kerr.Wrap("SBJVMGUOOA", err) } n.Rule = rule t, err := extractType(ctx, system.Pack(nil), rule) if err != nil { return kerr.Wrap("EQNRHQWXFJ", err) } if err := n.setType(ctx, t); err != nil { return kerr.Wrap("UPAQMUGDNH", err) } return nil }
func TestRuleWrapper_ZeroValue(t *testing.T) { cb := tests.Context("kego.io/system").Jauto().Sauto(parser.Parse) r := system.WrapRule(cb.Ctx(), &system.MapRule{ Object: &system.Object{Type: system.NewReference("kego.io/system", "@map")}, Rule: &system.Rule{}, Items: &system.StringRule{ Object: &system.Object{Type: system.NewReference("kego.io/system", "@string")}, Rule: &system.Rule{}, }, }) v, err := r.ZeroValue(true) require.NoError(t, err) assert.IsType(t, map[string]*system.String{}, v.Interface()) assert.Nil(t, v.Interface()) v, err = r.ZeroValue(false) require.NoError(t, err) assert.IsType(t, map[string]*system.String{}, v.Interface()) assert.NotNil(t, v.Interface()) vv := v.Interface().(map[string]*system.String) vv["a"] = system.NewString("") r = system.WrapRule(cb.Ctx(), &system.MapRule{ Object: &system.Object{Type: system.NewReference("kego.io/system", "@array")}, Rule: &system.Rule{}, Items: &system.StringRule{ Object: &system.Object{Type: system.NewReference("kego.io/system", "@string")}, Rule: &system.Rule{}, }, }) v, err = r.ZeroValue(true) require.NoError(t, err) assert.IsType(t, []*system.String{}, v.Interface()) assert.Nil(t, v.Interface()) v, err = r.ZeroValue(false) require.NoError(t, err) assert.IsType(t, []*system.String{}, v.Interface()) assert.NotNil(t, v.Interface()) va := v.Interface().([]*system.String) va = append(va, system.NewString("")) }
func checkReflectType(ctx context.Context, t *testing.T, path string, name string, field string, output string) { scache := sysctx.FromContext(ctx) p, ok := scache.Get(path) assert.True(t, ok) typ, ok := p.Types.Get(name) assert.True(t, ok) ty, ok := typ.Type.(*system.Type) assert.True(t, ok) r, ok := ty.Fields[field] assert.True(t, ok) rh := system.WrapRule(ctx, r) rt, err := rh.GetReflectType() require.NoError(t, err) assert.Equal(t, output, rt.String()) }
func (n *Node) initialiseFields(ctx context.Context, in system.Packed, updateVal bool) error { valueFields := map[string]system.Packed{} if in != nil && in.Type() != system.J_NULL { valueFields = in.Map() } typeFields := map[string]*system.Field{} if err := extractFields(ctx, typeFields, n.Type); err != nil { return kerr.Wrap("LPWTOSATQE", err) } for name, typeField := range typeFields { rule := system.WrapRule(ctx, typeField.Rule) valueField, valueExists := valueFields[name] childNode := NewNode() if err := childNode.initialiseObjectField(ctx, n, rule, name, typeField.Origin); err != nil { return kerr.Wrap("ILIHBXGROP", err) } if err := childNode.AddToObject(ctx, n, rule, name, updateVal); err != nil { return kerr.Wrap("LJUGPMWNPD", err) } if valueExists { if err := childNode.setValue(ctx, valueField, false); err != nil { return kerr.Wrap("UWOTRJJVNK", err) } } } for name, _ := range valueFields { _, ok := typeFields[name] if !ok { return kerr.New("SRANLETJRS", "Extra field %s, %s", name, n.Path()) } } return nil }
// AliasTypeDefinition returns the Go source for the definition of the type // of this alias type [collection prefix][optional pointer][type name] func AliasTypeDefinition(ctx context.Context, alias system.RuleInterface, path string, getAlias func(string) string) (string, error) { outer := system.WrapRule(ctx, alias) // if the rule is a complex collection, with possibly several maps and // arrays, this iterates over the rule and returns the go collection prefix // - e.g. []map[string] for an array of maps. It also returns the inner // rule. prefix, inner, err := collectionPrefixInnerRule(ctx, "", outer) if err != nil { return "", kerr.Wrap("BSWTXBHVTH", err) } pointer := "" // if we have a prefix we should also work out the innerPointer if prefix != "" && inner.PassedAsPointer(ctx) { pointer = "*" } name := Reference(inner.Parent.Id.Package, system.GoName(inner.Parent.Id.Name), path, getAlias) return fmt.Sprint(prefix, pointer, name), nil }
func printUnpackCode(ctx context.Context, env *envctx.Env, g *builder.Builder, in string, out string, depth int, f system.RuleInterface) error { field := system.WrapRule(ctx, f) fieldType := field.Parent fieldTypeName := builder.Reference(fieldType.Id.Package, system.GoName(fieldType.Id.Name), env.Path, g.Imports.Add) kind, alias := field.Kind(ctx) switch { case kind == system.KindStruct || alias: ptr := fieldType.PassedAsPointerInverseString(ctx) g.Println(out, " := ", ptr, "new(", fieldTypeName, ")") g.Println("if err := ", out, ".Unpack(ctx, ", in, ", false); err != nil {") { g.Println("return err") } g.Println("}") //if store { // g.Println("v.", fieldName, " = ob") //} case kind == system.KindValue: var funcName string switch fieldType.NativeJsonType(ctx) { case system.J_STRING: funcName = "UnpackString" case system.J_NUMBER: funcName = "UnpackNumber" case system.J_BOOL: funcName = "UnpackBool" default: return kerr.New("LSGUACQGHB", "Kind == KindValue but native json type==%s", fieldType.NativeJsonType(ctx)) } funcRef := g.SprintRef("kego.io/system", funcName) g.Println(out, ", err := ", funcRef, "(ctx, ", in, ")") g.Println("if err != nil {") { g.Println("return err") } g.Println("}") //if store { // g.Println("v.", fieldName, " = ob") //} case kind == system.KindInterface: var interfaceName string if fieldType.Interface { interfaceName = system.GoName(fieldType.Id.Name) } else { interfaceName = system.GoInterfaceName(fieldType.Id.Name) } unpackFuncName := builder.Reference(fieldType.Id.Package, "Unpack"+interfaceName, env.Path, g.Imports.Add) g.Println(out, ", err := ", unpackFuncName, "(ctx, ", in, ")") g.Println("if err != nil {") { g.Println("return err") } g.Println("}") //if store { // g.Println("v.", fieldName, " = ob") //} case kind == system.KindArray: fmtPkg := g.Imports.Add("fmt") g.Println("if ", in, ".Type() != ", g.SprintRef("kego.io/system", "J_ARRAY"), " {") { g.Println("return ", fmtPkg, ".Errorf(\"Unsupported json type %s found while unpacking into an array.\", ", in, ".Type())") } g.Println("}") fieldType, err := builder.TypeDefinition(ctx, f, env.Path, g.Imports.Add) if err != nil { return kerr.Wrap("UDPMSSFLTW", err) } g.Println(out, " := ", fieldType, "{}") iVar := fmt.Sprintf("i%d", depth) g.Println("for ", iVar, " := range ", in, ".Array() {") { childRule, err := field.ItemsRule() if err != nil { return kerr.Wrap("PJQBRUEHLD", err) } childDepth := depth + 1 childIn := in + ".Array()[" + iVar + "]" childOut := fmt.Sprintf("ob%d", childDepth) if err := printUnpackCode(ctx, env, g, childIn, childOut, childDepth, childRule.Interface); err != nil { return kerr.Wrap("XCHEJPDJDS", err) } g.Println(out, " = append(", out, ", ", childOut, ")") } g.Println("}") case kind == system.KindMap: fmtPkg := g.Imports.Add("fmt") g.Println("if ", in, ".Type() != ", g.SprintRef("kego.io/system", "J_MAP"), " {") { g.Println("return ", fmtPkg, ".Errorf(\"Unsupported json type %s found while unpacking into a map.\", ", in, ".Type())") } g.Println("}") fieldType, err := builder.TypeDefinition(ctx, f, env.Path, g.Imports.Add) if err != nil { return kerr.Wrap("IHNYODUIKG", err) } g.Println(out, " := ", fieldType, "{}") kVar := fmt.Sprintf("k%d", depth) g.Println("for ", kVar, " := range ", in, ".Map() {") { items, err := field.ItemsRule() if err != nil { return kerr.Wrap("FPOBYGVOPP", err) } childDepth := depth + 1 childIn := in + ".Map()[" + kVar + "]" childOut := fmt.Sprintf("ob%d", childDepth) if err := printUnpackCode(ctx, env, g, childIn, childOut, childDepth, items.Interface); err != nil { return kerr.Wrap("ONUJJGIKJE", err) } g.Println(out, "[", kVar, "] = ", childOut) } g.Println("}") } return nil }
func printUnpacker(ctx context.Context, env *envctx.Env, g *builder.Builder, typ *system.Type) error { name := system.GoName(typ.Id.Name) fmtPkg := g.Imports.Add("fmt") g.Println("func (v *", name, ") Unpack(ctx ", g.SprintRef("context", "Context"), ", in ", g.SprintRef("kego.io/system", "Packed"), ", iface bool) error {") { g.Println("if in == nil || in.Type() == ", g.SprintRef("kego.io/system", "J_NULL"), " {") { g.Println("return nil") } g.Println("}") kind, _ := typ.Kind(ctx) switch kind { case system.KindStruct: structType := typ if typ.Alias != nil { structType = system.WrapRule(ctx, typ.Alias).Parent } for _, embedRef := range structType.AllEmbeds() { embedType, ok := system.GetTypeFromCache(ctx, embedRef.Package, embedRef.Name) if !ok { return kerr.New("IOEEVJCDPU", "Type %s not found", embedRef.String()) } embedName := system.GoName(embedRef.Name) embedTypeName := builder.Reference(embedType.Id.Package, system.GoName(embedType.Id.Name), env.Path, g.Imports.Add) g.Println("if v.", embedName, " == nil {") { g.Println("v.", embedName, " = new(", embedTypeName, ")") } g.Println("}") g.Println("if err := v.", embedName, ".Unpack(ctx, in, false); err != nil {") { g.Println("return err") } g.Println("}") if embedRef.Package == "kego.io/system" && embedRef.Name == "object" { g.Println("if err := v.Object.InitializeType(", strconv.Quote(typ.Id.Package), ", ", strconv.Quote(typ.Id.Name), "); err != nil {") { g.Println("return err") } g.Println("}") } } for _, f := range structType.SortedFields() { g.Println("if field, ok := in.Map()[", strconv.Quote(f.Name), "]; ok && field.Type() != ", g.SprintRef("kego.io/system", "J_NULL"), " {") { in := "field" out := "ob0" depth := 0 if err := printUnpackCode(ctx, env, g, in, out, depth, f.Rule); err != nil { return kerr.Wrap("QLARKEBDBJ", err) } g.Println("v.", system.GoName(f.Name), " = ", out) } if dr, ok := f.Rule.(system.DefaultRule); ok && dr.GetDefault() != nil { g.Println("} else {") { b, err := json.Marshal(dr.GetDefault()) if err != nil { return kerr.Wrap("DLOUEHXVJF", err) } in := g.SprintFunctionCall("kego.io/system", "Pack", string(b)) out := "ob0" depth := 0 if err := printUnpackCode(ctx, env, g, in, out, depth, f.Rule); err != nil { return kerr.Wrap("UOWRFWSTNT", err) } g.Println("v.", system.GoName(f.Name), " = ", out) } g.Println("}") } else { g.Println("}") } } case system.KindValue: g.Println("if in.Type() == ", g.SprintRef("kego.io/system", "J_MAP"), " {") { g.Println("in = in.Map()[\"value\"]") } g.Println("}") switch typ.NativeJsonType(ctx) { case system.J_BOOL: g.Println("if in.Type() != ", g.SprintRef("kego.io/system", "J_BOOL"), " {") { g.Println("return ", fmtPkg, `.Errorf("Invalid type %s while unpacking a bool.", in.Type())`) } g.Println("}") g.Println("*v = ", name, "(in.Bool())") case system.J_STRING: g.Println("if in.Type() != ", g.SprintRef("kego.io/system", "J_STRING"), " {") { g.Println("return ", fmtPkg, `.Errorf("Invalid type %s while unpacking a string.", in.Type())`) } g.Println("}") g.Println("*v = ", name, "(in.String())") case system.J_NUMBER: g.Println("if in.Type() != ", g.SprintRef("kego.io/system", "J_NUMBER"), " {") { g.Println("return ", fmtPkg, `.Errorf("Invalid type %s while unpacking a number.", in.Type())`) } g.Println("}") g.Println("*v = ", name, "(in.Number())") default: panic(fmt.Sprintf("invalid type kind: %s, json native: %s", kind, typ.NativeJsonType(ctx))) } case system.KindArray: g.Println("if in.Type() == ", g.SprintRef("kego.io/system", "J_MAP"), " {") { g.Println("in = in.Map()[\"value\"]") } g.Println("}") g.Println("if in.Type() != ", g.SprintRef("kego.io/system", "J_ARRAY"), " {") { g.Println("return ", fmtPkg, `.Errorf("Invalid type %s while unpacking an array.", in.Type())`) } g.Println("}") in := "in" out := "ob0" depth := 0 if err := printUnpackCode(ctx, env, g, in, out, depth, typ.Alias); err != nil { return kerr.Wrap("VELYRXXGMC", err) } g.Println("*v = ", out) case system.KindMap: g.Println("if iface {") { g.Println("if in.Type() != ", g.SprintRef("kego.io/system", "J_MAP"), " {") { g.Println("return ", fmtPkg, `.Errorf("Invalid type %s while unpacking a map.", in.Type())`) } g.Println("}") g.Println("in = in.Map()[\"value\"]") } g.Println("}") g.Println("if in.Type() != ", g.SprintRef("kego.io/system", "J_MAP"), " {") { g.Println("return ", fmtPkg, `.Errorf("Invalid type %s while unpacking an array.", in.Type())`) } g.Println("}") in := "in" out := "ob0" depth := 0 if err := printUnpackCode(ctx, env, g, in, out, depth, typ.Alias); err != nil { return kerr.Wrap("TNEIUAFUNY", err) } g.Println("*v = ", out) } } g.Println("return nil") g.Println("}") return nil }
func printRepackCode(ctx context.Context, env *envctx.Env, g *builder.Builder, in string, out string, depth int, f system.RuleInterface, inStruct bool) error { field := system.WrapRule(ctx, f) kind, alias := field.Kind(ctx) repackerDef := g.SprintRef("kego.io/system", "Repacker") switch { case kind == system.KindInterface: valueVar := out + "_value" g.Println("var ", out, " interface{}") g.Println(valueVar, ", pkg, name, typ, err := ", in, ".(", repackerDef, ").Repack(ctx)") g.Println("if err != nil {") { g.Println(`return nil, "", "", "", err`) } g.Println("}") should := g.SprintFunctionCall( "kego.io/system", "ShouldUseExplicitTypeNotation", "pkg", "name", "typ", strconv.Quote(field.Parent.Id.Package), strconv.Quote(field.Parent.Id.Name)) g.Println("if ", should, " {") { newReferenceDef := g.SprintRef("kego.io/system", "NewReference") g.Println("typRef := ", newReferenceDef, "(pkg, name)") g.Println("typeVal, err := typRef.ValueContext(ctx)") g.Println("if err != nil {") { g.Println(`return nil, "", "", "", err`) } g.Println("}") g.Println(out, " = map[string]interface{}{") { g.Println("\"type\": typeVal,") g.Println("\"value\": ", valueVar, ",") } g.Println("}") } g.Println("} else {") { g.Println(out, " = ", valueVar) } g.Println("}") case kind == system.KindStruct || (alias && inStruct): g.Println(out, ", _, _, _, err := ", in, ".Repack(ctx)") g.Println("if err != nil {") { g.Println(`return nil, "", "", "", err`) } g.Println("}") case kind == system.KindValue: g.Println(out, " := ", in) case kind == system.KindArray: iVar := fmt.Sprintf("i%d", depth) g.Println(out, " := []interface{}{}") g.Println("for ", iVar, " := range ", in, " {") { childIn := in + "[" + iVar + "]" childDepth := depth + 1 childOut := fmt.Sprintf("ob%d", childDepth) childRule, err := field.ItemsRule() if err != nil { return kerr.Wrap("VUKWDVGVAT", err) } if err := printRepackCode(ctx, env, g, childIn, childOut, childDepth, childRule.Interface, true); err != nil { return kerr.Wrap("GDWUQWGFUI", err) } g.Println(out, " = append(", out, ", ", childOut, ")") } g.Println("}") case kind == system.KindMap: kVar := fmt.Sprintf("k%d", depth) g.Println(out, " := map[string]interface{}{}") g.Println("for ", kVar, " := range ", in, " {") { childIn := in + "[" + kVar + "]" childDepth := depth + 1 childOut := fmt.Sprintf("ob%d", childDepth) childRule, err := field.ItemsRule() if err != nil { return kerr.Wrap("NYDJVRENGA", err) } if err := printRepackCode(ctx, env, g, childIn, childOut, childDepth, childRule.Interface, true); err != nil { return kerr.Wrap("VNWOUDMDQC", err) } g.Println(out, "[", kVar, "] = ", childOut) } g.Println("}") } return nil }
func printRepacker(ctx context.Context, env *envctx.Env, g *builder.Builder, typ *system.Type) error { name := system.GoName(typ.Id.Name) context_Context := g.SprintRef("context", "Context") system_JsonType := g.SprintRef("kego.io/system", "JsonType") ptr := typ.PassedAsPointerString(ctx) v := "v" if typ.PassedAsPointer(ctx) { v = "(*v)" } g.Println("func (v ", ptr, name, ") Repack(ctx ", context_Context, ") (data interface{}, typePackage string, typeName string, jsonType ", system_JsonType, ", err error) {") { g.Println("if v == nil {") { system_J_NULL := g.SprintRef("kego.io/system", "J_NULL") g.Println("return nil, ", strconv.Quote(typ.Id.Package), ", ", strconv.Quote(typ.Id.Name), ", ", system_J_NULL, ", nil") } g.Println("}") jtype := typ.NativeJsonType(ctx) var jsonType string switch jtype { case system.J_NUMBER: jsonType = g.SprintRef("kego.io/system", "J_NUMBER") case system.J_STRING: jsonType = g.SprintRef("kego.io/system", "J_STRING") case system.J_BOOL: jsonType = g.SprintRef("kego.io/system", "J_BOOL") case system.J_MAP: jsonType = g.SprintRef("kego.io/system", "J_MAP") case system.J_OBJECT: jsonType = g.SprintRef("kego.io/system", "J_OBJECT") case system.J_ARRAY: jsonType = g.SprintRef("kego.io/system", "J_ARRAY") case system.J_NULL: jsonType = g.SprintRef("kego.io/system", "J_NULL") } kind, _ := typ.Kind(ctx) switch kind { case system.KindStruct: g.Println("m := map[string]interface{}{}") structType := typ if typ.Alias != nil { structType = system.WrapRule(ctx, typ.Alias).Parent } for _, embedRef := range structType.AllEmbeds() { embedName := system.GoName(embedRef.Name) g.Println("if v.", embedName, " != nil {") { g.Println("ob, _, _, _, err := v.", embedName, ".Repack(ctx)") g.Println("if err != nil {") { g.Println(`return nil, "", "", "", err`) } g.Println("}") g.Println("for key, val := range ob.(map[string]interface{}) {") { g.Println("m[key] = val") } g.Println("}") } g.Println("}") } for _, f := range structType.SortedFields() { fieldRule := system.WrapRule(ctx, f.Rule) fieldName := system.GoName(f.Name) fieldType := fieldRule.Parent kind, alias := fieldRule.Kind(ctx) switch { case kind == system.KindStruct || alias: g.Println("if v.", fieldName, " != nil {") { if err := printRepackCode(ctx, env, g, "v."+fieldName, "ob0", 0, f.Rule, true); err != nil { return kerr.Wrap("WSARHJIFHS", err) } g.Println("m[", strconv.Quote(f.Name), "] = ", "ob0") } g.Println("}") case kind == system.KindValue: switch fieldType.NativeJsonType(ctx) { case system.J_STRING: g.Println("if v.", fieldName, " != \"\" {") case system.J_NUMBER: g.Println("if v.", fieldName, " != 0.0 {") case system.J_BOOL: g.Println("if v.", fieldName, " != false {") } { if err := printRepackCode(ctx, env, g, "v."+fieldName, "ob0", 0, f.Rule, true); err != nil { return kerr.Wrap("YYDYVIMXPM", err) } g.Println("m[", strconv.Quote(f.Name), "] = ", "ob0") } g.Println("}") case kind == system.KindArray || kind == system.KindMap || kind == system.KindInterface: g.Println("if v.", fieldName, " != nil {") { if err := printRepackCode(ctx, env, g, "v."+fieldName, "ob0", 0, f.Rule, true); err != nil { return kerr.Wrap("YSFPHQTBNA", err) } g.Println("m[", strconv.Quote(f.Name), "] = ", "ob0") } g.Println("}") } } g.Println("return m, ", strconv.Quote(typ.Id.Package), ", ", strconv.Quote(typ.Id.Name), ", ", jsonType, ", nil") case system.KindValue: outer := typ inner := typ if typ.Alias != nil { inner = system.WrapRule(ctx, typ.Alias).Parent } switch inner.NativeJsonType(ctx) { case system.J_STRING: g.Println("if v != nil {") { g.Println("return string(", ptr, "v), ", strconv.Quote(outer.Id.Package), ", ", strconv.Quote(outer.Id.Name), ", ", jsonType, ", nil") } g.Println("}") g.Println("return nil, ", strconv.Quote(outer.Id.Package), ", ", strconv.Quote(outer.Id.Name), ", ", jsonType, ", nil") case system.J_NUMBER: g.Println("if v != nil {") { g.Println("return float64(", ptr, "v), ", strconv.Quote(outer.Id.Package), ", ", strconv.Quote(outer.Id.Name), ", ", jsonType, ", nil") } g.Println("}") g.Println("return nil, ", strconv.Quote(outer.Id.Package), ", ", strconv.Quote(outer.Id.Name), ", ", jsonType, ", nil") case system.J_BOOL: g.Println("if v != nil {") { g.Println("return bool(", ptr, "v), ", strconv.Quote(outer.Id.Package), ", ", strconv.Quote(outer.Id.Name), ", ", jsonType, ", nil") } g.Println("}") g.Println("return nil, ", strconv.Quote(outer.Id.Package), ", ", strconv.Quote(outer.Id.Name), ", ", jsonType, ", nil") } case system.KindArray: if err := printRepackCode(ctx, env, g, v, "ob0", 0, typ.Alias, false); err != nil { return kerr.Wrap("SYKLQKLCEO", err) } g.Println("return ob0, ", strconv.Quote(typ.Id.Package), ", ", strconv.Quote(typ.Id.Name), ", ", jsonType, ", nil") case system.KindMap: if err := printRepackCode(ctx, env, g, v, "ob0", 0, typ.Alias, false); err != nil { return kerr.Wrap("HBSGXLGKCD", err) } g.Println("return ob0, ", strconv.Quote(typ.Id.Package), ", ", strconv.Quote(typ.Id.Name), ", ", jsonType, ", nil") } } g.Println("}") return nil }
func TestRuleWrapper_InnerType(t *testing.T) { cb := tests.Context("kego.io/system").Jauto().Sauto(parser.Parse) r := system.WrapRule(cb.Ctx(), &system.MapRule{ Object: &system.Object{Type: system.NewReference("kego.io/system", "@map")}, Rule: &system.Rule{}, Items: &system.StringRule{ Object: &system.Object{Type: system.NewReference("kego.io/system", "@string")}, Rule: &system.Rule{}, }, }) inner := r.InnerType(cb.Ctx()) assert.Equal(t, "kego.io/system:string", inner.Id.String()) kind, alias := r.Kind(cb.Ctx()) assert.False(t, alias) assert.Equal(t, kind, system.KindMap) assert.False(t, r.PassedAsPointer(cb.Ctx())) r = system.WrapRule(cb.Ctx(), &system.DummyRule{ Object: &system.Object{Type: system.NewReference("kego.io/system", "@int")}, Rule: &system.Rule{}, }) assert.Equal(t, "kego.io/system:int", r.InnerType(cb.Ctx()).Id.String()) kind, alias = r.Kind(cb.Ctx()) assert.True(t, alias) assert.Equal(t, kind, system.KindValue) assert.True(t, r.PassedAsPointer(cb.Ctx())) r = system.WrapRule(cb.Ctx(), &system.DummyRule{ Object: &system.Object{Type: system.NewReference("kego.io/system", "@int")}, Rule: &system.Rule{ Interface: true, }, }) assert.Equal(t, "kego.io/system:int", r.InnerType(cb.Ctx()).Id.String()) kind, alias = r.Kind(cb.Ctx()) assert.False(t, alias) assert.Equal(t, kind, system.KindInterface) assert.False(t, r.PassedAsPointer(cb.Ctx())) r = system.WrapRule(cb.Ctx(), &system.DummyRule{ Object: &system.Object{Type: system.NewReference("kego.io/json", "@string")}, Rule: &system.Rule{}, }) assert.Equal(t, "kego.io/json:string", r.InnerType(cb.Ctx()).Id.String()) assert.False(t, r.PassedAsPointer(cb.Ctx())) r = system.WrapRule(cb.Ctx(), &system.DummyRule{ Object: &system.Object{Type: system.NewReference("kego.io/system", "@package")}, Rule: &system.Rule{}, }) assert.Equal(t, "kego.io/system:package", r.InnerType(cb.Ctx()).Id.String()) kind, alias = r.Kind(cb.Ctx()) assert.False(t, alias) assert.Equal(t, kind, system.KindStruct) assert.True(t, r.PassedAsPointer(cb.Ctx())) }