< Summary

Information
Class: AsiBackbone.Core.Results.OperationReason
Assembly: AsiBackbone.Core
File(s): /home/runner/work/AsiBackbone/AsiBackbone/src/AsiBackbone.Core/Results/OperationReason.cs
Line coverage
100%
Covered lines: 30
Uncovered lines: 0
Coverable lines: 30
Total lines: 113
Line coverage: 100%
Branch coverage
100%
Covered branches: 14
Total branches: 14
Branch coverage: 100%
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(...)100%11100%
.ctor(...)100%11100%
get_Code()100%11100%
get_Message()100%11100%
get_Metadata()100%11100%
get_HasMetadata()100%11100%
Create(...)100%11100%
Create(...)100%11100%
NormalizeMetadata(...)100%1414100%

File(s)

/home/runner/work/AsiBackbone/AsiBackbone/src/AsiBackbone.Core/Results/OperationReason.cs

#LineLine coverage
 1using System.Collections.ObjectModel;
 2
 3namespace AsiBackbone.Core.Results;
 4
 5/// <summary>
 6/// Represents a machine-readable reason associated with an operation result.
 7/// </summary>
 8public sealed class OperationReason
 9{
 610    private static readonly IReadOnlyDictionary<string, string> EmptyMetadata =
 611        new ReadOnlyDictionary<string, string>(
 612            new Dictionary<string, string>(StringComparer.Ordinal));
 13
 14    /// <summary>
 15    /// Initializes a new instance of the <see cref="OperationReason"/> class.
 16    /// </summary>
 17    /// <param name="code">The machine-readable reason code.</param>
 18    /// <param name="message">The human-readable reason message.</param>
 19    public OperationReason(string code, string message)
 24520        : this(code, message, null)
 21    {
 23922    }
 23
 24    /// <summary>
 25    /// Initializes a new instance of the <see cref="OperationReason"/> class.
 26    /// </summary>
 27    /// <param name="code">The machine-readable reason code.</param>
 28    /// <param name="message">The human-readable reason message.</param>
 29    /// <param name="metadata">Optional metadata associated with the reason.</param>
 28330    public OperationReason(
 28331        string code,
 28332        string message,
 28333        IReadOnlyDictionary<string, string>? metadata)
 34    {
 28335        ArgumentException.ThrowIfNullOrWhiteSpace(code);
 28036        ArgumentException.ThrowIfNullOrWhiteSpace(message);
 37
 27738        Code = code.Trim();
 27739        Message = message.Trim();
 27740        Metadata = NormalizeMetadata(metadata);
 27741    }
 42
 43    /// <summary>
 44    /// Gets the machine-readable reason code.
 45    /// </summary>
 35946    public string Code { get; }
 47
 48    /// <summary>
 49    /// Gets the human-readable reason message.
 50    /// </summary>
 11651    public string Message { get; }
 52
 53    /// <summary>
 54    /// Gets optional metadata associated with the reason.
 55    /// </summary>
 6456    public IReadOnlyDictionary<string, string> Metadata { get; }
 57
 58    /// <summary>
 59    /// Gets a value indicating whether this reason has metadata.
 60    /// </summary>
 861    public bool HasMetadata => Metadata.Count > 0;
 62
 63    /// <summary>
 64    /// Creates an operation reason.
 65    /// </summary>
 66    /// <param name="code">The machine-readable reason code.</param>
 67    /// <param name="message">The human-readable reason message.</param>
 68    /// <returns>An operation reason.</returns>
 69    public static OperationReason Create(string code, string message)
 70    {
 24571        return new OperationReason(code, message);
 72    }
 73
 74    /// <summary>
 75    /// Creates an operation reason with metadata.
 76    /// </summary>
 77    /// <param name="code">The machine-readable reason code.</param>
 78    /// <param name="message">The human-readable reason message.</param>
 79    /// <param name="metadata">Optional metadata associated with the reason.</param>
 80    /// <returns>An operation reason.</returns>
 81    public static OperationReason Create(
 82        string code,
 83        string message,
 84        IReadOnlyDictionary<string, string> metadata)
 85    {
 3786        return new OperationReason(code, message, metadata);
 87    }
 88
 89    private static IReadOnlyDictionary<string, string> NormalizeMetadata(
 90        IReadOnlyDictionary<string, string>? metadata)
 91    {
 27792        if (metadata is null || metadata.Count == 0)
 93        {
 24194            return EmptyMetadata;
 95        }
 96
 3697        Dictionary<string, string> normalizedMetadata = new(StringComparer.Ordinal);
 98
 28699        foreach (KeyValuePair<string, string> item in metadata)
 100        {
 107101            if (string.IsNullOrWhiteSpace(item.Key))
 102            {
 103                continue;
 104            }
 105
 104106            normalizedMetadata[item.Key.Trim()] = item.Value?.Trim() ?? string.Empty;
 107        }
 108
 36109        return normalizedMetadata.Count == 0
 36110            ? EmptyMetadata
 36111            : new ReadOnlyDictionary<string, string>(normalizedMetadata);
 112    }
 113}