1- using FlagsmithEngine . Segment . Models ;
21using FlagsmithEngine . Utils ;
32using Newtonsoft . Json ;
43using Newtonsoft . Json . Linq ;
54using Semver ;
65using System ;
76using System . Collections . Generic ;
87using System . Linq ;
8+ using System . Text . RegularExpressions ;
99
1010namespace 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