@@ -14,7 +14,7 @@ module Servant.JS.Internal where
1414import Control.Applicative
1515#endif
1616import Control.Lens
17−import Data.Char (toLower)
17+import Data.Char (toLower, toUpper)
1818import qualified Data.CharSet as Set
1919import qualified Data.CharSet.Unicode.Category as Set
2020import Data.List
@@ -29,7 +29,7 @@ import Servant.API
2929-- customize the output
3030data CommonGeneratorOptions = CommonGeneratorOptions
3131 {
32− functionRenamer :: String -> String -- ^ function transforming function names
32+ functionNameBuilder :: FunctionName -> String -- ^ function generating function names
3333 , requestBody :: String -- ^ name used when a user want to send the request body (to let you redefine it)
3434 , successCallback :: String -- ^ name of the callback parameter when the request was successful
3535 , errorCallback :: String -- ^ name of the callback parameter when the request reported an error
@@ -41,7 +41,7 @@ data CommonGeneratorOptions = CommonGeneratorOptions
4141--
4242-- @
4343-- > defCommonGeneratorOptions = CommonGeneratorOptions
44−-- > { functionRenamer = id
44+-- > { functionNameBuilder = camelCase
4545-- > , requestBody = "body"
4646-- > , successCallback = "onSuccess"
4747-- > , errorCallback = "onError"
@@ -52,13 +52,32 @@ data CommonGeneratorOptions = CommonGeneratorOptions
5252defCommonGeneratorOptions :: CommonGeneratorOptions
5353defCommonGeneratorOptions = CommonGeneratorOptions
5454 {
55− functionRenamer = id
55+ functionNameBuilder = camelCase
5656 , requestBody = "body"
5757 , successCallback = "onSuccess"
5858 , errorCallback = "onError"
5959 , moduleName = ""
6060 , urlPrefix = ""
6161 }
62+
63+-- | Function name builder that simply concat each part together
64+concatCase :: FunctionName -> String
65+concatCase = concat
66+
67+-- | Function name builder using the snake_case convention.
68+-- each part is separated by a single underscore character.
69+snakeCase :: FunctionName -> String
70+snakeCase = intercalate "_"
71+
72+-- | Function name builder using the CamelCase convention.
73+-- each part begins with an upper case character.
74+camelCase :: FunctionName -> String
75+camelCase [] = ""
76+camelCase (p:ps) = concat $ p : camelCase' ps
77+ where camelCase' [] = []
78+ camelCase' (r:rs) = capitalize r : camelCase' rs
79+ capitalize [] = []
80+ capitalize (x:xs) = toUpper x : xs
6281
6382type Arg = String
6483
@@ -149,7 +168,7 @@ data Url = Url
149168defUrl :: Url
150169defUrl = Url [] []
151170
152−type FunctionName = String
171+type FunctionName = [String]
153172type Method = String
154173
155174data AjaxReq = AjaxReq
@@ -226,7 +245,7 @@ paramToStr qarg notTheEnd =
226245 where name = qarg ^. argName
227246
228247defReq :: AjaxReq
229−defReq = AjaxReq defUrl "GET" [] False ""
248+defReq = AjaxReq defUrl "GET" [] False []
230249
231250type family Elem (a :: *) (ls::[*]) :: Constraint where
232251 Elem a '[] = 'False ~ 'True
@@ -252,6 +271,7 @@ instance (KnownSymbol sym, HasJS sublayout)
252271 javascriptFor Proxy req =
253272 javascriptFor (Proxy :: Proxy sublayout) $
254273 req & reqUrl.path <>~ [Segment (Cap str) []]
274+ & funcName %~ (++ ["by", str])
255275
256276 where str = symbolVal (Proxy :: Proxy sym)
257277
@@ -259,14 +279,14 @@ instance Elem JSON list => HasJS (Delete list a) where
259279 type JS (Delete list a) = AjaxReq
260280
261281 javascriptFor Proxy req =
262− req & funcName %~ ("delete" <>)
282+ req & funcName %~ ("delete" :)
263283 & reqMethod .~ "DELETE"
264284
265285instance Elem JSON list => HasJS (Get list a) where
266286 type JS (Get list a) = AjaxReq
267287
268288 javascriptFor Proxy req =
269− req & funcName %~ ("get" <>)
289+ req & funcName %~ ("get" :)
270290 & reqMethod .~ "GET"
271291
272292instance (KnownSymbol sym, HasJS sublayout)
@@ -283,14 +303,14 @@ instance Elem JSON list => HasJS (Post list a) where
283303 type JS (Post list a) = AjaxReq
284304
285305 javascriptFor Proxy req =
286− req & funcName %~ ("post" <>)
306+ req & funcName %~ ("post" :)
287307 & reqMethod .~ "POST"
288308
289309instance Elem JSON list => HasJS (Put list a) where
290310 type JS (Put list a) = AjaxReq
291311
292312 javascriptFor Proxy req =
293− req & funcName %~ ("put" <>)
313+ req & funcName %~ ("put" :)
294314 & reqMethod .~ "PUT"
295315
296316instance (KnownSymbol sym, HasJS sublayout)
@@ -358,7 +378,7 @@ instance HasJS Raw where
358378 type JS Raw = Method -> AjaxReq
359379
360380 javascriptFor Proxy req method =
361− req & funcName %~ ((toLower <$> method) <>)
381+ req & funcName %~ ((toLower <$> method) :)
362382 & reqMethod .~ method
363383
364384instance (Elem JSON list, HasJS sublayout) => HasJS (ReqBody list a :> sublayout) where
@@ -375,7 +395,7 @@ instance (KnownSymbol path, HasJS sublayout)
375395 javascriptFor Proxy req =
376396 javascriptFor (Proxy :: Proxy sublayout) $
377397 req & reqUrl.path <>~ [Segment (Static str) []]
378− & funcName %~ (str <>)
398+ & funcName %~ (++ [str])
379399
380400 where str = map (\c -> if c == '.' then '_' else c) $ symbolVal (Proxy :: Proxy path)
381401