@@ -13,18 +13,21 @@
13{-# LANGUAGE TypeOperators #-}
13{-# LANGUAGE TypeOperators #-}
14{-# LANGUAGE UndecidableInstances #-}
14{-# LANGUAGE UndecidableInstances #-}
15{-# LANGUAGE OverloadedStrings #-}
15{-# LANGUAGE OverloadedStrings #-}
16+{-# LANGUAGE PolyKinds #-}
17-- | Generalizes all the data needed to make code generation work with
18-- | Generalizes all the data needed to make code generation work with
18-- arbitrary programming languages.
19-- arbitrary programming languages.
19module Servant.Foreign.Internal where
20module Servant.Foreign.Internal where
21−import Control.Lens (makeLenses, (%~), (&), (.~), (<>~))
22+import Control.Lens (makeLenses, (%~), (&), (.~), (<>~))
22−import qualified Data.Char as C
23+import qualified Data.Char as C
23import Data.Proxy
24import Data.Proxy
24import Data.Text
25import Data.Text
26+import Data.Text.Encoding (decodeUtf8)
25−import GHC.Exts (Constraint)
27+import GHC.Exts (Constraint)
26import GHC.TypeLits
28import GHC.TypeLits
29+import qualified Network.HTTP.Types as HTTP
27−import Prelude hiding (concat)
30+import Prelude hiding (concat)
28import Servant.API
31import Servant.API
30-- | Function name builder that simply concat each part together
33-- | Function name builder that simply concat each part together
@@ -86,11 +89,10 @@ defUrl :: Url
86defUrl = Url [] []
89defUrl = Url [] []
88type FunctionName = [Text]
91type FunctionName = [Text]
91data Req = Req
93data Req = Req
92 { _reqUrl :: Url
94 { _reqUrl :: Url
93− , _reqMethod :: Method
95+ , _reqMethod :: HTTP.Method
94 , _reqHeaders :: [HeaderArg]
96 , _reqHeaders :: [HeaderArg]
95 , _reqBody :: Maybe ForeignType
97 , _reqBody :: Maybe ForeignType
96 , _reqReturnType :: ForeignType
98 , _reqReturnType :: ForeignType
@@ -185,27 +187,18 @@ instance (KnownSymbol sym, HasForeignType lang a, HasForeign lang sublayout)
185 str = pack . symbolVal $ (Proxy :: Proxy sym)
187 str = pack . symbolVal $ (Proxy :: Proxy sym)
186 arg = (str, typeFor lang (Proxy :: Proxy a))
188 arg = (str, typeFor lang (Proxy :: Proxy a))
188−instance (Elem JSON list, HasForeignType lang a)
190+instance (Elem JSON list, HasForeignType lang a, ReflectMethod method)
189− => HasForeign lang (Delete list a) where
191+ => HasForeign lang (Verb method status list a) where
190− type Foreign (Delete list a) = Req
192+ type Foreign (Verb method status list a) = Req
192 foreignFor lang Proxy req =
194 foreignFor lang Proxy req =
193− req & funcName %~ ("delete" :)
195+ req & funcName %~ (methodLC :)
194− & reqMethod .~ "DELETE"
195− & reqReturnType .~ retType
197− retType = typeFor lang (Proxy :: Proxy a)
199−instance (Elem JSON list, HasForeignType lang a)
200− => HasForeign lang (Get list a) where
201− type Foreign (Get list a) = Req
203− foreignFor lang Proxy req =
204− req & funcName %~ ("get" :)
205− & reqMethod .~ "GET"
196+ & reqMethod .~ method
206 & reqReturnType .~ retType
197 & reqReturnType .~ retType
208− retType = typeFor lang (Proxy :: Proxy a)
199+ retType = typeFor lang (Proxy :: Proxy a)
200+ method = reflectMethod (Proxy :: Proxy method)
201+ methodLC = toLower $ decodeUtf8 method
210instance (KnownSymbol sym, HasForeignType lang a, HasForeign lang sublayout)
203instance (KnownSymbol sym, HasForeignType lang a, HasForeign lang sublayout)
211 => HasForeign lang (Header sym a :> sublayout) where
204 => HasForeign lang (Header sym a :> sublayout) where
@@ -220,28 +213,6 @@ instance (KnownSymbol sym, HasForeignType lang a, HasForeign lang sublayout)
220 arg = (hname, typeFor lang (Proxy :: Proxy a))
213 arg = (hname, typeFor lang (Proxy :: Proxy a))
221 subP = Proxy :: Proxy sublayout
214 subP = Proxy :: Proxy sublayout
223−instance (Elem JSON list, HasForeignType lang a)
224− => HasForeign lang (Post list a) where
225− type Foreign (Post list a) = Req
227− foreignFor lang Proxy req =
228− req & funcName %~ ("post" :)
229− & reqMethod .~ "POST"
230− & reqReturnType .~ retType
232− retType = typeFor lang (Proxy :: Proxy a)
234−instance (Elem JSON list, HasForeignType lang a)
235− => HasForeign lang (Put list a) where
236− type Foreign (Put list a) = Req
238− foreignFor lang Proxy req =
239− req & funcName %~ ("put" :)
240− & reqMethod .~ "PUT"
241− & reqReturnType .~ retType
243− retType = typeFor lang (Proxy :: Proxy a)
245instance (KnownSymbol sym, HasForeignType lang a, HasForeign lang sublayout)
216instance (KnownSymbol sym, HasForeignType lang a, HasForeign lang sublayout)
246 => HasForeign lang (QueryParam sym a :> sublayout) where
217 => HasForeign lang (QueryParam sym a :> sublayout) where
247 type Foreign (QueryParam sym a :> sublayout) = Foreign sublayout
218 type Foreign (QueryParam sym a :> sublayout) = Foreign sublayout
@@ -279,10 +250,10 @@ instance (KnownSymbol sym, HasForeignType lang a, a ~ Bool, HasForeign lang subl
279 arg = (str, typeFor lang (Proxy :: Proxy a))
250 arg = (str, typeFor lang (Proxy :: Proxy a))
281instance HasForeign lang Raw where
252instance HasForeign lang Raw where
282− type Foreign Raw = Method -> Req
253+ type Foreign Raw = HTTP.Method -> Req
284 foreignFor _ Proxy req method =
255 foreignFor _ Proxy req method =
285− req & funcName %~ ((toLower method) :)
256+ req & funcName %~ ((toLower $ decodeUtf8 method) :)
286 & reqMethod .~ method
257 & reqMethod .~ method
288instance (Elem JSON list, HasForeignType lang a, HasForeign lang sublayout)
259instance (Elem JSON list, HasForeignType lang a, HasForeign lang sublayout)
@@ -346,4 +317,3 @@ instance (GenerateList start, GenerateList rest) => GenerateList (start :<|> res
346-- describing one endpoint from your API type.
317-- describing one endpoint from your API type.
347listFromAPI :: (HasForeign lang api, GenerateList (Foreign api)) => Proxy lang -> Proxy api -> [Req]
318listFromAPI :: (HasForeign lang api, GenerateList (Foreign api)) => Proxy lang -> Proxy api -> [Req]
348listFromAPI lang p = generateList (foreignFor lang p defReq)
319listFromAPI lang p = generateList (foreignFor lang p defReq)