예제 #1
0
파일: lexer.go 프로젝트: kego/ke
func lexNextToken(input string, scanners []scannerItem) (*token, int, error) {
	for _, scanner := range scanners {
		if scanner.regex.MatchString(input) {
			idx := scanner.regex.FindStringIndex(input)
			if idx[0] == 0 {
				if scanner.typ == S_EXPR && strings.Count(input[idx[0]:idx[1]], "(") != strings.Count(input[idx[0]:idx[1]], ")") {
					terminated := false
					var curr int
					for curr = idx[1]; curr <= len(input[idx[0]:]); curr++ {
						if strings.Count(input[idx[0]:curr], "(") == strings.Count(input[idx[0]:curr], ")") {
							terminated = true
							break
						}
					}
					if terminated == false {
						return nil, len(input), kerr.New("MMTRYGGLNE", "Unterminated expression: %s", input[idx[0]:curr-1])
					} else {
						idx[1] = curr
					}
				}
				token := getToken(
					scanner.typ,
					input[idx[0]:idx[1]],
				)
				return &token, idx[1], nil
			}
		}
	}
	return nil, len(input), kerr.New("DPJDASCGQX", "Selector parsing error at %s", input)
}
예제 #2
0
파일: node.go 프로젝트: kego/ke
func (n *Node) setZero(ctx context.Context, null bool, missing bool) error {

	if missing && !null {
		return kerr.New("NYQULBBBHO", "If missing, must also be null")
	}

	if missing && (n.Parent == nil || n.Parent.JsonType != system.J_OBJECT) {
		return kerr.New("XRYLQWRNPH", "Parent must be J_OBJECT")
	}

	if n.Type == nil {
		return kerr.New("ABXFQOYCBA", "Can't set value without a type")
	}

	if n.Type.IsNativeCollection() && n.Rule == nil {
		return kerr.New("VGKTIRMDTJ", "Can't create collection zero value without a rule")
	}

	n.Missing = missing
	n.Null = null
	n.ValueString = ""
	n.ValueNumber = 0.0
	n.ValueBool = false
	n.Array = []*Node{}
	n.Map = map[string]*Node{}

	if null {
		n.JsonType = system.J_NULL
	} else {
		// if this node was previously null, we must reset the json type
		n.JsonType = n.Type.NativeJsonType(ctx)
	}

	var rv reflect.Value
	if n.Type.IsNativeCollection() {
		var err error
		if rv, err = n.Rule.ZeroValue(null); err != nil {
			return kerr.Wrap("WNQLTRJRBD", err)
		}
	} else {
		// this is for both objects and native values
		var err error
		if rv, err = n.Type.ZeroValue(ctx, null); err != nil {
			return kerr.Wrap("UDBVTIDRIK", err)
		}
	}
	n.Value = rv.Interface()
	n.setVal(rv)

	if !null && n.Type.IsNativeObject() {
		if err := n.initialiseFields(ctx, nil, true); err != nil {
			return kerr.Wrap("VSAXCHGCOG", err)
		}
		if err := n.setCorrectTypeField(ctx); err != nil {
			return kerr.Wrap("CUCJDNBBSU", err)
		}
	}

	return nil
}
예제 #3
0
파일: bootstrap.go 프로젝트: kego/ke
func (v *Mappy) Unpack(ctx context.Context, in Packed, iface bool) error {

	if in == nil || in.Type() == J_NULL {
		return nil
	}

	if iface {
		if in.Type() != J_MAP {
			return kerr.New("DTLQPHOJDT", "Mappy.Unpack: %s must by J_MAP", in.Type())
		}
		in = in.Map()["value"]
	}

	if in.Type() != J_MAP {
		return kerr.New("KYPSXYBLNC", "Mappy.Unpack: %s must by J_MAP", in.Type())
	}

	for key, value := range in.Map() {
		ob, err := UnpackString(ctx, value)
		if err != nil {
			return kerr.Wrap("HOLNALWYBA", err)
		}
		(*v)[key] = ob
	}

	return nil
}
예제 #4
0
파일: struct.go 프로젝트: kego/ke
func (v *StructView) Render() *vecty.HTML {
	if v.model == nil {
		return elem.Div(vecty.Text("Struct (nil)"))
	}

	if v.model.Node.Type.Basic {
		// This view is only for types that embed system:object
		panic(kerr.New("QHDQMXTNIH", "Basic type %s not supported by StructView", v.model.Node.Type.Id.String()))
	}

	out := vecty.List{}

	// Always show the editor for system:object first
	objectEditor, ok := clientctx.FromContext(v.Ctx).Get("kego.io/system:object")
	if !ok {
		panic(kerr.New("BJRMXESSUV", "Can't find editor for system:object"))
	}
	out = append(out, objectEditor.EditorView(v.Ctx, v.model.Node, editable.Block))

	out = append(out, NewStructFragmentView(v.Ctx, v.model.Node, v.model.Node.Type.Id))

	return elem.Div(
		out,
	)

}
예제 #5
0
파일: rule.go 프로젝트: kego/ke
// ItemsRule returns Items rule for a collection Rule.
func (r *RuleWrapper) ItemsRule() (*RuleWrapper, error) {
	if !r.IsCollection() {
		return nil, kerr.New("VPAGXSTQHM", "%s is not a collection", r.Parent.Id.Value())
	}
	// I don't think this should be here:
	/*
		if r.Parent.Alias != nil {
			aw, err := WrapRule(r.Ctx, r.Parent.Alias)
			if err != nil {
				return nil, kerr.Wrap("PVCNTDVGWA", err)
			}
			if aw.IsCollection() {
				ir, err := aw.ItemsRule()
				if err != nil {
					return nil, kerr.Wrap("UIGQFXJLJE", err)
				}
				return ir, nil
			}
		}
	*/
	c, ok := r.Interface.(CollectionRule)
	if !ok {
		return nil, kerr.New("TNRVQVJIFH", "%T is not a CollectionRule", r.Interface)
	}
	ir := c.GetItemsRule()
	if ir == nil {
		return nil, kerr.New("SUJLYBXPYS", "%s has nil items rule", r.Parent.Id.Value())
	}
	w := WrapRule(r.Ctx, ir)
	return w, nil
}
예제 #6
0
파일: node.go 프로젝트: 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
}
예제 #7
0
파일: rule.go 프로젝트: kego/ke
func (r *RuleWrapper) GetReflectType() (reflect.Type, error) {

	if r.Struct != nil && r.Struct.Interface {
		typ, ok := r.Parent.GetReflectInterface(r.Ctx)
		if !ok {
			return nil, kerr.New("QGUVEUTXAN", "Type interface for %s not found", r.Parent.Id.Value())
		}
		return typ, nil
	}

	if c, ok := r.Interface.(CollectionRule); ok {
		itemsRule := c.GetItemsRule()
		if itemsRule != nil {
			items := WrapRule(r.Ctx, itemsRule)
			itemsType, err := items.GetReflectType()
			if err != nil {
				return nil, kerr.Wrap("LMKEHHWHKL", err)
			}
			if r.Parent.NativeJsonType(r.Ctx) == J_MAP {
				return reflect.MapOf(reflect.TypeOf(""), itemsType), nil
			}
			return reflect.SliceOf(itemsType), nil
		}
	}

	typ, ok := r.Parent.GetReflectType(r.Ctx)
	if !ok {
		return nil, kerr.New("DLAJJPJDPL", "Type %s not found", r.Parent.Id.Value())
	}

	return typ, nil

}
예제 #8
0
파일: type.go 프로젝트: kego/ke
func (t *Type) ZeroValue(ctx context.Context, null bool) (reflect.Value, error) {
	if t.IsNativeCollection() {
		return reflect.Value{}, kerr.New("PGUHCGBJWE", "ZeroValue must not be used with collection type")
	}
	rt, ok := t.GetReflectType(ctx)
	if !ok {
		return reflect.Value{}, kerr.New("RSWTEOTNBD", "Type not found for %s", t.Id)
	}
	return zeroValue(rt, null), nil
}
예제 #9
0
파일: reference.go 프로젝트: kego/ke
func GetReferencePartsFromTypeString(ctx context.Context, typeString string) (path string, name string, err error) {

	env := envctx.FromContext(ctx)

	if strings.Contains(typeString, "/") {
		// If the type name contains a slash, I'm assuming it's a fully
		// qualified type name of the form "kego.io/system:type".
		// TODO: Improve this with a regex?
		parts := strings.Split(typeString, ":")

		// We hard-code system and json to prevent them having to always be
		// specified in the aliases
		if parts[0] == "kego.io/system" {
			return "kego.io/system", parts[1], nil
		} else if parts[0] == "kego.io/json" {
			return "kego.io/json", parts[1], nil
		}

		_, found := findKey(env.Aliases, parts[0])
		if !found && parts[0] != env.Path {
			return "", "", UnknownPackageError{
				Struct:         kerr.New("KJSOXDESFD", "Unknown package %s", parts[0]),
				UnknownPackage: parts[0],
			}
		}
		return parts[0], parts[1], nil
	} else if strings.Contains(typeString, ":") {
		// If the type name contains a colon, I'm assuming it's an abreviated
		// qualified type name of the form "system:type". We should look the
		// package name up in the aliases map.
		// TODO: Improve this with a regex?
		parts := strings.Split(typeString, ":")

		// We hard-code system and json to prevent them having to always be
		// specified in the aliases
		if parts[0] == "system" {
			return "kego.io/system", parts[1], nil
		} else if parts[0] == "json" {
			return "kego.io/json", parts[1], nil
		}

		packagePath, ok := env.Aliases[parts[0]]
		if !ok {
			return "", "", UnknownPackageError{
				Struct:         kerr.New("DKKFLKDKYI", "Unknown package %s", parts[0]),
				UnknownPackage: parts[0],
			}
		}
		return packagePath, parts[1], nil
	} else {
		return env.Path, typeString, nil
	}
}
예제 #10
0
파일: editor.go 프로젝트: kego/ke
func GetEmbedEditable(ctx context.Context, node *node.Node, embed *system.Reference) (editable.Editable, error) {

	if node == nil || node.Null || node.Missing {
		return nil, nil
	}

	if *node.Type.Id == *embed {
		return GetEditable(ctx, node), nil
	}

	jcache := jsonctx.FromContext(ctx)
	nf, df, ok := jcache.GetNewFunc(embed.Package, embed.Name)
	if !ok {
		return nil, kerr.New("DGWDERFPVV", "Can't find %s in jsonctx", embed.String())
	}
	t := reflect.TypeOf(nf())
	if df != nil {
		t = t.Elem()
	}

	v := node.Val
	for v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface {
		v = v.Elem()
	}

	var field reflect.Value
	for i := 0; i < v.Type().NumField(); i++ {
		f := v.Type().Field(i)
		if f.Anonymous && f.Type == t {
			field = v.Field(i)
			break
		}
	}
	if field == (reflect.Value{}) {
		return nil, kerr.New("UDBOWYUBER", "Can't find %s field in struct", t)
	}

	// This is the recommended method of presenting an custom editor.
	if ed, ok := field.Interface().(editable.Editable); ok {
		return ed, nil
	}

	editors := clientctx.FromContext(ctx)

	// Don't do this. Implement the Editable interface instead. We can't do this
	// for system types so we use this method instead.
	if e, ok := editors.Get(embed.String()); ok {
		return e, nil
	}

	return nil, nil

}
예제 #11
0
파일: parser.go 프로젝트: kego/ke
func scanForTypesAndExports(ctx context.Context, env *envctx.Env, cache *sysctx.SysPackageInfo, hash *PackageHasher) error {

	// While we're scanning for types, we should use a custom unpacking env,
	// because the env from the context is the one of the local package.

	files := scanner.ScanDirToFiles(ctx, env.Dir, env.Recursive)
	bytes := scanner.ScanFilesToBytes(ctx, files)
	localContext := envctx.NewContext(ctx, env)
	for b := range bytes {
		if b.Err != nil {
			return kerr.Wrap("JACKALTIGG", b.Err)
		}

		o := &system.ObjectStub{}
		if err := system.Unmarshal(localContext, b.Bytes, o); err != nil {
			return kerr.Wrap("HCYGNBDFFA", err)
		}
		if o.Type == nil {
			return kerr.New("NUKWIHYFMQ", "%s has no type", b.File)
		}
		if o.Id == nil && *o.Type != *system.NewReference("kego.io/system", "package") {
			// we tolerate missing ID only for system:package
			return kerr.New("DLLMKTDYFW", "%s has no id", b.File)
		}
		relativeFile, err := filepath.Rel(env.Dir, b.File)
		if err != nil {
			return kerr.Wrap("AWYRJSCYQS", err)
		}
		switch *o.Type {
		case *system.NewReference("kego.io/system", "type"):
			if err := ProcessTypeFileBytes(ctx, env, relativeFile, b.Bytes, cache, hash); err != nil {
				return kerr.Wrap("IVEFDDSKHE", err)
			}
		case *system.NewReference("kego.io/system", "package"):
			cache.PackageBytes = b.Bytes
			cache.PackageFilename = relativeFile
		default:
			cache.Globals.Set(o.Id.Name, relativeFile)
			if o.Export {
				cache.Exports.Set(o.Id.Name, o.Type.Name, o.Type.Package, b.Bytes)
				if hash != nil {
					hash.Exports[o.Id.Name+" "+o.Type.Name+" "+o.Type.Package] = cityhash.CityHash64(b.Bytes, uint32(len(b.Bytes)))
				}
			}
		}

	}
	return nil
}
예제 #12
0
파일: envctx.go 프로젝트: kego/ke
// FromContext returns the User value stored in ctx, if any.
func FromContext(ctx context.Context) *Env {
	e, ok := ctx.Value(envKey).(*Env)
	if !ok {
		panic(kerr.New("WYDYAGVLCR", "No env in ctx").Error())
	}
	return e
}
예제 #13
0
파일: jsonctx.go 프로젝트: kego/ke
// FromContext returns the Cache value stored in ctx, and panics if it's not found.
func FromContext(ctx context.Context) *JsonCache {
	e, ok := ctx.Value(jsonKey).(*JsonCache)
	if !ok {
		panic(kerr.New("XUTUUVDMMX", "No json cache in ctx").Error())
	}
	return e
}
예제 #14
0
파일: wgctx.go 프로젝트: kego/ke
// FromContext returns the User value stored in ctx, if any.
func FromContext(ctx context.Context) *sync.WaitGroup {
	wg, ok := ctx.Value(wgKey).(*sync.WaitGroup)
	if !ok {
		panic(kerr.New("UNYGADKEGY", "No wg in ctx").Error())
	}
	return wg
}
예제 #15
0
파일: panel.go 프로젝트: kego/ke
func addNewFile(ctx context.Context, app *stores.App, all bool) {

	var types []*system.Type
	if all {
		rt := reflect.TypeOf((*system.ObjectInterface)(nil)).Elem()
		typesAll := system.GetAllTypesThatImplementReflectInterface(ctx, rt)

		// TODO: Work out a more elegant way of doing this!
		rule := reflect.TypeOf((*system.RuleInterface)(nil)).Elem()
		for _, t := range typesAll {
			if t.Id.Package == "kego.io/system" {
				// none of the system types should be added as a global
				continue
			}
			if t.Implements(ctx, rule) {
				// rules should never be added as a global
				continue
			}
			types = append(types, t)
		}

	} else {
		syscache := sysctx.FromContext(ctx)
		t, ok := syscache.GetType("kego.io/system", "type")
		if !ok {
			panic(kerr.New("NNFSJEXNKF", "Can't find system:type in sys ctx").Error())
		}
		types = []*system.Type{t.(*system.Type)}
	}

	app.Dispatch(&actions.OpenAddPopup{
		Types: types,
	})

}
예제 #16
0
파일: rule.go 프로젝트: kego/ke
func WrapRule(ctx context.Context, r RuleInterface) *RuleWrapper {

	ob, ok := r.(ObjectInterface)
	if !ok {
		panic(kerr.New("VKFNPJDNVB", "%T does not implement ObjectInterface", r).Error())
	}

	// ob.GetObject(nil).Type will be a @ rule type, so we change to the type,
	// which will be the parent
	t, ok := ob.GetObject(nil).Type.ChangeToType().GetType(ctx)
	if !ok {
		panic(kerr.New("KYCTDXKFYR", "GetType: type %v not found", ob.GetObject(nil).Type.ChangeToType().Value()).Error())
	}

	return &RuleWrapper{Ctx: ctx, Interface: r, Parent: t, Struct: r.GetRule(nil)}
}
예제 #17
0
파일: reference.go 프로젝트: kego/ke
func (r Reference) ValueContext(ctx context.Context) (string, error) {

	env := envctx.FromContextOrNil(ctx)
	if env == nil || env.Path == "" {
		return r.Value(), nil
	}

	if r.Package == "" && r.Name == "" {
		return "", nil
	}
	if r.Package == env.Path {
		return r.Name, nil
	}
	if r.Package == "kego.io/json" {
		return fmt.Sprintf("json:%s", r.Name), nil
	}
	if r.Package == "kego.io/system" {
		return fmt.Sprintf("system:%s", r.Name), nil
	}
	for alias, pkg := range env.Aliases {
		if pkg == r.Package {
			return fmt.Sprintf("%s:%s", alias, r.Name), nil
		}
	}
	return "", kerr.New("WGCDQQCFAD", "Package %s not found in aliases", r.Package)
}
예제 #18
0
파일: node.go 프로젝트: kego/ke
func (n *Node) ReorderArrayChild(from, to int) error {

	if n.JsonType != system.J_ARRAY {
		return kerr.New("MHEXGBUQOL", "Must be J_ARRAY")
	}

	a := n.Array

	// remove the item we're moving
	item := a[from]

	a = append(
		a[:from],
		a[from+1:]...)

	// insert it back in the correct place
	n.Array = append(
		a[:to],
		append([]*Node{item}, a[to:]...)...)

	// correct the indexes
	for i, c := range n.Array {
		c.Index = i
	}

	val := n.Val.Index(from).Interface()
	deleteFromSlice(n.Val, from)
	insertIntoSlice(n.Val, to, reflect.ValueOf(val))
	return nil
}
예제 #19
0
파일: clientctx.go 프로젝트: kego/ke
func FromContext(ctx context.Context) *EditorCache {
	ec, ok := ctx.Value(ctxKey).(*EditorCache)
	if !ok {
		panic(kerr.New("BIUVXISEMA", "No editors in ctx").Error())
	}
	return ec
}
예제 #20
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
}
예제 #21
0
파일: context.go 프로젝트: kego/ke
func FromContext(ctx context.Context) *App {
	app, ok := ctx.Value(ctxKey).(*App)
	if !ok {
		panic(kerr.New("EJRTLPWCKH", "No app in ctx").Error())
	}
	return app
}
예제 #22
0
파일: type.go 프로젝트: kego/ke
func GetAllTypesThatImplementReflectInterface(ctx context.Context, reflectType reflect.Type) []*Type {

	if reflectType.Kind() != reflect.Interface {
		panic(kerr.New("JUCCMVNDLR", "%v is not an interface", reflectType).Error())
	}

	scache := sysctx.FromContext(ctx)

	out := []*Type{}

	for _, pkgName := range scache.Keys() {
		pkgInfo, ok := scache.Get(pkgName)
		if !ok {
			// ke: {"block": {"notest": true}}
			continue
		}
		for _, typName := range pkgInfo.Types.Keys() {
			typ, ok := pkgInfo.Types.Get(typName)
			if !ok {
				// ke: {"block": {"notest": true}}
				continue
			}
			t := typ.Type.(*Type)
			if t.Interface {
				continue
			}
			if t.Implements(ctx, reflectType) {
				out = append(out, t)
			}
		}
	}

	return out
}
예제 #23
0
파일: reference.go 프로젝트: kego/ke
func (r *ReferenceRule) Enforce(ctx context.Context, data interface{}) (fail bool, messages []string, err error) {

	if i, ok := data.(ReferenceInterface); ok && i != nil {
		data = i.GetReference(ctx)
	}

	v, ok := data.(*Reference)
	if !ok && data != nil {
		return true, nil, kerr.New("BYDVGGETWW", "Reference rule: value %T should be *system.Reference", data)
	}

	// Pattern restriction should be the same as StringRule
	var s *String
	if v != nil {
		s = NewString(v.Name)
	}
	sr := StringRule{
		Rule:       &Rule{Optional: r.Optional},
		Pattern:    r.Pattern,
		PatternNot: r.PatternNot,
	}
	if fail, messages, err = sr.Enforce(ctx, s); err != nil {
		return true, nil, kerr.Wrap("KYYJLYOSHT", err)
	}
	return
}
예제 #24
0
파일: cmdctx.go 프로젝트: kego/ke
// FromContext returns the User value stored in ctx, if any.
func FromContext(ctx context.Context) *Cmd {
	e, ok := ctx.Value(cmdKey).(*Cmd)
	if !ok {
		panic(kerr.New("OQVLBQFQJW", "No cmd in ctx").Error())
	}
	return e
}
예제 #25
0
파일: validate.go 프로젝트: kego/ke
func comparePackageHash(ctx context.Context, path string) (changes bool, err error) {

	scache := sysctx.FromContext(ctx)
	spi, ok := scache.Get(path)
	if !ok {
		return false, kerr.New("NHXWLPHCHL", "%s not found in sys ctx", path)
	}

	for _, aliasPath := range spi.Aliases {
		changes, err := comparePackageHash(ctx, aliasPath)
		if err != nil {
			return false, kerr.Wrap("DGJTLHQOCQ", err)
		}
		if changes {
			return true, nil
		}
	}

	jcache := jsonctx.FromContext(ctx)
	jpi, ok := jcache.Packages.Get(path)
	if !ok {
		return true, nil
	}

	// pcache.Environment.Hash is computed after parsing all the data files.
	// h.Hash is in generated.go (jsonctx.InitPackage), and correct when the types were generated.
	if jpi.Hash != spi.Hash {
		return true, nil
	}
	return false, nil
}
예제 #26
0
파일: parser.go 프로젝트: kego/ke
func ProcessTypeFileBytes(ctx context.Context, env *envctx.Env, filename string, bytes []byte, cache *sysctx.SysPackageInfo, hash *PackageHasher) error {
	t := new(system.Type)
	if err := system.Unmarshal(envctx.NewContext(ctx, env), bytes, t); err != nil {
		return kerr.Wrap("NLRRVIDVWM", err)
	}
	if hash != nil {
		hash.Types[t.Id.Name] = cityhash.CityHash64(bytes, uint32(len(bytes)))
	}
	cache.Types.Set(t.Id.Name, filename, t)
	cache.Files.Set(t.Id.Name, filename, bytes)
	if t.Rule != nil {
		id := system.NewReference(t.Id.Package, fmt.Sprint("@", t.Id.Name))
		if t.Rule.Id != nil && *t.Rule.Id != *id {
			return kerr.New("JKARKEDTIW", "Incorrect id for %v - it should be %v", t.Rule.Id.String(), id.String())
		}
		t.Rule.Id = id

		// Check that the rule embeds system:rule
		found := false
		for _, em := range t.Rule.Embed {
			if *em == *system.NewReference("kego.io/system", "rule") {
				found = true
			}
		}
		if !found {
			return kerr.New("LMALEMKFDI", "%s does not embed system:rule", id.String())
		}

		cache.Types.Set(id.Name, filename, t.Rule)
	} else {
		// If the rule is missing, automatically create a default.
		id := system.NewReference(t.Id.Package, fmt.Sprint("@", t.Id.Name))
		rule := &system.Type{
			Object: &system.Object{
				Description: fmt.Sprintf("Automatically created basic rule for %s", t.Id.Name),
				Type:        system.NewReference("kego.io/system", "type"),
				Id:          id,
			},
			Embed:     []*system.Reference{system.NewReference("kego.io/system", "rule")},
			Native:    system.NewString("object"),
			Interface: false,
		}
		cache.Types.Set(id.Name, filename, rule)
	}

	return nil
}
예제 #27
0
파일: node.go 프로젝트: kego/ke
func (n *Node) DeleteMapChild(key string) error {
	if n.JsonType != system.J_MAP {
		return kerr.New("ACRGPCPPFK", "Must be J_MAP")
	}
	delete(n.Map, key)
	deleteFromMap(n.Val, key)
	return nil
}
예제 #28
0
파일: bootstrap.go 프로젝트: kego/ke
func UnpackMappyInterface(ctx context.Context, in Packed) (MappyInterface, error) {
	// Mappy is an map type, so we only accept a typed map
	switch in.Type() {
	case J_MAP:
		ob, err := UnpackUnknownType(ctx, in, true, "kego.io/system", "mappy")
		if err != nil {
			return nil, kerr.Wrap("QSTEIBUNWO", err)
		}
		i, ok := ob.(MappyInterface)
		if !ok {
			return nil, kerr.New("SMJXFKMKSP", "%T does not implement system.MappyInterface", ob)
		}
		return i, nil
	default:
		return nil, kerr.New("VYHBOJFSIM", "Unpacking into a MappyInterface, so input must be a map. Found %s", in.Type())
	}
}
예제 #29
0
파일: selectors.go 프로젝트: kego/ke
func (p *Parser) match(tokens []*token, typ tokenType) (interface{}, []*token, error) {
	value, matched, _ := p.peek(tokens, typ)
	if !matched {
		return nil, tokens, kerr.New("EGHVMCOKCS", "Match not successful")
	}
	_, tokens = tokens[0], tokens[1:]
	return value, tokens, nil
}
예제 #30
0
func UnpackNumber(ctx context.Context, in Packed) (float64, error) {
	if in == nil || in.Type() == J_NULL {
		return 0.0, nil
	}
	if in.Type() != J_NUMBER {
		return 0.0, kerr.New("PFHJQLAIFP", "UnpackNumber: %s must by J_NUMBER", in.Type())
	}
	return in.Number(), nil
}