Example #1
0
File: node.go Project: kego/ke
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
}
Example #2
0
File: type.go Project: kego/ke
// 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
}
Example #3
0
File: node.go Project: kego/ke
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
}
Example #4
0
File: node.go Project: kego/ke
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
}
Example #5
0
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(""))
}
Example #6
0
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())
}
Example #7
0
File: node.go Project: kego/ke
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
}
Example #8
0
File: type.go Project: kego/ke
// 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
}
Example #9
0
File: structs.go Project: kego/ke
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
}
Example #10
0
File: structs.go Project: kego/ke
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
}
Example #11
0
File: structs.go Project: kego/ke
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
}
Example #12
0
File: structs.go Project: kego/ke
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
}
Example #13
0
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()))
}