@@ -15,8 +15,18 @@ module Servant.Server.Internal.Config where
15import Data.Proxy
15import Data.Proxy
16import GHC.TypeLits
16import GHC.TypeLits
18−-- | The entire configuration.
18+-- | When calling 'Servant.Server.serve' you have to supply a configuration
19+-- value of type @'Config' configTypes@. This parameter is used to pass values
20+-- to combinators. (It shouldn't be confused with general configuration
21+-- parameters for your web app, like the port, etc.). If you don't use
22+-- combinators that require any config entries, you can just pass 'EmptyConfig'.
23+-- To create a config with entries, use the operator @(':.')@. The parameter of
24+-- the type 'Config' is a type-level list reflecting the types of the contained
27+-- >>> :type True :. () :. EmptyConfig
28+-- True :. () :. EmptyConfig :: Config '[Bool, ()]
19−data Config a where
29+data Config configTypes where
20 EmptyConfig :: Config '[]
30 EmptyConfig :: Config '[]
21 (:.) :: x -> Config xs -> Config (x ': xs)
31 (:.) :: x -> Config xs -> Config (x ': xs)
22infixr 5 :.
32infixr 5 :.
@@ -33,6 +43,19 @@ instance Eq (Config '[]) where
33instance (Eq a, Eq (Config as)) => Eq (Config (a ': as)) where
43instance (Eq a, Eq (Config as)) => Eq (Config (a ': as)) where
34 x1 :. y1 == x2 :. y2 = x1 == x2 && y1 == y2
44 x1 :. y1 == x2 :. y2 = x1 == x2 && y1 == y2
46+-- | This class is used to access config entries in 'Config's. 'getConfigEntry'
47+-- returns the first value where the type matches:
49+-- >>> getConfigEntry (True :. False :. EmptyConfig) :: Bool
52+-- If the 'Config' does not contain an entry of the requested type, you'll get
55+-- >>> getConfigEntry (True :. False :. EmptyConfig) :: String
57+-- No instance for (HasConfigEntry '[] [Char])
36class HasConfigEntry (config :: [*]) (val :: *) where
59class HasConfigEntry (config :: [*]) (val :: *) where
37 getConfigEntry :: Config config -> val
60 getConfigEntry :: Config config -> val
@@ -46,9 +69,28 @@ instance OVERLAPPING_
47-- * support for named subconfigs
70-- * support for named subconfigs
72+-- | Normally config entries are accessed by their types. In case you need
73+-- to have multiple values of the same type in your 'Config' and need to access
74+-- them, we provide 'NamedConfig'. You can think of it as sub-namespaces for
49data NamedConfig (name :: Symbol) (subConfig :: [*])
76data NamedConfig (name :: Symbol) (subConfig :: [*])
50 = NamedConfig (Config subConfig)
77 = NamedConfig (Config subConfig)
79+-- | 'descendIntoNamedConfig' allows you to access `NamedConfig's. Usually you
80+-- won't have to use it yourself but instead use a combinator like
81+-- 'Servant.API.WithNamedConfig.WithNamedConfig'.
83+-- This is how 'descendIntoNamedConfig' works:
85+-- >>> :set -XFlexibleContexts
86+-- >>> let subConfig = True :. EmptyConfig
87+-- >>> :type subConfig
88+-- subConfig :: Config '[Bool]
89+-- >>> let parentConfig = False :. (NamedConfig subConfig :: NamedConfig "subConfig" '[Bool]) :. EmptyConfig
90+-- >>> :type parentConfig
91+-- parentConfig :: Config '[Bool, NamedConfig "subConfig" '[Bool]]
92+-- >>> descendIntoNamedConfig (Proxy :: Proxy "subConfig") parentConfig :: Config '[Bool]
93+-- True :. EmptyConfig
52descendIntoNamedConfig :: forall config name subConfig .
94descendIntoNamedConfig :: forall config name subConfig .
53 HasConfigEntry config (NamedConfig name subConfig) =>
95 HasConfigEntry config (NamedConfig name subConfig) =>
54 Proxy (name :: Symbol) -> Config config -> Config subConfig
96 Proxy (name :: Symbol) -> Config config -> Config subConfig