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

Release 2.0.0 #22

Merged
merged 2 commits into from
Aug 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions internal/operator/abstract_operator.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package operator

import "github.com/sidhant92/bool-parser-go/pkg/constant"
import (
"github.com/sidhant92/bool-parser-go/pkg/constant"
"github.com/sidhant92/bool-parser-go/pkg/domain"
)

type AbstractOperator interface {
Evaluate(containerDataType constant.ContainerDataType, dataType constant.DataType, validated bool, left interface{}, right ...interface{}) (bool, error)
Evaluate(containerDataType constant.ContainerDataType, leftOperand interface{}, leftOperandDataType constant.DataType, rightOperands []domain.EvaluatedNode) (bool, error)

GetSymbol() string

Expand Down
16 changes: 10 additions & 6 deletions internal/operator/contains_all_operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,26 @@ package operator

import (
"github.com/sidhant92/bool-parser-go/pkg/constant"
"github.com/sidhant92/bool-parser-go/pkg/domain"
"reflect"
)

type ContainsAllOperator struct {
}

func (e *ContainsAllOperator) Evaluate(containerDataType constant.ContainerDataType, dataType constant.DataType, validated bool, left interface{}, right ...interface{}) (bool, error) {
var leftArray []interface{}
rv := reflect.ValueOf(left)
func (e *ContainsAllOperator) Evaluate(containerDataType constant.ContainerDataType, leftOperand interface{}, leftOperandDataType constant.DataType, rightOperands []domain.EvaluatedNode) (bool, error) {
var leftArray []domain.EvaluatedNode
rv := reflect.ValueOf(leftOperand)
if rv.Kind() == reflect.Slice {
for i := 0; i < rv.Len(); i++ {
leftArray = append(leftArray, rv.Index(i).Interface())
leftArray = append(leftArray, domain.EvaluatedNode{
Value: rv.Index(i).Interface(),
DataType: leftOperandDataType,
})
}
}
for _, value := range right {
res, err := GetOperator(constant.IN).Evaluate(constant.PRIMITIVE, dataType, validated, value, leftArray...)
for _, rightOperand := range rightOperands {
res, err := GetOperator(constant.IN).Evaluate(constant.PRIMITIVE, rightOperand.Value, rightOperand.DataType, leftArray)
if err != nil {
return false, err
}
Expand Down
16 changes: 10 additions & 6 deletions internal/operator/contains_any_operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,26 @@ package operator

import (
"github.com/sidhant92/bool-parser-go/pkg/constant"
"github.com/sidhant92/bool-parser-go/pkg/domain"
"reflect"
)

type ContainsAnyOperator struct {
}

func (e *ContainsAnyOperator) Evaluate(containerDataType constant.ContainerDataType, dataType constant.DataType, validated bool, left interface{}, right ...interface{}) (bool, error) {
var leftArray []interface{}
rv := reflect.ValueOf(left)
func (e *ContainsAnyOperator) Evaluate(containerDataType constant.ContainerDataType, leftOperand interface{}, leftOperandDataType constant.DataType, rightOperands []domain.EvaluatedNode) (bool, error) {
var leftArray []domain.EvaluatedNode
rv := reflect.ValueOf(leftOperand)
if rv.Kind() == reflect.Slice {
for i := 0; i < rv.Len(); i++ {
leftArray = append(leftArray, rv.Index(i).Interface())
leftArray = append(leftArray, domain.EvaluatedNode{
Value: rv.Index(i).Interface(),
DataType: leftOperandDataType,
})
}
}
for _, value := range right {
res, err := GetOperator(constant.IN).Evaluate(constant.PRIMITIVE, dataType, validated, value, leftArray...)
for _, rightOperand := range rightOperands {
res, err := GetOperator(constant.IN).Evaluate(constant.PRIMITIVE, rightOperand.Value, rightOperand.DataType, leftArray)
if err != nil {
return false, err
}
Expand Down
15 changes: 12 additions & 3 deletions internal/operator/equals_operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,29 @@ package operator
import (
"github.com/sidhant92/bool-parser-go/internal/datatype"
"github.com/sidhant92/bool-parser-go/pkg/constant"
"github.com/sidhant92/bool-parser-go/pkg/domain"
)

type EqualsOperator struct {
}

func (e *EqualsOperator) Evaluate(containerDataType constant.ContainerDataType, dataType constant.DataType, validated bool, left interface{}, right ...interface{}) (bool, error) {
dt := datatype.GetDataType(dataType)
res, err := dt.Compare(left, right[0], validated)
func (e *EqualsOperator) Evaluate(containerDataType constant.ContainerDataType, leftOperand interface{}, leftOperandDataType constant.DataType, rightOperands []domain.EvaluatedNode) (bool, error) {
comparableDataType := getComparableDataType(leftOperandDataType, rightOperands[0].DataType)
dt := datatype.GetDataType(comparableDataType)
res, err := dt.Compare(leftOperand, rightOperands[0].Value, true)
if err != nil {
return false, err
}
return res == 0, nil
}

func getComparableDataType(leftOperandDataType constant.DataType, rightOperandDataType constant.DataType) constant.DataType {
if constant.DataTypeAttributes[leftOperandDataType].Priority > constant.DataTypeAttributes[rightOperandDataType].Priority {
return leftOperandDataType
}
return rightOperandDataType
}

func (e *EqualsOperator) GetSymbol() string {
return "="
}
Expand Down
12 changes: 9 additions & 3 deletions internal/operator/greater_than_equal_operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,20 @@ package operator
import (
"github.com/sidhant92/bool-parser-go/internal/datatype"
"github.com/sidhant92/bool-parser-go/pkg/constant"
"github.com/sidhant92/bool-parser-go/pkg/domain"
)

type GreaterThanEqualOperator struct {
}

func (e *GreaterThanEqualOperator) Evaluate(containerDataType constant.ContainerDataType, dataType constant.DataType, validated bool, left interface{}, right ...interface{}) (bool, error) {
dt := datatype.GetDataType(dataType)
res, err := dt.Compare(left, right[0], validated)
func (e *GreaterThanEqualOperator) Evaluate(containerDataType constant.ContainerDataType, leftOperand interface{}, leftOperandDataType constant.DataType, rightOperands []domain.EvaluatedNode) (bool, error) {
err := Validate(leftOperand, leftOperandDataType, rightOperands[0].Value, rightOperands[0].DataType)
if err != nil {
return false, err
}
comparableDataType := GetComparableDataType(leftOperandDataType, rightOperands[0].DataType)
dt := datatype.GetDataType(comparableDataType)
res, err := dt.Compare(leftOperand, rightOperands[0].Value, true)
if err != nil {
return false, err
}
Expand Down
12 changes: 9 additions & 3 deletions internal/operator/greater_than_operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,20 @@ package operator
import (
"github.com/sidhant92/bool-parser-go/internal/datatype"
"github.com/sidhant92/bool-parser-go/pkg/constant"
"github.com/sidhant92/bool-parser-go/pkg/domain"
)

type GreaterThanOperator struct {
}

func (e *GreaterThanOperator) Evaluate(containerDataType constant.ContainerDataType, dataType constant.DataType, validated bool, left interface{}, right ...interface{}) (bool, error) {
dt := datatype.GetDataType(dataType)
res, err := dt.Compare(left, right[0], validated)
func (e *GreaterThanOperator) Evaluate(containerDataType constant.ContainerDataType, leftOperand interface{}, leftOperandDataType constant.DataType, rightOperands []domain.EvaluatedNode) (bool, error) {
err := Validate(leftOperand, leftOperandDataType, rightOperands[0].Value, rightOperands[0].DataType)
if err != nil {
return false, err
}
comparableDataType := GetComparableDataType(leftOperandDataType, rightOperands[0].DataType)
dt := datatype.GetDataType(comparableDataType)
res, err := dt.Compare(leftOperand, rightOperands[0].Value, true)
if err != nil {
return false, err
}
Expand Down
7 changes: 4 additions & 3 deletions internal/operator/in_operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ package operator

import (
"github.com/sidhant92/bool-parser-go/pkg/constant"
"github.com/sidhant92/bool-parser-go/pkg/domain"
)

type InOperator struct {
}

func (e *InOperator) Evaluate(containerDataType constant.ContainerDataType, dataType constant.DataType, validated bool, left interface{}, right ...interface{}) (bool, error) {
for _, value := range right {
res, err := GetOperator(constant.EQUALS).Evaluate(containerDataType, dataType, validated, left, value)
func (e *InOperator) Evaluate(containerDataType constant.ContainerDataType, leftOperand interface{}, leftOperandDataType constant.DataType, rightOperands []domain.EvaluatedNode) (bool, error) {
for _, value := range rightOperands {
res, err := GetOperator(constant.EQUALS).Evaluate(containerDataType, leftOperand, leftOperandDataType, []domain.EvaluatedNode{value})
if err != nil {
return false, err
}
Expand Down
12 changes: 9 additions & 3 deletions internal/operator/less_than_equal_operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,20 @@ package operator
import (
"github.com/sidhant92/bool-parser-go/internal/datatype"
"github.com/sidhant92/bool-parser-go/pkg/constant"
"github.com/sidhant92/bool-parser-go/pkg/domain"
)

type LessThanEqualOperator struct {
}

func (e *LessThanEqualOperator) Evaluate(containerDataType constant.ContainerDataType, dataType constant.DataType, validated bool, left interface{}, right ...interface{}) (bool, error) {
dt := datatype.GetDataType(dataType)
res, err := dt.Compare(left, right[0], validated)
func (e *LessThanEqualOperator) Evaluate(containerDataType constant.ContainerDataType, leftOperand interface{}, leftOperandDataType constant.DataType, rightOperands []domain.EvaluatedNode) (bool, error) {
err := Validate(leftOperand, leftOperandDataType, rightOperands[0].Value, rightOperands[0].DataType)
if err != nil {
return false, err
}
comparableDataType := GetComparableDataType(leftOperandDataType, rightOperands[0].DataType)
dt := datatype.GetDataType(comparableDataType)
res, err := dt.Compare(leftOperand, rightOperands[0].Value, true)
if err != nil {
return false, err
}
Expand Down
12 changes: 9 additions & 3 deletions internal/operator/less_than_operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,20 @@ package operator
import (
"github.com/sidhant92/bool-parser-go/internal/datatype"
"github.com/sidhant92/bool-parser-go/pkg/constant"
"github.com/sidhant92/bool-parser-go/pkg/domain"
)

type LessThanOperator struct {
}

func (e *LessThanOperator) Evaluate(containerDataType constant.ContainerDataType, dataType constant.DataType, validated bool, left interface{}, right ...interface{}) (bool, error) {
dt := datatype.GetDataType(dataType)
res, err := dt.Compare(left, right[0], validated)
func (e *LessThanOperator) Evaluate(containerDataType constant.ContainerDataType, leftOperand interface{}, leftOperandDataType constant.DataType, rightOperands []domain.EvaluatedNode) (bool, error) {
err := Validate(leftOperand, leftOperandDataType, rightOperands[0].Value, rightOperands[0].DataType)
if err != nil {
return false, err
}
comparableDataType := GetComparableDataType(leftOperandDataType, rightOperands[0].DataType)
dt := datatype.GetDataType(comparableDataType)
res, err := dt.Compare(leftOperand, rightOperands[0].Value, true)
if err != nil {
return false, err
}
Expand Down
5 changes: 3 additions & 2 deletions internal/operator/not_equals_operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ package operator

import (
"github.com/sidhant92/bool-parser-go/pkg/constant"
"github.com/sidhant92/bool-parser-go/pkg/domain"
)

type NotEqualsOperator struct {
}

func (e *NotEqualsOperator) Evaluate(containerDataType constant.ContainerDataType, dataType constant.DataType, validated bool, left interface{}, right ...interface{}) (bool, error) {
func (e *NotEqualsOperator) Evaluate(containerDataType constant.ContainerDataType, leftOperand interface{}, leftOperandDataType constant.DataType, rightOperands []domain.EvaluatedNode) (bool, error) {
eq := GetOperator(constant.EQUALS)
res, err := eq.Evaluate(containerDataType, dataType, validated, left, right[0])
res, err := eq.Evaluate(containerDataType, leftOperand, leftOperandDataType, rightOperands)
if err != nil {
return false, err
}
Expand Down
41 changes: 41 additions & 0 deletions internal/operator/numeric_operator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package operator

import (
"github.com/sidhant92/bool-parser-go/internal/datatype"
"github.com/sidhant92/bool-parser-go/pkg/constant"
errors2 "github.com/sidhant92/bool-parser-go/pkg/error"
"log"
)

func GetComparableDataType(leftOperandDataType constant.DataType, rightOperandDataType constant.DataType) constant.DataType {
if (constant.DataTypeAttributes[leftOperandDataType].Numeric && !constant.DataTypeAttributes[rightOperandDataType].Numeric) || (!constant.DataTypeAttributes[leftOperandDataType].Numeric && constant.DataTypeAttributes[rightOperandDataType].Numeric) {
if constant.DataTypeAttributes[leftOperandDataType].Numeric {
return leftOperandDataType
}
return rightOperandDataType
}
if constant.DataTypeAttributes[leftOperandDataType].Priority > constant.DataTypeAttributes[rightOperandDataType].Priority {
return leftOperandDataType
}
return rightOperandDataType
}

func Validate(leftOperand interface{}, leftOperandDataType constant.DataType, rightOperand interface{}, rightOperandDataType constant.DataType) error {
if constant.DataTypeAttributes[leftOperandDataType].Numeric && constant.DataTypeAttributes[rightOperandDataType].Numeric {
return nil
}
if !constant.DataTypeAttributes[leftOperandDataType].Numeric && !constant.DataTypeAttributes[rightOperandDataType].Numeric {
return nil
}
rightDataType := datatype.GetDataType(rightOperandDataType)
if !constant.DataTypeAttributes[leftOperandDataType].Numeric && !rightDataType.IsValid(leftOperand) {
log.Printf("Incompatible data types %s and %s", leftOperandDataType, rightOperandDataType)
return errors2.INCOMPATIBLE_DATA_TYPE
}
leftDataType := datatype.GetDataType(leftOperandDataType)
if !constant.DataTypeAttributes[rightOperandDataType].Numeric && !leftDataType.IsValid(rightOperand) {
log.Printf("Incompatible data types %s and %s", leftOperandDataType, rightOperandDataType)
return errors2.INCOMPATIBLE_DATA_TYPE
}
return nil
}
13 changes: 7 additions & 6 deletions internal/service/operator_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"github.com/sidhant92/bool-parser-go/internal/containerdatatype"
op "github.com/sidhant92/bool-parser-go/internal/operator"
"github.com/sidhant92/bool-parser-go/pkg/constant"
"github.com/sidhant92/bool-parser-go/pkg/domain"
errors2 "github.com/sidhant92/bool-parser-go/pkg/error"
"log"
"slices"
Expand All @@ -21,21 +22,21 @@ func (o *OperatorService) GetOperatorFromSymbol(symbol string) constant.Operator
panic("Unknown Operator " + symbol)
}

func (o *OperatorService) Evaluate(operator constant.Operator, containerDataType constant.ContainerDataType, dataType constant.DataType, leftOperand interface{}, rightOperand ...interface{}) (bool, error) {
func (o *OperatorService) Evaluate(operator constant.Operator, containerDataType constant.ContainerDataType, leftOperand interface{}, leftOperandDataType constant.DataType, rightOperands []domain.EvaluatedNode) (bool, error) {
var abstractOperator = op.GetOperator(operator)
if !slices.Contains(abstractOperator.GetAllowedContainerTypes(), containerDataType) {
log.Printf("Invalid container type %s for the the operator %s", containerDataType, operator)
return false, errors2.INVALID_CONTAINER_DATA_TYPE
}
if !slices.Contains(abstractOperator.GetAllowedDataTypes(), dataType) {
log.Printf("Invalid data type %s for the the operator %s", dataType, operator)
if !slices.Contains(abstractOperator.GetAllowedDataTypes(), leftOperandDataType) {
log.Printf("Invalid data type %s for the the operator %s for the operand %v", leftOperandDataType, operator, leftOperand)
return false, errors2.INVALID_DATA_TYPE
}
if !containerdatatype.GetContainerDataType(containerDataType).IsValid(dataType, leftOperand) {
log.Printf("validation failed for the operator %s for the the operand %v", operator, leftOperand)
if !containerdatatype.GetContainerDataType(containerDataType).IsValid(leftOperandDataType, leftOperand) {
log.Printf("validation failed for the operator %s for the the operand %v for data type %s", operator, leftOperand, leftOperandDataType)
return false, errors2.INVALID_DATA_TYPE
}
res, err := abstractOperator.Evaluate(containerDataType, dataType, true, leftOperand, rightOperand...)
res, err := abstractOperator.Evaluate(containerDataType, leftOperand, leftOperandDataType, rightOperands)
if err != nil {
return false, err
}
Expand Down
Loading
Loading