示例#1
0
文件: node.go 项目: 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
}
示例#2
0
文件: node.go 项目: kego/ke
func (n *Node) setValue(ctx context.Context, in system.Packed, unpack bool) error {

	n.Missing = false

	objectType, err := extractType(ctx, in, n.Rule)
	if err != nil {
		return kerr.Wrap("MKMNOOYQJY", err)
	}
	if err := n.setType(ctx, objectType); err != nil {
		return kerr.Wrap("BCMOTEMUJE", err)
	}

	if n.Rule == nil && objectType != nil {
		n.Rule = system.WrapEmptyRule(ctx, objectType)
	}

	if in.Type() == system.J_MAP && n.Type.IsNativeObject() {
		// for objects and maps, Type() from the system.Packed is always J_MAP,
		// so we correct it for object types here.
		n.JsonType = system.J_OBJECT
	} else {
		n.JsonType = in.Type()
	}
	n.Null = in.Type() == system.J_NULL

	// validate json type
	//	if !n.Null && n.Type.NativeJsonType() != n.JsonType {
	//		return kerr.New("VEPLUIJXSN", "json type is %s but object type is %s", n.JsonType, n.Type.NativeJsonType())
	//	}

	if unpack {
		if n.Rule.Struct == nil {
			if err := system.Unpack(ctx, in, &n.Value); err != nil {
				return kerr.Wrap("CQMWGPLYIJ", err)
			}
		} else {
			t, err := n.Rule.GetReflectType()
			if err != nil {
				return kerr.Wrap("DQJDYPIANO", err)
			}

			var val reflect.Value
			if t.Kind() == reflect.Ptr {
				val = reflect.New(t.Elem())
			} else {
				val = reflect.New(t).Elem()
			}

			if err := system.UnpackRefelctValue(ctx, in, val); err != nil {
				return kerr.Wrap("PEVKGFFHLL", err)
			}

			n.Value = val.Interface()
		}
		n.setVal(reflect.ValueOf(n.Value))
	}

	switch n.Type.NativeJsonType(ctx) {
	case system.J_STRING:
		if in.Type() == system.J_MAP {
			n.ValueString = in.Map()["value"].String()
		} else {
			n.ValueString = in.String()
		}
	case system.J_NUMBER:
		if in.Type() == system.J_MAP {
			n.ValueNumber = in.Map()["value"].Number()
		} else {
			n.ValueNumber = in.Number()
		}
	case system.J_BOOL:
		if in.Type() == system.J_MAP {
			n.ValueBool = in.Map()["value"].Bool()
		} else {
			n.ValueBool = in.Bool()
		}
	case system.J_ARRAY:
		children := in.Array()
		for i, child := range children {
			childNode := NewNode()
			if err := childNode.InitialiseArrayItem(ctx, n, i); err != nil {
				return kerr.Wrap("XHQKQTNRJV", err)
			}
			if err := childNode.AddToArray(ctx, n, i, false); err != nil {
				return kerr.Wrap("VWWYPDIJKP", err)
			}
			if err := childNode.setValue(ctx, child, false); err != nil {
				return kerr.Wrap("KUCBPFFJNT", err)
			}
		}
	case system.J_MAP:
		n.Map = map[string]*Node{}
		children := in.Map()
		for name, child := range children {
			childNode := NewNode()
			if err := childNode.InitialiseMapItem(ctx, n, name); err != nil {
				return kerr.Wrap("TBNWBMJDIE", err)
			}
			if err := childNode.AddToMap(ctx, n, name, false); err != nil {
				return kerr.Wrap("HTOPDOKPRE", err)
			}
			if err := childNode.setValue(ctx, child, false); err != nil {
				return kerr.Wrap("LWCSAHSBDF", err)
			}
		}
	case system.J_OBJECT:
		if err := n.initialiseFields(ctx, in, false); err != nil {
			return kerr.Wrap("XCRYJWKPKP", err)
		}
	}

	return nil
}