module Cfg.Source.NestedConfig where
import Cfg.Options (ConfigOptions (..))
import Cfg.Source (NestedConfig (..))
import Data.Kind (Type)
import Data.Text (Text)
import Data.Text qualified as T
import Data.Tree (Tree (..))
import GHC.Generics
defaultToNestedConfig :: forall a. (Generic a, GConfigForest (Rep a)) => ConfigOptions -> [Tree Text]
defaultToNestedConfig :: forall a.
(Generic a, GConfigForest (Rep a)) =>
ConfigOptions -> [Tree Text]
defaultToNestedConfig ConfigOptions
opts = forall (a :: * -> *).
GConfigForest a =>
ConfigOptions -> [Tree Text]
gToForest @(Rep a) ConfigOptions
opts
class GConfigForest (a :: Type -> Type) where
gToForest :: ConfigOptions -> [Tree Text]
instance GConfigForest V1 where
gToForest :: ConfigOptions -> [Tree Text]
gToForest ConfigOptions
_ = []
instance GConfigForest U1 where
gToForest :: ConfigOptions -> [Tree Text]
gToForest ConfigOptions
_ = []
instance NestedConfig a => GConfigForest (K1 R a) where
gToForest :: ConfigOptions -> [Tree Text]
gToForest ConfigOptions
_ = forall a. NestedConfig a => [Tree Text]
toNestedConfig @a
instance GConfigForest f => GConfigForest (M1 D s f) where
gToForest :: ConfigOptions -> [Tree Text]
gToForest ConfigOptions
opts = forall (a :: * -> *).
GConfigForest a =>
ConfigOptions -> [Tree Text]
gToForest @f ConfigOptions
opts
instance (Constructor c, GConfigForest f) => GConfigForest (M1 C c f) where
gToForest :: ConfigOptions -> [Tree Text]
gToForest ConfigOptions
opts = forall (a :: * -> *).
GConfigForest a =>
ConfigOptions -> [Tree Text]
gToForest @f ConfigOptions
opts
instance (Selector s, GConfigForest f) => GConfigForest (M1 S s f) where
gToForest :: ConfigOptions -> [Tree Text]
gToForest ConfigOptions
opts =
if Any s f Any -> [Char]
forall {k} (s :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
(f :: k1 -> *) (a :: k1).
Selector s =>
t s f a -> [Char]
forall k1 (t :: Meta -> (k1 -> *) -> k1 -> *) (f :: k1 -> *)
(a :: k1).
t s f a -> [Char]
selName Any s f Any
forall (t :: Meta -> (* -> *) -> * -> *) a. t s f a
m [Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
== [Char]
""
then [Char] -> [Tree Text]
forall a. HasCallStack => [Char] -> a
error [Char]
"Can only create a tree for named product types i.e. Records with named fields"
else
[ Text -> [Tree Text] -> Tree Text
forall a. a -> [Tree a] -> Tree a
Node
(ConfigOptions -> Text -> Text
configOptionsLabelModifier ConfigOptions
opts (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ [Char] -> Text
T.pack (Any s f Any -> [Char]
forall {k} (s :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
(f :: k1 -> *) (a :: k1).
Selector s =>
t s f a -> [Char]
forall k1 (t :: Meta -> (k1 -> *) -> k1 -> *) (f :: k1 -> *)
(a :: k1).
t s f a -> [Char]
selName Any s f Any
forall (t :: Meta -> (* -> *) -> * -> *) a. t s f a
m))
(forall (a :: * -> *).
GConfigForest a =>
ConfigOptions -> [Tree Text]
gToForest @f ConfigOptions
opts)
]
where
m :: t s f a
m :: forall (t :: Meta -> (* -> *) -> * -> *) a. t s f a
m = t s f a
forall a. HasCallStack => a
undefined
instance (GConfigForest a, GConfigForest b) => GConfigForest (a :*: b) where
gToForest :: ConfigOptions -> [Tree Text]
gToForest ConfigOptions
opts = forall (a :: * -> *).
GConfigForest a =>
ConfigOptions -> [Tree Text]
gToForest @a ConfigOptions
opts [Tree Text] -> [Tree Text] -> [Tree Text]
forall a. Semigroup a => a -> a -> a
<> forall (a :: * -> *).
GConfigForest a =>
ConfigOptions -> [Tree Text]
gToForest @b ConfigOptions
opts
instance GConfigForest (a :+: b) where
gToForest :: ConfigOptions -> [Tree Text]
gToForest ConfigOptions
_ = []