module Options.Harg.Sources
  ( accumSourceResults,
    HiddenSources,
    hiddenSources,
    DefaultSources,
    defaultSources,
  )
where

import qualified Barbies as B
import Data.Foldable (foldr')
import Data.Functor.Compose (Compose (..))
import Options.Harg.Sources.DefaultStr (DefaultStrSource (..))
import Options.Harg.Sources.Env (EnvSource (..))
import Options.Harg.Sources.Types

-- | Accumulate all the successful source results and return them,
-- along with a list of errors.
accumSourceResults ::
  forall a f.
  B.TraversableB a =>
  [Either SourceRunError (a (Compose SourceRunResult f))] ->
  ([SourceRunError], [a (Compose Maybe f)])
accumSourceResults :: [Either SourceRunError (a (Compose SourceRunResult f))]
-> ([SourceRunError], [a (Compose Maybe f)])
accumSourceResults =
  (Either SourceRunError (a (Compose SourceRunResult f))
 -> ([SourceRunError], [a (Compose Maybe f)])
 -> ([SourceRunError], [a (Compose Maybe f)]))
-> ([SourceRunError], [a (Compose Maybe f)])
-> [Either SourceRunError (a (Compose SourceRunResult f))]
-> ([SourceRunError], [a (Compose Maybe f)])
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr' Either SourceRunError (a (Compose SourceRunResult f))
-> ([SourceRunError], [a (Compose Maybe f)])
-> ([SourceRunError], [a (Compose Maybe f)])
accumResult ([], [])
  where
    accumResult ::
      Either SourceRunError (a (Compose SourceRunResult f)) ->
      ([SourceRunError], [a (Compose Maybe f)]) ->
      ([SourceRunError], [a (Compose Maybe f)])
    accumResult :: Either SourceRunError (a (Compose SourceRunResult f))
-> ([SourceRunError], [a (Compose Maybe f)])
-> ([SourceRunError], [a (Compose Maybe f)])
accumResult res :: Either SourceRunError (a (Compose SourceRunResult f))
res (e :: [SourceRunError]
e, a :: [a (Compose Maybe f)]
a) =
      case Either SourceRunError (a (Compose SourceRunResult f))
res of
        Left sre :: SourceRunError
sre -> (SourceRunError
sre SourceRunError -> [SourceRunError] -> [SourceRunError]
forall a. a -> [a] -> [a]
: [SourceRunError]
e, [a (Compose Maybe f)]
a)
        Right res' :: a (Compose SourceRunResult f)
res' ->
          case (forall a.
 Compose SourceRunResult f a
 -> ([SourceRunError], Compose Maybe f a))
-> a (Compose SourceRunResult f)
-> ([SourceRunError], a (Compose Maybe f))
forall k (b :: (k -> *) -> *) (e :: * -> *) (f :: k -> *)
       (g :: k -> *).
(TraversableB b, Applicative e) =>
(forall (a :: k). f a -> e (g a)) -> b f -> e (b g)
B.btraverse forall a.
Compose SourceRunResult f a
-> ([SourceRunError], Compose Maybe f a)
go a (Compose SourceRunResult f)
res' of
            (e' :: [SourceRunError]
e', a' :: a (Compose Maybe f)
a') -> ([SourceRunError]
e' [SourceRunError] -> [SourceRunError] -> [SourceRunError]
forall a. Semigroup a => a -> a -> a
<> [SourceRunError]
e, a (Compose Maybe f)
a' a (Compose Maybe f)
-> [a (Compose Maybe f)] -> [a (Compose Maybe f)]
forall a. a -> [a] -> [a]
: [a (Compose Maybe f)]
a)
    go ::
      Compose SourceRunResult f x ->
      ([SourceRunError], Compose Maybe f x)
    go :: Compose SourceRunResult f x
-> ([SourceRunError], Compose Maybe f x)
go x :: Compose SourceRunResult f x
x =
      case Compose SourceRunResult f x -> SourceRunResult (f x)
forall k1 (f :: k1 -> *) k2 (g :: k2 -> k1) (a :: k2).
Compose f g a -> f (g a)
getCompose Compose SourceRunResult f x
x of
        OptParsed a :: f x
a ->
          ([], Maybe (f x) -> Compose Maybe f x
forall k k1 (f :: k -> *) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose (f x -> Maybe (f x)
forall a. a -> Maybe a
Just f x
a))
        OptNotFound ->
          ([], Maybe (f x) -> Compose Maybe f x
forall k k1 (f :: k -> *) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose Maybe (f x)
forall a. Maybe a
Nothing)

type HiddenSources = DefaultStrSource

-- | Sources hidden from user that are always enabled
hiddenSources :: HiddenSources f
hiddenSources :: HiddenSources f
hiddenSources = HiddenSources f
forall (f :: * -> *). DefaultStrSource f
DefaultStrSource

type DefaultSources = EnvSource

-- | Default sources, equivalent to 'EnvSource'
defaultSources :: DefaultSources f
defaultSources :: DefaultSources f
defaultSources = DefaultSources f
forall (f :: * -> *). EnvSource f
EnvSource