Skip to content

Commit

Permalink
handling dynamic types for short-circuited parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
thepurunjaybhal committed Oct 18, 2024
1 parent dc52989 commit f863ac0
Showing 1 changed file with 28 additions and 4 deletions.
32 changes: 28 additions & 4 deletions src/RulesEngine/ExpressionBuilders/RuleExpressionParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,19 @@
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Linq.Dynamic.Core.Exceptions;
using System.Linq.Dynamic.Core.Parser;
using System.Linq.Expressions;
using System.Reflection;
using System.Text.RegularExpressions;

namespace RulesEngine.ExpressionBuilders
{
public class RuleExpressionParser
{
private readonly ReSettings _reSettings;
private readonly IDictionary<string, MethodInfo> _methodInfo;
private readonly IDictionary<string, MethodInfo> _methodInfo;
private readonly Regex propertyErrorPattern = new Regex(@"No property or field '(.*?)' exists in type '(.*?)'",RegexOptions.Compiled | RegexOptions.IgnoreCase);

public RuleExpressionParser(ReSettings reSettings = null)
{
Expand All @@ -36,11 +39,32 @@ public Expression Parse(string expression, ParameterExpression[] parameters, Typ
var config = new ParsingConfig {
CustomTypeProvider = new CustomTypeProvider(_reSettings.CustomTypes),
IsCaseSensitive = _reSettings.IsExpressionCaseSensitive
};
return new ExpressionParser(parameters, expression, new object[] { }, config).Parse(returnType);

};

// Instead of immediately returning default values, allow for expression parsing to handle dynamic evaluation.
try
{
return new ExpressionParser(parameters, expression, Array.Empty<object>(), config).Parse(returnType);
}
catch (ParseException ex) when (propertyErrorPattern.IsMatch(ex.Message))
{
return Expression.Constant(GetDefaultValueForType(returnType));
}
catch (Exception ex)
{
throw new Exception($"Expression parsing error: {ex.Message}", ex);
}
}

private object GetDefaultValueForType(Type type)
{
if (type == typeof(bool))
return false;
if (type == typeof(int) || type == typeof(float) || type == typeof(double))
return 0;
return null;
}

public Func<object[], T> Compile<T>(string expression, RuleParameter[] ruleParams)
{
var rtype = typeof(T);
Expand Down

0 comments on commit f863ac0

Please sign in to comment.