< Summary

Information
Class: Fluorite.Strainer.Services.Filtering.FilterOperatorMapper
Assembly: Fluorite.Strainer
File(s): /builds/fluorite/strainer/src/Strainer/Services/Filtering/FilterOperatorMapper.cs
Line coverage
100%
Covered lines: 453
Uncovered lines: 0
Coverable lines: 453
Total lines: 503
Line coverage: 100%
Branch coverage
100%
Covered branches: 52
Total branches: 52
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

/builds/fluorite/strainer/src/Strainer/Services/Filtering/FilterOperatorMapper.cs

#LineLine coverage
 1using Fluorite.Extensions;
 2using Fluorite.Strainer.Models.Filtering.Operators;
 3using System.Collections.ObjectModel;
 4using System.Linq.Expressions;
 5using System.Reflection;
 6
 7namespace Fluorite.Strainer.Services.Filtering;
 8
 9public static class FilterOperatorMapper
 10{
 11    static FilterOperatorMapper()
 12    {
 113        DefaultOperators = new ReadOnlyDictionary<string, IFilterOperator>(
 114            GetDefaultFilterOperators()
 4115                .ToDictionary(filterOperator => filterOperator.Symbol, filterOperator => filterOperator));
 116    }
 17
 35218    public static IReadOnlyDictionary<string, IFilterOperator> DefaultOperators { get; }
 19
 20    private static IFilterOperator[] GetDefaultFilterOperators()
 21    {
 122        return GetEqualFilterOperators()
 123            .Concat(
 124                GetLessThanFilterOperators(),
 125                GetGreaterThanFilterOperators(),
 126                GetStringFilterOperators(),
 127                GetStringNegatedFilterOperators(),
 128                GetEqualCaseInsensitiveFilterOperators(),
 129                GetStringCaseInsensitiveFilterOperators(),
 130                GetStringNegatedCaseInsensitiveFilterOperators())
 131            .ToArray();
 32    }
 33
 34    private static List<IFilterOperator> GetEqualFilterOperators()
 35    {
 136        return new List<IFilterOperator>
 137        {
 138            new FilterOperatorBuilder()
 139                .HasSymbol(FilterOperatorSymbols.EqualsSymbol)
 140                .HasName("equal")
 141                .HasExpression((context) =>
 142                {
 2043                    if (context.IsMaterializedQueryable && context.IsCaseInsensitiveForValues && context.IsStringBasedPr
 144                    {
 1045                        return Expression.Call(
 1046                            typeof(string).GetMethod(
 1047                                nameof(string.Equals),
 1048                                BindingFlags.Static | BindingFlags.Public,
 1049                                null,
 1050                                new Type[] { typeof(string), typeof(string), typeof(StringComparison) },
 1051                                null),
 1052                            context.PropertyValue,
 1053                            context.FilterValue,
 1054                            Expression.Constant(StringComparison.OrdinalIgnoreCase));
 155                    }
 156                    else
 157                    {
 1058                        return Expression.Equal(context.PropertyValue, context.FilterValue);
 159                    }
 160                })
 161                .Build(),
 162            new FilterOperatorBuilder()
 163                .HasSymbol(FilterOperatorSymbols.DoesNotEqual)
 164                .HasName("does not equal")
 165                .HasExpression((context) =>
 166                {
 2067                    if (context.IsMaterializedQueryable && context.IsCaseInsensitiveForValues && context.IsStringBasedPr
 168                    {
 1069                        return Expression.Not(Expression.Call(
 1070                            typeof(string).GetMethod(
 1071                                nameof(string.Equals),
 1072                                BindingFlags.Static | BindingFlags.Public,
 1073                                null,
 1074                                new Type[] { typeof(string), typeof(string), typeof(StringComparison) },
 1075                                null),
 1076                            context.PropertyValue,
 1077                            context.FilterValue,
 1078                            Expression.Constant(StringComparison.OrdinalIgnoreCase)));
 179                    }
 180                    else
 181                    {
 1082                        return Expression.NotEqual(context.PropertyValue, context.FilterValue);
 183                    }
 184                })
 185                .Build(),
 186        };
 87    }
 88
 89    private static IEnumerable<IFilterOperator> GetLessThanFilterOperators()
 90    {
 191        return new List<IFilterOperator>
 192        {
 193            new FilterOperatorBuilder().HasSymbol(FilterOperatorSymbols.LessThan)
 194                .HasName("less than")
 695                .HasExpression((context) => Expression.LessThan(context.PropertyValue, context.FilterValue))
 196                .Build(),
 197            new FilterOperatorBuilder().HasSymbol(FilterOperatorSymbols.LessThanOrEqualTo)
 198                .HasName("less than or equal to")
 699                .HasExpression((context) => Expression.LessThanOrEqual(context.PropertyValue, context.FilterValue))
 1100                .Build(),
 1101        };
 102    }
 103
 104    private static IEnumerable<IFilterOperator> GetGreaterThanFilterOperators()
 105    {
 1106        return new List<IFilterOperator>
 1107        {
 1108            new FilterOperatorBuilder().HasSymbol(FilterOperatorSymbols.GreaterThan)
 1109                .HasName("greater than")
 6110                .HasExpression((context) => Expression.GreaterThan(context.PropertyValue, context.FilterValue))
 1111                .Build(),
 1112            new FilterOperatorBuilder().HasSymbol(FilterOperatorSymbols.GreaterThanOrEqualTo)
 1113                .HasName("greater than or equal to")
 6114                .HasExpression((context) => Expression.GreaterThanOrEqual(context.PropertyValue, context.FilterValue))
 1115                .Build(),
 1116        };
 117    }
 118
 119    private static IEnumerable<IFilterOperator> GetStringFilterOperators()
 120    {
 1121        return new List<IFilterOperator>
 1122        {
 1123            new FilterOperatorBuilder()
 1124                .HasSymbol(FilterOperatorSymbols.Contains)
 1125                .HasName("contains")
 1126                .HasExpression((context) =>
 1127                {
 18128                    if (context.IsMaterializedQueryable && context.IsCaseInsensitiveForValues)
 1129                    {
 9130                        return Expression.Call(
 9131                            context.PropertyValue,
 9132                            typeof(string).GetMethod(nameof(string.Contains), new Type[] { typeof(string), typeof(String
 9133                            context.FilterValue,
 9134                            Expression.Constant(StringComparison.OrdinalIgnoreCase));
 1135                    }
 1136                    else
 1137                    {
 9138                        return Expression.Call(
 9139                            context.PropertyValue,
 9140                            typeof(string).GetMethod(nameof(string.Contains), new Type[] { typeof(string) }),
 9141                            context.FilterValue);
 1142                    }
 1143                })
 1144                .IsStringBased()
 1145                .Build(),
 1146            new FilterOperatorBuilder()
 1147                .HasSymbol(FilterOperatorSymbols.StartsWith)
 1148                .HasName("starts with")
 1149                .HasExpression((context) =>
 1150                {
 18151                    if (context.IsMaterializedQueryable && context.IsCaseInsensitiveForValues)
 1152                    {
 9153                        return Expression.Call(
 9154                            context.PropertyValue,
 9155                            typeof(string).GetMethod(nameof(string.StartsWith), new Type[] { typeof(string), typeof(Stri
 9156                            context.FilterValue,
 9157                            Expression.Constant(StringComparison.OrdinalIgnoreCase));
 1158                    }
 1159                    else
 1160                    {
 9161                        return Expression.Call(
 9162                            context.PropertyValue,
 9163                            typeof(string).GetMethod(nameof(string.StartsWith), new Type[] { typeof(string) }),
 9164                            context.FilterValue);
 1165                    }
 1166                })
 1167                .IsStringBased()
 1168                .Build(),
 1169            new FilterOperatorBuilder()
 1170                .HasSymbol(FilterOperatorSymbols.EndsWith)
 1171                .HasName("ends with")
 1172                .HasExpression((context) =>
 1173                {
 18174                    if (context.IsMaterializedQueryable && context.IsCaseInsensitiveForValues)
 1175                    {
 9176                        return Expression.Call(
 9177                            context.PropertyValue,
 9178                            typeof(string).GetMethod(nameof(string.EndsWith), new Type[] { typeof(string), typeof(String
 9179                            context.FilterValue,
 9180                            Expression.Constant(StringComparison.OrdinalIgnoreCase));
 1181                    }
 1182                    else
 1183                    {
 9184                        return Expression.Call(
 9185                            context.PropertyValue,
 9186                            typeof(string).GetMethod(nameof(string.EndsWith), new Type[] { typeof(string) }),
 9187                            context.FilterValue);
 1188                    }
 1189                })
 1190                .IsStringBased()
 1191                .Build(),
 1192        };
 193    }
 194
 195    private static IEnumerable<IFilterOperator> GetStringNegatedFilterOperators()
 196    {
 1197        return new List<IFilterOperator>
 1198        {
 1199            new FilterOperatorBuilder()
 1200                .HasSymbol(FilterOperatorSymbols.DoesNotContain)
 1201                .HasName("does not contain")
 1202                .HasExpression((context) =>
 1203                {
 18204                    if (context.IsMaterializedQueryable && context.IsCaseInsensitiveForValues)
 1205                    {
 9206                        return Expression.Not(Expression.Call(
 9207                            context.PropertyValue,
 9208                            typeof(string).GetMethod(nameof(string.Contains), new Type[] { typeof(string), typeof(String
 9209                            context.FilterValue,
 9210                            Expression.Constant(StringComparison.OrdinalIgnoreCase)));
 1211                    }
 1212                    else
 1213                    {
 9214                        return Expression.Not(Expression.Call(
 9215                            context.PropertyValue,
 9216                            typeof(string).GetMethod(nameof(string.Contains), new Type[] { typeof(string) }),
 9217                            context.FilterValue));
 1218                    }
 1219                })
 1220                .IsStringBased()
 1221                .Build(),
 1222            new FilterOperatorBuilder()
 1223                .HasSymbol(FilterOperatorSymbols.DoesNotStartWith)
 1224                .HasName("does not start with")
 1225                .HasExpression((context) =>
 1226                {
 18227                    if (context.IsMaterializedQueryable && context.IsCaseInsensitiveForValues)
 1228                    {
 9229                        return Expression.Not(Expression.Call(
 9230                            context.PropertyValue,
 9231                            typeof(string).GetMethod(nameof(string.StartsWith), new Type[] { typeof(string), typeof(Stri
 9232                            context.FilterValue,
 9233                            Expression.Constant(StringComparison.OrdinalIgnoreCase)));
 1234                    }
 1235                    else
 1236                    {
 9237                        return Expression.Not(Expression.Call(
 9238                            context.PropertyValue,
 9239                            typeof(string).GetMethod(nameof(string.StartsWith), new Type[] { typeof(string) }),
 9240                            context.FilterValue));
 1241                    }
 1242                })
 1243                .IsStringBased()
 1244                .Build(),
 1245            new FilterOperatorBuilder()
 1246                .HasSymbol(FilterOperatorSymbols.DoesNotEndWith)
 1247                .HasName("does not end with")
 1248                .HasExpression((context) =>
 1249                {
 18250                    if (context.IsMaterializedQueryable && context.IsCaseInsensitiveForValues)
 1251                    {
 9252                        return Expression.Not(Expression.Call(
 9253                            context.PropertyValue,
 9254                            typeof(string).GetMethod(nameof(string.EndsWith), new Type[] { typeof(string), typeof(String
 9255                            context.FilterValue,
 9256                            Expression.Constant(StringComparison.OrdinalIgnoreCase)));
 1257                    }
 1258                    else
 1259                    {
 9260                        return Expression.Not(Expression.Call(
 9261                            context.PropertyValue,
 9262                            typeof(string).GetMethod(nameof(string.EndsWith), new Type[] { typeof(string) }),
 9263                            context.FilterValue));
 1264                    }
 1265                })
 1266                .IsStringBased()
 1267                .Build(),
 1268        };
 269    }
 270
 271    private static IEnumerable<IFilterOperator> GetEqualCaseInsensitiveFilterOperators()
 272    {
 1273        return new List<IFilterOperator>
 1274        {
 1275            new FilterOperatorBuilder()
 1276                .HasSymbol(FilterOperatorSymbols.EqualsCaseInsensitive)
 1277                .HasName("equal (case insensitive)")
 1278                .HasExpression((context) =>
 1279                {
 20280                    if (context.IsMaterializedQueryable)
 1281                    {
 10282                        return Expression.Call(
 10283                            typeof(string).GetMethod(
 10284                                nameof(string.Equals),
 10285                                BindingFlags.Static | BindingFlags.Public,
 10286                                null,
 10287                                new Type[] { typeof(string), typeof(string), typeof(StringComparison) },
 10288                                null),
 10289                            context.PropertyValue,
 10290                            context.FilterValue,
 10291                            Expression.Constant(StringComparison.OrdinalIgnoreCase));
 1292                    }
 1293                    else
 1294                    {
 10295                        return Expression.Call(
 10296                            typeof(string).GetMethod(
 10297                                nameof(string.Equals),
 10298                                BindingFlags.Static | BindingFlags.Public,
 10299                                null,
 10300                                new Type[] { typeof(string), typeof(string) },
 10301                                null),
 10302                            context.PropertyValue,
 10303                            context.FilterValue);
 1304                    }
 1305                })
 1306                .IsStringBased()
 1307                .IsCaseInsensitive()
 1308                .Build(),
 1309            new FilterOperatorBuilder()
 1310                .HasSymbol(FilterOperatorSymbols.DoesNotEqualCaseInsensitive)
 1311                .HasName("does not equal (case insensitive)")
 1312                .HasExpression((context) =>
 1313                {
 20314                    if (context.IsMaterializedQueryable)
 1315                    {
 10316                        return Expression.Not(Expression.Call(
 10317                            typeof(string).GetMethod(
 10318                                nameof(string.Equals),
 10319                                BindingFlags.Static | BindingFlags.Public,
 10320                                null,
 10321                                new Type[] { typeof(string), typeof(string), typeof(StringComparison) },
 10322                                null),
 10323                            context.PropertyValue,
 10324                            context.FilterValue,
 10325                            Expression.Constant(StringComparison.OrdinalIgnoreCase)));
 1326                    }
 1327                    else
 1328                    {
 10329                        return Expression.Not(Expression.Call(
 10330                            typeof(string).GetMethod(
 10331                                nameof(string.Equals),
 10332                                BindingFlags.Static | BindingFlags.Public,
 10333                                null,
 10334                                new Type[] { typeof(string), typeof(string) },
 10335                                null),
 10336                            context.PropertyValue,
 10337                            context.FilterValue));
 1338                    }
 1339                })
 1340                .IsStringBased()
 1341                .IsCaseInsensitive()
 1342                .Build(),
 1343        };
 344    }
 345
 346    private static IEnumerable<IFilterOperator> GetStringCaseInsensitiveFilterOperators()
 347    {
 1348        return new List<IFilterOperator>
 1349        {
 1350            new FilterOperatorBuilder()
 1351                .HasSymbol(FilterOperatorSymbols.ContainsCaseInsensitive)
 1352                .HasName("contains (case insensitive)")
 1353                .HasExpression((context) =>
 1354                {
 18355                    if (context.IsMaterializedQueryable)
 1356                    {
 9357                        return Expression.Call(
 9358                            context.PropertyValue,
 9359                            typeof(string).GetMethod(nameof(string.Contains), new Type[] { typeof(string), typeof(String
 9360                            context.FilterValue,
 9361                            Expression.Constant(StringComparison.OrdinalIgnoreCase));
 1362                    }
 1363                    else
 1364                    {
 9365                        return Expression.Call(
 9366                            context.PropertyValue,
 9367                            typeof(string).GetMethod(nameof(string.Contains), new Type[] { typeof(string) }),
 9368                            context.FilterValue);
 1369                    }
 1370                })
 1371                .IsStringBased()
 1372                .IsCaseInsensitive()
 1373                .Build(),
 1374            new FilterOperatorBuilder()
 1375                .HasSymbol(FilterOperatorSymbols.StartsWithCaseInsensitive)
 1376                .HasName("starts with (case insensitive)")
 1377                .HasExpression((context) =>
 1378                {
 18379                    if (context.IsMaterializedQueryable)
 1380                    {
 9381                        return Expression.Call(
 9382                            context.PropertyValue,
 9383                            typeof(string).GetMethod(nameof(string.StartsWith), new Type[] { typeof(string), typeof(Stri
 9384                            context.FilterValue,
 9385                            Expression.Constant(StringComparison.OrdinalIgnoreCase));
 1386                    }
 1387                    else
 1388                    {
 9389                        return Expression.Call(
 9390                            context.PropertyValue,
 9391                            typeof(string).GetMethod(nameof(string.StartsWith), new Type[] { typeof(string) }),
 9392                            context.FilterValue);
 1393                    }
 1394                })
 1395                .IsStringBased()
 1396                .IsCaseInsensitive()
 1397                .Build(),
 1398            new FilterOperatorBuilder()
 1399                .HasSymbol(FilterOperatorSymbols.EndsWithCaseInsensitive)
 1400                .HasName("ends with (case insensitive)")
 1401                .HasExpression((context) =>
 1402                {
 18403                    if (context.IsMaterializedQueryable)
 1404                    {
 9405                        return Expression.Call(
 9406                            context.PropertyValue,
 9407                            typeof(string).GetMethod(nameof(string.EndsWith), new Type[] { typeof(string), typeof(String
 9408                            context.FilterValue,
 9409                            Expression.Constant(StringComparison.OrdinalIgnoreCase));
 1410                    }
 1411                    else
 1412                    {
 9413                        return Expression.Call(
 9414                            context.PropertyValue,
 9415                            typeof(string).GetMethod(nameof(string.EndsWith), new Type[] { typeof(string) }),
 9416                            context.FilterValue);
 1417                    }
 1418                })
 1419                .IsStringBased()
 1420                .IsCaseInsensitive()
 1421                .Build(),
 1422        };
 423    }
 424
 425    private static IEnumerable<IFilterOperator> GetStringNegatedCaseInsensitiveFilterOperators()
 426    {
 1427        return new List<IFilterOperator>
 1428        {
 1429            new FilterOperatorBuilder()
 1430                .HasSymbol(FilterOperatorSymbols.DoesNotContainCaseInsensitive)
 1431                .HasName("does not contain (case insensitive)")
 1432                .HasExpression((context) =>
 1433                {
 18434                    if (context.IsMaterializedQueryable)
 1435                    {
 9436                        return Expression.Not(Expression.Call(
 9437                            context.PropertyValue,
 9438                            typeof(string).GetMethod(nameof(string.Contains), new Type[] { typeof(string), typeof(String
 9439                            context.FilterValue,
 9440                            Expression.Constant(StringComparison.OrdinalIgnoreCase)));
 1441                    }
 1442                    else
 1443                    {
 9444                        return Expression.Not(Expression.Call(
 9445                            context.PropertyValue,
 9446                            typeof(string).GetMethod(nameof(string.Contains), new Type[] { typeof(string) }),
 9447                            context.FilterValue));
 1448                    }
 1449                })
 1450                .IsStringBased()
 1451                .IsCaseInsensitive()
 1452                .Build(),
 1453            new FilterOperatorBuilder()
 1454                .HasSymbol(FilterOperatorSymbols.DoesNotStartWithCaseInsensitive)
 1455                .HasName("does not start with (case insensitive)")
 1456                .HasExpression((context) =>
 1457                {
 18458                    if (context.IsMaterializedQueryable)
 1459                    {
 9460                        return Expression.Not(Expression.Call(
 9461                            context.PropertyValue,
 9462                            typeof(string).GetMethod(nameof(string.StartsWith), new Type[] { typeof(string), typeof(Stri
 9463                            context.FilterValue,
 9464                            Expression.Constant(StringComparison.OrdinalIgnoreCase)));
 1465                    }
 1466                    else
 1467                    {
 9468                        return Expression.Not(Expression.Call(
 9469                            context.PropertyValue,
 9470                            typeof(string).GetMethod(nameof(string.StartsWith), new Type[] { typeof(string) }),
 9471                            context.FilterValue));
 1472                    }
 1473                })
 1474                .IsStringBased()
 1475                .IsCaseInsensitive()
 1476                .Build(),
 1477            new FilterOperatorBuilder()
 1478                .HasSymbol(FilterOperatorSymbols.DoesNotEndWithCaseInsensitive)
 1479                .HasName("does not end with (case insensitive)")
 1480                .HasExpression((context) =>
 1481                {
 18482                    if (context.IsMaterializedQueryable)
 1483                    {
 9484                        return Expression.Not(Expression.Call(
 9485                            context.PropertyValue,
 9486                            typeof(string).GetMethod(nameof(string.EndsWith), new Type[] { typeof(string), typeof(String
 9487                            context.FilterValue,
 9488                            Expression.Constant(StringComparison.OrdinalIgnoreCase)));
 1489                    }
 1490                    else
 1491                    {
 9492                        return Expression.Not(Expression.Call(
 9493                            context.PropertyValue,
 9494                            typeof(string).GetMethod(nameof(string.EndsWith), new Type[] { typeof(string) }),
 9495                            context.FilterValue));
 1496                    }
 1497                })
 1498                .IsStringBased()
 1499                .IsCaseInsensitive()
 1500                .Build(),
 1501        };
 502    }
 503}