@@ -24,29 +24,12 @@ import Servant.API
25type Arg = String
25type Arg = String
27−data Segment = Static String -- ^ a static path segment. like "/foo"
27+data Segment = Segment { _segment :: SegmentType, _matrix :: [MatrixArg] }
28− | Cap Arg -- ^ a capture. like "/:userid"
29 deriving (Eq, Show)
28 deriving (Eq, Show)
31−
30+data SegmentType = Static String -- ^ a static path segment. like "/foo"
32−isCapture :: Segment -> Bool
31+ | Cap Arg -- ^ a capture. like "/:userid"
33−isCapture (Cap _) = True
32+ deriving (Eq, Show)
36−captureArg :: Segment -> Arg
37−captureArg (Cap s) = s
38−captureArg _ = error "captureArg called on non capture"
40−jsSegments :: [Segment] -> String
42−jsSegments [x] = "/" ++ segmentToStr x False
43−jsSegments (x:xs) = "/" ++ segmentToStr x True ++ jsSegments xs
45−segmentToStr :: Segment -> Bool -> String
46−segmentToStr (Static s) notTheEnd =
47− if notTheEnd then s else s ++ "'"
48−segmentToStr (Cap s) notTheEnd =
49− "' + encodeURIComponent(" ++ s ++ if notTheEnd then ") + '" else ")"
51type Path = [Segment]
34type Path = [Segment]
@@ -113,6 +96,8 @@ toValidFunctionName (x:xs) = [setFirstChar x] <> filter remainder xs
113 , Set.connectorPunctuation ]
96 , Set.connectorPunctuation ]
114toValidFunctionName [] = "_"
97toValidFunctionName [] = "_"
99+type MatrixArg = QueryArg
116data Url = Url
101data Url = Url
117 { _path :: Path
102 { _path :: Path
118 , _queryStr :: [QueryArg]
103 , _queryStr :: [QueryArg]
@@ -133,13 +118,52 @@ data AjaxReq = AjaxReq
133 } deriving (Eq, Show)
118 } deriving (Eq, Show)
135makeLenses ''QueryArg
120makeLenses ''QueryArg
136makeLenses ''Url
122makeLenses ''Url
137makeLenses ''AjaxReq
123makeLenses ''AjaxReq
125+isCapture :: Segment -> Bool
126+isCapture (Segment (Cap _) _) = True
129+hasMatrixArgs :: Segment -> Bool
130+hasMatrixArgs (Segment _ (_:_)) = True
131+hasMatrixArgs _ = False
133+hasArgs :: Segment -> Bool
134+hasArgs s = isCapture s || hasMatrixArgs s
136+matrixArgs :: Segment -> [MatrixArg]
137+matrixArgs (Segment _ ms) = ms
139+captureArg :: Segment -> Arg
140+captureArg (Segment (Cap s) _) = s
141+captureArg _ = error "captureArg called on non capture"
143+jsSegments :: [Segment] -> String
145+jsSegments [x] = "/" ++ segmentToStr x False
146+jsSegments (x:xs) = "/" ++ segmentToStr x True ++ jsSegments xs
148+segmentToStr :: Segment -> Bool -> String
149+segmentToStr (Segment st ms) notTheEnd =
150+ segmentTypeToStr st ++ jsMParams ms ++ if notTheEnd then "" else "'"
152+segmentTypeToStr :: SegmentType -> String
153+segmentTypeToStr (Static s) = s
154+segmentTypeToStr (Cap s) = "' + encodeURIComponent(" ++ s ++ ") + '"
156+jsGParams :: String -> [QueryArg] -> String
158+jsGParams _ [x] = paramToStr x False
159+jsGParams s (x:xs) = paramToStr x True ++ s ++ jsGParams s xs
139jsParams :: [QueryArg] -> String
161jsParams :: [QueryArg] -> String
140−jsParams [] = ""
162+jsParams = jsGParams "&"
141−jsParams [x] = paramToStr x False
163+
142−jsParams (x:xs) = paramToStr x True ++ "&" ++ jsParams xs
164+jsMParams :: [MatrixArg] -> String
166+jsMParams xs = ";" ++ jsGParams ";" xs
144paramToStr :: QueryArg -> Bool -> String
168paramToStr :: QueryArg -> Bool -> String
145paramToStr qarg notTheEnd =
169paramToStr qarg notTheEnd =
@@ -184,7 +208,7 @@ instance (KnownSymbol sym, HasJQ sublayout)
185 jqueryFor Proxy req =
209 jqueryFor Proxy req =
186 jqueryFor (Proxy :: Proxy sublayout) $
210 jqueryFor (Proxy :: Proxy sublayout) $
187− req & reqUrl.path <>~ [Cap str]
211+ req & reqUrl.path <>~ [Segment (Cap str) []]
189 where str = symbolVal (Proxy :: Proxy sym)
213 where str = symbolVal (Proxy :: Proxy sym)
@@ -256,6 +280,37 @@ instance (KnownSymbol sym, HasJQ sublayout)
257 where str = symbolVal (Proxy :: Proxy sym)
281 where str = symbolVal (Proxy :: Proxy sym)
283+instance (KnownSymbol sym, HasJQ sublayout)
284+ => HasJQ (MatrixParam sym a :> sublayout) where
285+ type JQ (MatrixParam sym a :> sublayout) = JQ sublayout
287+ jqueryFor Proxy req =
288+ jqueryFor (Proxy :: Proxy sublayout) $
289+ req & reqUrl.path._last.matrix <>~ [QueryArg strArg Normal]
291+ where str = symbolVal (Proxy :: Proxy sym)
292+ strArg = str ++ "Value"
294+instance (KnownSymbol sym, HasJQ sublayout)
295+ => HasJQ (MatrixParams sym a :> sublayout) where
296+ type JQ (MatrixParams sym a :> sublayout) = JQ sublayout
298+ jqueryFor Proxy req =
299+ jqueryFor (Proxy :: Proxy sublayout) $
300+ req & reqUrl.path._last.matrix <>~ [QueryArg str List]
302+ where str = symbolVal (Proxy :: Proxy sym)
304+instance (KnownSymbol sym, HasJQ sublayout)
305+ => HasJQ (MatrixFlag sym :> sublayout) where
306+ type JQ (MatrixFlag sym :> sublayout) = JQ sublayout
308+ jqueryFor Proxy req =
309+ jqueryFor (Proxy :: Proxy sublayout) $
310+ req & reqUrl.path._last.matrix <>~ [QueryArg str Flag]
312+ where str = symbolVal (Proxy :: Proxy sym)
259instance HasJQ Raw where
314instance HasJQ Raw where
260 type JQ Raw = Method -> AjaxReq
315 type JQ Raw = Method -> AjaxReq
@@ -276,7 +331,7 @@ instance (KnownSymbol path, HasJQ sublayout)
277 jqueryFor Proxy req =
332 jqueryFor Proxy req =
278 jqueryFor (Proxy :: Proxy sublayout) $
333 jqueryFor (Proxy :: Proxy sublayout) $
279− req & reqUrl.path <>~ [Static str]
334+ req & reqUrl.path <>~ [Segment (Static str) []]
280 & funcName %~ (str <>)
335 & funcName %~ (str <>)
282 where str = map (\c -> if c == '.' then '_' else c) $ symbolVal (Proxy :: Proxy path)
337 where str = map (\c -> if c == '.' then '_' else c) $ symbolVal (Proxy :: Proxy path)