using System; using System.Linq.Expressions; using VCommon.Linq.Expressions.Predicate.Internals; namespace VCommon.Linq.Expressions.Predicate { public static class PredicateWrap { public static PredicateWrap Op(this Expression> exp) => new PredicateWrap(exp); } public class PredicateWrap { private readonly Expression> _expression; internal PredicateWrap(Expression> expression) => _expression = expression; public PredicateWrap When(bool condition) => condition ? this : null; public static implicit operator Expression>(PredicateWrap me) { var expression = me?._expression; if (true == expression?.CanReduce) return (Expression>)expression.Reduce(); return expression; } public static implicit operator PredicateWrap(Expression> me) => me == null ? null : new PredicateWrap(me); public static PredicateWrap operator &(PredicateWrap a, PredicateWrap b) { var aIsNull = null == a?._expression; var bIsNull = null == b?._expression; if (aIsNull && bIsNull) return null; if (aIsNull) return b; if (bIsNull) return a; return new PredicateWrap(a._expression.And(b._expression)); } public static PredicateWrap operator &(PredicateWrap a, Expression> b) { var aIsNull = null == a?._expression; var bIsNull = null == b; if (aIsNull && bIsNull) return null; if (aIsNull) return b; if (bIsNull) return a; return new PredicateWrap(a._expression.And(b)); } public static PredicateWrap operator &(Expression> a, PredicateWrap b) { var aIsNull = null == a; var bIsNull = null == b?._expression; if (aIsNull && bIsNull) return null; if (aIsNull) return b; if (bIsNull) return a; return new PredicateWrap(a.And(b._expression)); } public static PredicateWrap operator |(PredicateWrap a, PredicateWrap b) { var aIsNull = null == a?._expression; var bIsNull = null == b?._expression; if (aIsNull && bIsNull) return null; if (aIsNull) return b; if (bIsNull) return a; return new PredicateWrap(a._expression.Or(b._expression)); } public static PredicateWrap operator |(PredicateWrap a, Expression> b) { var aIsNull = null == a?._expression; var bIsNull = null == b; if (aIsNull && bIsNull) return null; if (aIsNull) return b; if (bIsNull) return a; return new PredicateWrap(a._expression.Or(b)); } public static PredicateWrap operator |(Expression> a, PredicateWrap b) { var aIsNull = null == a; var bIsNull = null == b?._expression; if (aIsNull && bIsNull) return null; if (aIsNull) return b; if (bIsNull) return a; return new PredicateWrap(a.Or(b._expression)); } } }