{-# LANGUAGE DataKinds           #-}
{-# LANGUAGE FlexibleContexts    #-}
{-# LANGUAGE FlexibleInstances   #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies        #-}
{-# LANGUAGE TypeOperators       #-}

{-|
Module      : GHCup.Utils.Prelude
Description : MegaParsec utilities
Copyright   : (c) Julian Ospald, 2020
License     : LGPL-3.0
Maintainer  : hasufell@hasufell.de
Stability   : experimental
Portability : POSIX

GHCup specific prelude. Lots of Excepts functionality.
-}
module GHCup.Utils.Prelude where

import           Control.Applicative
import           Control.Exception.Safe
import           Control.Monad
import           Control.Monad.IO.Class
import           Control.Monad.Trans.Class      ( lift )
import           Data.Bifunctor
import           Data.ByteString                ( ByteString )
import           Data.String
import           Data.Text                      ( Text )
import           Data.Versions
import           Data.Word8
import           Haskus.Utils.Types.List
import           Haskus.Utils.Variant.Excepts
import           System.IO.Error
import           System.Posix.Env.ByteString    ( getEnvironment )

import qualified Data.ByteString               as B
import qualified Data.ByteString.Lazy          as L
import qualified Data.Strict.Maybe             as S
import qualified Data.Text                     as T
import qualified Data.Text.Encoding            as E
import qualified Data.Text.Encoding.Error      as E
import qualified Data.Text.Lazy                as TL
import qualified Data.Text.Lazy.Builder        as B
import qualified Data.Text.Lazy.Builder.Int    as B
import qualified Data.Text.Lazy.Encoding       as TLE



fS :: IsString a => String -> a
fS :: String -> a
fS = String -> a
forall a. IsString a => String -> a
fromString

fromStrictMaybe :: S.Maybe a -> Maybe a
fromStrictMaybe :: Maybe a -> Maybe a
fromStrictMaybe = Maybe a -> (a -> Maybe a) -> Maybe a -> Maybe a
forall b a. b -> (a -> b) -> Maybe a -> b
S.maybe Maybe a
forall a. Maybe a
Nothing a -> Maybe a
forall a. a -> Maybe a
Just

fSM :: S.Maybe a -> Maybe a
fSM :: Maybe a -> Maybe a
fSM = Maybe a -> Maybe a
forall a. Maybe a -> Maybe a
fromStrictMaybe

toStrictMaybe :: Maybe a -> S.Maybe a
toStrictMaybe :: Maybe a -> Maybe a
toStrictMaybe = Maybe a -> (a -> Maybe a) -> Maybe a -> Maybe a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Maybe a
forall a. Maybe a
S.Nothing a -> Maybe a
forall a. a -> Maybe a
S.Just

tSM :: Maybe a -> S.Maybe a
tSM :: Maybe a -> Maybe a
tSM = Maybe a -> Maybe a
forall a. Maybe a -> Maybe a
toStrictMaybe

internalError :: String -> IO a
internalError :: String -> IO a
internalError = String -> IO a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> IO a) -> (String -> String) -> String -> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String
"Internal error: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<>)

iE :: String -> IO a
iE :: String -> IO a
iE = String -> IO a
forall a. String -> IO a
internalError


showT :: Show a => a -> Text
showT :: a -> Text
showT = String -> Text
forall a. IsString a => String -> a
fS (String -> Text) -> (a -> String) -> a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> String
forall a. Show a => a -> String
show

-- | Like 'when', but where the test can be monadic.
whenM :: Monad m => m Bool -> m () -> m ()
whenM :: m Bool -> m () -> m ()
whenM ~m Bool
b ~m ()
t = m Bool -> m () -> m () -> m ()
forall (m :: * -> *) a. Monad m => m Bool -> m a -> m a -> m a
ifM m Bool
b m ()
t (() -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ())

-- | Like 'unless', but where the test can be monadic.
unlessM :: Monad m => m Bool -> m () -> m ()
unlessM :: m Bool -> m () -> m ()
unlessM ~m Bool
b ~m ()
f = m Bool -> m () -> m () -> m ()
forall (m :: * -> *) a. Monad m => m Bool -> m a -> m a -> m a
ifM m Bool
b (() -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()) m ()
f

-- | Like @if@, but where the test can be monadic.
ifM :: Monad m => m Bool -> m a -> m a -> m a
ifM :: m Bool -> m a -> m a -> m a
ifM ~m Bool
b ~m a
t ~m a
f = do
  Bool
b' <- m Bool
b
  if Bool
b' then m a
t else m a
f

whileM :: Monad m => m a -> (a -> m Bool) -> m a
whileM :: m a -> (a -> m Bool) -> m a
whileM ~m a
action ~a -> m Bool
f = do
  a
a  <- m a
action
  Bool
b' <- a -> m Bool
f a
a
  if Bool
b' then m a -> (a -> m Bool) -> m a
forall (m :: * -> *) a. Monad m => m a -> (a -> m Bool) -> m a
whileM m a
action a -> m Bool
f else a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
a

whileM_ :: Monad m => m a -> (a -> m Bool) -> m ()
whileM_ :: m a -> (a -> m Bool) -> m ()
whileM_ ~m a
action = m a -> m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (m a -> m ()) -> ((a -> m Bool) -> m a) -> (a -> m Bool) -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m a -> (a -> m Bool) -> m a
forall (m :: * -> *) a. Monad m => m a -> (a -> m Bool) -> m a
whileM m a
action

guardM :: (Monad m, Alternative m) => m Bool -> m ()
guardM :: m Bool -> m ()
guardM ~m Bool
f = Bool -> m ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> m ()) -> m Bool -> m ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< m Bool
f


handleIO' :: (MonadIO m, MonadCatch m)
          => IOErrorType
          -> (IOException -> m a)
          -> m a
          -> m a
handleIO' :: IOErrorType -> (IOException -> m a) -> m a -> m a
handleIO' IOErrorType
err IOException -> m a
handler = (IOException -> m a) -> m a -> m a
forall (m :: * -> *) a.
MonadCatch m =>
(IOException -> m a) -> m a -> m a
handleIO
  (\IOException
e -> if IOErrorType
err IOErrorType -> IOErrorType -> Bool
forall a. Eq a => a -> a -> Bool
== IOException -> IOErrorType
ioeGetErrorType IOException
e then IOException -> m a
handler IOException
e else IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO a -> m a) -> IO a -> m a
forall a b. (a -> b) -> a -> b
$ IOException -> IO a
forall a. IOException -> IO a
ioError IOException
e)


(??) :: forall e es a m . (Monad m, e :< es) => Maybe a -> e -> Excepts es m a
?? :: Maybe a -> e -> Excepts es m a
(??) Maybe a
m e
e = Excepts es m a
-> (a -> Excepts es m a) -> Maybe a -> Excepts es m a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (e -> Excepts es m a
forall e (es :: [*]) a (m :: * -> *).
(Monad m, e :< es) =>
e -> Excepts es m a
throwE e
e) a -> Excepts es m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe a
m


(!?) :: forall e es a m
      . (Monad m, e :< es)
     => m (Maybe a)
     -> e
     -> Excepts es m a
!? :: m (Maybe a) -> e -> Excepts es m a
(!?) m (Maybe a)
em e
e = m (Maybe a) -> Excepts es m (Maybe a)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m (Maybe a)
em Excepts es m (Maybe a)
-> (Maybe a -> Excepts es m a) -> Excepts es m a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Maybe a -> e -> Excepts es m a
forall e (es :: [*]) a (m :: * -> *).
(Monad m, e :< es) =>
Maybe a -> e -> Excepts es m a
?? e
e)


lE :: forall e es a m . (Monad m, e :< es) => Either e a -> Excepts es m a
lE :: Either e a -> Excepts es m a
lE = Excepts '[e] m a -> Excepts es m a
forall (es' :: [*]) (es :: [*]) a (m :: * -> *).
(Monad m, VEitherLift es es') =>
Excepts es m a -> Excepts es' m a
liftE (Excepts '[e] m a -> Excepts es m a)
-> (Either e a -> Excepts '[e] m a) -> Either e a -> Excepts es m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VEither '[e] a -> Excepts '[e] m a
forall (m :: * -> *) (es :: [*]) a.
Monad m =>
VEither es a -> Excepts es m a
veitherToExcepts (VEither '[e] a -> Excepts '[e] m a)
-> (Either e a -> VEither '[e] a) -> Either e a -> Excepts '[e] m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Either e a -> VEither '[e] a
forall a b. Either a b -> VEither '[a] b
fromEither

lE' :: forall e' e es a m
     . (Monad m, e :< es)
    => (e' -> e)
    -> Either e' a
    -> Excepts es m a
lE' :: (e' -> e) -> Either e' a -> Excepts es m a
lE' e' -> e
f = Excepts '[e] m a -> Excepts es m a
forall (es' :: [*]) (es :: [*]) a (m :: * -> *).
(Monad m, VEitherLift es es') =>
Excepts es m a -> Excepts es' m a
liftE (Excepts '[e] m a -> Excepts es m a)
-> (Either e' a -> Excepts '[e] m a)
-> Either e' a
-> Excepts es m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VEither '[e] a -> Excepts '[e] m a
forall (m :: * -> *) (es :: [*]) a.
Monad m =>
VEither es a -> Excepts es m a
veitherToExcepts (VEither '[e] a -> Excepts '[e] m a)
-> (Either e' a -> VEither '[e] a)
-> Either e' a
-> Excepts '[e] m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Either e a -> VEither '[e] a
forall a b. Either a b -> VEither '[a] b
fromEither (Either e a -> VEither '[e] a)
-> (Either e' a -> Either e a) -> Either e' a -> VEither '[e] a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (e' -> e) -> Either e' a -> Either e a
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first e' -> e
f

lEM :: forall e es a m . (Monad m, e :< es) => m (Either e a) -> Excepts es m a
lEM :: m (Either e a) -> Excepts es m a
lEM m (Either e a)
em = m (Either e a) -> Excepts es m (Either e a)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m (Either e a)
em Excepts es m (Either e a)
-> (Either e a -> Excepts es m a) -> Excepts es m a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Either e a -> Excepts es m a
forall e (es :: [*]) a (m :: * -> *).
(Monad m, e :< es) =>
Either e a -> Excepts es m a
lE

lEM' :: forall e' e es a m
      . (Monad m, e :< es)
     => (e' -> e)
     -> m (Either e' a)
     -> Excepts es m a
lEM' :: (e' -> e) -> m (Either e' a) -> Excepts es m a
lEM' e' -> e
f m (Either e' a)
em = m (Either e' a) -> Excepts es m (Either e' a)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m (Either e' a)
em Excepts es m (Either e' a)
-> (Either e' a -> Excepts es m a) -> Excepts es m a
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Either e a -> Excepts es m a
forall e (es :: [*]) a (m :: * -> *).
(Monad m, e :< es) =>
Either e a -> Excepts es m a
lE (Either e a -> Excepts es m a)
-> (Either e' a -> Either e a) -> Either e' a -> Excepts es m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (e' -> e) -> Either e' a -> Either e a
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first e' -> e
f

fromEither :: Either a b -> VEither '[a] b
fromEither :: Either a b -> VEither '[a] b
fromEither = (a -> VEither '[a] b)
-> (b -> VEither '[a] b) -> Either a b -> VEither '[a] b
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (V '[a] -> VEither '[a] b
forall x (xs :: [*]). V xs -> VEither xs x
VLeft (V '[a] -> VEither '[a] b) -> (a -> V '[a]) -> a -> VEither '[a] b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> V '[a]
forall c (cs :: [*]). (c :< cs) => c -> V cs
V) b -> VEither '[a] b
forall x (xs :: [*]). x -> VEither xs x
VRight


liftIOException' :: ( MonadCatch m
                    , MonadIO m
                    , Monad m
                    , e :< es'
                    , LiftVariant es es'
                    )
                 => IOErrorType
                 -> e
                 -> Excepts es m a
                 -> Excepts es' m a
liftIOException' :: IOErrorType -> e -> Excepts es m a -> Excepts es' m a
liftIOException' IOErrorType
errType e
ex =
  (IOException -> Excepts es' m a)
-> Excepts es' m a -> Excepts es' m a
forall (m :: * -> *) a.
MonadCatch m =>
(IOException -> m a) -> m a -> m a
handleIO
      (\IOException
e ->
        if IOErrorType
errType IOErrorType -> IOErrorType -> Bool
forall a. Eq a => a -> a -> Bool
== IOException -> IOErrorType
ioeGetErrorType IOException
e then e -> Excepts es' m a
forall e (es :: [*]) a (m :: * -> *).
(Monad m, e :< es) =>
e -> Excepts es m a
throwE e
ex else IO a -> Excepts es' m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO a -> Excepts es' m a) -> IO a -> Excepts es' m a
forall a b. (a -> b) -> a -> b
$ IOException -> IO a
forall a. IOException -> IO a
ioError IOException
e
      )
    (Excepts es' m a -> Excepts es' m a)
-> (Excepts es m a -> Excepts es' m a)
-> Excepts es m a
-> Excepts es' m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Excepts es m a -> Excepts es' m a
forall (es' :: [*]) (es :: [*]) a (m :: * -> *).
(Monad m, VEitherLift es es') =>
Excepts es m a -> Excepts es' m a
liftE


liftIOException :: (MonadCatch m, MonadIO m, Monad m, e :< es')
                => IOErrorType
                -> e
                -> m a
                -> Excepts es' m a
liftIOException :: IOErrorType -> e -> m a -> Excepts es' m a
liftIOException IOErrorType
errType e
ex =
  (IOException -> Excepts es' m a)
-> Excepts es' m a -> Excepts es' m a
forall (m :: * -> *) a.
MonadCatch m =>
(IOException -> m a) -> m a -> m a
handleIO
      (\IOException
e ->
        if IOErrorType
errType IOErrorType -> IOErrorType -> Bool
forall a. Eq a => a -> a -> Bool
== IOException -> IOErrorType
ioeGetErrorType IOException
e then e -> Excepts es' m a
forall e (es :: [*]) a (m :: * -> *).
(Monad m, e :< es) =>
e -> Excepts es m a
throwE e
ex else IO a -> Excepts es' m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO a -> Excepts es' m a) -> IO a -> Excepts es' m a
forall a b. (a -> b) -> a -> b
$ IOException -> IO a
forall a. IOException -> IO a
ioError IOException
e
      )
    (Excepts es' m a -> Excepts es' m a)
-> (m a -> Excepts es' m a) -> m a -> Excepts es' m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m a -> Excepts es' m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift


-- | Uses safe-exceptions.
hideError :: (MonadIO m, MonadCatch m) => IOErrorType -> m () -> m ()
hideError :: IOErrorType -> m () -> m ()
hideError IOErrorType
err = (IOException -> m ()) -> m () -> m ()
forall (m :: * -> *) a.
MonadCatch m =>
(IOException -> m a) -> m a -> m a
handleIO (\IOException
e -> if IOErrorType
err IOErrorType -> IOErrorType -> Bool
forall a. Eq a => a -> a -> Bool
== IOException -> IOErrorType
ioeGetErrorType IOException
e then () -> m ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure () else IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> (IOException -> IO ()) -> IOException -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IOException -> IO ()
forall a. IOException -> IO a
ioError (IOException -> m ()) -> IOException -> m ()
forall a b. (a -> b) -> a -> b
$ IOException
e)


hideErrorDef :: [IOErrorType] -> a -> IO a -> IO a
hideErrorDef :: [IOErrorType] -> a -> IO a -> IO a
hideErrorDef [IOErrorType]
errs a
def =
  (IOException -> IO a) -> IO a -> IO a
forall (m :: * -> *) a.
MonadCatch m =>
(IOException -> m a) -> m a -> m a
handleIO (\IOException
e -> if IOException -> IOErrorType
ioeGetErrorType IOException
e IOErrorType -> [IOErrorType] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [IOErrorType]
errs then a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
def else IOException -> IO a
forall a. IOException -> IO a
ioError IOException
e)


hideErrorDefM :: [IOErrorType] -> IO a -> IO a -> IO a
hideErrorDefM :: [IOErrorType] -> IO a -> IO a -> IO a
hideErrorDefM [IOErrorType]
errs IO a
def =
  (IOException -> IO a) -> IO a -> IO a
forall (m :: * -> *) a.
MonadCatch m =>
(IOException -> m a) -> m a -> m a
handleIO (\IOException
e -> if IOException -> IOErrorType
ioeGetErrorType IOException
e IOErrorType -> [IOErrorType] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [IOErrorType]
errs then IO a
def else IOException -> IO a
forall a. IOException -> IO a
ioError IOException
e)


-- TODO: does this work?
hideExcept :: forall e es es' a m
            . (Monad m, e :< es, LiftVariant (Remove e es) es')
           => e
           -> a
           -> Excepts es m a
           -> Excepts es' m a
hideExcept :: e -> a -> Excepts es m a -> Excepts es' m a
hideExcept e
_ a
a =
  (e -> Excepts es' m a) -> Excepts es m a -> Excepts es' m a
forall e (es :: [*]) (es' :: [*]) a (m :: * -> *).
(Monad m, e :< es, LiftVariant (Remove e es) es') =>
(e -> Excepts es' m a) -> Excepts es m a -> Excepts es' m a
catchLiftLeft ((\e
_ -> a -> Excepts es' m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
a) :: (e -> Excepts es' m a))


hideExcept' :: forall e es es' m
             . (Monad m, e :< es, LiftVariant (Remove e es) es')
            => e
            -> Excepts es m ()
            -> Excepts es' m ()
hideExcept' :: e -> Excepts es m () -> Excepts es' m ()
hideExcept' e
_ =
  (e -> Excepts es' m ()) -> Excepts es m () -> Excepts es' m ()
forall e (es :: [*]) (es' :: [*]) a (m :: * -> *).
(Monad m, e :< es, LiftVariant (Remove e es) es') =>
(e -> Excepts es' m a) -> Excepts es m a -> Excepts es' m a
catchLiftLeft ((\e
_ -> () -> Excepts es' m ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()) :: (e -> Excepts es' m ()))


reThrowAll :: forall e es es' a m
            . (Monad m, e :< es')
           => (V es -> e)
           -> Excepts es m a
           -> Excepts es' m a
reThrowAll :: (V es -> e) -> Excepts es m a -> Excepts es' m a
reThrowAll V es -> e
f = (V es -> Excepts es' m a) -> Excepts es m a -> Excepts es' m a
forall (m :: * -> *) (es :: [*]) (es' :: [*]) a.
Monad m =>
(V es -> Excepts es' m a) -> Excepts es m a -> Excepts es' m a
catchAllE (e -> Excepts es' m a
forall e (es :: [*]) a (m :: * -> *).
(Monad m, e :< es) =>
e -> Excepts es m a
throwE (e -> Excepts es' m a) -> (V es -> e) -> V es -> Excepts es' m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. V es -> e
f)


reThrowAllIO :: forall e es es' a m
              . (MonadCatch m, Monad m, MonadIO m, e :< es')
             => (V es -> e)
             -> (IOException -> e)
             -> Excepts es m a
             -> Excepts es' m a
reThrowAllIO :: (V es -> e)
-> (IOException -> e) -> Excepts es m a -> Excepts es' m a
reThrowAllIO V es -> e
f IOException -> e
g = (IOException -> Excepts es' m a)
-> Excepts es' m a -> Excepts es' m a
forall (m :: * -> *) a.
MonadCatch m =>
(IOException -> m a) -> m a -> m a
handleIO (e -> Excepts es' m a
forall e (es :: [*]) a (m :: * -> *).
(Monad m, e :< es) =>
e -> Excepts es m a
throwE (e -> Excepts es' m a)
-> (IOException -> e) -> IOException -> Excepts es' m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IOException -> e
g) (Excepts es' m a -> Excepts es' m a)
-> (Excepts es m a -> Excepts es' m a)
-> Excepts es m a
-> Excepts es' m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (V es -> Excepts es' m a) -> Excepts es m a -> Excepts es' m a
forall (m :: * -> *) (es :: [*]) (es' :: [*]) a.
Monad m =>
(V es -> Excepts es' m a) -> Excepts es m a -> Excepts es' m a
catchAllE (e -> Excepts es' m a
forall e (es :: [*]) a (m :: * -> *).
(Monad m, e :< es) =>
e -> Excepts es m a
throwE (e -> Excepts es' m a) -> (V es -> e) -> V es -> Excepts es' m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. V es -> e
f)


throwEither :: (Exception a, MonadThrow m) => Either a b -> m b
throwEither :: Either a b -> m b
throwEither Either a b
a = case Either a b
a of
  Left  a
e -> a -> m b
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM a
e
  Right b
r -> b -> m b
forall (f :: * -> *) a. Applicative f => a -> f a
pure b
r


throwEither' :: (Exception a, MonadThrow m) => a -> Either x b -> m b
throwEither' :: a -> Either x b -> m b
throwEither' a
e Either x b
eth = case Either x b
eth of
  Left  x
_ -> a -> m b
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM a
e
  Right b
r -> b -> m b
forall (f :: * -> *) a. Applicative f => a -> f a
pure b
r


verToBS :: Version -> ByteString
verToBS :: Version -> ByteString
verToBS = Text -> ByteString
E.encodeUtf8 (Text -> ByteString) -> (Version -> Text) -> Version -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Version -> Text
prettyVer


intToText :: Integral a => a -> T.Text
intToText :: a -> Text
intToText = Text -> Text
TL.toStrict (Text -> Text) -> (a -> Text) -> a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Text
B.toLazyText (Builder -> Text) -> (a -> Builder) -> a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Builder
forall a. Integral a => a -> Builder
B.decimal


removeLensFieldLabel :: String -> String
removeLensFieldLabel :: String -> String
removeLensFieldLabel String
str' =
  String -> (Text -> String) -> Maybe Text -> String
forall b a. b -> (a -> b) -> Maybe a -> b
maybe String
str' Text -> String
T.unpack (Maybe Text -> String)
-> (String -> Maybe Text) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text -> Maybe Text
T.stripPrefix (String -> Text
T.pack String
"_") (Text -> Maybe Text) -> (String -> Text) -> String -> Maybe Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String
str'


addToCurrentEnv :: MonadIO m
                => [(ByteString, ByteString)]
                -> m [(ByteString, ByteString)]
addToCurrentEnv :: [(ByteString, ByteString)] -> m [(ByteString, ByteString)]
addToCurrentEnv [(ByteString, ByteString)]
adds = do
  [(ByteString, ByteString)]
cEnv <- IO [(ByteString, ByteString)] -> m [(ByteString, ByteString)]
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO [(ByteString, ByteString)]
getEnvironment
  [(ByteString, ByteString)] -> m [(ByteString, ByteString)]
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([(ByteString, ByteString)]
adds [(ByteString, ByteString)]
-> [(ByteString, ByteString)] -> [(ByteString, ByteString)]
forall a. [a] -> [a] -> [a]
++ [(ByteString, ByteString)]
cEnv)


pvpToVersion :: PVP -> Version
pvpToVersion :: PVP -> Version
pvpToVersion =
  (ParsingError -> Version)
-> (Version -> Version) -> Either ParsingError Version -> Version
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (\ParsingError
_ -> String -> Version
forall a. HasCallStack => String -> a
error String
"Couldn't convert PVP to Version") Version -> Version
forall a. a -> a
id
    (Either ParsingError Version -> Version)
-> (PVP -> Either ParsingError Version) -> PVP -> Version
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either ParsingError Version
version
    (Text -> Either ParsingError Version)
-> (PVP -> Text) -> PVP -> Either ParsingError Version
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PVP -> Text
prettyPVP


-- | Safe 'decodeUtf8With'. Replaces an invalid input byte with
-- the Unicode replacement character U+FFFD.
decUTF8Safe :: ByteString -> Text
decUTF8Safe :: ByteString -> Text
decUTF8Safe = OnDecodeError -> ByteString -> Text
E.decodeUtf8With OnDecodeError
E.lenientDecode

decUTF8Safe' :: L.ByteString -> Text
decUTF8Safe' :: ByteString -> Text
decUTF8Safe' = Text -> Text
TL.toStrict (Text -> Text) -> (ByteString -> Text) -> ByteString -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OnDecodeError -> ByteString -> Text
TLE.decodeUtf8With OnDecodeError
E.lenientDecode


-- | Escape a version for use in regex
escapeVerRex :: Version -> ByteString
escapeVerRex :: Version -> ByteString
escapeVerRex = [Word8] -> ByteString
B.pack ([Word8] -> ByteString)
-> (Version -> [Word8]) -> Version -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Word8] -> [Word8]
go ([Word8] -> [Word8]) -> (Version -> [Word8]) -> Version -> [Word8]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> [Word8]
B.unpack (ByteString -> [Word8])
-> (Version -> ByteString) -> Version -> [Word8]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Version -> ByteString
verToBS
 where
  go :: [Word8] -> [Word8]
go [] = []
  go (Word8
x : [Word8]
xs) | Word8
x Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
_period = [Word8
_backslash, Word8
_period] [Word8] -> [Word8] -> [Word8]
forall a. [a] -> [a] -> [a]
++ [Word8] -> [Word8]
go [Word8]
xs
              | Bool
otherwise    = Word8
x Word8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
: [Word8] -> [Word8]
go [Word8]
xs