on master help sign in
Update comment in Servant.Client.Generic
commit01324754da713435d051fa66a63f4a04d97bc0f4 authorCatherine Galkina <catherine@getshoptv.com> dateTue 13 Dec 2016, 16:40 (10 years ago) parent5fa99be
2 files changed+52−5
servant-client/servant-client.cabal+1−1 servant-client/src/Servant/Client/Generic.hs+51−4
servant-client/servant-client.cabal+1−1
@@ -43,7 +43,7 @@ library
4343 , base64-bytestring >= 1.0.0.1 && < 1.1
4444 , bytestring >= 0.10 && < 0.11
4545 , exceptions >= 0.8 && < 0.9
46− , generics-sop
46+ , generics-sop >= 0.1.0.0 && < 0.3
4747 , http-api-data >= 0.3 && < 0.4
4848 , http-client >= 0.4.18.1 && < 0.6
4949 , http-client-tls >= 0.2.2 && < 0.4
servant-client/src/Servant/Client/Generic.hs+51−4
@@ -12,7 +12,7 @@ module Servant.Client.Generic
1212 , genericMkClientP
1313 ) where
1414
15−import Generics.SOP (Code, Generic, I(..), NP(..), NS(Z), Rep, SOP(..), to)
15+import Generics.SOP (Code, Generic, I(..), NP(..), NS(Z), SOP(..), to)
1616import Servant.API ((:<|>)(..))
1717import Servant.Client (ClientM)
1818
@@ -38,7 +38,7 @@ import Servant.Client (ClientM)
3838-- > , mkNestedClient :: Int -> NestedClient
3939-- > } deriving GHC.Generic
4040-- >
41−-- > instance Generic.SOP.Generic APIClient
41+-- > instance Generics.SOP.Generic APIClient
4242-- > instance (Client API ~ client) => ClientLike client APIClient
4343-- >
4444-- > data NestedClient = NestedClient
@@ -46,11 +46,57 @@ import Servant.Client (ClientM)
4646-- > , postBaz :: Maybe Char -> ClientM ()
4747-- > } deriving GHC.Generic
4848-- >
49−-- > instance Generic.SOP.Generic NestedClient
49+-- > instance Generics.SOP.Generic NestedClient
5050-- > instance (Client NestedAPI ~ client) => ClientLike client NestedClient
5151-- >
5252-- > mkAPIClient :: APIClient
5353-- > mkAPIClient = mkClient (client (Proxy :: Proxy API))
54+--
55+-- By default, left-nested alternatives are expanded:
56+--
57+-- > type API1
58+-- > = "foo" :> Capture "x" Int :> Get '[JSON] Int
59+-- > :<|> "bar" :> QueryParam "a" Char :> Post '[JSON] String
60+-- >
61+-- > type API2
62+-- > = "baz" :> QueryParam "c" Char :> Post '[JSON] ()
63+-- >
64+-- > type API = API1 :<|> API2
65+-- >
66+-- > data APIClient = APIClient
67+-- > { getFoo :: Int -> ClientM Int
68+-- > , postBar :: Maybe Char -> ClientM String
69+-- > , postBaz :: Maybe Char -> ClientM ()
70+-- > } deriving GHC.Generic
71+-- >
72+-- > instance Generics.SOP.Generic APIClient
73+-- > instance (Client API ~ client) => ClientLike client APIClient
74+-- >
75+-- > mkAPIClient :: APIClient
76+-- > mkAPIClient = mkClient (client (Proxy :: Proxy API))
77+--
78+-- If you want to define client for @API1@ as a separate data structure,
79+-- you can use 'genericMkClientP':
80+--
81+-- > data APIClient1 = APIClient1
82+-- > { getFoo :: Int -> ClientM Int
83+-- > , postBar :: Maybe Char -> ClientM String
84+-- > } deriving GHC.Generic
85+-- >
86+-- > instance Generics.SOP.Generic APIClient1
87+-- > instance (Client API1 ~ client) => ClientLike client APIClient1
88+-- >
89+-- > data APIClient = APIClient
90+-- > { mkAPIClient1 :: APIClient1
91+-- > , postBaz :: Maybe Char -> ClientM ()
92+-- > } deriving GHC.Generic
93+-- >
94+-- > instance Generics.SOP.Generic APIClient
95+-- > instance (Client API ~ client) => ClientLike client APIClient where
96+-- > mkClient = genericMkClientP
97+-- >
98+-- > mkAPIClient :: APIClient
99+-- > mkAPIClient = mkClient (client (Proxy :: Proxy API))
54100class ClientLike client custom where
55101 mkClient :: client -> custom
56102 default mkClient :: (Generic custom, Code custom ~ '[xs], GClientList client '[], GClientLikeL (ClientList client '[]) xs)
@@ -100,11 +146,12 @@ instance {-# OVERLAPPABLE #-} (ClientList client acc ~ (client ': acc))
100146 => GClientList client acc where
101147 gClientList c acc = I c :* acc
102148
103−-- | Generate client structure from client type.
149+-- | Generate client structure from client type, expanding left-nested API (done by default).
104150genericMkClientL :: (Generic custom, Code custom ~ '[xs], GClientList client '[], GClientLikeL (ClientList client '[]) xs)
105151 => client -> custom
106152genericMkClientL = to . SOP . Z . gMkClientL . flip gClientList Nil
107153
154+-- | Generate client structure from client type, regarding left-nested API clients as separate data structures.
108155genericMkClientP :: (Generic custom, Code custom ~ '[xs], GClientLikeP client xs)
109156 => client -> custom
110157genericMkClientP = to . SOP . Z . gMkClientP