module ServantSerf.Type.Config where

import qualified Control.Monad as Monad
import qualified Control.Monad.Catch as Exception
import qualified ServantSerf.Exception.InvalidDepth as InvalidDepth
import qualified ServantSerf.Exception.InvalidModuleName as InvalidModuleName
import qualified ServantSerf.Type.Depth as Depth
import qualified ServantSerf.Type.Flag as Flag
import qualified ServantSerf.Type.ModuleName as ModuleName

data Config = Config
  { Config -> String
apiName :: String
  , Config -> Depth
depth :: Depth.Depth
  , Config -> String
excludeSuffix :: String
  , Config -> Bool
help :: Bool
  , Config -> Maybe ModuleName
moduleName :: Maybe ModuleName.ModuleName
  , Config -> String
serverName :: String
  , Config -> Bool
version :: Bool
  }
  deriving (Config -> Config -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Config -> Config -> Bool
$c/= :: Config -> Config -> Bool
== :: Config -> Config -> Bool
$c== :: Config -> Config -> Bool
Eq, Int -> Config -> ShowS
[Config] -> ShowS
Config -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Config] -> ShowS
$cshowList :: [Config] -> ShowS
show :: Config -> String
$cshow :: Config -> String
showsPrec :: Int -> Config -> ShowS
$cshowsPrec :: Int -> Config -> ShowS
Show)

fromFlags :: (Foldable t, Exception.MonadThrow m) => t Flag.Flag -> m Config
fromFlags :: forall (t :: * -> *) (m :: * -> *).
(Foldable t, MonadThrow m) =>
t Flag -> m Config
fromFlags = forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
Monad.foldM forall (m :: * -> *). MonadThrow m => Config -> Flag -> m Config
applyFlag Config
initial

applyFlag :: Exception.MonadThrow m => Config -> Flag.Flag -> m Config
applyFlag :: forall (m :: * -> *). MonadThrow m => Config -> Flag -> m Config
applyFlag Config
config Flag
flag = case Flag
flag of
  Flag.ApiName String
x -> forall (f :: * -> *) a. Applicative f => a -> f a
pure Config
config { apiName :: String
apiName = String
x }
  Flag.Depth String
x -> case String -> Maybe Depth
Depth.fromString String
x of
    Maybe Depth
Nothing -> forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
Exception.throwM forall a b. (a -> b) -> a -> b
$ String -> InvalidDepth
InvalidDepth.InvalidDepth String
x
    Just Depth
y -> forall (f :: * -> *) a. Applicative f => a -> f a
pure Config
config { depth :: Depth
depth = Depth
y }
  Flag.ExcludeSuffix String
x -> forall (f :: * -> *) a. Applicative f => a -> f a
pure Config
config { excludeSuffix :: String
excludeSuffix = String
x }
  Flag
Flag.Help -> forall (f :: * -> *) a. Applicative f => a -> f a
pure Config
config { help :: Bool
help = Bool
True }
  Flag.ModuleName String
x -> case String -> Maybe ModuleName
ModuleName.fromString String
x of
    Maybe ModuleName
Nothing -> forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
Exception.throwM forall a b. (a -> b) -> a -> b
$ String -> InvalidModuleName
InvalidModuleName.InvalidModuleName String
x
    Just ModuleName
y -> forall (f :: * -> *) a. Applicative f => a -> f a
pure Config
config { moduleName :: Maybe ModuleName
moduleName = forall a. a -> Maybe a
Just ModuleName
y }
  Flag.ServerName String
x -> forall (f :: * -> *) a. Applicative f => a -> f a
pure Config
config { serverName :: String
serverName = String
x }
  Flag
Flag.Version -> forall (f :: * -> *) a. Applicative f => a -> f a
pure Config
config { version :: Bool
version = Bool
True }

initial :: Config
initial :: Config
initial = Config
  { apiName :: String
apiName = String
"API"
  , depth :: Depth
depth = Depth
Depth.Deep
  , excludeSuffix :: String
excludeSuffix = String
""
  , help :: Bool
help = Bool
False
  , moduleName :: Maybe ModuleName
moduleName = forall a. Maybe a
Nothing
  , serverName :: String
serverName = String
"server"
  , version :: Bool
version = Bool
False
  }