< Summary

Information
Class: MyNet.Primitives.ComparableExtensions
Assembly: MyNet.Primitives
File(s): https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.Primitives/Extensions/ComparableExtensions.cs
Tag: 323_28699572109
Line coverage
100%
Covered lines: 57
Uncovered lines: 0
Coverable lines: 57
Total lines: 189
Line coverage: 100%
Branch coverage
93%
Covered branches: 59
Total branches: 63
Branch coverage: 93.6%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
Compare(...)100%1111100%
Compare(...)94.11%1717100%
Compare(...)90.9%1111100%
IsBetween(...)100%22100%
Max(...)75%44100%
Min(...)100%44100%
MinMax(...)75%44100%
MinMax(...)100%22100%
SafeClamp(...)100%66100%
CompareNullableTo(...)100%11100%
CompareNullableTo(...)100%11100%
InRange(...)100%22100%

File(s)

https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.Primitives/Extensions/ComparableExtensions.cs

#LineLine coverage
 1// -----------------------------------------------------------------------
 2// <copyright file="ComparableExtensions.cs" company="Stéphane ANDRE">
 3// Copyright (c) Stéphane ANDRE. All rights reserved.
 4// </copyright>
 5// -----------------------------------------------------------------------
 6
 7using System;
 8using MyNet.Primitives.Comparers;
 9using MyNet.Primitives.Intervals;
 10
 11#pragma warning disable IDE0130 // Namespace does not match folder structure
 12namespace MyNet.Primitives;
 13#pragma warning restore IDE0130 // Namespace does not match folder structure
 14
 15/// <summary>
 16/// Extension methods to compare values using custom comparison operators.
 17/// </summary>
 18public static class ComparableExtensions
 19{
 20    extension(IComparable? x)
 21    {
 22        /// <summary>
 23        /// Compares two IComparable values using the supplied operator.
 24        /// </summary>
 25        public bool Compare(IComparable? y, ComparableOperator sign)
 26        {
 3927            if (x == null || y == null)
 628                return false;
 29
 3330            var compare = x.CompareTo(y);
 31
 3332            return sign switch
 3333            {
 634                ComparableOperator.EqualsTo => compare == 0,
 635                ComparableOperator.NotEqualsTo => compare != 0,
 636                ComparableOperator.LessThan => compare < 0,
 637                ComparableOperator.GreaterThan => compare > 0,
 338                ComparableOperator.LessEqualThan => compare <= 0,
 339                ComparableOperator.GreaterEqualThan => compare >= 0,
 340                _ => throw new ArgumentException(null, nameof(sign))
 3341            };
 42        }
 43
 44        /// <summary>
 45        /// Compares a value against a range using a complex operator.
 46        /// </summary>
 47        public bool Compare(IComparable? from, IComparable? to, ComplexComparableOperator sign)
 48        {
 3649            if (x == null || from == null || to == null)
 950                return false;
 51
 2752            var compareFrom = x.CompareTo(from);
 2753            var compareTo = x.CompareTo(to);
 54
 2755            var result = compareFrom >= 0 && compareTo <= 0;
 56
 2757            return sign switch
 2758            {
 359                ComplexComparableOperator.IsBetween => result,
 360                ComplexComparableOperator.IsNotBetween => !result,
 361                ComplexComparableOperator.EqualsTo => compareFrom == 0,
 362                ComplexComparableOperator.NotEqualsTo => compareFrom != 0,
 363                ComplexComparableOperator.LessThan => compareTo < 0,
 364                ComplexComparableOperator.GreaterThan => compareFrom > 0,
 365                ComplexComparableOperator.LessEqualThan => compareTo <= 0,
 366                ComplexComparableOperator.GreaterEqualThan => compareFrom >= 0,
 367                _ => throw new ArgumentException(null, nameof(sign))
 2768            };
 69        }
 70    }
 71
 72    /// <summary>
 73    /// Compares a generic comparable against a range using a complex operator.
 74    /// </summary>
 75    public static bool Compare<T>(this IComparable<T> x, T? from, T? to, ComplexComparableOperator sign)
 76        where T : struct, IComparable<T>
 77    {
 2778        var compareFrom = x.CompareNullableTo(from);
 2779        var compareTo = x.CompareNullableTo(to);
 80
 2781        var result = compareFrom >= 0 && compareTo <= 0;
 82
 2783        return sign switch
 2784        {
 385            ComplexComparableOperator.IsBetween => result,
 386            ComplexComparableOperator.IsNotBetween => !result,
 387            ComplexComparableOperator.EqualsTo => compareFrom == 0,
 388            ComplexComparableOperator.NotEqualsTo => compareFrom != 0,
 389            ComplexComparableOperator.LessThan => compareTo < 0,
 390            ComplexComparableOperator.GreaterThan => compareFrom > 0,
 391            ComplexComparableOperator.LessEqualThan => compareTo <= 0,
 392            ComplexComparableOperator.GreaterEqualThan => compareFrom >= 0,
 393            _ => throw new ArgumentException(null, nameof(sign))
 2794        };
 95    }
 96
 97    extension<T>(IComparable<T>? value)
 98        where T : struct, IComparable<T>
 99    {
 100        /// <summary>
 101        /// Determines if the current value is between two other values, handling nulls safely. The range is exclusive, 
 102        /// </summary>
 103        /// <param name="from">The lower bound value.</param>
 104        /// <param name="to">The upper bound value.</param>
 105        /// <returns><c>true</c> if the current value is between the specified values; otherwise, <c>false</c>.</returns
 12106        public bool IsBetween(T? from, T? to) => value is T t && new Interval<T>(from, to, false).Contains(t);
 107
 108        /// <summary>
 109        /// Returns the maximum of two IComparable values.
 110        /// </summary>
 111        /// <param name="other">The value to compare with.</param>
 112        /// <returns>The maximum of the two values.</returns>
 15113        public T Max(T other) => value is T t && t.CompareTo(other) > 0 ? t : other;
 114
 115        /// <summary>
 116        /// Returns the minimum of two IComparable values.
 117        /// </summary>
 118        /// <param name="other">The value to compare with.</param>
 119        /// <returns>The minimum of the two values.</returns>
 15120        public T Min(T other) => value is T t && t.CompareTo(other) < 0 ? t : other;
 121
 122        /// <summary>
 123        /// Returns a MinMax struct containing the minimum and maximum of the current value and another value. The metho
 124        /// </summary>
 125        /// <param name="other">The value to compare with.</param>
 126        /// <returns>A MinMax struct containing the minimum and maximum values.</returns>
 127        /// <exception cref="InvalidCastException">Thrown if the current value is null or not of type T.</exception>
 60128        public MinMax<T> MinMax(T other) => value is T t ? (t.CompareTo(other) >= 0 ? new(other, t) : new(t, other)) : t
 129
 130        /// <summary>
 131        /// Returns a MinMax struct containing the minimum and maximum of the current value and another value. The metho
 132        /// </summary>
 133        /// <param name="other">The value to compare with.</param>
 134        /// <returns>A MinMax struct containing the minimum and maximum values.</returns>
 135        /// <exception cref="InvalidCastException">Thrown if the current value is null or not of type T.</exception>
 75136        public OptionalMinMax<T> MinMax(T? other) => new NullableComparer<T>().Compare(value, other) >= 0 ? new(other, v
 137
 138        /// <summary>
 139        ///     Clamps a value between a minimum and maximum value.
 140        /// </summary>
 141        /// <param name="min"> The minimum value. </param>
 142        /// <param name="max"> The maximum value. </param>
 143        public T SafeClamp(T min, T max)
 144        {
 54145            var minMax = min.MinMax(max);
 146
 54147            return value is not T t
 54148                ? throw new InvalidCastException()
 54149                : t.CompareTo(minMax.Min) < 0 ? minMax.Min : t.CompareTo(minMax.Max) > 0 ? minMax.Max : t;
 150        }
 151
 152        /// <summary>
 153        /// Safely compares a nullable comparable to a value.
 154        /// </summary>
 12155        public int CompareNullableTo(T other) => new NullableComparer<T>().Compare(value, other);
 156
 157        /// <summary>
 158        /// Safely compares a nullable comparable to a nullable value.
 159        /// </summary>
 69160        public int CompareNullableTo(T? other) => new NullableComparer<T>().Compare(value, other);
 161
 162        /// <summary>
 163        /// Determines if the current value is in a range defined by two other values, handling nulls safely. The range 
 164        /// </summary>
 165        /// <param name="from">The lower bound value.</param>
 166        /// <param name="to">The upper bound value.</param>
 167        /// <returns><c>true</c> if the current value is in the specified range; otherwise, <c>false</c>.</returns>
 24168        public bool InRange(T? from, T? to) => value is T t && new Interval<T>(from, to).Contains(t);
 169    }
 170}
 171
 172/// <summary>
 173/// Represents a minimum and maximum value of a comparable type. This struct is immutable and provides a convenient way 
 174/// </summary>
 175/// <param name="Min">The minimum value.</param>
 176/// <param name="Max">The maximum value.</param>
 177/// <typeparam name="T">The type of the comparable values.</typeparam>
 178public readonly record struct MinMax<T>(T Min, T Max)
 179    where T : struct, IComparable<T>;
 180
 181/// <summary>
 182/// Represents an optional minimum and maximum value of a comparable type. This struct is immutable and provides a conve
 183/// </summary>
 184/// <param name="Min">The minimum value, or null if unbounded.</param>
 185/// <param name="Max">The maximum value, or null if unbounded.</param>
 186/// <typeparam name="T">The type of the comparable values.</typeparam>
 187public readonly record struct OptionalMinMax<T>(T? Min, T? Max)
 188    where T : struct, IComparable<T>;
 189