using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; namespace Jellyfin.Server.Implementations.Extensions; /// /// Provides extension methods. /// public static class ExpressionExtensions { /// /// Combines two predicates into a single predicate using a logical OR operation. /// /// The predicate parameter type. /// The first predicate expression to combine. /// The second predicate expression to combine. /// A new expression representing the OR combination of the input predicates. public static Expression> Or(this Expression> firstPredicate, Expression> secondPredicate) { ArgumentNullException.ThrowIfNull(firstPredicate); ArgumentNullException.ThrowIfNull(secondPredicate); var invokedExpression = Expression.Invoke(secondPredicate, firstPredicate.Parameters); return Expression.Lambda>(Expression.OrElse(firstPredicate.Body, invokedExpression), firstPredicate.Parameters); } /// /// Combines multiple predicates into a single predicate using a logical OR operation. /// /// The predicate parameter type. /// A collection of predicate expressions to combine. /// A new expression representing the OR combination of all input predicates. public static Expression> Or(this IEnumerable>> predicates) { ArgumentNullException.ThrowIfNull(predicates); return predicates.Aggregate((aggregatePredicate, nextPredicate) => aggregatePredicate.Or(nextPredicate)); } /// /// Combines two predicates into a single predicate using a logical AND operation. /// /// The predicate parameter type. /// The first predicate expression to combine. /// The second predicate expression to combine. /// A new expression representing the AND combination of the input predicates. public static Expression> And(this Expression> firstPredicate, Expression> secondPredicate) { ArgumentNullException.ThrowIfNull(firstPredicate); ArgumentNullException.ThrowIfNull(secondPredicate); var invokedExpression = Expression.Invoke(secondPredicate, firstPredicate.Parameters); return Expression.Lambda>(Expression.AndAlso(firstPredicate.Body, invokedExpression), firstPredicate.Parameters); } /// /// Combines multiple predicates into a single predicate using a logical AND operation. /// /// The predicate parameter type. /// A collection of predicate expressions to combine. /// A new expression representing the AND combination of all input predicates. public static Expression> And(this IEnumerable>> predicates) { ArgumentNullException.ThrowIfNull(predicates); return predicates.Aggregate((aggregatePredicate, nextPredicate) => aggregatePredicate.And(nextPredicate)); } }