private FluidValue Evaluate(FluidValue leftValue, FluidValue rightValue) { // If the values are of the same type, use the default comparison. if (leftValue.Type == rightValue.Type) { if (FailIfEqual) { return(leftValue.Equals(rightValue) ? BooleanValue.False : BooleanValue.True); } else { return(leftValue.Equals(rightValue) ? BooleanValue.True : BooleanValue.False); } } // If either value is boolean, perform a boolean comparison. if (leftValue is BooleanValue || rightValue is BooleanValue) { // If comparing with an empty string, any value will satisfy the predicate. if (leftValue.Type == FluidValues.String && leftValue.ToStringValue() == string.Empty) { return(FailIfEqual ? BooleanValue.True : BooleanValue.False); } else if (rightValue.Type == FluidValues.String && rightValue.ToStringValue() == string.Empty) { return(FailIfEqual ? BooleanValue.True : BooleanValue.False); } var leftBoolean = leftValue.ToBooleanValue(); var rightBoolean = rightValue.ToBooleanValue(); if (FailIfEqual) { return(leftBoolean == rightBoolean ? BooleanValue.False : BooleanValue.True); } else { return(leftBoolean == rightBoolean ? BooleanValue.True : BooleanValue.False); } } // If either value is an Enum, perform an Enum comparison. if (leftValue is LavaEnumValue lv) { return(EnumValueIsEqualToOtherTypeValue(lv, rightValue)); } if (rightValue is LavaEnumValue rv) { return(EnumValueIsEqualToOtherTypeValue(rv, leftValue)); } // If either value is numeric, and both values can be converted to a number, perform a numeric comparison. if (leftValue is NumberValue || rightValue is NumberValue) { decimal leftDecimal; decimal rightDecimal; if (decimal.TryParse(leftValue.ToStringValue(), out leftDecimal) && decimal.TryParse(rightValue.ToStringValue(), out rightDecimal)) { if (FailIfEqual) { return(leftDecimal == rightDecimal ? BooleanValue.False : BooleanValue.True); } else { return(leftDecimal == rightDecimal ? BooleanValue.True : BooleanValue.False); } } } // If either value is a Date, perform a Date comparison. if (leftValue.Type == FluidValues.DateTime || rightValue.Type == FluidValues.DateTime) { var leftDateTime = leftValue.AsDateTimeOrDefault(); var rightDateTime = rightValue.AsDateTimeOrDefault(); if (FailIfEqual) { return(leftDateTime == rightDateTime ? BooleanValue.False : BooleanValue.True); } else { return(leftDateTime == rightDateTime ? BooleanValue.True : BooleanValue.False); } } // Use the default comparison. if (FailIfEqual) { return(leftValue.Equals(rightValue) ? BooleanValue.False : BooleanValue.True); } else { return(leftValue.Equals(rightValue) ? BooleanValue.True : BooleanValue.False); } }
private FluidValue Evaluate(FluidValue leftValue, FluidValue rightValue) { if (leftValue.IsNil() || rightValue.IsNil()) { if (FailIfEqual) { return(BooleanValue.False); } return(leftValue.IsNil() && rightValue.IsNil() ? BooleanValue.True : BooleanValue.False); } // If either value is numeric, perform a numeric comparison. if (leftValue is NumberValue || rightValue is NumberValue) { var leftDecimal = leftValue.ToNumberValue(); var rightDecimal = rightValue.ToNumberValue(); if (FailIfEqual) { return(leftDecimal > rightDecimal ? BooleanValue.True : BooleanValue.False); } return(leftDecimal >= rightDecimal ? BooleanValue.True : BooleanValue.False); } // If either value is a Date, perform a Date comparison. if (leftValue.Type == FluidValues.DateTime || rightValue.Type == FluidValues.DateTime) { var leftDateTime = leftValue.AsDateTimeOrDefault(); var rightDateTime = rightValue.AsDateTimeOrDefault(); if (FailIfEqual) { return(leftDateTime > rightDateTime ? BooleanValue.True : BooleanValue.False); } return(leftDateTime >= rightDateTime ? BooleanValue.True : BooleanValue.False); } // If either value supports IComparable, attempt to use a built-in comparison. var leftObject = leftValue.ToRealObjectValue(); var rightObject = rightValue.ToRealObjectValue(); if (leftObject is IComparable leftComparable) { if (FailIfEqual) { return(leftComparable.CompareTo(rightObject) > 0 ? BooleanValue.True : BooleanValue.False); } else { return(leftComparable.CompareTo(rightObject) >= 0 ? BooleanValue.True : BooleanValue.False); } } if (rightObject is IComparable rightComparable) { if (FailIfEqual) { return(rightComparable.CompareTo(leftObject) > 0 ? BooleanValue.True : BooleanValue.False); } else { return(rightComparable.CompareTo(leftObject) >= 0 ? BooleanValue.True : BooleanValue.False); } } // The values cannot be compared in a meaningful way. return(NilValue.Instance); }