private static string ComputeArray(Expression array, ArrayPostfixMode arrayPostfixMode, RequestBuilderConfiguration configuration) { var list = string.Join( ",", (array as NewArrayExpression).Expressions.Select(e => Run(e as ConstantExpression, configuration)) ); return(arrayPostfixMode switch { ArrayPostfixMode.ContainsAny => $"({list})", ArrayPostfixMode.ContainsAll => $"[{list}]", ArrayPostfixMode.ExactMatch => $"{{{list}}}", _ => throw new Exception("Unknown array postfix mode"), });
/// <summary> /// Interpretes a predicate to convert it to a string usable by IGDB API /// </summary> /// <param name="predicate"></param> /// <returns></returns> public static string Run(Expression predicate, RequestBuilderConfiguration configuration, bool invert = false, ArrayPostfixMode arrayPostfixMode = ArrayPostfixMode.ContainsAny) { if (predicate is null) { throw new ArgumentNullException(nameof(predicate)); } var binaryPredicate = predicate as BinaryExpression; switch (predicate.NodeType) { /* * First part of switch : binary operators * ------- * if Node type referes to a binary operators we set the operator * and let the method continue after the switch to create the * expression. * binary operators are either logical operators (&& or ||), * relational operators (>, >=, <, <=) or equality operators (==, !=) */ case ExpressionType.AndAlso: return(ComputeBinaryOperator(binaryPredicate.Left, binaryPredicate.Right, "&", configuration)); case ExpressionType.OrElse: return(ComputeBinaryOperator(binaryPredicate.Left, binaryPredicate.Right, "|", configuration)); case ExpressionType.GreaterThan: return(ComputeBinaryOperator(binaryPredicate.Left, binaryPredicate.Right, ">", configuration)); case ExpressionType.GreaterThanOrEqual: return(ComputeBinaryOperator(binaryPredicate.Left, binaryPredicate.Right, ">=", configuration)); case ExpressionType.LessThan: return(ComputeBinaryOperator(binaryPredicate.Left, binaryPredicate.Right, "<", configuration)); case ExpressionType.LessThanOrEqual: return(ComputeBinaryOperator(binaryPredicate.Left, binaryPredicate.Right, "<=", configuration)); case ExpressionType.NotEqual: return(ComputeBinaryOperator(binaryPredicate.Left, binaryPredicate.Right, "!=", configuration)); case ExpressionType.Equal: return(ComputeBinaryOperator(binaryPredicate.Left, binaryPredicate.Right, "=", configuration)); /* * Second part of switch : members * ------- * If node type refers to a member, a constant or an array then * then return an interpretation. */ case ExpressionType.MemberAccess: return(ComputeMemberAccess(predicate, configuration)); case ExpressionType.Constant: return(ComputeConstant(predicate, configuration)); case ExpressionType.NewArrayInit: return(ComputeArray(predicate, arrayPostfixMode, configuration)); /* * Third part of switch : methods * ------- * if node type referes to a method corresponding to */ case ExpressionType.Not: return(ComputeNotCall(predicate, configuration)); case ExpressionType.Call: return(ComputeMethodCall(predicate, configuration, invert)); default: throw new InvalidPredicateException(predicate); } }