func And(left, right Expr) AndExpr {
	return AndExpr{
		Left:  left,
		Right: right,
	}
}
And returns && expression
package builder
import (
	"fmt"
	"strings"
)
type Expr interface {
	String() string
}
type IdentifierExpr string
func (i IdentifierExpr) String() string {
	return string(i)
}
func Identifier(v string) IdentifierExpr {
	return IdentifierExpr(v)
}
func String(v string) StringExpr {
	return StringExpr(v)
}
type StringExpr string
func (s StringExpr) String() string {
	return fmt.Sprintf("%q", string(s))
}
type StringsExpr []string
func (s StringsExpr) String() string {
	var out []string
	for _, val := range s {
		out = append(out, fmt.Sprintf("%q", val))
	}
	return strings.Join(out, ",")
}
func Equals(left, right Expr) EqualsExpr {
	return EqualsExpr{Left: left, Right: right}
}
type EqualsExpr struct {
	Left Expr
	Right Expr
}
func (i EqualsExpr) String() string {
	return fmt.Sprintf("equals(%v, %v)", i.Left, i.Right)
}
func Not(expr Expr) NotExpr {
	return NotExpr{Expr: expr}
}
type NotExpr struct {
	Expr Expr
}
func (n NotExpr) String() string {
	return fmt.Sprintf("!%v", n.Expr)
}
func Contains(a, b Expr) ContainsExpr {
	return ContainsExpr{Left: a, Right: b}
}
type ContainsExpr struct {
	Left Expr
	Right Expr
}
func (i ContainsExpr) String() string {
	return fmt.Sprintf("contains(%v, %v)", i.Left, i.Right)
}