diff --git a/app/Main.hs b/app/Main.hs index 799cb06..a191b4a 100644 --- a/app/Main.hs +++ b/app/Main.hs @@ -79,8 +79,8 @@ main :: IO () main = do cfg <- Envy.load @ConfigT >>= \case - Left err -> do - Log.error $ printf "failed to read config: %s" err + Left errs -> do + forM_ errs $ Log.error . printf "failed to read config: %s" exitFailure Right c -> pure c diff --git a/src/Envy.hs b/src/Envy.hs index 6e23301..1625b98 100644 --- a/src/Envy.hs +++ b/src/Envy.hs @@ -56,13 +56,13 @@ type t ? d = Optional t d load :: forall (m :: ConfigVariant -> Type) . (Generic (m Value), GFromEnv (Rep (m Spec)) (Rep (m Value))) - => IO (Either String (m Value)) + => IO (Either [String] (m Value)) load = do env <- getEnvironment pure $ to <$> gFromEnv @(Rep (m Spec)) @(Rep (m Value)) Proxy env class GFromEnv spec value where - gFromEnv :: Proxy (spec c) -> [(String, String)] -> Either String (value c) + gFromEnv :: Proxy (spec c) -> [(String, String)] -> Either [String] (value c) instance (GFromEnv i o) @@ -77,7 +77,15 @@ instance gFromEnv Proxy env = M1 <$> gFromEnv @i @o Proxy env instance (GFromEnv i1 o1, GFromEnv i2 o2) => GFromEnv (i1 :*: i2) (o1 :*: o2) where - gFromEnv Proxy env = (:*:) <$> gFromEnv @i1 @o1 Proxy env <*> gFromEnv @i2 @o2 Proxy env + gFromEnv Proxy env = + case (eLhs, eRhs) of + (Left errs1, Right _) -> Left errs1 + (Right _, Left errs2) -> Left errs2 + (Left errs1, Left errs2) -> Left $ errs1 ++ errs2 + (Right lhs, Right rhs) -> Right $ lhs :*: rhs + where + eLhs = gFromEnv @i1 @o1 Proxy env + eRhs = gFromEnv @i2 @o2 Proxy env instance (KnownSymbol sym, EnvVarSpec s t) @@ -86,7 +94,7 @@ instance (M1 S meta2 (Rec0 t)) where gFromEnv Proxy env = - M1 . K1 <$> decodeEnvVar @s @t Proxy varName (lookup varName env) + M1 . K1 <$> first (: []) (decodeEnvVar @s @t Proxy varName (lookup varName env)) where varName = selectorNameToEnvVarName $ symbolVal $ Proxy @sym