{-# LANGUAGE QuasiQuotes #-} {- | Module : HCovGuard.Coverage.HpcLoader Description : Functions for loading HPC .tix and .mix files Copyright : (c) Trevis Elser, 2026 License : MIT Maintainer : oss@treviselser.com -} module HCovGuard.Coverage.HpcLoader ( loadTix , loadMix , LoadError (..) , showLoadError ) where import qualified Control.Exception as Exception import qualified Data.String.Interpolate as Interpolate import qualified Data.Text as Text import qualified Trace.Hpc.Mix as HpcMix import qualified Trace.Hpc.Tix as HpcTix import qualified System.OsPath as OsPath data LoadError = TixNotFound !FilePath | TixParseError !FilePath | TixPathEncodingError !OsPath.OsPath !Text.Text | MixPathEncodingError !OsPath.OsPath !Text.Text {- | Load a .tix file from the given path @since 0.1.0.0 -} loadTix :: OsPath.OsPath -> IO (Either LoadError HpcTix.Tix) loadTix path = do let tryDecode :: IO (Either Exception.SomeException FilePath) tryDecode = Exception.try (OsPath.decodeFS path) decodeResult <- tryDecode case decodeResult of Left err -> pure . Left $ TixPathEncodingError path (Text.pack $ Exception.displayException err) Right filePath -> do let withMbTix :: Maybe HpcTix.Tix -> Either LoadError HpcTix.Tix withMbTix = maybe (Left $ TixNotFound filePath) pure fmap withMbTix (HpcTix.readTix filePath) {- | Load a .mix file for a given module @since 0.1.0.0 -} loadMix :: [OsPath.OsPath] -> HpcTix.TixModule -> IO (Either LoadError HpcMix.Mix) loadMix mixDirs tixMod = do let decodeOne :: OsPath.OsPath -> IO (Either LoadError FilePath) decodeOne osPath = do let tryDecode :: IO (Either Exception.SomeException FilePath) tryDecode = Exception.try (OsPath.decodeFS osPath) result <- tryDecode pure $ either (Left . MixPathEncodingError osPath . Text.pack . Exception.displayException) Right result decodeResults <- traverse decodeOne mixDirs case sequenceA decodeResults of Left err -> pure (Left err) Right filePaths -> fmap Right (HpcMix.readMix filePaths (Right tixMod)) {- | Format a load error as a human-readable message @since 0.1.0.0 -} showLoadError :: LoadError -> Text.Text showLoadError (TixNotFound path) = [Interpolate.i|Error: [Hcovguard-5891] Tix file not found: |] <> Text.pack path showLoadError (TixParseError path) = [Interpolate.i|Error: [Hcovguard-2476] Failed to parse tix file: |] <> Text.pack path showLoadError (TixPathEncodingError path msg) = Text.unlines [ [Interpolate.i|Error: [Hcovguard-8234]|] , [Interpolate.i|Invalid tix file path encoding|] , [Interpolate.i| Path: |] <> Text.pack (show path) , [Interpolate.i| Error: |] <> msg ] showLoadError (MixPathEncodingError path msg) = Text.unlines [ [Interpolate.i|Error: [Hcovguard-9156]|] , [Interpolate.i|Invalid mix directory path encoding|] , [Interpolate.i| Path: |] <> Text.pack (show path) , [Interpolate.i| Error: |] <> msg ]