PredicateBuilder<TResult>
Defines a builder for creating predicates for TResult and Exception combinations.
using Polly.Utils;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
namespace Polly
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
public sealed class PredicateBuilder<[System.Runtime.CompilerServices.Nullable(2)] TResult>
{
[System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
0,
1
})]
private readonly List<Predicate<Outcome<TResult>>> _predicates = new List<Predicate<Outcome<TResult>>>();
internal PredicateBuilder()
{
}
public PredicateBuilder<TResult> Handle<[System.Runtime.CompilerServices.Nullable(0)] TException>() where TException : Exception
{
return Handle((TException _) => true);
}
public PredicateBuilder<TResult> Handle<[System.Runtime.CompilerServices.Nullable(0)] TException>(Func<TException, bool> predicate) where TException : Exception
{
Guard.NotNull<Func<TException, bool>>(predicate, "predicate");
return this.Add((Predicate<Outcome<TResult>>)delegate(Outcome<TResult> outcome) {
TException val = outcome.Exception as TException;
if (val != null)
return predicate(val);
return false;
});
}
public PredicateBuilder<TResult> HandleInner<[System.Runtime.CompilerServices.Nullable(0)] TException>() where TException : Exception
{
return HandleInner((TException _) => true);
}
public PredicateBuilder<TResult> HandleInner<[System.Runtime.CompilerServices.Nullable(0)] TException>(Func<TException, bool> predicate) where TException : Exception
{
Guard.NotNull<Func<TException, bool>>(predicate, "predicate");
return this.Add((Predicate<Outcome<TResult>>)delegate(Outcome<TResult> outcome) {
TException val = outcome.Exception?.InnerException as TException;
if (val != null)
return predicate(val);
return false;
});
}
public PredicateBuilder<TResult> HandleResult(Func<TResult, bool> predicate)
{
return Add(delegate(Outcome<TResult> outcome) {
if (outcome.TryGetResult(out TResult result))
return predicate(result);
return false;
});
}
public PredicateBuilder<TResult> HandleResult(TResult result, [System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1
})] IEqualityComparer<TResult> comparer = null)
{
if (comparer == null)
comparer = EqualityComparer<TResult>.Default;
return HandleResult((TResult r) => comparer.Equals(r, result));
}
[System.Runtime.CompilerServices.NullableContext(2)]
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
1,
0,
1,
1,
0
})]
internal Func<OutcomeArguments<TResult, TArgs>, ValueTask<bool>> CreatePredicate<TArgs>()
{
switch (this._predicates.Count) {
case 0:
throw new ValidationException("No predicates were configured. There must be at least one predicate added.");
case 1:
return CreatePredicate<TArgs>(this._predicates[0]);
default:
return CreatePredicate<TArgs>(this._predicates.ToArray());
}
}
[System.Runtime.CompilerServices.NullableContext(2)]
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
1,
0,
1,
1,
0
})]
private static Func<OutcomeArguments<TResult, TArgs>, ValueTask<bool>> CreatePredicate<TArgs>([System.Runtime.CompilerServices.Nullable(new byte[] {
1,
0,
1
})] Predicate<Outcome<TResult>> predicate)
{
return (OutcomeArguments<TResult, TArgs> args) => new ValueTask<bool>(predicate(args.Outcome));
}
[System.Runtime.CompilerServices.NullableContext(2)]
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
1,
0,
1,
1,
0
})]
private static Func<OutcomeArguments<TResult, TArgs>, ValueTask<bool>> CreatePredicate<TArgs>([System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
0,
1
})] Predicate<Outcome<TResult>>[] predicates)
{
return delegate(OutcomeArguments<TResult, TArgs> args) {
Predicate<Outcome<TResult>>[] array = predicates;
for (int i = 0; i < array.Length; i++) {
if (array[i](args.Outcome))
return new ValueTask<bool>(true);
}
return new ValueTask<bool>(false);
};
}
private PredicateBuilder<TResult> Add([System.Runtime.CompilerServices.Nullable(new byte[] {
1,
0,
1
})] Predicate<Outcome<TResult>> predicate)
{
_predicates.Add(predicate);
return this;
}
}
}