Skip to content

Commit 1734178

Browse files
emyllerclaude
andcommitted
Merge Evaluator into ContextEvaluator
Co-authored-by: Claude <noreply@anthropic.com>
1 parent 31caa66 commit 1734178

File tree

2 files changed

+77
-186
lines changed

2 files changed

+77
-186
lines changed

Flagsmith.Engine/Segment/Evaluator.cs

Lines changed: 77 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
using FlagsmithEngine.Segment.Models;
21
using FlagsmithEngine.Utils;
32
using Newtonsoft.Json;
43
using Newtonsoft.Json.Linq;
54
using Semver;
65
using System;
76
using System.Collections.Generic;
87
using System.Linq;
8+
using System.Text.RegularExpressions;
99

1010
namespace FlagsmithEngine.Segment
1111
{
@@ -196,14 +196,7 @@ private static bool ContextMatchesCondition<_, __>(EvaluationContext<_, __> cont
196196
if (contextValue == null)
197197
return false;
198198

199-
var segmentConditionModel = new SegmentConditionModel
200-
{
201-
Operator = JsonConvert.SerializeObject(condition.Operator).Replace("\"", ""),
202-
Value = condition.Value.String,
203-
Property = condition.Property
204-
};
205-
206-
return Evaluator.MatchesContextValue(contextValue, segmentConditionModel);
199+
return MatchesContextValue(contextValue, condition);
207200
}
208201
}
209202

@@ -269,144 +262,152 @@ private static FlagResult<FeatureMetadataT> GetFlagResult<_, FeatureMetadataT>(E
269262

270263
return flagResult;
271264
}
272-
}
273265

274-
public static class Evaluator
275-
{
276-
public static bool MatchesContextValue(object contextValue, SegmentConditionModel condition)
266+
private static bool MatchesContextValue(object contextValue, Condition condition)
267+
{
268+
switch (condition.Operator)
269+
{
270+
case Operator.NotContains:
271+
return !contextValue.ToString().Contains(condition.Value.String);
272+
case Operator.Regex:
273+
return Regex.Match(contextValue.ToString(), condition.Value.String).Success;
274+
case Operator.Modulo:
275+
return EvaluateModulo(contextValue.ToString(), condition.Value.String);
276+
default:
277+
return MatchingFunctionName(contextValue, condition);
278+
}
279+
}
280+
281+
private static bool EvaluateModulo(string contextValue, string conditionValue)
277282
{
278-
var exceptionOperatorMethods = new Dictionary<string, string>()
283+
try
279284
{
280-
{ Constants.NotContains, "EvaluateNotContains" },
281-
{ Constants.Regex, "EvaluateRegex" },
282-
{ Constants.Modulo, "EvaluateModulo" },
283-
};
285+
string[] parts = conditionValue.Split('|');
286+
if (parts.Length != 2) { return false; }
287+
288+
double divisor = Convert.ToDouble(parts[0]);
289+
double remainder = Convert.ToDouble(parts[1]);
284290

285-
if (exceptionOperatorMethods.TryGetValue(condition.Operator, out var operatorMethod))
291+
return Convert.ToDouble(contextValue) % divisor == remainder;
292+
}
293+
catch (FormatException)
286294
{
287-
return (bool)typeof(SegmentConditionModel).GetMethod(operatorMethod).Invoke(condition, new object[] { contextValue.ToString() });
295+
return false;
288296
}
289-
290-
return MatchingFunctionName(contextValue, condition);
291297
}
292298

293-
static bool MatchingFunctionName(object traitValue, SegmentConditionModel condition)
299+
private static bool MatchingFunctionName(object contextValue, Condition condition)
294300
{
295-
switch (traitValue.GetType().FullName)
301+
switch (contextValue.GetType().FullName)
296302
{
297303
case "System.Int32":
298-
return intOperations((Int32)traitValue, condition);
304+
return IntOperations((Int32)contextValue, condition);
299305
case "System.Int64":
300-
return longOperations((Int64)traitValue, condition);
306+
return LongOperations((Int64)contextValue, condition);
301307
case "System.Double":
302-
return doubleOperations((double)traitValue, condition);
308+
return DoubleOperations((double)contextValue, condition);
303309
case "System.Boolean":
304-
return boolOperations((bool)traitValue, condition);
310+
return BoolOperations((bool)contextValue, condition);
305311
default:
306-
return stringOperations((string)traitValue, condition);
312+
return StringOperations((string)contextValue, condition);
307313
}
308314
}
309315

310-
static bool stringOperations(string traitValue, SegmentConditionModel condition)
316+
private static bool StringOperations(string contextValue, Condition condition)
311317
{
312-
var currentValue = condition.Value;
318+
var conditionValue = condition.Value.String;
313319

314-
if (currentValue.EndsWith(":semver"))
320+
if (conditionValue.EndsWith(":semver"))
315321
{
316-
return semVerOperations(traitValue, condition);
322+
return SemVerOperations(contextValue, condition);
317323
}
318324

319325
switch (condition.Operator)
320326
{
321-
case Constants.Equal: return traitValue == currentValue;
322-
case Constants.NotEqual: return traitValue != currentValue;
323-
case Constants.Contains: return traitValue.Contains(currentValue);
324-
case Constants.In: return condition.Value.Split(',').Contains(traitValue);
327+
case Operator.Equal: return contextValue == conditionValue;
328+
case Operator.NotEqual: return contextValue != conditionValue;
329+
case Operator.Contains: return contextValue.Contains(conditionValue);
325330
default: throw new ArgumentException("Invalid Operator");
326331
}
327332
}
328333

329-
static bool longOperations(long traitValue, SegmentConditionModel condition)
334+
private static bool LongOperations(long contextValue, Condition condition)
330335
{
331336
long conditionValue;
332337
try
333338
{
334-
conditionValue = Convert.ToInt64(condition.Value);
339+
conditionValue = Convert.ToInt64(condition.Value.String);
335340
}
336341
catch (FormatException)
337342
{
338343
return false;
339344
}
340345
switch (condition.Operator)
341346
{
342-
case Constants.Equal: return traitValue == conditionValue;
343-
case Constants.NotEqual: return traitValue != conditionValue;
344-
case Constants.GreaterThan: return traitValue > conditionValue;
345-
case Constants.GreaterThanInclusive: return traitValue >= conditionValue;
346-
case Constants.LessThan: return traitValue < conditionValue;
347-
case Constants.LessThanInclusive: return traitValue <= conditionValue;
348-
case Constants.In: return condition.Value.Split(',').Contains(traitValue.ToString());
347+
case Operator.Equal: return contextValue == conditionValue;
348+
case Operator.NotEqual: return contextValue != conditionValue;
349+
case Operator.GreaterThan: return contextValue > conditionValue;
350+
case Operator.GreaterThanInclusive: return contextValue >= conditionValue;
351+
case Operator.LessThan: return contextValue < conditionValue;
352+
case Operator.LessThanInclusive: return contextValue <= conditionValue;
349353
default: throw new ArgumentException("Invalid Operator");
350354
}
351355
}
352356

353-
static bool intOperations(long traitValue, SegmentConditionModel condition)
357+
private static bool IntOperations(long contextValue, Condition condition)
354358
{
355359
switch (condition.Operator)
356360
{
357-
case Constants.Equal: return traitValue == Convert.ToInt32(condition.Value);
358-
case Constants.NotEqual: return traitValue != Convert.ToInt32(condition.Value);
359-
case Constants.GreaterThan: return traitValue > Convert.ToInt32(condition.Value);
360-
case Constants.GreaterThanInclusive: return traitValue >= Convert.ToInt32(condition.Value);
361-
case Constants.LessThan: return traitValue < Convert.ToInt32(condition.Value);
362-
case Constants.LessThanInclusive: return traitValue <= Convert.ToInt32(condition.Value);
363-
case Constants.In: return condition.Value.Split(',').Contains(traitValue.ToString());
361+
case Operator.Equal: return contextValue == Convert.ToInt32(condition.Value.String);
362+
case Operator.NotEqual: return contextValue != Convert.ToInt32(condition.Value.String);
363+
case Operator.GreaterThan: return contextValue > Convert.ToInt32(condition.Value.String);
364+
case Operator.GreaterThanInclusive: return contextValue >= Convert.ToInt32(condition.Value.String);
365+
case Operator.LessThan: return contextValue < Convert.ToInt32(condition.Value.String);
366+
case Operator.LessThanInclusive: return contextValue <= Convert.ToInt32(condition.Value.String);
364367
default: throw new ArgumentException("Invalid Operator");
365368
}
366369
}
367370

368-
static bool doubleOperations(double traitValue, SegmentConditionModel condition)
371+
private static bool DoubleOperations(double contextValue, Condition condition)
369372
{
370373
switch (condition.Operator)
371374
{
372-
case Constants.Equal: return traitValue == Convert.ToDouble(condition.Value);
373-
case Constants.NotEqual: return traitValue != Convert.ToDouble(condition.Value);
374-
case Constants.GreaterThan: return traitValue > Convert.ToDouble(condition.Value);
375-
case Constants.GreaterThanInclusive: return traitValue >= Convert.ToDouble(condition.Value);
376-
case Constants.LessThan: return traitValue < Convert.ToDouble(condition.Value);
377-
case Constants.LessThanInclusive: return traitValue <= Convert.ToDouble(condition.Value);
378-
case Constants.In: return false;
375+
case Operator.Equal: return contextValue == Convert.ToDouble(condition.Value.String);
376+
case Operator.NotEqual: return contextValue != Convert.ToDouble(condition.Value.String);
377+
case Operator.GreaterThan: return contextValue > Convert.ToDouble(condition.Value.String);
378+
case Operator.GreaterThanInclusive: return contextValue >= Convert.ToDouble(condition.Value.String);
379+
case Operator.LessThan: return contextValue < Convert.ToDouble(condition.Value.String);
380+
case Operator.LessThanInclusive: return contextValue <= Convert.ToDouble(condition.Value.String);
379381
default: throw new ArgumentException("Invalid Operator");
380382
}
381383
}
382384

383-
static bool boolOperations(bool traitValue, SegmentConditionModel condition)
385+
private static bool BoolOperations(bool contextValue, Condition condition)
384386
{
385387
switch (condition.Operator)
386388
{
387-
case Constants.Equal: return traitValue == toBoolean(condition.Value);
388-
case Constants.NotEqual: return traitValue != toBoolean(condition.Value);
389-
case Constants.In: return false;
389+
case Operator.Equal: return contextValue == ToBoolean(condition.Value.String);
390+
case Operator.NotEqual: return contextValue != ToBoolean(condition.Value.String);
390391
default: throw new ArgumentException("Invalid Operator");
391392
}
392393
}
393394

394-
static bool semVerOperations(string traitValue, SegmentConditionModel condition)
395+
private static bool SemVerOperations(string contextValue, Condition condition)
395396
{
396397
try
397398
{
398-
string conditionValue = condition.Value.Substring(0, condition.Value.Length - 7);
399+
string conditionValue = condition.Value.String.Substring(0, condition.Value.String.Length - 7);
399400
SemVersion conditionValueAsVersion = SemVersion.Parse(conditionValue, SemVersionStyles.Strict);
400-
SemVersion traitValueAsVersion = SemVersion.Parse(traitValue, SemVersionStyles.Strict);
401+
SemVersion contextValueAsVersion = SemVersion.Parse(contextValue, SemVersionStyles.Strict);
401402

402403
switch (condition.Operator)
403404
{
404-
case Constants.Equal: return traitValueAsVersion == conditionValueAsVersion;
405-
case Constants.NotEqual: return traitValueAsVersion != conditionValueAsVersion;
406-
case Constants.GreaterThan: return traitValueAsVersion > conditionValueAsVersion;
407-
case Constants.GreaterThanInclusive: return traitValueAsVersion >= conditionValueAsVersion;
408-
case Constants.LessThan: return traitValueAsVersion < conditionValueAsVersion;
409-
case Constants.LessThanInclusive: return traitValueAsVersion <= conditionValueAsVersion;
405+
case Operator.Equal: return contextValueAsVersion == conditionValueAsVersion;
406+
case Operator.NotEqual: return contextValueAsVersion != conditionValueAsVersion;
407+
case Operator.GreaterThan: return contextValueAsVersion.ComparePrecedenceTo(conditionValueAsVersion) > 0;
408+
case Operator.GreaterThanInclusive: return contextValueAsVersion.ComparePrecedenceTo(conditionValueAsVersion) >= 0;
409+
case Operator.LessThan: return contextValueAsVersion.ComparePrecedenceTo(conditionValueAsVersion) < 0;
410+
case Operator.LessThanInclusive: return contextValueAsVersion.ComparePrecedenceTo(conditionValueAsVersion) <= 0;
410411
default: throw new ArgumentException("Invalid Operator");
411412
}
412413
}
@@ -416,6 +417,6 @@ static bool semVerOperations(string traitValue, SegmentConditionModel condition)
416417
}
417418
}
418419

419-
static bool toBoolean(string conditionValue) => !new[] { "false", "False" }.Contains(conditionValue);
420+
private static bool ToBoolean(string conditionValue) => !new[] { "false", "False" }.Contains(conditionValue);
420421
}
421422
}

0 commit comments

Comments
 (0)