module Hix.Data.Error where

import Control.Monad.Trans.Except (ExceptT, throwE)
import qualified Data.Text.IO as Text
import Exon (exon)
import Path (Path, toFilePath)
import System.IO (stderr)
import System.IO.Error (tryIOError)

data Error =
  PreprocError Text
  |
  EnvError Text
  |
  GhciError Text
  |
  NewError Text
  |
  BootstrapError Text
  |
  NoMatch Text
  |
  Fatal Text
  deriving stock (Error -> Error -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Error -> Error -> Bool
$c/= :: Error -> Error -> Bool
== :: Error -> Error -> Bool
$c== :: Error -> Error -> Bool
Eq, Int -> Error -> ShowS
[Error] -> ShowS
Error -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Error] -> ShowS
$cshowList :: [Error] -> ShowS
show :: Error -> String
$cshow :: Error -> String
showsPrec :: Int -> Error -> ShowS
$cshowsPrec :: Int -> Error -> ShowS
Show, forall x. Rep Error x -> Error
forall x. Error -> Rep Error x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Error x -> Error
$cfrom :: forall x. Error -> Rep Error x
Generic)

pathText :: Path b t -> Text
pathText :: forall b t. Path b t -> Text
pathText =
  forall a. ToText a => a -> Text
toText forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b t. Path b t -> String
toFilePath

printPreprocError ::
  MonadIO m =>
  Text ->
  m ()
printPreprocError :: forall (m :: * -> *). MonadIO m => Text -> m ()
printPreprocError Text
msg =
  forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Handle -> Text -> IO ()
Text.hPutStrLn Handle
stderr [exon|>>> Preprocessor generator failed: #{msg}|])

printEnvError ::
  MonadIO m =>
  Text ->
  m ()
printEnvError :: forall (m :: * -> *). MonadIO m => Text -> m ()
printEnvError Text
msg =
  forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Handle -> Text -> IO ()
Text.hPutStrLn Handle
stderr [exon|>>> Invalid env config: #{msg}|])

printGhciError ::
  MonadIO m =>
  Text ->
  m ()
printGhciError :: forall (m :: * -> *). MonadIO m => Text -> m ()
printGhciError Text
msg =
  forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Handle -> Text -> IO ()
Text.hPutStrLn Handle
stderr [exon|>>> Invalid ghci config: #{msg}|])

printNewError ::
  MonadIO m =>
  Text ->
  m ()
printNewError :: forall (m :: * -> *). MonadIO m => Text -> m ()
printNewError Text
msg =
  forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Handle -> Text -> IO ()
Text.hPutStrLn Handle
stderr [exon|>>> Can't create new project: #{msg}|])

printBootstrapError ::
  MonadIO m =>
  Text ->
  m ()
printBootstrapError :: forall (m :: * -> *). MonadIO m => Text -> m ()
printBootstrapError Text
msg =
  forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Handle -> Text -> IO ()
Text.hPutStrLn Handle
stderr [exon|>>> Can't bootstrap project: #{msg}|])

printFatalError ::
  MonadIO m =>
  Text ->
  m ()
printFatalError :: forall (m :: * -> *). MonadIO m => Text -> m ()
printFatalError Text
msg =
  forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Handle -> Text -> IO ()
Text.hPutStrLn Handle
stderr [exon|>>> Fatal error: #{msg}|])

sourceError :: Text -> Path b t -> Text
sourceError :: forall b t. Text -> Path b t -> Text
sourceError Text
reason Path b t
source =
  [exon|#{reason} the source file '#{pathText source}'|]

tryIO ::
  IO a ->
  ExceptT Error IO a
tryIO :: forall a. IO a -> ExceptT Error IO a
tryIO IO a
ma =
  forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (forall a. IO a -> IO (Either IOError a)
tryIOError IO a
ma) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
    Right a
a -> forall (f :: * -> *) a. Applicative f => a -> f a
pure a
a
    Left IOError
err -> forall (m :: * -> *) e a. Monad m => e -> ExceptT e m a
throwE (Text -> Error
Fatal (forall b a. (Show a, IsString b) => a -> b
show IOError
err))

note :: Text -> Maybe a -> ExceptT Error IO a
note :: forall a. Text -> Maybe a -> ExceptT Error IO a
note Text
err =
  forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall (m :: * -> *) e a. Monad m => e -> ExceptT e m a
throwE (Text -> Error
GhciError Text
err)) forall (f :: * -> *) a. Applicative f => a -> f a
pure