indigo

package module
v0.7.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 17, 2023 License: LGPL-3.0 Imports: 10 Imported by: 0

README

Go Reference

Indigo

Indigo is a rules engine created to enable application developers to build systems whose logic can be controlled by end-users via rules. Rules are expressions (such as "a > b") that are evaluated, and the outcomes used to direct appliation logic. Indigo does not itself provide a language for expressions, relying instead on a backend compiler (interface ExpressionCompiler) and evaluator (interface ExpressionEvaluator) to provide that. You can create your own backend evaluator, or use the default one, Google's Common Expression Language, CEL.

Development Status

Indigo is pre-release and there may be breaking changes between releases. When 1.0.0 is released, the API will be frozen.

Google's Common Expression Language

Indigo supports the CEL language as an evaluation back-end. See https://github.com/google/cel-go and https://opensource.google/projects/cel for more information about CEL and the Go implementation of it. CEL is a rich expression language, providing not only boolean expression output, but also calculations and object construction. Particularly powerful is the "native" use of protocol buffers in CEL's schema, rule language and return types.

Usage

The example ExampleHelloWorld shows basic usage of the engine.


func ExampleHelloWorld() {

	// Step 1: Create a schema
	schema := indigo.Schema{
		Elements: []indigo.DataElement{
			{Name: "message", Type: indigo.String{}},
		},
	}

	// Step 2: Create rules
	rule := indigo.Rule{
		ID:     "hello_check",
		Schema: schema,
		Expr:   `message == "hello world"`,
	}

	// Step 3: Create Indigo and give it an evaluator
	// In this case, CEL
	evaluator := cel.NewEvaluator()
	engine := indigo.NewEngine(evaluator)

	// Step 4: Compile the rule
	err := engine.Compile(&rule)
	if err != nil {
		fmt.Println(err)
		return
	}

	data := map[string]interface{}{
		"message": "hello world",
	}

	// Step 5: Evaluate and check the results
	results, err := engine.Evaluate(data, &rule)
	fmt.Println(results.ExpressiongPass)
	// Output: true
}

For More Information

The Indigo Guide gives a deeper guide to using Indigo.

The use cases page gives examples of ways you can struture rules in Indigo.

The documentation for the CEL package gives examples of using the CEL expression language.

Documentation

Overview

Package indigo provides a rules engine.

Indigo is a rules engine created to enable application developers to build systems whose logic can be controlled by end-users via rules. Rules are expressions (such as "a > b") that are evaluated, and the outcomes used to direct appliation logic.

Indigo does not specify a language for rules, relying instead on a rule evaluator to perform the work. The default rule evaluator (in the cel package) is the Common Expression Language from Google (https://github.com/google/cel-go).

Compilation and Evaluation

Indigo provides methods to compile and evaluate rules. The compilation step gives the evaluator a chance to pre-process the rule, provide feedback on rule correctness, and store an intermediate form of the rule for evaluation efficiency. The evaluation evaluates the rule against input data and provides the output.

Basic Structure

Indigo organizes rules in hierarchies. A parent rule can have 0 or many child rules. You do not have to organize rules in a complex tree; a single parent with 1,000s of child rules is OK. There are 3 main reasons for using a tree to organize rules:

  1. Allow atomic rule updates (see separate section)
  2. Use options on the parent rule to control if child rules are evaluated (in effect, child rules "inherit" the parent rule's condition)
  3. Use options on the parent rule to control which child rules are returned as results (such as returning true or false results, or both)
  4. Logically separate disparate groups of rules

Rule Ownership

The calling application is responsible for managing the lifecycle of rules, including ensuring concurrency safety. Some things to keep in mind:

  1. You must not allow changes to a rule during compilation.
  2. You may not modify the rule after compilation and before evaluation.
  3. You must not allow changes to a rule during evaluation.
  4. You should not modify a rule after it's been evaluated and before the results have been consumed.
  5. A rule must not be a child rule of more than one parent.

Updating Rules

To add or remove rules, you do so by modifying the parent rule's map of Rules

delete(parent.Rules, "child-id-to-delete")

and

myNewRule.Compile(myCompiler)
parent.Rules["my-new-rule"] = myNewRule

It is not recommended to update a rule IN PLACE, unless you manage the rule lifecycle beyond evaluation and use of the rule in interpreting the results. Users of your result should expect that the definition of the rule stays constant. Instead, we recommend creating a new rule with a new version number in the ID to separate updates.

WARNING! YOU **MUST** COMPILE THE RULE AFTER MAKING MODIFICATIONS TO THE RULE, INCLUDING
THE LIST OF CHILD RULES.

Structuring Rule Hierarchies for Updates

The ability to organize rules in a hierarchy is useful to ensure that rule updates are atomic and consistent.

You should structure the hierarchy so that a rule and its children can be seen as a "transaction" as far as updates are concerned.

In this example, where Indigo is being used to enforce firewall rules, being able to update ALL firewall rules as a group, rather than one by one (where one update may fail) is important.

Firewall Rules (parent)
  "Deny all traffic" (child 1)
  "Allow traffic from known_IPs" (child 2)

If the user changes child 1 to be "Allow all traffic" and changes child 2 to "Deny all traffic, except for known_IPs", there's a risk that child 1 is changed first, without the child 2 change happening. This would leave us with this:

Firewall Rules (parent)
  "Allow all traffic" (child 1)
  "Allow traffic from known_IPs" (child 2)

This is clearly bad!

Instead of accepting a change to child 1 and child 2 separately, ONLY accept a change to your rule hierarchy for the Firewall Rules parent. That way the update succeeds or fails as a "transaction".

If Firewall Rules is itself a child of a larger set of parent rules, it's recommended to compile the Firewall Rules parent and children BEFORE adding it to its eventual parent. That way you ensure that if compilation of Firewall Rules fails, the "production" firewall rules are still intact.

Example

Example showing basic use of the Indigo rules engine with the CEL evaluator

package main

import (
	"context"
	"fmt"

	"github.com/ezachrisen/indigo"
	"github.com/ezachrisen/indigo/cel"
)

func main() {

	// Step 1: Create a schema
	schema := indigo.Schema{
		Elements: []indigo.DataElement{
			{Name: "message", Type: indigo.String{}},
		},
	}

	// Step 2: Create rules
	rule := indigo.Rule{
		ID:         "hello_check",
		Schema:     schema,
		Expr:       `message == "hello world"`,
		ResultType: indigo.Bool{},
	}

	// Step 3: Create an Engine with a CEL evaluator
	engine := indigo.NewEngine(cel.NewEvaluator())

	// Step 4: Compile the rule
	err := engine.Compile(&rule)
	if err != nil {
		fmt.Println(err)
		return
	}

	// The data we wish to evaluate the rule on
	data := map[string]interface{}{
		"message": "hello world",
	}

	// Step 5: Evaluate and check the results
	results, err := engine.Eval(context.Background(), &rule, data)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(results.ExpressionPass)
	}
}
Output:

true

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func ApplyToRule added in v0.6.0

func ApplyToRule(r *Rule, f func(r *Rule) error) error

ApplyToRule applies the function f to the rule r and its children recursively.

Example

Demonstrate applying a function to a rule

r := makeRule()

err := indigo.ApplyToRule(r, func(r *indigo.Rule) error {
	fmt.Printf("%s ", r.ID)
	return nil
})

if err != nil {
	fmt.Println("Failure!")
}

fmt.Printf("\n")
// Output unordered: rule1 B b1 b2 b3 b4 b4-1 b4-2 E e1 e2 e3 D d1 d2 d3
Output:

func DiagnosticsReport added in v0.6.2

func DiagnosticsReport(u *Result, data map[string]interface{}) string

DiagnosticsReport produces an ASCII report of the input rules, input data, the evaluation diagnostics and the results.

func SortRulesAlpha added in v0.6.9

func SortRulesAlpha(rules []*Rule, i, j int) bool

SortRulesAlpha will sort rules alphabetically by their rule ID

func SortRulesAlphaDesc added in v0.6.9

func SortRulesAlphaDesc(rules []*Rule, i, j int) bool

SortRulesAlphaDesc will sort rules alphabetically (descending) by their rule ID

Types

type Any

type Any struct{}

Any defines an Indigo type for an "undefined" or unspecified type.

func (Any) String

func (Any) String() string

type Bool

type Bool struct{}

Bool defines an Indigo type for true/false.

func (Bool) String

func (Bool) String() string

type CompilationOption added in v0.6.0

type CompilationOption func(f *compileOptions)

CompilationOption is a functional option to specify compilation behavior.

func CollectDiagnostics

func CollectDiagnostics(b bool) CompilationOption

CollectDiagnostics instructs the engine and its evaluator to save any intermediate results of compilation in order to provide good diagnostic information after evaluation. Not all evaluators need to have this option set.

func DryRun added in v0.6.0

func DryRun(b bool) CompilationOption

DryRun specifies to perform all compilation steps, but do not save the results. This is to allow a client to check all rules in a rule tree before committing the actual compilation results to the rule.

type Compiler added in v0.6.5

type Compiler interface {
	Compile(r *Rule, opts ...CompilationOption) error
}

Compiler is the interface that wraps the Compile method. Compile pre-processes the rule recursively using an ExpressionCompiler, which is applied to each rule.

type DataElement

type DataElement struct {
	// Short, user-friendly name of the variable. This is the name
	// that will be used in rules to refer to data passed in.
	//
	// RESERVED NAMES:
	//   selfKey (see const)
	Name string `json:"name"`

	// One of the Type interface defined.
	Type Type `json:"type"`

	// Optional description of the type.
	Description string `json:"description"`
}

DataElement defines a named variable in a schema

func (*DataElement) String added in v0.6.0

func (e *DataElement) String() string

String returns a human-readable representation of the element

type DefaultEngine added in v0.6.0

type DefaultEngine struct {
	// contains filtered or unexported fields
}

DefaultEngine provides an implementation of the Indigo Engine interface to evaluate rules locally.

func NewEngine

NewEngine initializes and returns a DefaultEngine.

func (*DefaultEngine) Compile added in v0.6.0

func (e *DefaultEngine) Compile(r *Rule, opts ...CompilationOption) error

Compile uses the Evaluator's compile method to check the rule and its children, returning any validation errors. Stores a compiled version of the rule in the rule.Program field (if the compiler returns a program).

func (*DefaultEngine) Eval added in v0.6.0

func (e *DefaultEngine) Eval(ctx context.Context, r *Rule,
	d map[string]interface{}, opts ...EvalOption) (*Result, error)

Eval evaluates the expression of the rule and its children. It uses the evaluation options of each rule to determine what to do with the results, and whether to proceed evaluating. Options passed to this function will override the options set on the rules. Eval uses the Evaluator provided to the engine to perform the expression evaluation.

type Diagnostics added in v0.6.2

type Diagnostics struct {
	Expr      string // the part of the rule expression evaluated
	Interface interface{}
	Source    ValueSource   // where the value came from: input data, or evaluted by the engine
	Line      int           // the 1-based line number in the original source expression
	Column    int           // the 0-based column number in the original source expression
	Offset    int           // the 0-based character offset from the start of the original source expression
	Children  []Diagnostics // one child per sub-expression. Each Evaluator may produce different results.
}

Diagnostics holds the internal rule-engine intermediate results. Request diagnostics for an evaluation to help understand how the engine reached the final output value. Diagnostics is a nested set of nodes, with 1 root node per rule evaluated. The children represent elements of the expression evaluated.

func (*Diagnostics) String added in v0.6.2

func (d *Diagnostics) String() string

String produces an ASCII table with human-readable diagnostics.

type Duration

type Duration struct{}

Duration defines an Indigo type for the time.Duration type.

func (Duration) String

func (Duration) String() string

type Engine

type Engine interface {
	Compiler
	Evaluator
}

Engine is the interface that groups the Compiler and Evaluator interfaces. An Engine is used to compile and evaluate rules.

type EvalOption

type EvalOption func(f *EvalOptions)

EvalOption is a functional option for specifying how evaluations behave.

func DiscardFail added in v0.6.0

func DiscardFail(k FailAction) EvalOption

DiscardFail specifies whether to omit failed rules from the results.

func DiscardPass added in v0.6.0

func DiscardPass(b bool) EvalOption

DiscardPass specifies whether to omit passed rules from the results.

func ReturnDiagnostics

func ReturnDiagnostics(b bool) EvalOption

ReturnDiagnostics specifies that diagnostics should be returned from this evaluation. You must first turn on diagnostic collectionat the engine level when compiling the rule.

func SortFunc

func SortFunc(x func(rules []*Rule, i, j int) bool) EvalOption

SortFunc specifies the function used to sort child rules before evaluation. Sorting is only performed if the evaluation order of the child rules is important (i.e., if an option such as StopFirstNegativeChild is set).

Example

Demonstrate setting the sorting function for all rules to be alphabetical, based on the rule ID

r := makeRule()

err := indigo.ApplyToRule(r, func(r *indigo.Rule) error {
	r.EvalOptions.SortFunc = func(rules []*indigo.Rule, i, j int) bool {
		return rules[i].ID < rules[j].ID
	}
	return nil
})

if err != nil {
	fmt.Println("Failure!")
}

fmt.Println("Ok")
Output:

Ok

func StopFirstNegativeChild

func StopFirstNegativeChild(b bool) EvalOption

StopFirstNegativeChild stops the evaluation of child rules once the first negative child has been found.

func StopFirstPositiveChild

func StopFirstPositiveChild(b bool) EvalOption

StopFirstPositiveChild stops the evaluation of child rules once the first positive child has been found.

func StopIfParentNegative

func StopIfParentNegative(b bool) EvalOption

StopIfParentNegative prevents the evaluation of child rules if the parent rule itself is negative.

type EvalOptions

type EvalOptions struct {

	// TrueIfAny makes a parent rule Pass = true if any of its child rules are true.
	// The default behavior is that a rule is only true if all of its child rules are true, and
	// the parent rule itself is true.
	// Setting TrueIfAny changes this behvior so that the parent rule is true if at least one of its child rules
	// are true, and the parent rule itself is true.
	TrueIfAny bool `json:"true_if_any"`

	// StopIfParentNegative prevents the evaluation of child rules if the parent's expression is false.
	// Use case: apply a "global" rule to all the child rules.
	StopIfParentNegative bool `json:"stop_if_parent_negative"`

	// Stops the evaluation of child rules when the first positive child is encountered.
	// Results will be partial. Only the child rules that were evaluated will be in the results.
	// Use case: role-based access; allow action if any child rule (permission rule) allows it.
	StopFirstPositiveChild bool `json:"stop_first_positive_child"`

	// Stops the evaluation of child rules when the first negative child is encountered.
	// Results will be partial. Only the child rules that were evaluated will be in the results.
	// Use case: you require ALL child rules to be satisfied.
	StopFirstNegativeChild bool `json:"stop_first_negative_child"`

	// Do not return rules that passed
	// Default: all rules are returned
	DiscardPass bool `json:"discard_pass"`

	// Decide what to do to rules that failed
	// Default: all rules are returned
	DiscardFail FailAction

	// Include diagnostic information with the results.
	// To enable this option, you must first turn on diagnostic
	// collection at the engine level with the CollectDiagnostics EngineOption.
	ReturnDiagnostics bool `json:"return_diagnostics"`

	// Specify the function used to sort the child rules before evaluation.
	// Useful in scenarios where you are asking the engine to stop evaluating
	// after either the first negative or first positive child in order to
	// select a rule with some relative characteristic, such as the "highest
	// priority rule".
	//
	// See the ExampleSortFunc() for an example.
	// The function returns whether rules[i] < rules[j] for some attribute.
	// Default: No sort
	SortFunc func(rules []*Rule, i, j int) bool `json:"-"`
	// contains filtered or unexported fields
}

EvalOptions determines how the engine should treat the results of evaluating a rule.

type Evaluator

type Evaluator interface {
	Eval(ctx context.Context, r *Rule, d map[string]interface{}, opts ...EvalOption) (*Result, error)
}

Evaluator is the interface that wraps the Evaluate method. Evaluate tests the rule recursively against the input data using an ExpressionEvaluator, which is applied to each rule.

type ExpressionCompiler added in v0.6.5

type ExpressionCompiler interface {
	Compile(expr string, s Schema, resultType Type, collectDiagnostics, dryRun bool) (interface{}, error)
}

ExpressionCompiler is the interface that wraps the Compile method. Compile pre-processes the expression, returning a compiled version. The Indigo Compiler will store the compiled version, later providing it back to the evaluator.

collectDiagnostics instructs the compiler to generate additional information to help provide diagnostic information on the evaluation later. dryRun performs the compilation, but doesn't store the results, mainly for the purpose of checking rule correctness.

type ExpressionCompilerEvaluator added in v0.6.5

type ExpressionCompilerEvaluator interface {
	ExpressionCompiler
	ExpressionEvaluator
}

ExpressionCompilerEvaluator is the interface that groups the ExpressionCompiler and ExpressionEvaluator interfaces for back-end evaluators that require a compile and an evaluate step.

type ExpressionEvaluator added in v0.6.5

type ExpressionEvaluator interface {
	Evaluate(data map[string]interface{}, expr string, s Schema,
		self interface{}, evalData interface{}, resultType Type, returnDiagnostics bool) (interface{}, *Diagnostics, error)
}

ExpressionEvaluator is the interface that wraps the Evaluate method. Evaluate tests the rule expression against the data. Returns the result of the evaluation and a string containing diagnostic information. Diagnostic information is only returned if explicitly requested. Evaluate should check the result against the expected resultType and return an error if the result does not match.

type FailAction added in v0.7.0

type FailAction int

FailAction is used to tell Indigo what to do with the results of rules that did not pass.

const (
	// KeepAll means that all results, whether the rule passed or not,
	// are returned by Indigo after evaluation.
	KeepAll FailAction = iota

	// Discard means that the results of rules that failed are not
	// returned by Indigo after evaluation, though their effect on a parent
	// rule's pass/fail state is retained.
	Discard

	// DiscardOnlyIfExpressionFailed means that the result of a rule will
	// not be discarded unless it's ExpressionPass result is false.
	// Even if the rule itself has result of Pass = false, the rule will
	// be returned in the result.
	DiscardOnlyIfExpressionFailed
)

type Float

type Float struct{}

Float defines an Indigo float type. The implementation of the float (size, precision) depends on the evaluator used.

func (Float) String

func (Float) String() string

type Int

type Int struct{}

Int defines an Indigo int type. The exact "Int" implementation and size depends on the evaluator used.

func (Int) String

func (Int) String() string

String Methods

type List

type List struct {
	ValueType Type // the type of element stored in the list
}

List defines an Indigo type representing a slice of values

func (List) String

func (t List) String() string

type Map

type Map struct {
	KeyType   Type // the type of the map key
	ValueType Type // the type of the value stored in the map
}

Map defines an Indigo type representing a map of keys and values.

func (Map) String

func (t Map) String() string

type Proto

type Proto struct {
	Message proto.Message // an instance of the proto message
}

Proto defines an Indigo type for a protobuf type.

func (*Proto) ProtoFullName added in v0.6.5

func (p *Proto) ProtoFullName() (string, error)

ProtoFullName uses protocol buffer reflection to obtain the full name of the proto type.

func (Proto) String

func (p Proto) String() string

type Result

type Result struct {
	// The Rule that was evaluated
	Rule *Rule

	// Whether the rule is true.
	// The default is TRUE.
	// Pass is the result of rolling up all child rules and evaluating the
	// rule's own expression. All child rules and the rule's expression must be
	// true for Pass to be true.
	Pass bool

	// Whether evaluating the rule expression yielded a TRUE logical value.
	// The default is TRUE.
	// The result will not be affected by the results of the child rules.
	// If no rule expression is supplied for a rule, the result will be TRUE.
	ExpressionPass bool

	// The raw result of evaluating the expression. Boolean for logical expressions.
	// Calculations, object constructions or string manipulations will return the appropriate Go type.
	// This value is never affected by child rules.
	Value interface{}

	// Results of evaluating the child rules.
	Results map[string]*Result

	// Diagnostic data; only available if you turn on diagnostics for the evaluation
	Diagnostics *Diagnostics

	// The evaluation options used
	EvalOptions EvalOptions

	// A list of the rules evaluated, in the order they were evaluated
	// Only available if you turn on diagnostics for the evaluation
	// This may be different from the rules represented in Results, if
	// If we're discarding failed/passed rules, they will not be in the results,
	// and will not show up in diagnostics, but they will be in this list.
	RulesEvaluated []*Rule
}

Result of evaluating a rule.

func (*Result) String added in v0.6.0

func (u *Result) String() string

String produces a list of rules (including child rules) executed and the result of the evaluation.

func (*Result) Summary added in v0.6.7

func (u *Result) Summary() string

String produces a list of rules (including child rules) executed and the result of the evaluation.

type Rule

type Rule struct {
	// A rule identifer. (required)
	ID string `json:"id"`

	// The expression to evaluate (optional)
	// The expression can return a boolean (true or false), or any
	// other value the underlying expression engine can produce.
	// All values are returned in the Results.Value field.
	// Boolean values are also returned in the results as Pass = true  / false
	// If the expression is blank, the result will be true.
	Expr string `json:"expr"`

	// The output type of the expression. Evaluators with the ability to check
	// whether an expression produces the desired output should return an error
	// if the expression does not.
	// If no type is provided, evaluation and compilation will default to Bool
	ResultType Type `json:"result_type,omitempty"`

	// The schema describing the data provided in the Evaluate input. (optional)
	// Some implementations of Evaluator require a schema.
	Schema Schema `json:"schema,omitempty"`

	// A reference to an object whose values can be used in the rule expression.
	// Add the corresponding object in the data with the reserved key name selfKey
	// (see constants).
	// Child rules do not inherit the self value.
	Self interface{} `json:"-"`

	// A set of child rules.
	Rules map[string]*Rule `json:"rules,omitempty"`

	// Reference to intermediate compilation / evaluation data.
	Program interface{} `json:"-"`

	// A reference to any object.
	// Not used by the rules engine.
	Meta interface{} `json:"-"`

	// Options determining how the child rules should be handled.
	EvalOptions EvalOptions `json:"eval_options"`
	// contains filtered or unexported fields
}

A Rule defines logic that can be evaluated by an Evaluator. The logic for evaluation is specified by an expression. A rule can have child rules. Rule options specify to the Evaluator how child rules should be handled. Child rules can in turn have children, enabling you to create a hierarchy of rules.

Example Rule Structures

A hierchy of parent/child rules, combined with evaluation options give many different ways of using the rules engine.

Rule with expression, no child rules:
 Parent rule expression is evaluated and result returned.

Rule with expression and child rules:
 No options specified
 - Parent rule xpression is evaluated, and so are all the child rules.
 - All children and their evaluation results are returned

Rule with expression and child rules
Option set: StopIfParentNegative
- Parent rule expression is evaluated
- If the parent rule is a boolean, and it returns FALSE,
  the children are NOT evaluated
- If the parent rule returns TRUE, or if it's not a
  boolean, all the children and their resulsts are returned

func NewRule added in v0.6.0

func NewRule(id string, expr string) *Rule

NewRule initializes a rule with the ID and rule expression. The ID and expression can be empty.

func (*Rule) String added in v0.6.0

func (r *Rule) String() string

String returns a list of all the rules in hierarchy, with child rules sorted in evaluation order.

type Schema

type Schema struct {
	// Identifier for the schema. Useful for the hosting application; not used by Indigo internally.
	ID string `json:"id,omitempty"`
	// User-friendly name for the schema
	Name string `json:"name,omitempty"`
	// A user-friendly description of the schema
	Description string `json:"description,omitempty"`
	// User-defined value
	Meta interface{} `json:"-"`
	// List of data elements supported by this schema
	Elements []DataElement `json:"elements,omitempty"`
}

Schema defines the variable names and their data types used in a rule expression. The same keys and types must be supplied in the data map when rules are evaluated.

func (*Schema) String added in v0.6.0

func (s *Schema) String() string

String returns a human-readable representation of the schema

type String

type String struct{}

String defines an Indigo string type.

func (String) String

func (String) String() string

type Timestamp

type Timestamp struct{}

Timestamp defines an Indigo type for the time.Time type.

func (Timestamp) String

func (Timestamp) String() string

type Type

type Type interface {
	// Implements the stringer interface
	String() string
}

Type defines a type in the Indigo type system. These types are used to define schemas and define required evaluation results. Not all implementations of Evaluator support all types.

func ParseType added in v0.6.0

func ParseType(t string) (Type, error)

ParseType parses a string that represents an Indigo type and returns the type. The primitive types are their lower-case names (string, int, duration, etc.) Maps and lists look like Go maps and slices: map[string]float and []string. Proto types look like this: proto(protoname) Before parsing types, protocol buffer types must be available in the global protocol buffer registry, either by importing at compile time or registering them separately from a descriptor file at run time. ParseType returns an error if a protocol buffer type is missing.

Example

Demonstrate parsing indigo types represented as strings

package main

import (
	"fmt"

	"github.com/ezachrisen/indigo"
)

func main() {

	// Parse a string to obtain the Indigo type.
	raw, err := indigo.ParseType("map[int]float")
	if err != nil {
		fmt.Println(err)
	}

	// Check that we actually got a Map type
	t, ok := raw.(indigo.Map)
	if !ok {
		fmt.Println("Incorrect type!")
	}

	fmt.Println(t.KeyType, t.ValueType)
}
Output:

int float

type ValueSource added in v0.6.2

type ValueSource int

ValueSource indicates the source of a value within a diagnostic report

const (
	// Input means that the value in the diagnostic output came from the
	// input provided to rule evaluation from the user.
	// Some rule evaluators may not accurately distinguish between evaluated and input.
	Input ValueSource = iota

	// Evaluated means that the value in the diagnostic output was
	// calculated by the rule evaluator.
	// Some rule evaluators may not accurately distinguish between evaluated and input.
	Evaluated
)

func (ValueSource) String added in v0.6.2

func (i ValueSource) String() string

Directories

Path Synopsis
Package cel provides an implementation of the Indigo evaluator and compiler interfaces backed by Google's cel-go rules engine.
Package cel provides an implementation of the Indigo evaluator and compiler interfaces backed by Google's cel-go rules engine.
examples

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL