-- |
-- Module      : Git.FastForward.Types.UpdateResult
-- License     : BSD3
-- Maintainer  : tbidne@gmail.com
-- Provides functions and types for descrbing the result of an
-- update attempt.
module Git.FastForward.Types.UpdateResult
  ( SplitResults (..),
    UpdateResult (..),
    splitResults,
  )
where

import qualified Data.Foldable as F
import qualified Data.Text as T
import Git.Types.GitTypes

-- | Describes the result of an attempt to update a branch.
data UpdateResult
  = -- | Indicates updating 'Name' failed.
    Failure Name
  | -- | Indicates updating 'Name' resulted in no change.
    NoChange Name
  | -- | Indicates updating 'Name' succeeded.
    Success Name
  deriving (Int -> UpdateResult -> ShowS
[UpdateResult] -> ShowS
UpdateResult -> String
(Int -> UpdateResult -> ShowS)
-> (UpdateResult -> String)
-> ([UpdateResult] -> ShowS)
-> Show UpdateResult
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [UpdateResult] -> ShowS
$cshowList :: [UpdateResult] -> ShowS
show :: UpdateResult -> String
$cshow :: UpdateResult -> String
showsPrec :: Int -> UpdateResult -> ShowS
$cshowsPrec :: Int -> UpdateResult -> ShowS
Show)

-- | Groups the 'String' 'Name' of all results by 'UpdateResult'.
data SplitResults
  = SplitResults
      { SplitResults -> [String]
failures :: [String],
        SplitResults -> [String]
noChanges :: [String],
        SplitResults -> [String]
successes :: [String]
      }
  deriving (Int -> SplitResults -> ShowS
[SplitResults] -> ShowS
SplitResults -> String
(Int -> SplitResults -> ShowS)
-> (SplitResults -> String)
-> ([SplitResults] -> ShowS)
-> Show SplitResults
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SplitResults] -> ShowS
$cshowList :: [SplitResults] -> ShowS
show :: SplitResults -> String
$cshow :: SplitResults -> String
showsPrec :: Int -> SplitResults -> ShowS
$cshowsPrec :: Int -> SplitResults -> ShowS
Show)

-- | Maps ['UpdateResult'] to intermediate 'SplitResults'.
splitResults :: [UpdateResult] -> SplitResults
splitResults :: [UpdateResult] -> SplitResults
splitResults = (SplitResults -> UpdateResult -> SplitResults)
-> SplitResults -> [UpdateResult] -> SplitResults
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
F.foldl' SplitResults -> UpdateResult -> SplitResults
f ([String] -> [String] -> [String] -> SplitResults
SplitResults [] [] [])
  where
    f :: SplitResults -> UpdateResult -> SplitResults
f (SplitResults fs :: [String]
fs ns :: [String]
ns ss :: [String]
ss) (Failure (Name x :: Text
x)) = [String] -> [String] -> [String] -> SplitResults
SplitResults (Text -> String
T.unpack Text
x String -> [String] -> [String]
forall a. a -> [a] -> [a]
: [String]
fs) [String]
ns [String]
ss
    f (SplitResults fs :: [String]
fs ns :: [String]
ns ss :: [String]
ss) (NoChange (Name x :: Text
x)) = [String] -> [String] -> [String] -> SplitResults
SplitResults [String]
fs (Text -> String
T.unpack Text
x String -> [String] -> [String]
forall a. a -> [a] -> [a]
: [String]
ns) [String]
ss
    f (SplitResults fs :: [String]
fs ns :: [String]
ns ss :: [String]
ss) (Success (Name x :: Text
x)) = [String] -> [String] -> [String] -> SplitResults
SplitResults [String]
fs [String]
ns (Text -> String
T.unpack Text
x String -> [String] -> [String]
forall a. a -> [a] -> [a]
: [String]
ss)