< Summary - Code Coverage

Information
Class: Plainquire.Filter.Abstractions.Range
Assembly: Plainquire.Filter.Abstractions
File(s): /home/runner/work/plainquire/plainquire/Plainquire.Filter/Plainquire.Filter.Abstractions/Models/Range.cs
Tag: 64_13932151703
Line coverage
100%
Covered lines: 1
Uncovered lines: 0
Coverable lines: 1
Total lines: 264
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage
100%
Covered methods: 1
Total methods: 1
Method coverage: 100%

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
Create(...)100%11100%

File(s)

/home/runner/work/plainquire/plainquire/Plainquire.Filter/Plainquire.Filter.Abstractions/Models/Range.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3
 4namespace Plainquire.Filter.Abstractions;
 5
 6/// <summary>
 7/// Represents a range of <typeparamref name="TType"/>.
 8/// </summary>
 9public class Range<TType> : IEquatable<Range<TType>>, IConvertible where TType : IComparable<TType>
 10{
 11    /// <summary>
 12    /// The start of range.
 13    /// </summary>
 14    public TType? Start { get; }
 15
 16    /// <summary>
 17    /// The end of range.
 18    /// </summary>
 19    public TType? End { get; }
 20
 21    /// <summary>
 22    /// Gets the distance between <see cref="Start"/> and <see cref="End"/>.
 23    /// </summary>
 24    /// <autogeneratedoc />
 25    public double Distance => ToDouble(End) - ToDouble(Start);
 26
 27    /// <summary>
 28    /// Initializes a new instance of the <see cref="Range{TType}"/> class.
 29    /// </summary>
 30    /// <param name="start">The start of range.</param>
 31    /// <param name="end">The end of range.</param>
 32    public Range(TType? start, TType? end)
 33    {
 34        Start = start;
 35        End = end;
 36    }
 37
 38    /// <inheritdoc />
 39    public override string ToString()
 40    {
 41        var start = ToString(Start);
 42        var end = ToString(End);
 43
 44        return $"{start}_{end}";
 45
 46        //if (start != null && end != null)
 47        //    return $"{start}_{end}";
 48        //if (start != null)
 49        //    return start;
 50        //if (end != null)
 51        //    return end;
 52        //return string.Empty;
 53    }
 54
 55    /// <inheritdoc />
 56    public override bool Equals(object? obj)
 57        => Equals(obj as Range<TType>);
 58
 59    /// <inheritdoc />
 60    public bool Equals(Range<TType>? other)
 61        => other != null && EqualityComparer<TType?>.Default.Equals(Start, other.Start) && EqualityComparer<TType?>.Defa
 62
 63    /// <inheritdoc />
 64    public override int GetHashCode()
 65        => HashCode.Combine(Start, End);
 66
 67    /// <summary>
 68    /// Indicates whether the <paramref name="val1"/> object is equal to <paramref name="val2"/> object.
 69    /// </summary>
 70    /// <param name="val1">The object to compare with <paramref name="val2"/>.</param>
 71    /// <param name="val2">The object to compare with <paramref name="val1"/>.</param>
 72    public static bool operator ==(Range<TType>? val1, Range<TType>? val2)
 73        => EqualityComparer<Range<TType>?>.Default.Equals(val1, val2);
 74
 75    /// <summary>
 76    /// Indicates whether the <paramref name="val1"/> object is not equal to <paramref name="val2"/> object.
 77    /// </summary>
 78    /// <param name="val1">The object to compare with <paramref name="val2"/>.</param>
 79    /// <param name="val2">The object to compare with <paramref name="val1"/>.</param>
 80    public static bool operator !=(Range<TType>? val1, Range<TType>? val2)
 81        => !(val1 == val2);
 82
 83    /// <summary>
 84    /// Indicates whether the range of <paramref name="val1"/> is lower than the range of <paramref name="val2"/> object
 85    /// </summary>
 86    /// <param name="val1">The object to compare with <paramref name="val2"/>.</param>
 87    /// <param name="val2">The object to compare with <paramref name="val1"/>.</param>
 88    public static bool operator <(Range<TType> val1, Range<TType> val2)
 89        => ((IConvertible)val1).ToDecimal(null) < ((IConvertible)val2).ToDecimal(null);
 90
 91    /// <summary>
 92    /// Indicates whether the range of <paramref name="val1"/> is greater than the range of <paramref name="val2"/> obje
 93    /// </summary>
 94    /// <param name="val1">The object to compare with <paramref name="val2"/>.</param>
 95    /// <param name="val2">The object to compare with <paramref name="val1"/>.</param>
 96    public static bool operator >(Range<TType> val1, Range<TType> val2)
 97        => ((IConvertible)val1).ToDecimal(null) > ((IConvertible)val2).ToDecimal(null);
 98
 99    /// <summary>
 100    /// Indicates whether the range of <paramref name="val1"/> is lower than or equal to the range of <paramref name="va
 101    /// </summary>
 102    /// <param name="val1">The object to compare with <paramref name="val2"/>.</param>
 103    /// <param name="val2">The object to compare with <paramref name="val1"/>.</param>
 104    public static bool operator <=(Range<TType> val1, Range<TType> val2)
 105        => ((IConvertible)val1).ToDecimal(null) <= ((IConvertible)val2).ToDecimal(null);
 106
 107    /// <summary>
 108    /// Indicates whether the range of <paramref name="val1"/> is greater than or equal to the range of <paramref name="
 109    /// </summary>
 110    /// <param name="val1">The object to compare with <paramref name="val2"/>.</param>
 111    /// <param name="val2">The object to compare with <paramref name="val1"/>.</param>
 112    public static bool operator >=(Range<TType> val1, Range<TType> val2)
 113        => ((IConvertible)val1).ToDecimal(null) >= ((IConvertible)val2).ToDecimal(null);
 114
 115    private static string? ToString(TType? value)
 116        => value switch
 117        {
 118            null => null,
 119            DateTime dateTime => dateTime.ToString("o"),
 120            DateTimeOffset dateTime => dateTime.ToString("o"),
 121            _ => value.ToString()
 122        };
 123
 124    private static double ToDouble(TType? val)
 125        => val switch
 126        {
 127            null => 0,
 128            DateTime dateTime => dateTime.Ticks,
 129            DateTimeOffset dateTime => dateTime.Ticks,
 130            IConvertible convertible => convertible.ToDouble(null),
 131            _ => throw new InvalidOperationException($"The type {typeof(TType).Name} is not convertible to {nameof(Doubl
 132        };
 133
 134    #region IConvertible
 135    TypeCode IConvertible.GetTypeCode()
 136        => TypeCode.Object;
 137
 138    bool IConvertible.ToBoolean(IFormatProvider? provider)
 139        => throw new InvalidCastException($"Invalid cast from {nameof(Range)} to {nameof(Boolean)}");
 140
 141    char IConvertible.ToChar(IFormatProvider? provider)
 142        => throw new InvalidCastException($"Invalid cast from {nameof(Range)} to {nameof(Char)}");
 143
 144    DateTime IConvertible.ToDateTime(IFormatProvider? provider)
 145        => throw new InvalidCastException($"Invalid cast from {nameof(Range)} to {nameof(DateTime)}");
 146
 147    string IConvertible.ToString(IFormatProvider? provider)
 148        => this.ToString();
 149
 150    object IConvertible.ToType(Type conversionType, IFormatProvider? provider)
 151    {
 152        try
 153        {
 154            return ((IConvertible)((IConvertible)this).ToDouble(provider)).ToType(conversionType, provider);
 155        }
 156        catch (OverflowException)
 157        {
 158            throw new OverflowException($"Range was too large for a {conversionType.Name}");
 159        }
 160    }
 161
 162    byte IConvertible.ToByte(IFormatProvider? provider)
 163    {
 164        var result = ToDouble(End) - ToDouble(Start);
 165        if (result <= byte.MaxValue)
 166            return (byte)result;
 167        throw new OverflowException($"Range was too large for a {nameof(Byte)}");
 168    }
 169
 170    decimal IConvertible.ToDecimal(IFormatProvider? provider)
 171    {
 172        try
 173        {
 174            return Convert.ToDecimal(ToDouble(End) - ToDouble(Start));
 175        }
 176        catch (OverflowException)
 177        {
 178            throw new OverflowException($"Range was too large for a {nameof(Decimal)}");
 179        }
 180    }
 181
 182    double IConvertible.ToDouble(IFormatProvider? provider)
 183        => ToDouble(End) - ToDouble(Start);
 184
 185    short IConvertible.ToInt16(IFormatProvider? provider)
 186    {
 187        var result = ToDouble(End) - ToDouble(Start);
 188        if (result <= short.MaxValue)
 189            return (short)result;
 190        throw new OverflowException($"Range was too large for a {nameof(Int16)}");
 191    }
 192
 193    int IConvertible.ToInt32(IFormatProvider? provider)
 194    {
 195        var result = ToDouble(End) - ToDouble(Start);
 196        if (result <= int.MaxValue)
 197            return (int)result;
 198        throw new OverflowException($"Range was too large for a {nameof(Int32)}");
 199    }
 200
 201    long IConvertible.ToInt64(IFormatProvider? provider)
 202    {
 203        var result = ToDouble(End) - ToDouble(Start);
 204        if (result <= long.MaxValue)
 205            return (long)result;
 206        throw new OverflowException($"Range was too large for a {nameof(Int64)}");
 207    }
 208
 209    sbyte IConvertible.ToSByte(IFormatProvider? provider)
 210    {
 211        var result = ToDouble(End) - ToDouble(Start);
 212        if (result <= sbyte.MaxValue)
 213            return (sbyte)result;
 214        throw new OverflowException($"Range was too large for a {nameof(SByte)}");
 215    }
 216
 217    float IConvertible.ToSingle(IFormatProvider? provider)
 218    {
 219        var result = ToDouble(End) - ToDouble(Start);
 220        if (result < float.MaxValue)
 221            return (float)result;
 222        throw new OverflowException($"Range was too large for a {nameof(Single)}");
 223    }
 224
 225    ushort IConvertible.ToUInt16(IFormatProvider? provider)
 226    {
 227        var result = ToDouble(End) - ToDouble(Start);
 228        if (result <= ushort.MaxValue)
 229            return (ushort)result;
 230        throw new OverflowException($"Range was too large for a {nameof(UInt16)}");
 231    }
 232
 233    uint IConvertible.ToUInt32(IFormatProvider? provider)
 234    {
 235        var result = ToDouble(End) - ToDouble(Start);
 236        if (result <= uint.MaxValue)
 237            return (uint)result;
 238        throw new OverflowException($"Range was too large for a {nameof(UInt32)}");
 239    }
 240
 241    ulong IConvertible.ToUInt64(IFormatProvider? provider)
 242    {
 243        var result = ToDouble(End) - ToDouble(Start);
 244        if (result <= ulong.MaxValue)
 245            return (ulong)result;
 246        throw new OverflowException($"Range was too large for a {nameof(UInt64)}");
 247    }
 248    #endregion
 249}
 250
 251/// <summary>
 252/// Utility class to create a <see cref="Range{TType}"/>.
 253/// </summary>
 254public static class Range
 255{
 256    /// <summary>
 257    /// Creates a <see cref="Range{TType}"/>.
 258    /// </summary>
 259    /// <typeparam name="TType">The type of the values represented by range.</typeparam>
 260    /// <param name="start">The start of range.</param>
 261    /// <param name="end">The end of range.</param>
 262    public static Range<TType> Create<TType>(TType? start, TType? end) where TType : IComparable<TType>
 6263        => new(start, end);
 264}

Methods/Properties

Create(TType,TType)