< 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: 84
Uncovered lines: 1
Coverable lines: 85
Total lines: 237
Line coverage: 98.8%
Branch coverage
84%
Covered branches: 37
Total branches: 44
Branch coverage: 84%
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_IsSuccess()100%11100%
get_ShouldRetry()100%88100%
get_IsTerminal()100%44100%
get_HasMetadata()100%11100%
Pending(...)100%11100%
Delivered(...)100%11100%
Deferred(...)100%44100%
Failed(...)50%22100%
RetryableFailure(...)50%22100%
DeadLettered(...)50%22100%
DeliveredFromNormalizedMetadata(...)50%22100%
NormalizeOptional(...)100%22100%
NormalizeMetadata(...)85.71%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{
 310    private static readonly IReadOnlyDictionary<string, string> EmptyMetadata =
 311        new ReadOnlyDictionary<string, string>(
 312            new Dictionary<string, string>(StringComparer.Ordinal));
 13
 25514    private GovernanceEmissionResult(
 25515        GovernanceEmissionStatus status,
 25516        string? providerName,
 25517        string? providerRecordId,
 25518        DateTimeOffset? retryAfterUtc,
 25519        GovernanceEmissionError? error,
 25520        IReadOnlyDictionary<string, string> metadata)
 21    {
 25522        if (!Enum.IsDefined(status))
 23        {
 024            throw new ArgumentOutOfRangeException(nameof(status), status, "Emission status must be defined.");
 25        }
 26
 25527        Status = status;
 25528        ProviderName = NormalizeOptional(providerName);
 25529        ProviderRecordId = NormalizeOptional(providerRecordId);
 25530        RetryAfterUtc = retryAfterUtc?.ToUniversalTime();
 25531        Error = error;
 25532        Metadata = metadata;
 25533    }
 34
 35    /// <summary>
 36    /// Gets the provider-neutral result status.
 37    /// </summary>
 38    public GovernanceEmissionStatus Status { get; }
 39
 40    /// <summary>
 41    /// Gets the provider name that handled or attempted the emission, when available.
 42    /// </summary>
 43    public string? ProviderName { get; }
 44
 45    /// <summary>
 46    /// Gets the provider-side record identifier, when one is returned and safe to keep.
 47    /// </summary>
 48    public string? ProviderRecordId { get; }
 49
 50    /// <summary>
 51    /// Gets the UTC retry timestamp for deferred or retryable outcomes, when supplied.
 52    /// </summary>
 53    public DateTimeOffset? RetryAfterUtc { get; }
 54
 55    /// <summary>
 56    /// Gets provider-neutral error information, when the emission did not deliver successfully.
 57    /// </summary>
 58    public GovernanceEmissionError? Error { get; }
 59
 60    /// <summary>
 61    /// Gets minimized provider-neutral result metadata.
 62    /// </summary>
 63    public IReadOnlyDictionary<string, string> Metadata { get; }
 64
 65    /// <summary>
 66    /// Gets a value indicating whether the emission was delivered successfully.
 67    /// </summary>
 24568    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>
 1773    public bool ShouldRetry => Status is GovernanceEmissionStatus.Deferred or GovernanceEmissionStatus.RetryableFailure
 1774        || Error?.IsRetryable == true;
 75
 76    /// <summary>
 77    /// Gets a value indicating whether the result is terminal and should not be retried automatically.
 78    /// </summary>
 1179    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>
 684    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    {
 993        return new GovernanceEmissionResult(
 994            GovernanceEmissionStatus.Pending,
 995            providerName,
 996            providerRecordId: null,
 997            retryAfterUtc: null,
 998            error: null,
 999            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    {
 188110        return DeliveredFromNormalizedMetadata(
 188111            providerName,
 188112            providerRecordId,
 188113            NormalizeMetadata(metadata));
 114    }
 115
 116    /// <summary>
 117    /// Creates a deferred emission result.
 118    /// </summary>
 119    public static GovernanceEmissionResult Deferred(
 120        GovernanceEmissionError? error = null,
 121        DateTimeOffset? retryAfterUtc = null,
 122        string? providerName = null,
 123        IReadOnlyDictionary<string, string>? metadata = null)
 124    {
 9125        return new GovernanceEmissionResult(
 9126            GovernanceEmissionStatus.Deferred,
 9127            providerName ?? error?.ProviderName,
 9128            providerRecordId: null,
 9129            retryAfterUtc,
 9130            error,
 9131            NormalizeMetadata(metadata));
 132    }
 133
 134    /// <summary>
 135    /// Creates a failed emission result.
 136    /// </summary>
 137    public static GovernanceEmissionResult Failed(
 138        GovernanceEmissionError error,
 139        string? providerName = null,
 140        IReadOnlyDictionary<string, string>? metadata = null)
 141    {
 34142        ArgumentNullException.ThrowIfNull(error);
 143
 32144        return new GovernanceEmissionResult(
 32145            GovernanceEmissionStatus.Failed,
 32146            providerName ?? error.ProviderName,
 32147            providerRecordId: null,
 32148            retryAfterUtc: null,
 32149            error,
 32150            NormalizeMetadata(metadata));
 151    }
 152
 153    /// <summary>
 154    /// Creates a retryable failure emission result.
 155    /// </summary>
 156    public static GovernanceEmissionResult RetryableFailure(
 157        GovernanceEmissionError error,
 158        DateTimeOffset? retryAfterUtc = null,
 159        string? providerName = null,
 160        IReadOnlyDictionary<string, string>? metadata = null)
 161    {
 10162        ArgumentNullException.ThrowIfNull(error);
 163
 8164        return new GovernanceEmissionResult(
 8165            GovernanceEmissionStatus.RetryableFailure,
 8166            providerName ?? error.ProviderName,
 8167            providerRecordId: null,
 8168            retryAfterUtc,
 8169            error,
 8170            NormalizeMetadata(metadata));
 171    }
 172
 173    /// <summary>
 174    /// Creates a dead-letter emission result.
 175    /// </summary>
 176    public static GovernanceEmissionResult DeadLettered(
 177        GovernanceEmissionError error,
 178        string? providerName = null,
 179        IReadOnlyDictionary<string, string>? metadata = null)
 180    {
 9181        ArgumentNullException.ThrowIfNull(error);
 182
 7183        return new GovernanceEmissionResult(
 7184            GovernanceEmissionStatus.DeadLettered,
 7185            providerName ?? error.ProviderName,
 7186            providerRecordId: null,
 7187            retryAfterUtc: null,
 7188            error,
 7189            NormalizeMetadata(metadata));
 190    }
 191
 192    internal static GovernanceEmissionResult DeliveredFromNormalizedMetadata(
 193        string? providerName = null,
 194        string? providerRecordId = null,
 195        IReadOnlyDictionary<string, string>? normalizedMetadata = null)
 196    {
 190197        return new GovernanceEmissionResult(
 190198            GovernanceEmissionStatus.Delivered,
 190199            providerName,
 190200            providerRecordId,
 190201            retryAfterUtc: null,
 190202            error: null,
 190203            normalizedMetadata ?? EmptyMetadata);
 204    }
 205
 206    private static string? NormalizeOptional(string? value)
 207    {
 510208        return string.IsNullOrWhiteSpace(value)
 510209            ? null
 510210            : value.Trim();
 211    }
 212
 213    private static IReadOnlyDictionary<string, string> NormalizeMetadata(
 214        IReadOnlyDictionary<string, string>? metadata)
 215    {
 253216        if (metadata is null || metadata.Count == 0)
 217        {
 227218            return EmptyMetadata;
 219        }
 220
 26221        Dictionary<string, string> normalizedMetadata = new(metadata.Count, StringComparer.Ordinal);
 222
 200223        foreach (KeyValuePair<string, string> item in metadata)
 224        {
 74225            if (string.IsNullOrWhiteSpace(item.Key))
 226            {
 227                continue;
 228            }
 229
 69230            normalizedMetadata[item.Key.Trim()] = item.Value?.Trim() ?? string.Empty;
 231        }
 232
 26233        return normalizedMetadata.Count == 0
 26234            ? EmptyMetadata
 26235            : new ReadOnlyDictionary<string, string>(normalizedMetadata);
 236    }
 237}

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_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>)
DeliveredFromNormalizedMetadata(System.String,System.String,System.Collections.Generic.IReadOnlyDictionary`2<System.String,System.String>)
NormalizeOptional(System.String)
NormalizeMetadata(System.Collections.Generic.IReadOnlyDictionary`2<System.String,System.String>)