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));
}
}