コード例 #1
0
        public static bool EndsWith(
            FilterOperation operation,
            IInputType type,
            IValueNode value,
            IQueryableFilterVisitorContext context,
            [NotNullWhen(true)] out Expression?result)
        {
            object parsedValue = type.ParseLiteral(value);

            if (parsedValue == null)
            {
                context.ReportError(
                    ErrorHelper.CreateNonNullError(operation, type, value, context));

                result = null;
                return(false);
            }

            if (operation.Type == typeof(string) &&
                type.IsInstanceOfType(value))
            {
                Expression property = GetProperty(operation, context);

                result = FilterExpressionBuilder.EndsWith(property, parsedValue);
                return(true);
            }
            else
            {
                throw new InvalidOperationException();
            }
        }
コード例 #2
0
        public bool TryHandle(
            FilterOperation operation,
            IInputType type,
            IValueNode value,
            Expression instance,
            ITypeConversion converter,
            out Expression expression)
        {
            if (operation.Type == typeof(bool) &&
                type.IsInstanceOfType(value))
            {
                MemberExpression property =
                    Expression.Property(instance, operation.Property);

                object parserValue = type.ParseLiteral(value);

                switch (operation.Kind)
                {
                case FilterOperationKind.Equals:
                    expression = FilterExpressionBuilder.Equals(
                        property, parserValue);
                    return(true);

                case FilterOperationKind.NotEquals:
                    expression = FilterExpressionBuilder.Not(
                        FilterExpressionBuilder.Equals(
                            property, parserValue)
                        );
                    return(true);
                }
            }

            expression = null;
            return(false);
        }
コード例 #3
0
        public bool TryHandle(
            FilterOperation operation,
            IInputType type,
            IValueNode value,
            Expression instance,
            ITypeConversion converter,
            out Expression expression)
        {
            if (operation.Type == typeof(string) &&
                (value is StringValueNode || value.IsNull()))
            {
                object parsedValue = type.ParseLiteral(value);

                MemberExpression property =
                    Expression.Property(instance, operation.Property);

                return(TryCreateExpression(
                           operation,
                           property,
                           parsedValue,
                           out expression));
            }

            expression = null;
            return(false);
        }
コード例 #4
0
        public bool TryHandle(
            FilterOperation operation,
            IInputType type,
            IValueNode value,
            Expression instance,
            ITypeConversion converter,
            out Expression expression)
        {
            if (operation.Type == typeof(string) &&
                type.IsInstanceOfType(value))
            {
                object parsedValue = type.ParseLiteral(value);

                Expression property = instance;

                if (!operation.IsSimpleArrayType())
                {
                    property = Expression.Property(instance, operation.Property);
                }


                return(TryCreateExpression(
                           operation,
                           property,
                           parsedValue,
                           out expression));
            }

            expression = null;
            return(false);
        }
コード例 #5
0
        public bool TryHandle(
            FilterOperation operation,
            IInputType type,
            IValueNode value,
            Expression instance,
            ITypeConversion converter,
            out Expression expression)
        {
            if (operation.Type == typeof(IComparable) &&
                type.IsInstanceOfType(value))
            {
                MemberExpression property =
                    Expression.Property(instance, operation.Property);
                var parsedValue = type.ParseLiteral(value);

                if (operation.Property.PropertyType
                    .IsInstanceOfType(parsedValue))
                {
                    parsedValue = converter.Convert(
                        typeof(object),
                        operation.Property.PropertyType,
                        parsedValue);
                }

                return(TryCreateExpression(
                           operation,
                           property,
                           parsedValue,
                           out expression));
            }

            expression = null;
            return(false);
        }
コード例 #6
0
        public bool TryHandle(
            FilterOperation operation,
            IInputType type,
            IValueNode value,
            IQueryableFilterVisitorContext context,
            [NotNullWhen(true)] out Expression?expression)
        {
            if (operation.Type == typeof(bool) && type.IsInstanceOfType(value))
            {
                Expression property = context.GetInstance();

                if (!operation.IsSimpleArrayType())
                {
                    property = Expression.Property(context.GetInstance(), operation.Property);
                }

                object parserValue = type.ParseLiteral(value);

                switch (operation.Kind)
                {
                case FilterOperationKind.Equals:
                    expression = FilterExpressionBuilder.Equals(
                        property, parserValue);
                    return(true);

                case FilterOperationKind.NotEquals:
                    expression = FilterExpressionBuilder.NotEquals(
                        property, parserValue);
                    return(true);
                }
            }

            expression = null;
            return(false);
        }
コード例 #7
0
        public bool TryHandle(
            FilterOperation operation,
            IInputType type,
            IValueNode value,
            IQueryableFilterVisitorContext context,
            out Expression expression)
        {
            if (operation.Type == typeof(string) &&
                type.IsInstanceOfType(value))
            {
                object parsedValue = type.ParseLiteral(value);

                Expression property = context.GetInstance();

                if (!operation.IsSimpleArrayType())
                {
                    property = Expression.Property(
                        context.GetInstance(), operation.Property);
                }

                return(TryCreateExpression(
                           operation,
                           property,
                           parsedValue,
                           out expression));
            }

            expression = null;
            return(false);
        }
コード例 #8
0
        public bool TryHandle(
            FilterOperation operation,
            IInputType type,
            IValueNode value,
            IQueryableFilterVisitorContext context,
            [NotNullWhen(true)] out Expression?expression)
        {
            if (operation.Type == typeof(IComparable) &&
                type.IsInstanceOfType(value))
            {
                Expression property = context.GetInstance();

                if (!operation.IsSimpleArrayType())
                {
                    property = Expression.Property(context.GetInstance(), operation.Property);
                }

                if (operation.Kind == FilterOperationKind.In)
                {
                    expression = FilterExpressionBuilder.In(
                        property,
                        operation.Property.PropertyType,
                        ParseValue());
                    return(true);
                }

                if (operation.Kind == FilterOperationKind.NotIn)
                {
                    expression = FilterExpressionBuilder.Not(
                        FilterExpressionBuilder.In(
                            property,
                            operation.Property.PropertyType,
                            ParseValue()));
                    return(true);
                }
            }

            expression = null;
            return(false);

            object ParseValue()
            {
                var  parsedValue = type.ParseLiteral(value);
                Type elementType = type.ElementType().ToRuntimeType();

                if (operation.Property.PropertyType != elementType)
                {
                    Type listType = typeof(List <>).MakeGenericType(
                        operation.Property.PropertyType);

                    parsedValue = context.TypeConverter.Convert(
                        typeof(object),
                        listType,
                        parsedValue);
                }

                return(parsedValue);
            }
        }
コード例 #9
0
        private object ParseLiteral(IInputType argumentType, IValueNode value)
        {
            IInputType type = (argumentType is NonNullType)
                ? (IInputType)argumentType.InnerType()
                : argumentType;

            return(type.ParseLiteral(value));
        }
コード例 #10
0
        public bool TryHandle(
            FilterOperation operation,
            IInputType type,
            IValueNode value,
            Expression instance,
            ITypeConversion converter,
            out Expression expression)
        {
            if (operation.Type == typeof(IComparable) &&
                type.IsInstanceOfType(value))
            {
                MemberExpression property =
                    Expression.Property(instance, operation.Property);

                switch (operation.Kind)
                {
                case FilterOperationKind.In:
                    expression = FilterExpressionBuilder.In(
                        property,
                        operation.Property.PropertyType,
                        ParseValue());
                    return(true);

                case FilterOperationKind.NotIn:
                    expression = FilterExpressionBuilder.Not(
                        FilterExpressionBuilder.In(
                            property,
                            operation.Property.PropertyType,
                            ParseValue())
                        );
                    return(true);
                }
            }

            expression = null;
            return(false);

            object ParseValue()
            {
                var  parsedValue = type.ParseLiteral(value);
                Type elementType = type.ElementType().ToClrType();

                if (operation.Property.PropertyType != elementType)
                {
                    Type listType = typeof(List <>).MakeGenericType(
                        operation.Property.PropertyType);

                    parsedValue = converter.Convert(
                        typeof(object),
                        listType,
                        parsedValue);
                }

                return(parsedValue);
            }
        }
コード例 #11
0
        private static object?ParseLiteral(IInputField argument, IValueNode value)
        {
            IInputType type = argument.Type is NonNullType
                ? (IInputType)argument.Type.InnerType()
                : argument.Type;

            object?runtimeValue = type.ParseLiteral(value);

            return(argument.Formatter is not null
                ? argument.Formatter.OnAfterDeserialize(runtimeValue)
                : runtimeValue);
        }
コード例 #12
0
        private static object ParseScalarType(
            IInputType sourceType,
            Type targetType,
            IValueNode literal)
        {
            object value = sourceType.ParseLiteral(literal.ValueOrNullValue());

            if (!sourceType.ClrType.IsAssignableFrom(targetType))
            {
                value = Convert.ChangeType(value, targetType);
            }

            return(value);
        }
コード例 #13
0
ファイル: ListType.cs プロジェクト: michaelstaib/hotchocolate
        private object CreateArray(ListValueNode listValueLiteral)
        {
            Type elementType = _inputType.NativeType;
            var  array       = Array.CreateInstance(
                elementType,
                listValueLiteral.Items.Count);

            for (var i = 0; i < listValueLiteral.Items.Count; i++)
            {
                object element = _inputType.ParseLiteral(listValueLiteral.Items[i]);
                array.SetValue(element, i);
            }

            return(array);
        }
コード例 #14
0
        private static object?DeserializeScalarResult(IInputType inputType, object?value)
        {
            switch (value)
            {
            case IReadOnlyList <object> list:
            {
                IInputType elementType = inputType;
                Type       runtimeType = typeof(List <object>);
                if (inputType.IsListType())
                {
                    elementType = (IInputType)inputType.ElementType();
                    runtimeType = inputType.RuntimeType;
                }

                var deserializedList =
                    (IList)Activator.CreateInstance(runtimeType) !;

                foreach (object?item in list)
                {
                    deserializedList.Add(DeserializeScalarResult(elementType, item));
                }

                return(deserializedList);
            }

            case ListValueNode listLiteral:
            {
                var elementType = (IInputType)inputType.ElementType();
                var list        = new List <object?>();

                foreach (IValueNode item in listLiteral.Items)
                {
                    list.Add(DeserializeScalarResult(elementType, item));
                }

                return(list);
            }

            case IValueNode literal:
                return(inputType.ParseLiteral(literal));

            default:
                return(inputType.Deserialize(value));
            }
        }
コード例 #15
0
        public bool TryHandle(
            FilterOperation operation,
            IInputType type,
            IValueNode value,
            Expression instance,
            ITypeConversion converter,
            bool inMemory,
            out Expression expression)
        {
            if (operation.Kind == FilterOperationKind.ArrayAny &&
                type.IsInstanceOfType(value) &&
                type.ParseLiteral(value) is bool parsedValue)
            {
                MemberExpression property =
                    Expression.Property(instance, operation.Property);
                Type propertType = operation.Type;

                if (operation.TryGetSimpleFilterBaseType(out Type baseType))
                {
                    propertType = baseType;
                }

                if (parsedValue)
                {
                    expression = FilterExpressionBuilder.Any(
                        propertType,
                        property);
                }
                else
                {
                    expression = FilterExpressionBuilder.Not(
                        FilterExpressionBuilder.Any(
                            propertType,
                            property));
                }
                if (inMemory)
                {
                    expression = FilterExpressionBuilder.NotNullAndAlso(property, expression);
                }
                return(true);
            }
            expression = null;
            return(false);
        }
コード例 #16
0
        public bool TryHandle(
            FilterOperation operation,
            IInputType type,
            IValueNode value,
            IQueryableFilterVisitorContext context,
            [NotNullWhen(true)] out Expression?expression)
        {
            if (operation.Kind == FilterOperationKind.ArrayAny &&
                type.IsInstanceOfType(value) &&
                type.ParseLiteral(value) is bool parsedValue)
            {
                MemberExpression property =
                    Expression.Property(context.GetInstance(), operation.Property);
                Type propertType = operation.Type;

                if (operation.TryGetSimpleFilterBaseType(out Type? baseType))
                {
                    propertType = baseType;
                }

                if (parsedValue)
                {
                    expression = FilterExpressionBuilder.Any(
                        propertType,
                        property);
                }
                else
                {
                    expression = FilterExpressionBuilder.Not(
                        FilterExpressionBuilder.Any(
                            propertType,
                            property));
                }
                if (context.InMemory)
                {
                    expression =
                        FilterExpressionBuilder.NotNullAndAlso(property, expression);
                }
                return(true);
            }
            expression = null;
            return(false);
        }
コード例 #17
0
        public bool TryHandle(
            FilterOperation operation,
            IInputType type,
            IValueNode value,
            Expression instance,
            ITypeConversion converter,
            bool inMemory,
            out Expression expression)
        {
            if (operation.Type == typeof(string) && type.IsInstanceOfType(value))
            {
                Expression property = instance;

                if (!operation.IsSimpleArrayType())
                {
                    property = Expression.Property(instance, operation.Property);
                }

                var parsedValue = type.ParseLiteral(value);

                switch (operation.Kind)
                {
                case FilterOperationKind.In:
                    expression = FilterExpressionBuilder.In(
                        property,
                        operation.Property.PropertyType,
                        parsedValue);
                    return(true);

                case FilterOperationKind.NotIn:
                    expression = FilterExpressionBuilder.Not(
                        FilterExpressionBuilder.In(
                            property,
                            operation.Property.PropertyType,
                            parsedValue));
                    return(true);
                }
            }

            expression = null;
            return(false);
        }
コード例 #18
0
        public bool TryHandle(
            FilterOperation operation,
            IInputType type,
            IValueNode value,
            IQueryableFilterVisitorContext context,
            [NotNullWhen(true)] out Expression?expression)
        {
            if (operation.Type == typeof(string) && type.IsInstanceOfType(value))
            {
                Expression property = context.GetInstance();

                if (!operation.IsSimpleArrayType())
                {
                    property = Expression.Property(
                        context.GetInstance(), operation.Property);
                }

                object?parsedValue = type.ParseLiteral(value);

                if (operation.Kind == FilterOperationKind.In)
                {
                    expression = FilterExpressionBuilder.In(
                        property,
                        operation.Property.PropertyType,
                        parsedValue);
                    return(true);
                }

                if (operation.Kind == FilterOperationKind.NotIn)
                {
                    expression = FilterExpressionBuilder.Not(
                        FilterExpressionBuilder.In(
                            property,
                            operation.Property.PropertyType,
                            parsedValue));
                    return(true);
                }
            }

            expression = null;
            return(false);
        }
コード例 #19
0
        public bool TryHandle(
            FilterOperation operation,
            IInputType type,
            IValueNode value,
            IQueryableFilterVisitorContext context,
            [NotNullWhen(true)] out Expression?expression)
        {
            if (operation.Type == typeof(IComparable) &&
                type.IsInstanceOfType(value))
            {
                Expression property = context.GetInstance();

                if (!operation.IsSimpleArrayType())
                {
                    property = Expression.Property(context.GetInstance(), operation.Property);
                }

                return(TryCreateExpression(
                           operation,
                           property,
                           ParseValue,
                           out expression));
            }

            expression = null;
            return(false);

            object ParseValue()
            {
                var parsedValue = type.ParseLiteral(value);

                if (!operation.Property.PropertyType.IsInstanceOfType(parsedValue))
                {
                    parsedValue = context.TypeConverter.Convert(
                        typeof(object),
                        operation.Property.PropertyType,
                        parsedValue);
                }

                return(parsedValue);
            }
        }
コード例 #20
0
        public object ParseLiteral(IValueNode literal)
        {
            if (literal == null)
            {
                throw new ArgumentNullException(nameof(literal));
            }

            if (_isInputType)
            {
                if (literal is NullValueNode)
                {
                    throw new ArgumentException(
                              "A non null type cannot parse null value literals.");
                }

                return(_inputType.ParseLiteral(literal));
            }

            throw new InvalidOperationException(
                      "The specified type is not an input type.");
        }
コード例 #21
0
        private static object?DeserializeEnumResult(IInputType inputType, object?value)
        {
            switch (value)
            {
            case IReadOnlyList <object> list:
            {
                var elementType      = (IInputType)inputType.ElementType();
                var deserializedList = (IList)Activator.CreateInstance(inputType.RuntimeType) !;

                foreach (object?item in list)
                {
                    deserializedList.Add(DeserializeEnumResult(elementType, item));
                }

                return(deserializedList);
            }

            case ListValueNode listLiteral:
            {
                var elementType = (IInputType)inputType.ElementType();
                var list        = new List <object?>();

                foreach (IValueNode item in listLiteral.Items)
                {
                    list.Add(DeserializeEnumResult(elementType, item));
                }

                return(list);
            }

            case StringValueNode stringLiteral:
                return(inputType.Deserialize(stringLiteral.Value));

            case IValueNode literal:
                return(inputType.ParseLiteral(literal));

            default:
                return(inputType.Deserialize(value));
            }
        }
コード例 #22
0
        public object ParseLiteral(IValueNode literal)
        {
            if (literal == null)
            {
                throw new ArgumentNullException(nameof(literal));
            }

            if (_isInputType)
            {
                if (literal is NullValueNode)
                {
                    throw new ArgumentException(
                              TypeResources.NonNullType_ValueIsNull,
                              nameof(literal));
                }

                return(_inputType.ParseLiteral(literal));
            }

            throw new InvalidOperationException(
                      TypeResources.NonNullType_NotAnInputType);
        }
コード例 #23
0
        public static bool NotEquals(
            FilterOperation operation,
            IInputType type,
            IValueNode value,
            IQueryableFilterVisitorContext context,

            [NotNullWhen(true)] out Expression?result)
        {
            object parsedValue = type.ParseLiteral(value);

            if (parsedValue == null)
            {
                context.ReportError(
                    ErrorHelper.CreateNonNullError(operation, type, value, context));

                result = null;
                return(false);
            }

            if (operation.Type == typeof(bool) &&
                type.IsInstanceOfType(value) &&
                parsedValue is bool)
            {
                Expression property = context.GetInstance();

                if (!operation.IsSimpleArrayType())
                {
                    property = Expression.Property(context.GetInstance(), operation.Property);
                }

                result = FilterExpressionBuilder.NotEquals(property, parsedValue);
                return(true);
            }
            else
            {
                throw new InvalidOperationException();
            }
        }
コード例 #24
0
        public bool TryHandle(
            FilterOperation operation,
            IInputType type,
            IValueNode value,
            Expression instance,
            ITypeConversion converter,
            out Expression expression)
        {
            if (operation.Type == typeof(IComparable) &&
                value is ListValueNode li)
            {
                MemberExpression property =
                    Expression.Property(instance, operation.Property);
                var parsedValue = type.ParseLiteral(value);

                switch (operation.Kind)
                {
                case FilterOperationKind.In:
                    expression = FilterExpressionBuilder.In(
                        property,
                        operation.Property.PropertyType,
                        parsedValue);
                    return(true);

                case FilterOperationKind.NotIn:
                    expression = FilterExpressionBuilder.Not(
                        FilterExpressionBuilder.In(
                            property,
                            operation.Property.PropertyType,
                            parsedValue)
                        );
                    return(true);
                }
            }

            expression = null;
            return(false);
        }
コード例 #25
0
        public bool TryHandle(
            FilterOperation operation,
            IInputType type,
            IValueNode value,
            Expression instance,
            ITypeConversion converter,
            out Expression expression)
        {
            if (operation.Kind == FilterOperationKind.ArrayAny &&
                type.IsInstanceOfType(value) &&
                type.ParseLiteral(value) is bool parsedValue)
            {
                Expression property = instance;

                if (!operation.IsSimpleArrayType())
                {
                    property = Expression.Property(instance, operation.Property);
                }

                if (parsedValue)
                {
                    expression = FilterExpressionBuilder.Any(
                        operation.Type,
                        property);
                }
                else
                {
                    expression = FilterExpressionBuilder.Not(
                        FilterExpressionBuilder.Any(
                            operation.Type,
                            property));
                }
                return(true);
            }
            expression = null;
            return(false);
        }
コード例 #26
0
        public bool TryHandle(
            FilterOperation operation,
            IInputType type,
            IValueNode value,
            Expression instance,
            ITypeConversion converter,
            out Expression expression)
        {
            if (operation.Type == typeof(IComparable) &&
                value is IValueNode <IComparable> s)
            {
                MemberExpression property =
                    Expression.Property(instance, operation.Property);
                var parsedValue = type.ParseLiteral(value);

                if (operation.Property.PropertyType
                    .IsInstanceOfType(parsedValue))
                {
                    parsedValue = converter.Convert(
                        typeof(object),
                        operation.Property.PropertyType,
                        parsedValue);
                }

                switch (operation.Kind)
                {
                case FilterOperationKind.Equals:
                    expression = FilterExpressionBuilder.Equals(
                        property, parsedValue);
                    return(true);

                case FilterOperationKind.NotEquals:
                    expression = FilterExpressionBuilder.Not(
                        FilterExpressionBuilder.Equals(
                            property, parsedValue)
                        );
                    return(true);

                case FilterOperationKind.GreaterThan:
                    expression = FilterExpressionBuilder.GreaterThan(
                        property, parsedValue);
                    return(true);

                case FilterOperationKind.NotGreaterThan:
                    expression = FilterExpressionBuilder.Not(
                        FilterExpressionBuilder.GreaterThan(
                            property, parsedValue)
                        );
                    return(true);

                case FilterOperationKind.GreaterThanOrEqual:
                    expression = FilterExpressionBuilder.GreaterThanOrEqual(
                        property, parsedValue);
                    return(true);

                case FilterOperationKind.NotGreaterThanOrEqual:
                    expression = FilterExpressionBuilder.Not(
                        FilterExpressionBuilder.GreaterThanOrEqual(
                            property, parsedValue)
                        );
                    return(true);

                case FilterOperationKind.LowerThan:
                    expression = FilterExpressionBuilder.LowerThan(
                        property, parsedValue);
                    return(true);

                case FilterOperationKind.NotLowerThan:
                    expression = FilterExpressionBuilder.Not(
                        FilterExpressionBuilder.LowerThan(
                            property, parsedValue));
                    return(true);

                case FilterOperationKind.LowerThanOrEqual:
                    expression = FilterExpressionBuilder.LowerThanOrEqual(
                        property, parsedValue);
                    return(true);

                case FilterOperationKind.NotLowerThanOrEqual:
                    expression = FilterExpressionBuilder.Not(
                        FilterExpressionBuilder.LowerThanOrEqual(
                            property, parsedValue));
                    return(true);
                }
            }

            if (operation.Type == typeof(IComparable) && value is ListValueNode li)
            {
                MemberExpression property =
                    Expression.Property(instance, operation.Property);
                var parsedValue = type.ParseLiteral(value);

                switch (operation.Kind)
                {
                case FilterOperationKind.In:
                    expression = FilterExpressionBuilder.In(
                        property,
                        operation.Property.PropertyType,
                        parsedValue);
                    return(true);

                case FilterOperationKind.NotIn:
                    expression = FilterExpressionBuilder.Not(
                        FilterExpressionBuilder.In(
                            property,
                            operation.Property.PropertyType,
                            parsedValue)
                        );
                    return(true);
                }
            }

            expression = null;
            return(false);
        }
コード例 #27
0
        public static bool ArrayAny(
            FilterOperation operation,
            IInputType type,
            IValueNode value,
            IQueryableFilterVisitorContext context,
            [NotNullWhen(true)] out Expression?result)
        {
            object parsedValue = type.ParseLiteral(value);

            if (parsedValue == null)
            {
                context.ReportError(
                    ErrorHelper.CreateNonNullError(operation, type, value, context));

                result = null;
                return(false);
            }

            if (operation.Kind == FilterOperationKind.ArrayAny &&
                type.IsInstanceOfType(value) &&
                parsedValue is bool parsedBool)
            {
                MemberExpression property =
                    Expression.Property(context.GetInstance(), operation.Property);

                Type propertType = operation.Type;

                if (operation.TryGetSimpleFilterBaseType(out Type? baseType))
                {
                    propertType = baseType;
                }

                Expression expression;
                if (parsedBool)
                {
                    expression = FilterExpressionBuilder.Any(
                        propertType,
                        property);
                }
                else
                {
                    expression = FilterExpressionBuilder.Not(
                        FilterExpressionBuilder.Any(
                            propertType,
                            property));
                }

                if (context.InMemory)
                {
                    expression =
                        FilterExpressionBuilder.NotNullAndAlso(property, expression);
                }

                result = expression;
                return(true);
            }
            else
            {
                throw new InvalidOperationException();
            }
        }
コード例 #28
0
        public bool TryHandle(
            FilterOperation operation,
            IInputType type,
            IValueNode value,
            Expression instance,
            ITypeConversion converter,
            out Expression expression)
        {
            if (operation.Type == typeof(string) && value is StringValueNode s)
            {
                MemberExpression property =
                    Expression.Property(instance, operation.Property);

                switch (operation.Kind)
                {
                case FilterOperationKind.Equals:
                    expression = FilterExpressionBuilder.Equals(
                        property, s.Value);
                    return(true);

                case FilterOperationKind.NotEquals:
                    expression = FilterExpressionBuilder.Not(
                        FilterExpressionBuilder.Equals(property, s.Value)
                        );
                    return(true);

                case FilterOperationKind.StartsWith:
                    expression = FilterExpressionBuilder.StartsWith(
                        property, s.Value);
                    return(true);

                case FilterOperationKind.EndsWith:
                    expression = FilterExpressionBuilder.EndsWith(
                        property, s.Value);
                    return(true);

                case FilterOperationKind.NotStartsWith:
                    expression = FilterExpressionBuilder.Not(
                        FilterExpressionBuilder.StartsWith(
                            property, s.Value)
                        );
                    return(true);

                case FilterOperationKind.NotEndsWith:
                    expression = FilterExpressionBuilder.Not(
                        FilterExpressionBuilder.EndsWith(property, s.Value)
                        );
                    return(true);

                case FilterOperationKind.Contains:
                    expression = FilterExpressionBuilder.Contains(
                        property, s.Value);
                    return(true);

                case FilterOperationKind.NotContains:
                    expression = FilterExpressionBuilder.Not(
                        FilterExpressionBuilder.Contains(property, s.Value)
                        );
                    return(true);
                }
            }

            if (operation.Type == typeof(string) && value is ListValueNode li)
            {
                MemberExpression property =
                    Expression.Property(instance, operation.Property);
                var parsedValue = type.ParseLiteral(value);

                switch (operation.Kind)
                {
                case FilterOperationKind.In:
                    expression = FilterExpressionBuilder.In(
                        property,
                        operation.Property.PropertyType,
                        parsedValue);
                    return(true);

                case FilterOperationKind.NotIn:
                    expression = FilterExpressionBuilder.Not(
                        FilterExpressionBuilder.In(
                            property,
                            operation.Property.PropertyType,
                            parsedValue));
                    return(true);
                }
            }

            expression = null;
            return(false);
        }