< Summary

Information
Class: AsiBackbone.Core.Emissions.GovernanceEmissionResult
Assembly: AsiBackbone.Core
File(s): /home/runner/work/AsiBackbone/AsiBackbone/src/AsiBackbone.Core/Emissions/GovernanceEmissionResult.cs
Line coverage
98%
Covered lines: 86
Uncovered lines: 1
Coverable lines: 87
Total lines: 226
Line coverage: 98.8%
Branch coverage
78%
Covered branches: 33
Total branches: 42
Branch coverage: 78.5%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%11100%
.ctor(...)75%4493.75%
get_Status()100%11100%
get_ProviderName()100%11100%
get_ProviderRecordId()100%11100%
get_RetryAfterUtc()100%11100%
get_Error()100%11100%
get_Metadata()100%11100%
get_IsSuccess()100%11100%
get_ShouldRetry()100%88100%
get_IsTerminal()100%44100%
get_HasMetadata()100%11100%
Pending(...)100%11100%
Delivered(...)100%11100%
Deferred(...)50%44100%
Failed(...)50%22100%
RetryableFailure(...)50%22100%
DeadLettered(...)50%22100%
NormalizeOptional(...)100%22100%
NormalizeMetadata(...)78.57%1414100%

File(s)

/home/runner/work/AsiBackbone/AsiBackbone/src/AsiBackbone.Core/Emissions/GovernanceEmissionResult.cs

#LineLine coverage
 1using System.Collections.ObjectModel;
 2
 3namespace AsiBackbone.Core.Emissions;
 4
 5/// <summary>
 6/// Represents the provider-neutral result of a governance emission attempt.
 7/// </summary>
 8public sealed class GovernanceEmissionResult
 9{
 510    private static readonly IReadOnlyDictionary<string, string> EmptyMetadata =
 511        new ReadOnlyDictionary<string, string>(
 512            new Dictionary<string, string>(StringComparer.Ordinal));
 13
 4914    private GovernanceEmissionResult(
 4915        GovernanceEmissionStatus status,
 4916        string? providerName,
 4917        string? providerRecordId,
 4918        DateTimeOffset? retryAfterUtc,
 4919        GovernanceEmissionError? error,
 4920        IReadOnlyDictionary<string, string> metadata)
 21    {
 4922        if (!Enum.IsDefined(status))
 23        {
 024            throw new ArgumentOutOfRangeException(nameof(status), status, "Emission status must be defined.");
 25        }
 26
 4927        Status = status;
 4928        ProviderName = NormalizeOptional(providerName);
 4929        ProviderRecordId = NormalizeOptional(providerRecordId);
 4930        RetryAfterUtc = retryAfterUtc?.ToUniversalTime();
 4931        Error = error;
 4932        Metadata = metadata;
 4933    }
 34
 35    /// <summary>
 36    /// Gets the provider-neutral result status.
 37    /// </summary>
 9638    public GovernanceEmissionStatus Status { get; }
 39
 40    /// <summary>
 41    /// Gets the provider name that handled or attempted the emission, when available.
 42    /// </summary>
 3143    public string? ProviderName { get; }
 44
 45    /// <summary>
 46    /// Gets the provider-side record identifier, when one is returned and safe to keep.
 47    /// </summary>
 2448    public string? ProviderRecordId { get; }
 49
 50    /// <summary>
 51    /// Gets the UTC retry timestamp for deferred or retryable outcomes, when supplied.
 52    /// </summary>
 1253    public DateTimeOffset? RetryAfterUtc { get; }
 54
 55    /// <summary>
 56    /// Gets provider-neutral error information, when the emission did not deliver successfully.
 57    /// </summary>
 1858    public GovernanceEmissionError? Error { get; }
 59
 60    /// <summary>
 61    /// Gets minimized provider-neutral result metadata.
 62    /// </summary>
 2563    public IReadOnlyDictionary<string, string> Metadata { get; }
 64
 65    /// <summary>
 66    /// Gets a value indicating whether the emission was delivered successfully.
 67    /// </summary>
 5268    public bool IsSuccess => Status is GovernanceEmissionStatus.Delivered;
 69
 70    /// <summary>
 71    /// Gets a value indicating whether the emission should be retried according to provider-neutral status or error met
 72    /// </summary>
 773    public bool ShouldRetry => Status is GovernanceEmissionStatus.Deferred or GovernanceEmissionStatus.RetryableFailure
 774        || Error?.IsRetryable == true;
 75
 76    /// <summary>
 77    /// Gets a value indicating whether the result is terminal and should not be retried automatically.
 78    /// </summary>
 379    public bool IsTerminal => Status is GovernanceEmissionStatus.Delivered or GovernanceEmissionStatus.DeadLettered;
 80
 81    /// <summary>
 82    /// Gets a value indicating whether result metadata is present.
 83    /// </summary>
 284    public bool HasMetadata => Metadata.Count > 0;
 85
 86    /// <summary>
 87    /// Creates a pending emission result.
 88    /// </summary>
 89    public static GovernanceEmissionResult Pending(
 90        string? providerName = null,
 91        IReadOnlyDictionary<string, string>? metadata = null)
 92    {
 393        return new GovernanceEmissionResult(
 394            GovernanceEmissionStatus.Pending,
 395            providerName,
 396            providerRecordId: null,
 397            retryAfterUtc: null,
 398            error: null,
 399            NormalizeMetadata(metadata));
 100    }
 101
 102    /// <summary>
 103    /// Creates a delivered emission result.
 104    /// </summary>
 105    public static GovernanceEmissionResult Delivered(
 106        string? providerName = null,
 107        string? providerRecordId = null,
 108        IReadOnlyDictionary<string, string>? metadata = null)
 109    {
 29110        return new GovernanceEmissionResult(
 29111            GovernanceEmissionStatus.Delivered,
 29112            providerName,
 29113            providerRecordId,
 29114            retryAfterUtc: null,
 29115            error: null,
 29116            NormalizeMetadata(metadata));
 117    }
 118
 119    /// <summary>
 120    /// Creates a deferred emission result.
 121    /// </summary>
 122    public static GovernanceEmissionResult Deferred(
 123        GovernanceEmissionError? error = null,
 124        DateTimeOffset? retryAfterUtc = null,
 125        string? providerName = null,
 126        IReadOnlyDictionary<string, string>? metadata = null)
 127    {
 2128        return new GovernanceEmissionResult(
 2129            GovernanceEmissionStatus.Deferred,
 2130            providerName ?? error?.ProviderName,
 2131            providerRecordId: null,
 2132            retryAfterUtc,
 2133            error,
 2134            NormalizeMetadata(metadata));
 135    }
 136
 137    /// <summary>
 138    /// Creates a failed emission result.
 139    /// </summary>
 140    public static GovernanceEmissionResult Failed(
 141        GovernanceEmissionError error,
 142        string? providerName = null,
 143        IReadOnlyDictionary<string, string>? metadata = null)
 144    {
 1145        ArgumentNullException.ThrowIfNull(error);
 146
 1147        return new GovernanceEmissionResult(
 1148            GovernanceEmissionStatus.Failed,
 1149            providerName ?? error.ProviderName,
 1150            providerRecordId: null,
 1151            retryAfterUtc: null,
 1152            error,
 1153            NormalizeMetadata(metadata));
 154    }
 155
 156    /// <summary>
 157    /// Creates a retryable failure emission result.
 158    /// </summary>
 159    public static GovernanceEmissionResult RetryableFailure(
 160        GovernanceEmissionError error,
 161        DateTimeOffset? retryAfterUtc = null,
 162        string? providerName = null,
 163        IReadOnlyDictionary<string, string>? metadata = null)
 164    {
 12165        ArgumentNullException.ThrowIfNull(error);
 166
 12167        return new GovernanceEmissionResult(
 12168            GovernanceEmissionStatus.RetryableFailure,
 12169            providerName ?? error.ProviderName,
 12170            providerRecordId: null,
 12171            retryAfterUtc,
 12172            error,
 12173            NormalizeMetadata(metadata));
 174    }
 175
 176    /// <summary>
 177    /// Creates a dead-letter emission result.
 178    /// </summary>
 179    public static GovernanceEmissionResult DeadLettered(
 180        GovernanceEmissionError error,
 181        string? providerName = null,
 182        IReadOnlyDictionary<string, string>? metadata = null)
 183    {
 2184        ArgumentNullException.ThrowIfNull(error);
 185
 2186        return new GovernanceEmissionResult(
 2187            GovernanceEmissionStatus.DeadLettered,
 2188            providerName ?? error.ProviderName,
 2189            providerRecordId: null,
 2190            retryAfterUtc: null,
 2191            error,
 2192            NormalizeMetadata(metadata));
 193    }
 194
 195    private static string? NormalizeOptional(string? value)
 196    {
 98197        return string.IsNullOrWhiteSpace(value)
 98198            ? null
 98199            : value.Trim();
 200    }
 201
 202    private static IReadOnlyDictionary<string, string> NormalizeMetadata(
 203        IReadOnlyDictionary<string, string>? metadata)
 204    {
 49205        if (metadata is null || metadata.Count == 0)
 206        {
 33207            return EmptyMetadata;
 208        }
 209
 16210        Dictionary<string, string> normalizedMetadata = new(StringComparer.Ordinal);
 211
 112212        foreach (KeyValuePair<string, string> item in metadata)
 213        {
 40214            if (string.IsNullOrWhiteSpace(item.Key))
 215            {
 216                continue;
 217            }
 218
 39219            normalizedMetadata[item.Key.Trim()] = item.Value?.Trim() ?? string.Empty;
 220        }
 221
 16222        return normalizedMetadata.Count == 0
 16223            ? EmptyMetadata
 16224            : new ReadOnlyDictionary<string, string>(normalizedMetadata);
 225    }
 226}

Methods/Properties

.cctor()
.ctor(AsiBackbone.Core.Emissions.GovernanceEmissionStatus,System.String,System.String,System.Nullable`1<System.DateTimeOffset>,AsiBackbone.Core.Emissions.GovernanceEmissionError,System.Collections.Generic.IReadOnlyDictionary`2<System.String,System.String>)
get_Status()
get_ProviderName()
get_ProviderRecordId()
get_RetryAfterUtc()
get_Error()
get_Metadata()
get_IsSuccess()
get_ShouldRetry()
get_IsTerminal()
get_HasMetadata()
Pending(System.String,System.Collections.Generic.IReadOnlyDictionary`2<System.String,System.String>)
Delivered(System.String,System.String,System.Collections.Generic.IReadOnlyDictionary`2<System.String,System.String>)
Deferred(AsiBackbone.Core.Emissions.GovernanceEmissionError,System.Nullable`1<System.DateTimeOffset>,System.String,System.Collections.Generic.IReadOnlyDictionary`2<System.String,System.String>)
Failed(AsiBackbone.Core.Emissions.GovernanceEmissionError,System.String,System.Collections.Generic.IReadOnlyDictionary`2<System.String,System.String>)
RetryableFailure(AsiBackbone.Core.Emissions.GovernanceEmissionError,System.Nullable`1<System.DateTimeOffset>,System.String,System.Collections.Generic.IReadOnlyDictionary`2<System.String,System.String>)
DeadLettered(AsiBackbone.Core.Emissions.GovernanceEmissionError,System.String,System.Collections.Generic.IReadOnlyDictionary`2<System.String,System.String>)
NormalizeOptional(System.String)
NormalizeMetadata(System.Collections.Generic.IReadOnlyDictionary`2<System.String,System.String>)