hyperjumptech/grule-rule-engine

Map Key Does Not Exist - Errors - How to write such rules with maps?

Opened this issue · 2 comments

alok87 commented

Fact

fact := &Fact{
		ItemCount:     5,
		SkuCount:      3,
		CategoryCount: 3,
		CatList:       []string{"cat1,cat2,cat3"},
		SkuList:       "sku1,sku2,sku3",
		Category: map[string]fact.Category{
			"cat1": {
				ItemCount: 5,
				SkuCount:  3,
			},
		},
		Skus: map[string]fact.Sku{
			"sku1": {
				ItemCount:    5,
				VariantCount: 3,
			},
		},
	}

Rule

Fact.Category["cat2"].ItemCount > 5

This errors saying "cat2" does not exist in Category. How do you write such rules?

alok87 commented

Custom functions works!

Rule:

When:     "Magic.CategoryItemCount("cat2") > 3",

Custom Function works

func (m Magic) CategoryItemCount(category string) int {
	if _, ok := m.Category[category]; !ok {
		return -1
	}
	return m.Category[category].ItemCount
}

There's a small mistake in your provided example - you populate the Category map with a key cat1 but appear to be checking for cat2 in your rule.

Regardless, this should work. You can access properties on structs in maps as expected. One key note is that this does not work for maps to interfaces! i.e. map[string]fact.Category is fine, but map[string]interface{} is not. However map[string]interface{} will work for basic types (int64 / string / bool / float64).

Simple things to check:

  • that your keys do match
  • you are using the correct name for your fact (as it was added to the DataContext)