@@ -12,6 +12,7 @@
12{-# LANGUAGE TypeFamilies #-}
12{-# LANGUAGE TypeFamilies #-}
13{-# LANGUAGE TypeOperators #-}
13{-# LANGUAGE TypeOperators #-}
14{-# LANGUAGE UndecidableInstances #-}
14{-# LANGUAGE UndecidableInstances #-}
15+{-# LANGUAGE OverloadedStrings #-}
16-- | Generalizes all the data needed to make code generation work with
17-- | Generalizes all the data needed to make code generation work with
17-- arbitrary programming languages.
18-- arbitrary programming languages.
@@ -46,43 +47,39 @@ module Servant.Foreign
46 , module Servant.API
47 , module Servant.API
49−#if !MIN_VERSION_base(4,8,0)
50−import Control.Applicative
52import Control.Lens (makeLenses, (%~), (&), (.~),
50import Control.Lens (makeLenses, (%~), (&), (.~),
53 (<>~), _last)
51 (<>~), _last)
54−import Data.Char (toLower, toUpper)
52+import Data.Monoid ((<>))
55−import Data.List
53+import Data.Text
56import Data.Proxy
54import Data.Proxy
57import GHC.Exts (Constraint)
55import GHC.Exts (Constraint)
58import GHC.TypeLits
56import GHC.TypeLits
59import Servant.API
57import Servant.API
58+import Prelude hiding (concat)
61-- | Function name builder that simply concat each part together
60-- | Function name builder that simply concat each part together
62−concatCase :: FunctionName -> String
61+concatCase :: FunctionName -> Text
63concatCase = concat
62concatCase = concat
65-- | Function name builder using the snake_case convention.
64-- | Function name builder using the snake_case convention.
66-- each part is separated by a single underscore character.
65-- each part is separated by a single underscore character.
67−snakeCase :: FunctionName -> String
66+snakeCase :: FunctionName -> Text
68snakeCase = intercalate "_"
67snakeCase = intercalate "_"
70-- | Function name builder using the CamelCase convention.
69-- | Function name builder using the CamelCase convention.
71-- each part begins with an upper case character.
70-- each part begins with an upper case character.
72−camelCase :: FunctionName -> String
71+camelCase :: FunctionName -> Text
73camelCase [] = ""
72camelCase [] = ""
74camelCase (p:ps) = concat $ p : camelCase' ps
73camelCase (p:ps) = concat $ p : camelCase' ps
75 where camelCase' [] = []
74 where camelCase' [] = []
76− camelCase' (r:rs) = capitalize r : camelCase' rs
75+ camelCase' (r:rs) = toUpper r : camelCase' rs
78− capitalize (x:xs) = toUpper x : xs
80−type Arg = String
77+type Arg = Text
82data Segment = Segment { _segment :: SegmentType, _matrix :: [MatrixArg] }
79data Segment = Segment { _segment :: SegmentType, _matrix :: [MatrixArg] }
83 deriving (Eq, Show)
80 deriving (Eq, Show)
85−data SegmentType = Static String -- ^ a static path segment. like "/foo"
82+data SegmentType = Static Text -- ^ a static path segment. like "/foo"
86 | Cap Arg -- ^ a capture. like "/:userid"
83 | Cap Arg -- ^ a capture. like "/:userid"
87 deriving (Eq, Show)
84 deriving (Eq, Show)
@@ -100,11 +97,11 @@ data QueryArg = QueryArg
100 } deriving (Eq, Show)
97 } deriving (Eq, Show)
102data HeaderArg = HeaderArg
99data HeaderArg = HeaderArg
103− { headerArgName :: String
100+ { headerArgName :: Text
105 | ReplaceHeaderArg
102 | ReplaceHeaderArg
106− { headerArgName :: String
103+ { headerArgName :: Text
107− , headerPattern :: String
104+ , headerPattern :: Text
108 } deriving (Eq, Show)
105 } deriving (Eq, Show)
@@ -118,8 +115,8 @@ data Url = Url
118defUrl :: Url
115defUrl :: Url
119defUrl = Url [] []
116defUrl = Url [] []
121−type FunctionName = [String]
118+type FunctionName = [Text]
122−type Method = String
119+type Method = Text
124data Req = Req
121data Req = Req
125 { _reqUrl :: Url
122 { _reqUrl :: Url
@@ -175,7 +172,7 @@ instance (KnownSymbol sym, HasForeign sublayout)
175 req & reqUrl.path <>~ [Segment (Cap str) []]
172 req & reqUrl.path <>~ [Segment (Cap str) []]
176 & funcName %~ (++ ["by", str])
173 & funcName %~ (++ ["by", str])
178− where str = symbolVal (Proxy :: Proxy sym)
175+ where str = pack . symbolVal $ (Proxy :: Proxy sym)
180instance Elem JSON list => HasForeign (Delete list a) where
177instance Elem JSON list => HasForeign (Delete list a) where
181 type Foreign (Delete list a) = Req
178 type Foreign (Delete list a) = Req
@@ -198,7 +195,7 @@ instance (KnownSymbol sym, HasForeign sublayout)
198 foreignFor Proxy req =
195 foreignFor Proxy req =
199 foreignFor subP (req & reqHeaders <>~ [HeaderArg hname])
196 foreignFor subP (req & reqHeaders <>~ [HeaderArg hname])
201− where hname = symbolVal (Proxy :: Proxy sym)
198+ where hname = pack . symbolVal $ (Proxy :: Proxy sym)
202 subP = Proxy :: Proxy sublayout
199 subP = Proxy :: Proxy sublayout
204instance Elem JSON list => HasForeign (Post list a) where
201instance Elem JSON list => HasForeign (Post list a) where
@@ -223,7 +220,7 @@ instance (KnownSymbol sym, HasForeign sublayout)
223 foreignFor (Proxy :: Proxy sublayout) $
220 foreignFor (Proxy :: Proxy sublayout) $
224 req & reqUrl.queryStr <>~ [QueryArg str Normal]
221 req & reqUrl.queryStr <>~ [QueryArg str Normal]
226− where str = symbolVal (Proxy :: Proxy sym)
223+ where str = pack . symbolVal $ (Proxy :: Proxy sym)
228instance (KnownSymbol sym, HasForeign sublayout)
225instance (KnownSymbol sym, HasForeign sublayout)
229 => HasForeign (QueryParams sym a :> sublayout) where
226 => HasForeign (QueryParams sym a :> sublayout) where
@@ -233,7 +230,7 @@ instance (KnownSymbol sym, HasForeign sublayout)
233 foreignFor (Proxy :: Proxy sublayout) $
230 foreignFor (Proxy :: Proxy sublayout) $
234 req & reqUrl.queryStr <>~ [QueryArg str List]
231 req & reqUrl.queryStr <>~ [QueryArg str List]
236− where str = symbolVal (Proxy :: Proxy sym)
233+ where str = pack . symbolVal $ (Proxy :: Proxy sym)
238instance (KnownSymbol sym, HasForeign sublayout)
235instance (KnownSymbol sym, HasForeign sublayout)
239 => HasForeign (QueryFlag sym :> sublayout) where
236 => HasForeign (QueryFlag sym :> sublayout) where
@@ -243,7 +240,7 @@ instance (KnownSymbol sym, HasForeign sublayout)
243 foreignFor (Proxy :: Proxy sublayout) $
240 foreignFor (Proxy :: Proxy sublayout) $
244 req & reqUrl.queryStr <>~ [QueryArg str Flag]
241 req & reqUrl.queryStr <>~ [QueryArg str Flag]
246− where str = symbolVal (Proxy :: Proxy sym)
243+ where str = pack . symbolVal $ (Proxy :: Proxy sym)
248instance (KnownSymbol sym, HasForeign sublayout)
245instance (KnownSymbol sym, HasForeign sublayout)
249 => HasForeign (MatrixParam sym a :> sublayout) where
246 => HasForeign (MatrixParam sym a :> sublayout) where
@@ -253,8 +250,8 @@ instance (KnownSymbol sym, HasForeign sublayout)
253 foreignFor (Proxy :: Proxy sublayout) $
250 foreignFor (Proxy :: Proxy sublayout) $
254 req & reqUrl.path._last.matrix <>~ [QueryArg strArg Normal]
251 req & reqUrl.path._last.matrix <>~ [QueryArg strArg Normal]
256− where str = symbolVal (Proxy :: Proxy sym)
253+ where str = pack . symbolVal $ (Proxy :: Proxy sym)
257− strArg = str ++ "Value"
254+ strArg = str <> "Value"
259instance (KnownSymbol sym, HasForeign sublayout)
256instance (KnownSymbol sym, HasForeign sublayout)
260 => HasForeign (MatrixParams sym a :> sublayout) where
257 => HasForeign (MatrixParams sym a :> sublayout) where
@@ -264,7 +261,7 @@ instance (KnownSymbol sym, HasForeign sublayout)
264 foreignFor (Proxy :: Proxy sublayout) $
261 foreignFor (Proxy :: Proxy sublayout) $
265 req & reqUrl.path._last.matrix <>~ [QueryArg str List]
262 req & reqUrl.path._last.matrix <>~ [QueryArg str List]
267− where str = symbolVal (Proxy :: Proxy sym)
264+ where str = pack . symbolVal $ (Proxy :: Proxy sym)
269instance (KnownSymbol sym, HasForeign sublayout)
266instance (KnownSymbol sym, HasForeign sublayout)
270 => HasForeign (MatrixFlag sym :> sublayout) where
267 => HasForeign (MatrixFlag sym :> sublayout) where
@@ -274,13 +271,13 @@ instance (KnownSymbol sym, HasForeign sublayout)
274 foreignFor (Proxy :: Proxy sublayout) $
271 foreignFor (Proxy :: Proxy sublayout) $
275 req & reqUrl.path._last.matrix <>~ [QueryArg str Flag]
272 req & reqUrl.path._last.matrix <>~ [QueryArg str Flag]
277− where str = symbolVal (Proxy :: Proxy sym)
274+ where str = pack . symbolVal $ (Proxy :: Proxy sym)
279instance HasForeign Raw where
276instance HasForeign Raw where
280 type Foreign Raw = Method -> Req
277 type Foreign Raw = Method -> Req
282 foreignFor Proxy req method =
279 foreignFor Proxy req method =
283− req & funcName %~ ((toLower <$> method) :)
280+ req & funcName %~ ((toLower method) :)
284 & reqMethod .~ method
281 & reqMethod .~ method
286instance (Elem JSON list, HasForeign sublayout) => HasForeign (ReqBody list a :> sublayout) where
283instance (Elem JSON list, HasForeign sublayout) => HasForeign (ReqBody list a :> sublayout) where
@@ -299,7 +296,7 @@ instance (KnownSymbol path, HasForeign sublayout)
299 req & reqUrl.path <>~ [Segment (Static str) []]
296 req & reqUrl.path <>~ [Segment (Static str) []]
300 & funcName %~ (++ [str])
297 & funcName %~ (++ [str])
302− where str = map (\c -> if c == '.' then '_' else c) $ symbolVal (Proxy :: Proxy path)
299+ where str = Data.Text.map (\c -> if c == '.' then '_' else c) . pack . symbolVal $ (Proxy :: Proxy path)
304instance HasForeign sublayout => HasForeign (RemoteHost :> sublayout) where
301instance HasForeign sublayout => HasForeign (RemoteHost :> sublayout) where
305 type Foreign (RemoteHost :> sublayout) = Foreign sublayout
302 type Foreign (RemoteHost :> sublayout) = Foreign sublayout