{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TupleSections #-}
module Panfiguration.Core (
     Panfiguration(..)
    , Result(..)
    , Source(..)
    , declCase
    , asCase
    , withNames
    , envs
    , opts
    , defaults
    , fullDefaults
    , logger
    , Panfigurable
    , exec
    , run
    , runMaybe
    ) where

import Barbies
import Barbies.Bare
import Barbies.Constraints (Dict(..))
import Barbies.TH
import Control.Applicative
import Control.Monad (forM)
import Data.Bifunctor
import Data.Functor.Compose
import Data.Functor.Identity
import Data.List (intercalate)
import qualified Data.List.NonEmpty as NE
import Data.Maybe (fromMaybe)
import Data.Monoid (First(..))
import qualified Options.Applicative as O
import System.Environment (getEnvironment)

import Panfiguration.FromParam
import Panfiguration.Case

data Result a = Result
    { forall a. Result a -> [String]
resultSources :: [String]
    , forall a. Result a -> [String]
resultUsed :: [String]
    , forall a. Result a -> Maybe a
resultContent :: Maybe a
    }
    deriving (Int -> Result a -> ShowS
forall a. Show a => Int -> Result a -> ShowS
forall a. Show a => [Result a] -> ShowS
forall a. Show a => Result a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Result a] -> ShowS
$cshowList :: forall a. Show a => [Result a] -> ShowS
show :: Result a -> String
$cshow :: forall a. Show a => Result a -> String
showsPrec :: Int -> Result a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Result a -> ShowS
Show, Result a -> Result a -> Bool
forall a. Eq a => Result a -> Result a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Result a -> Result a -> Bool
$c/= :: forall a. Eq a => Result a -> Result a -> Bool
== :: Result a -> Result a -> Bool
$c== :: forall a. Eq a => Result a -> Result a -> Bool
Eq, Result a -> Result a -> Bool
Result a -> Result a -> Ordering
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall {a}. Ord a => Eq (Result a)
forall a. Ord a => Result a -> Result a -> Bool
forall a. Ord a => Result a -> Result a -> Ordering
forall a. Ord a => Result a -> Result a -> Result a
min :: Result a -> Result a -> Result a
$cmin :: forall a. Ord a => Result a -> Result a -> Result a
max :: Result a -> Result a -> Result a
$cmax :: forall a. Ord a => Result a -> Result a -> Result a
>= :: Result a -> Result a -> Bool
$c>= :: forall a. Ord a => Result a -> Result a -> Bool
> :: Result a -> Result a -> Bool
$c> :: forall a. Ord a => Result a -> Result a -> Bool
<= :: Result a -> Result a -> Bool
$c<= :: forall a. Ord a => Result a -> Result a -> Bool
< :: Result a -> Result a -> Bool
$c< :: forall a. Ord a => Result a -> Result a -> Bool
compare :: Result a -> Result a -> Ordering
$ccompare :: forall a. Ord a => Result a -> Result a -> Ordering
Ord)

mkResult :: String -> Maybe a -> Result a
mkResult :: forall a. String -> Maybe a -> Result a
mkResult String
key = forall a. [String] -> [String] -> Maybe a -> Result a
Result [String
key] [String
key]

instance FromParam a => Semigroup (Result a) where
    Result [String]
s0 [String]
_ Maybe a
Nothing <> :: Result a -> Result a -> Result a
<> Result [String]
s1 [String]
_ Maybe a
Nothing = forall a. [String] -> [String] -> Maybe a -> Result a
Result ([String]
s0 forall a. Semigroup a => a -> a -> a
<> [String]
s1) forall a. Monoid a => a
mempty forall a. Maybe a
Nothing
    Result [String]
s0 [String]
_ Maybe a
Nothing <> Result [String]
s1 [String]
u (Just a
a) = forall a. [String] -> [String] -> Maybe a -> Result a
Result ([String]
s0 forall a. Semigroup a => a -> a -> a
<> [String]
s1) [String]
u (forall a. a -> Maybe a
Just a
a)
    Result [String]
s0 [String]
u (Just a
a) <> Result [String]
s1 [String]
_ Maybe a
Nothing = forall a. [String] -> [String] -> Maybe a -> Result a
Result ([String]
s0 forall a. Semigroup a => a -> a -> a
<> [String]
s1) [String]
u (forall a. a -> Maybe a
Just a
a)
    Result [String]
s0 [String]
u0 (Just a
a) <> Result [String]
s1 [String]
u1 (Just a
b)
        =   let (Ordering
side, a
c) = forall a. FromParam a => a -> a -> (Ordering, a)
mergeParams a
a a
b
                used :: [String]
used = case Ordering
side of
                    Ordering
LT -> [String]
u0
                    Ordering
EQ -> [String]
u0 forall a. Semigroup a => a -> a -> a
<> [String]
u1
                    Ordering
GT -> [String]
u1
            in forall a. [String] -> [String] -> Maybe a -> Result a
Result ([String]
s0 forall a. Semigroup a => a -> a -> a
<> [String]
s1) [String]
used forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just a
c

instance FromParam a => Monoid (Result a) where
    mempty :: Result a
mempty = forall a. [String] -> [String] -> Maybe a -> Result a
Result [] [] forall a. Maybe a
Nothing

data Source h = Source
    { forall (h :: (* -> *) -> *). Source h -> Case
sourceCase :: Case
    , forall (h :: (* -> *) -> *).
Source h -> h (Const String) -> IO (h Result)
sourceRun :: h (Const String) -> IO (h Result)
    }

mapConsts :: FunctorB h => (a -> b) -> h (Const a) -> h (Const b)
mapConsts :: forall (h :: (* -> *) -> *) a b.
FunctorB h =>
(a -> b) -> h (Const a) -> h (Const b)
mapConsts a -> b
f = forall k (b :: (k -> *) -> *) (f :: k -> *) (g :: k -> *).
FunctorB b =>
(forall (a :: k). f a -> g a) -> b f -> b g
bmap (forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first a -> b
f)

data Panfiguration h = Panfiguration
    { forall (h :: (* -> *) -> *). Panfiguration h -> First Case
fieldNameCase :: First Case
    , forall (h :: (* -> *) -> *).
Panfiguration h -> First (String -> IO ())
loggerFunction :: First (String -> IO ())
    , forall (h :: (* -> *) -> *). Panfiguration h -> [Source h]
sources :: [Source h]
    }

instance Semigroup (Panfiguration h) where
    Panfiguration First Case
a First (String -> IO ())
b [Source h]
c <> :: Panfiguration h -> Panfiguration h -> Panfiguration h
<> Panfiguration First Case
x First (String -> IO ())
y [Source h]
z = forall (h :: (* -> *) -> *).
First Case
-> First (String -> IO ()) -> [Source h] -> Panfiguration h
Panfiguration (First Case
a forall a. Semigroup a => a -> a -> a
<> First Case
x) (First (String -> IO ())
b forall a. Semigroup a => a -> a -> a
<> First (String -> IO ())
y) ([Source h]
c forall a. Semigroup a => a -> a -> a
<> [Source h]
z)

instance Monoid (Panfiguration h) where
    mempty :: Panfiguration h
mempty = forall (h :: (* -> *) -> *).
First Case
-> First (String -> IO ()) -> [Source h] -> Panfiguration h
Panfiguration forall a. Monoid a => a
mempty forall a. Monoid a => a
mempty forall a. Monoid a => a
mempty

mkSource :: Case -> (h (Const String) -> IO (h Result)) -> Panfiguration h
mkSource :: forall (h :: (* -> *) -> *).
Case -> (h (Const String) -> IO (h Result)) -> Panfiguration h
mkSource Case
c h (Const String) -> IO (h Result)
f = forall a. Monoid a => a
mempty { sources :: [Source h]
sources = [forall (h :: (* -> *) -> *).
Case -> (h (Const String) -> IO (h Result)) -> Source h
Source Case
c h (Const String) -> IO (h Result)
f] }

-- | Set the letter case of the data declaration
declCase :: Case -> Panfiguration h
declCase :: forall (h :: (* -> *) -> *). Case -> Panfiguration h
declCase Case
c = forall a. Monoid a => a
mempty { fieldNameCase :: First Case
fieldNameCase = forall (f :: * -> *) a. Applicative f => a -> f a
pure Case
c }

-- | Set the letter case of the sources
asCase :: Panfiguration h -> Case -> Panfiguration h
asCase :: forall (h :: (* -> *) -> *).
Panfiguration h -> Case -> Panfiguration h
asCase Panfiguration h
pfg Case
c = Panfiguration h
pfg { sources :: [Source h]
sources = [ Source h
s { sourceCase :: Case
sourceCase = Case
c } | Source h
s <- forall (h :: (* -> *) -> *). Panfiguration h -> [Source h]
sources Panfiguration h
pfg] }

-- | Update names being used for the backends
withNames :: Panfiguration h -> (h (Const String) -> h (Const String)) -> Panfiguration h
withNames :: forall (h :: (* -> *) -> *).
Panfiguration h
-> (h (Const String) -> h (Const String)) -> Panfiguration h
withNames Panfiguration h
pfg h (Const String) -> h (Const String)
f = Panfiguration h
pfg { sources :: [Source h]
sources = [ Source h
s { sourceRun :: h (Const String) -> IO (h Result)
sourceRun = forall (h :: (* -> *) -> *).
Source h -> h (Const String) -> IO (h Result)
sourceRun Source h
s forall b c a. (b -> c) -> (a -> b) -> a -> c
. h (Const String) -> h (Const String)
f } | Source h
s <- forall (h :: (* -> *) -> *). Panfiguration h -> [Source h]
sources Panfiguration h
pfg] }

envs :: (TraversableB h, ConstraintsB h, AllB FromParam h) => Panfiguration h
envs :: forall (h :: (* -> *) -> *).
(TraversableB h, ConstraintsB h, AllB FromParam h) =>
Panfiguration h
envs = forall (h :: (* -> *) -> *).
Case -> (h (Const String) -> IO (h Result)) -> Panfiguration h
mkSource Case
SNAKE forall a b. (a -> b) -> a -> b
$ \h (Const String)
envNames -> do
    [(String, String)]
vars <- IO [(String, String)]
getEnvironment
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall {k} (c :: k -> Constraint) (b :: (k -> *) -> *)
       (f :: k -> *) (g :: k -> *) (e :: * -> *).
(TraversableB b, ConstraintsB b, AllB c b, Applicative e) =>
(forall (a :: k). c a => f a -> e (g a)) -> b f -> e (b g)
btraverseC @FromParam
        (\(Const String
k) -> forall a. String -> Maybe a -> Result a
tag String
k forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse forall a. FromParam a => String -> Either String a
fromParam (forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup String
k [(String, String)]
vars))
        h (Const String)
envNames
  where
    tag :: String -> Maybe a -> Result a
tag String
k = forall a. String -> Maybe a -> Result a
mkResult forall a b. (a -> b) -> a -> b
$ String
"env:" forall a. Semigroup a => a -> a -> a
<> String
k

opts :: (TraversableB h, ConstraintsB h, AllB FromParam h) => Panfiguration h
opts :: forall (h :: (* -> *) -> *).
(TraversableB h, ConstraintsB h, AllB FromParam h) =>
Panfiguration h
opts = forall (h :: (* -> *) -> *).
Case -> (h (Const String) -> IO (h Result)) -> Panfiguration h
mkSource Case
kebab forall a b. (a -> b) -> a -> b
$ \h (Const String)
optNames -> do
    let parsers :: Parser (h Result)
parsers = forall {k} (c :: k -> Constraint) (b :: (k -> *) -> *)
       (f :: k -> *) (g :: k -> *) (e :: * -> *).
(TraversableB b, ConstraintsB b, AllB c b, Applicative e) =>
(forall (a :: k). c a => f a -> e (g a)) -> b f -> e (b g)
btraverseC @FromParam
            (\(Const String
k) -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a. String -> Maybe a -> Result a
tag String
k) forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional forall a b. (a -> b) -> a -> b
$ forall {a}. FromParam a => String -> Parser a
mkOption String
k)
            h (Const String)
optNames
    forall a. ParserInfo a -> IO a
O.execParser forall a b. (a -> b) -> a -> b
$ forall a. Parser a -> InfoMod a -> ParserInfo a
O.info (Parser (h Result)
parsers forall (f :: * -> *) a b. Applicative f => f a -> f (a -> b) -> f b
<**> forall a. Parser (a -> a)
O.helper) forall a. Monoid a => a
mempty
  where
    tag :: String -> Maybe a -> Result a
tag String
k = forall a. String -> Maybe a -> Result a
mkResult forall a b. (a -> b) -> a -> b
$ String
"--" forall a. Semigroup a => a -> a -> a
<> String
k
    mkOption :: String -> Parser a
mkOption String
k = forall a. ReadM a -> Mod OptionFields a -> Parser a
O.option (forall a. (String -> Either String a) -> ReadM a
O.eitherReader forall a. FromParam a => String -> Either String a
fromParam) forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. HasName f => String -> Mod f a
O.long String
k

defaults :: FunctorB h => h Maybe -> Panfiguration h
defaults :: forall (h :: (* -> *) -> *).
FunctorB h =>
h Maybe -> Panfiguration h
defaults h Maybe
def = forall (h :: (* -> *) -> *).
Case -> (h (Const String) -> IO (h Result)) -> Panfiguration h
mkSource Case
AsIs forall a b. (a -> b) -> a -> b
$ forall a b. a -> b -> a
const forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall k (b :: (k -> *) -> *) (f :: k -> *) (g :: k -> *).
FunctorB b =>
(forall (a :: k). f a -> g a) -> b f -> b g
bmap (forall a. String -> Maybe a -> Result a
mkResult String
"the default") h Maybe
def

-- | Provide all the default values by a plain record
fullDefaults :: (BareB b, FunctorB (b Covered)) => b Bare Identity  -> Panfiguration (b Covered)
fullDefaults :: forall (b :: * -> (* -> *) -> *).
(BareB b, FunctorB (b Covered)) =>
b Bare Identity -> Panfiguration (b Covered)
fullDefaults = forall (h :: (* -> *) -> *).
FunctorB h =>
h Maybe -> Panfiguration h
defaults forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k (b :: (k -> *) -> *) (f :: k -> *) (g :: k -> *).
FunctorB b =>
(forall (a :: k). f a -> g a) -> b f -> b g
bmap (forall a. a -> Maybe a
Just forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Identity a -> a
runIdentity) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (b :: * -> (* -> *) -> *).
BareB b =>
b Bare Identity -> b Covered Identity
bcover

logger :: (String -> IO ()) -> Panfiguration h
logger :: forall (h :: (* -> *) -> *). (String -> IO ()) -> Panfiguration h
logger String -> IO ()
f = forall a. Monoid a => a
mempty { loggerFunction :: First (String -> IO ())
loggerFunction = forall (f :: * -> *) a. Applicative f => a -> f a
pure String -> IO ()
f }

resolve :: (String -> IO ()) -> Dict Show a -> Const (NE.NonEmpty String) a -> Result a -> Compose IO Maybe a
resolve :: forall a.
(String -> IO ())
-> Dict Show a
-> Const (NonEmpty String) a
-> Result a
-> Compose IO Maybe a
resolve String -> IO ()
logFunc Dict Show a
Dict (Const NonEmpty String
key) (Result [String]
srcs [String]
used Maybe a
r) = forall {k} {k1} (f :: k -> *) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose forall a b. (a -> b) -> a -> b
$ Maybe a
r forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ case Maybe a
r of
    Maybe a
Nothing -> String -> IO ()
logFunc forall a b. (a -> b) -> a -> b
$ [String] -> String
unwords [NonEmpty String -> String
displayKey NonEmpty String
key forall a. Semigroup a => a -> a -> a
<> String
":", String
"None of", [String] -> String
commas [String]
srcs, String
"provides a value"]
    Just a
v -> String -> IO ()
logFunc forall a b. (a -> b) -> a -> b
$ [String] -> String
unwords [NonEmpty String -> String
displayKey NonEmpty String
key forall a. Semigroup a => a -> a -> a
<> String
":", String
"using", forall a. Show a => a -> String
show a
v, String
"from", [String] -> String
commas [String]
used]
    where
        displayKey :: NonEmpty String -> String
displayKey = forall a. [a] -> [[a]] -> [a]
intercalate String
"." forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. NonEmpty a -> [a]
NE.toList
        commas :: [String] -> String
commas [] = String
""
        commas [String
a] = String
a
        commas [String
a, String
b] = [String] -> String
unwords [String
a, String
"and", String
b]
        commas (String
x : [String]
xs) = String
x forall a. Semigroup a => a -> a -> a
<> String
", " forall a. Semigroup a => a -> a -> a
<> [String] -> String
commas [String]
xs


type Panfigurable h = (FieldNamesB h
    , TraversableB h
    , ApplicativeB h
    , ConstraintsB h
    , AllB Show h
    , AllB FromParam h)

-- | Parse all the relevant environment variables and command line options, then merges them.
exec :: (Panfigurable h)
    => Panfiguration h
    -> IO (h Result)
exec :: forall (h :: (* -> *) -> *).
Panfigurable h =>
Panfiguration h -> IO (h Result)
exec Panfiguration{[Source h]
First Case
First (String -> IO ())
sources :: [Source h]
loggerFunction :: First (String -> IO ())
fieldNameCase :: First Case
sources :: forall (h :: (* -> *) -> *). Panfiguration h -> [Source h]
loggerFunction :: forall (h :: (* -> *) -> *).
Panfiguration h -> First (String -> IO ())
fieldNameCase :: forall (h :: (* -> *) -> *). Panfiguration h -> First Case
..} = do
    let names :: h (Const (NonEmpty [String]))
names = forall (h :: (* -> *) -> *) a b.
FunctorB h =>
(a -> b) -> h (Const a) -> h (Const b)
mapConsts
            (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a -> b) -> a -> b
$ Case -> String -> [String]
split forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a -> a
fromMaybe Case
camel forall a b. (a -> b) -> a -> b
$ forall a. First a -> Maybe a
getFirst First Case
fieldNameCase)
            forall {k} (b :: (k -> *) -> *) a.
(FieldNamesB b, IsString a) =>
b (Const (NonEmpty a))
bnestedFieldNames

    [h Result]
results <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [Source h]
sources forall a b. (a -> b) -> a -> b
$ \Source{Case
h (Const String) -> IO (h Result)
sourceRun :: h (Const String) -> IO (h Result)
sourceCase :: Case
sourceRun :: forall (h :: (* -> *) -> *).
Source h -> h (Const String) -> IO (h Result)
sourceCase :: forall (h :: (* -> *) -> *). Source h -> Case
..} -> h (Const String) -> IO (h Result)
sourceRun
        forall a b. (a -> b) -> a -> b
$ forall (h :: (* -> *) -> *) a b.
FunctorB h =>
(a -> b) -> h (Const a) -> h (Const b)
mapConsts (Case -> [String] -> String
join Case
sourceCase forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat) h (Const (NonEmpty [String]))
names
 
    forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (forall {k} (c :: k -> Constraint) (b :: (k -> *) -> *)
       (f :: k -> *) (g :: k -> *) (h :: k -> *).
(AllB c b, ConstraintsB b, ApplicativeB b) =>
(forall (a :: k). c a => f a -> g a -> h a) -> b f -> b g -> b h
bzipWithC @FromParam forall a. Semigroup a => a -> a -> a
(<>)) (forall {k} (c :: k -> Constraint) (f :: k -> *)
       (b :: (k -> *) -> *).
(AllB c b, ConstraintsB b, ApplicativeB b) =>
(forall (a :: k). c a => f a) -> b f
bpureC @FromParam forall a. Monoid a => a
mempty) [h Result]
results

runMaybe :: (Panfigurable h)
    => Panfiguration h
    -> IO (h Maybe)
runMaybe :: forall (h :: (* -> *) -> *).
Panfigurable h =>
Panfiguration h -> IO (h Maybe)
runMaybe Panfiguration h
panfig = do
    h Result
result <- forall (h :: (* -> *) -> *).
Panfigurable h =>
Panfiguration h -> IO (h Result)
exec Panfiguration h
panfig
    let logFunc :: String -> IO ()
logFunc = forall a. a -> Maybe a -> a
fromMaybe forall a. Monoid a => a
mempty forall a b. (a -> b) -> a -> b
$ forall a. First a -> Maybe a
getFirst forall a b. (a -> b) -> a -> b
$ forall (h :: (* -> *) -> *).
Panfiguration h -> First (String -> IO ())
loggerFunction Panfiguration h
panfig
    forall {k} (e :: * -> *) (b :: (k -> *) -> *) (f :: k -> *).
(Applicative e, TraversableB b) =>
b (Compose e f) -> e (b f)
bsequence forall a b. (a -> b) -> a -> b
$ forall {k} (b :: (k -> *) -> *) (f :: k -> *) (g :: k -> *)
       (h :: k -> *) (i :: k -> *).
ApplicativeB b =>
(forall (a :: k). f a -> g a -> h a -> i a)
-> b f -> b g -> b h -> b i
bzipWith3 (forall a.
(String -> IO ())
-> Dict Show a
-> Const (NonEmpty String) a
-> Result a
-> Compose IO Maybe a
resolve String -> IO ()
logFunc) forall {k} (c :: k -> Constraint) (b :: (k -> *) -> *).
(ConstraintsB b, ApplicativeB b, AllB c b) =>
b (Dict c)
bdicts forall {k} (b :: (k -> *) -> *) a.
(FieldNamesB b, IsString a) =>
b (Const (NonEmpty a))
bnestedFieldNames h Result
result

run :: (BareB b, Panfigurable (b Covered))
    => Panfiguration (b Covered)
    -> IO (b Bare Identity)
run :: forall (b :: * -> (* -> *) -> *).
(BareB b, Panfigurable (b Covered)) =>
Panfiguration (b Covered) -> IO (b Bare Identity)
run Panfiguration (b Covered)
panfig = do
    b Covered Maybe
maybes <- forall (h :: (* -> *) -> *).
Panfigurable h =>
Panfiguration h -> IO (h Maybe)
runMaybe Panfiguration (b Covered)
panfig
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall (b :: * -> (* -> *) -> *).
BareB b =>
b Covered Identity -> b Bare Identity
bstrip forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall a. HasCallStack => String -> a
error String
"Failed to run panfiguration") forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall (e :: * -> *) (b :: (* -> *) -> *).
(Applicative e, TraversableB b) =>
b e -> e (b Identity)
bsequence' b Covered Maybe
maybes