{-# LANGUAGE DataKinds #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}

-- |
-- Module      : Git.Stale.Types.ResultsWithErrs
-- License     : BSD3
-- Maintainer  : tbidne@gmail.com
-- Provides a `ResultsWithErrs` type that wraps `Results` along with
-- a list of errors.
module Git.Stale.Types.ResultsWithErrs
  ( ErrDisp (..),
    ResultsWithErrs (..),
    ResultsWithErrsDisp (..),
    toResultsErrDisp,
    toResultsWithErrs,
  )
where

import qualified Data.Foldable as F
import qualified Data.Text as T
import Git.Stale.Types.Branch
import Git.Stale.Types.Error
import Git.Stale.Types.Results

-- | Wraps `Results` and includes [`Err`].
data ResultsWithErrs
  = ResultsWithErrs
      { -- | All errors encountered.
        ResultsWithErrs -> [Err]
errList :: [Err],
        -- | The `Results`.
        ResultsWithErrs -> Results
results :: Results
      }
  deriving (Int -> ResultsWithErrs -> ShowS
[ResultsWithErrs] -> ShowS
ResultsWithErrs -> String
(Int -> ResultsWithErrs -> ShowS)
-> (ResultsWithErrs -> String)
-> ([ResultsWithErrs] -> ShowS)
-> Show ResultsWithErrs
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ResultsWithErrs] -> ShowS
$cshowList :: [ResultsWithErrs] -> ShowS
show :: ResultsWithErrs -> String
$cshow :: ResultsWithErrs -> String
showsPrec :: Int -> ResultsWithErrs -> ShowS
$cshowsPrec :: Int -> ResultsWithErrs -> ShowS
Show)

-- | Newtype wrapper for errors over (display string, num branches).
newtype ErrDisp = ErrDisp (T.Text, Int)

-- | Newtype wrapper over ('ErrDisp', 'ResultsDisp').
newtype ResultsWithErrsDisp = ResultsWithErrsDisp (ErrDisp, ResultsDisp)

-- | Transforms the 'ResultsWithErrs' into a 'ResultsWithErrsDisp' for display
-- purposes. Strips out the @prefix@ from the branches, if it exists.
toResultsErrDisp :: T.Text -> ResultsWithErrs -> ResultsWithErrsDisp
toResultsErrDisp :: Text -> ResultsWithErrs -> ResultsWithErrsDisp
toResultsErrDisp prefix :: Text
prefix ResultsWithErrs {[Err]
errList :: [Err]
errList :: ResultsWithErrs -> [Err]
errList, Results
results :: Results
results :: ResultsWithErrs -> Results
results} = (ErrDisp, ResultsDisp) -> ResultsWithErrsDisp
ResultsWithErrsDisp (ErrDisp
errDisp, ResultsDisp
res)
  where
    errDisp :: ErrDisp
errDisp = (Text, Int) -> ErrDisp
ErrDisp ([Err] -> Text
forall a. Show a => a -> Text
showText [Err]
errList, [Err] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Err]
errList)
    res :: ResultsDisp
res = Text -> Results -> ResultsDisp
toResultsDisp Text
prefix Results
results

-- | Maps [`ErrOr` `AnyBranch`] to `ResultsWithErrs`.
toResultsWithErrs :: [ErrOr AnyBranch] -> ResultsWithErrs
toResultsWithErrs :: [ErrOr AnyBranch] -> ResultsWithErrs
toResultsWithErrs xs :: [ErrOr AnyBranch]
xs = [Err] -> Results -> ResultsWithErrs
ResultsWithErrs [Err]
errs ([AnyBranch] -> Results
toResults [AnyBranch]
results)
  where
    (errs :: [Err]
errs, results :: [AnyBranch]
results) = [ErrOr AnyBranch] -> ([Err], [AnyBranch])
splitErrs [ErrOr AnyBranch]
xs

splitErrs :: [ErrOr AnyBranch] -> ([Err], [AnyBranch])
splitErrs :: [ErrOr AnyBranch] -> ([Err], [AnyBranch])
splitErrs = (([Err], [AnyBranch]) -> ErrOr AnyBranch -> ([Err], [AnyBranch]))
-> ([Err], [AnyBranch])
-> [ErrOr AnyBranch]
-> ([Err], [AnyBranch])
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
F.foldl' ([Err], [AnyBranch]) -> ErrOr AnyBranch -> ([Err], [AnyBranch])
forall a a. ([a], [a]) -> Either a a -> ([a], [a])
f ([], [])
  where
    f :: ([a], [a]) -> Either a a -> ([a], [a])
f (es :: [a]
es, bs :: [a]
bs) (Left e :: a
e) = (a
e a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
es, [a]
bs)
    f (es :: [a]
es, bs :: [a]
bs) (Right b :: a
b) = ([a]
es, a
b a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
bs)

showText :: Show a => a -> T.Text
showText :: a -> Text
showText = String -> Text
T.pack (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