Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Panic on using map[string]interface{} #9

Open
akamensky opened this issue Oct 7, 2019 · 4 comments
Open

Panic on using map[string]interface{} #9

akamensky opened this issue Oct 7, 2019 · 4 comments
Labels
enhancement New feature or request

Comments

@akamensky
Copy link

I am trying to use this library for evaluation of user provided expressions. Which means that there are no defined structs for objects. Instead it is a parsed JSON, (which simply outputs map[string]interface{}). However, this library seems unable to handle such use case? Or am I using it wrong way?

Example code:

func main() {
	userjson := `{"id": 123}`

	filejson := `{"owner": 123}`

	var User map[string]interface{}
	var File map[string]interface{}

	err := fastjson.Unmarshal([]byte(userjson), &User)
	if err != nil {
		panic(err)
	}

	err = fastjson.Unmarshal([]byte(filejson), &File)
	if err != nil {
		panic(err)
	}

	type Env map[string]interface{}

	e := map[string]interface{}{
		"file": File,
		"user": User,
	}

	expr := "file.owner == user.id"

	eval, err := bexpr.CreateEvaluatorForType(expr, nil, (*map[string]interface{})(nil))
	if err != nil {
		panic(err)
	}

	result, err := eval.Evaluate(e)
	if err != nil {
		panic(err)
	}

	fmt.Println(result)
}
@mkeeler
Copy link
Member

mkeeler commented Oct 7, 2019

@akamensky This library is really intended for filtering outputs of structured data at the moment.

Internally we generate potential selectable fields from the data type not the datas value. So in the case of map[string]interface{} we end up with no selectable fields as we have no way of knowing what might be behind that interface{}.

Currently evaluation ensures that only those fields that we know about from during the introspection of the data type are used and only those operations that we know should be allowed based on the original data are used. In fact we take a preliminary pass and validating all fields used in an expression with the field configuration prior to evaluating anything.

While we could potentially allow for more lazy expression validation during evaluation its not something that fits into the core use cases behind creating this library (which really was to have the ability to filter API outputs rather than inputs. For now at least your best bet is probably to use an alternative library. https://github.com/antonmedv/expr is one which I have seen and is geared towards more general use cases I believe.

@mkeeler mkeeler added the enhancement New feature or request label Oct 7, 2019
@mkeeler
Copy link
Member

mkeeler commented Oct 7, 2019

Enhancement:

• Allow for lazy field selector validation through interface{} types.

@akamensky
Copy link
Author

For now at least your best bet is probably to use an alternative library. https://github.com/antonmedv/expr is one which I have seen and is geared towards more general use cases I believe.

I already looked at https://github.com/antonmedv/expr, but while it can do exactly just that, it does not restrict expressions to boolean only, and in my use case I need exactly only boolean expressions and not allow any other types to be returned. From the expression syntax perspective this library would fit my needs best.

Thanks anyway for your response, looks like I would have to stick with expr for now.

@antonmedv
Copy link

@akamensky you can restrict it to booleans only: https://godoc.org/github.com/antonmedv/expr#AsBool

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants