evaluator

package module
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Jul 2, 2025 License: MIT Imports: 5 Imported by: 0

README

Evaluator

The evaluator package implements a small expression language for querying Go structs. Expressions are represented as Go structs that can be combined using logical operators. Comparison expressions support both numeric and string values.

Features

  • Equality and inequality checks (Is, IsNot)
  • Numeric and lexical comparisons (GT, GTE, LT, LTE)
  • Membership checks with Contains
  • Logical composition using And, Or and Not
  • JSON serialisation for easy storage or transmission of queries

Basic Usage

Create a query using the provided expression types and call Evaluate with your target struct:

q := evaluator.Query{
    Expression: &evaluator.AndExpression{Expressions: []evaluator.Query{
        {Expression: &evaluator.IsExpression{Field: "Name", Value: "bob"}},
        {Expression: &evaluator.GreaterThanExpression{Field: "Age", Value: 30}},
    }},
}

matched := q.Evaluate(&User{Name: "bob", Age: 35})

JSON Queries

Queries can be marshalled to and from JSON. This is handy for configuration files or network APIs.

js := `{
  "Expression": {
    "Type": "Contains",
    "Expression": {
      "Field": "Tags",
      "Value": "go"
    }
  }
}`
var q evaluator.Query
if err := json.Unmarshal([]byte(js), &q); err != nil {
    log.Fatal(err)
}

Expression Guide

Each query expression implements the Expression interface. The table below lists the available types and their purpose:

Type Purpose
Is / IsNot Check equality or inequality of a field
GT / GTE Numeric or lexical "greater than" comparisons
LT / LTE Numeric or lexical "less than" comparisons
Contains Test that a slice field contains a value
And / Or / Not Compose other expressions logically

Example usage:

evaluator.Query{Expression: &evaluator.NotExpression{Expression: evaluator.Query{
    Expression: &evaluator.IsExpression{Field: "Deleted", Value: true},
}}}

Command-line Tools

The project includes small utilities for working with common data formats.

  • csvfilter – filters CSV rows. Usage: csvfilter -e '<expression>' [file ...] When no files are specified, input is read from standard input.
  • jsonlfilter – filters newline-delimited JSON records. It accepts the same arguments as csvfilter and writes matching JSON objects to standard output.
  • jsontest – evaluates a single JSON document. It exits with status 0 if the expression matches and 1 otherwise. Multiple files can be supplied and all must satisfy the expression. With no files it reads from standard input.
  • yamltest – like jsontest but for YAML documents.

Expressions use the simple syntax implemented by the parser in parser/simple. For example:

jsonlfilter -e 'GT(age,30) and Is(country,"US")' users.jsonl

Running Tests

Run go test ./... to execute the unit tests.

License

This project is licensed under the MIT License.

Documentation

Overview

Package evaluator provides a simple expression language for querying Go structs. Expressions are represented as Go structs which can be evaluated against arbitrary values or composed together using logical operators. The package also supports marshaling and unmarshaling expressions to and from JSON for storage or transmission.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AndExpression

type AndExpression struct {
	Expressions []Query `json:"Expressions"`
}

AndExpression evaluates to true only if all child Expressions do as well.

func (AndExpression) Evaluate

func (e AndExpression) Evaluate(i interface{}) bool

type ContainsExpression

type ContainsExpression struct {
	Field string
	Value interface{}
}

ContainsExpression checks whether a slice field contains the given Value.

func (ContainsExpression) Evaluate

func (e ContainsExpression) Evaluate(i interface{}) bool

type Expression

type Expression interface {
	// Evaluate returns true if the expression matches the supplied value.
	Evaluate(i interface{}) bool
}

Expression represents a single boolean expression that can be evaluated against a struct value.

type GreaterThanExpression

type GreaterThanExpression struct {
	Field string
	Value interface{}
}

GreaterThanExpression compares Field to Value and succeeds when the field is greater than the provided value.

func (GreaterThanExpression) Evaluate

func (e GreaterThanExpression) Evaluate(i interface{}) bool

type GreaterThanOrEqualExpression

type GreaterThanOrEqualExpression struct {
	Field string
	Value interface{}
}

GreaterThanOrEqualExpression succeeds when Field is greater than or equal to Value.

func (GreaterThanOrEqualExpression) Evaluate

func (e GreaterThanOrEqualExpression) Evaluate(i interface{}) bool

type IsExpression

type IsExpression struct {
	Field string
	Value interface{}
}

IsExpression succeeds when the specified Field equals Value.

func (IsExpression) Evaluate

func (e IsExpression) Evaluate(i interface{}) bool

type IsNotExpression

type IsNotExpression struct {
	Field string
	Value interface{}
}

IsNotExpression succeeds when the specified Field does not equal Value.

func (IsNotExpression) Evaluate

func (e IsNotExpression) Evaluate(i interface{}) bool

type LessThanExpression

type LessThanExpression struct {
	Field string
	Value interface{}
}

LessThanExpression succeeds when Field is strictly less than Value.

func (LessThanExpression) Evaluate

func (e LessThanExpression) Evaluate(i interface{}) bool

type LessThanOrEqualExpression

type LessThanOrEqualExpression struct {
	Field string
	Value interface{}
}

LessThanOrEqualExpression succeeds when Field is less than or equal to Value.

func (LessThanOrEqualExpression) Evaluate

func (e LessThanOrEqualExpression) Evaluate(i interface{}) bool

type NotExpression

type NotExpression struct {
	Expression Query `json:"Expression"`
}

NotExpression inverts the result of a single child Expression.

func (NotExpression) Evaluate

func (e NotExpression) Evaluate(i interface{}) bool

type OrExpression

type OrExpression struct {
	Expressions []Query `json:"Expressions"`
}

OrExpression evaluates to true if any of the child Expressions do.

func (OrExpression) Evaluate

func (e OrExpression) Evaluate(i interface{}) bool

type Query

type Query QueryRaw

Query wraps QueryRaw and provides evaluation and JSON unmarshalling helpers.

Example (UnmarshalJSON)

Example showing how to unmarshal a query from JSON.

js := `{
        "Expression": {
            "Type": "Contains",
            "Expression": {
                "Field": "Tags",
                "Value": "go"
            }
        }
    }`
var q evaluator.Query
json.Unmarshal([]byte(js), &q)
type Post struct{ Tags []string }
fmt.Println(q.Evaluate(&Post{Tags: []string{"go", "news"}}))
Output:

true

func (*Query) Evaluate

func (q *Query) Evaluate(i interface{}) bool
Example

Example demonstrating manual construction of a query and evaluation.

type User struct {
	Name string
	Age  int
}
q := evaluator.Query{
	Expression: &evaluator.AndExpression{Expressions: []evaluator.Query{
		{Expression: &evaluator.IsExpression{Field: "Name", Value: "bob"}},
		{Expression: &evaluator.GreaterThanExpression{Field: "Age", Value: 30}},
	}},
}
fmt.Println(q.Evaluate(&User{Name: "bob", Age: 35}))
Output:

true

func (Query) MarshalJSON

func (q Query) MarshalJSON() ([]byte, error)

func (*Query) UnmarshalJSON

func (q *Query) UnmarshalJSON(data []byte) error

type QueryRaw

type QueryRaw struct {
	Expression        Expression      `json:"-"`
	ExpressionRawJson json.RawMessage `json:"Expression"`
}

QueryRaw is the JSON representation of a query. ExpressionRawJson stores the raw JSON for the underlying expression and is resolved during unmarshalling.

Directories

Path Synopsis
cmd
csvfilter command
jsonlfilter command
jsontest command
yamltest command
parser

Jump to

Keyboard shortcuts

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