136 lines
3.2 KiB
Go
136 lines
3.2 KiB
Go
package parser
|
|
|
|
import (
|
|
"reflect"
|
|
"strings"
|
|
)
|
|
|
|
// evaluateAllConditions checks all conditional logic
|
|
func (p *Parser) evaluateAllConditions(fieldTag *FieldTag, _ reflect.Value) bool {
|
|
if fieldTag.Condition != nil && !p.evaluateCondition(fieldTag.Condition) {
|
|
return false
|
|
}
|
|
|
|
if fieldTag.IfVariableSet != "" && !p.isVariableSet(fieldTag.IfVariableSet) {
|
|
return false
|
|
}
|
|
|
|
if fieldTag.IfVariableNotSet != "" && p.isVariableSet(fieldTag.IfVariableNotSet) {
|
|
return false
|
|
}
|
|
|
|
if fieldTag.IfFlag != "" && !p.flags[fieldTag.IfFlag] {
|
|
return false
|
|
}
|
|
|
|
if fieldTag.IfFlagNotSet != "" && p.flags[fieldTag.IfFlagNotSet] {
|
|
return false
|
|
}
|
|
|
|
if fieldTag.IfEquals != "" {
|
|
parts := strings.Split(fieldTag.IfEquals, "=")
|
|
if len(parts) == 2 && !p.evaluateEqualsCondition(parts[0], parts[1]) {
|
|
return false
|
|
}
|
|
}
|
|
|
|
if fieldTag.IfNotEquals != "" {
|
|
parts := strings.Split(fieldTag.IfNotEquals, "=")
|
|
if len(parts) == 2 && p.evaluateEqualsCondition(parts[0], parts[1]) {
|
|
return false
|
|
}
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
// evaluateCondition evaluates conditions for conditional fields
|
|
func (p *Parser) evaluateCondition(condition *FieldCondition) bool {
|
|
if condition.Type == "simple" {
|
|
return p.isVariableSet(condition.Variable)
|
|
}
|
|
|
|
cachedValue, exists := p.fieldCache[condition.Variable]
|
|
if !exists {
|
|
if p.currentStruct.IsValid() {
|
|
if structField := p.currentStruct.FieldByName(condition.Variable); structField.IsValid() {
|
|
cachedValue = structField.Interface()
|
|
} else {
|
|
return false
|
|
}
|
|
} else {
|
|
return false
|
|
}
|
|
}
|
|
|
|
compareValue, err := p.convertValue(condition.Value, cachedValue)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
return p.compareValues(cachedValue, compareValue, condition.Operator)
|
|
}
|
|
|
|
// isVariableSet checks if a variable exists and has a truthy value
|
|
func (p *Parser) isVariableSet(variable string) bool {
|
|
if cachedValue, exists := p.fieldCache[variable]; exists {
|
|
return p.isTruthy(cachedValue)
|
|
}
|
|
|
|
if p.currentStruct.IsValid() {
|
|
if field := p.currentStruct.FieldByName(variable); field.IsValid() {
|
|
return p.isTruthy(field.Interface())
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
// evaluateEqualsCondition checks field equality
|
|
func (p *Parser) evaluateEqualsCondition(variable, value string) bool {
|
|
cachedValue, exists := p.fieldCache[variable]
|
|
if !exists && p.currentStruct.IsValid() {
|
|
if field := p.currentStruct.FieldByName(variable); field.IsValid() {
|
|
cachedValue = field.Interface()
|
|
exists = true
|
|
}
|
|
}
|
|
|
|
if !exists {
|
|
return false
|
|
}
|
|
|
|
compareValue, err := p.convertValue(value, cachedValue)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
return p.compareValues(cachedValue, compareValue, "==")
|
|
}
|
|
|
|
// evaluateType2Criteria evaluates type2 criteria for alternative types
|
|
func (p *Parser) evaluateType2Criteria(criteria string) bool {
|
|
operators := []string{"!=", "==", ">=", "<=", ">", "<"}
|
|
|
|
for _, op := range operators {
|
|
if idx := strings.Index(criteria, op); idx > 0 {
|
|
fieldName := strings.TrimSpace(criteria[:idx])
|
|
valueStr := strings.TrimSpace(criteria[idx+len(op):])
|
|
|
|
cachedValue, exists := p.fieldCache[fieldName]
|
|
if !exists {
|
|
return false
|
|
}
|
|
|
|
compareValue, err := p.convertValue(valueStr, cachedValue)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
return p.compareValues(cachedValue, compareValue, op)
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|