{- | Module : HCovGuard.Checks.ThresholdCheck Description : Threshold validation types and functionality. Copyright : (c) Trevis Elser, 2026 License : MIT Maintainer : oss@treviselser.com Notably this is entirely abstracted from any notion of "level" for the threshold as well as to what code the threshold applies to. -} module HCovGuard.Checks.ThresholdCheck ( checkCoverage , CoverageFailure (..) , MinimumNotMet (..) , MaximumExceeded (..) ) where import qualified HCovGuard.Config as Config data MinimumNotMet = MinimumNotMet { mnmActualCovered :: !Int , mnmRequiredCovered :: !Int } data MaximumExceeded = MaximumExceeded { meActualUncovered :: !Int , meAllowedUncovered :: !Int } data CoverageFailure = MinimumCoveredNotMet !MinimumNotMet | MaximumUncoveredExceeded !MaximumExceeded checkCoverage :: Config.CoverageThreshold -> Int -- ^ Total count -> Int -- ^ Covered count -> [CoverageFailure] checkCoverage threshold total covered = let uncovered = total - covered minFail = case Config.minimumCovered threshold of Nothing -> mempty Just required -> if covered < required then [MinimumCoveredNotMet (MinimumNotMet{mnmActualCovered = covered, mnmRequiredCovered = required})] else mempty maxFail = case Config.maximumUncovered threshold of Nothing -> mempty Just allowed -> if uncovered > allowed then [ MaximumUncoveredExceeded (MaximumExceeded{meActualUncovered = uncovered, meAllowedUncovered = allowed}) ] else mempty in minFail <> maxFail