@@ -49,12 +49,16 @@ apiAlias n ls = TypeDecl noLoc n [] alias
50-- type Method = :> ...
50-- type Method = :> ...
51verbAlias :: Name -> Method Solved -> Decl
51verbAlias :: Name -> Method Solved -> Decl
52−verbAlias n m = TypeDecl noLoc n [] (alias (path ++ qry ++ media))
52+verbAlias n m
53+ | _mSupportsMediaDownload m = TypeDecl noLoc n [] download
54+ | otherwise = TypeDecl noLoc n [] rest
56+ rest = alias verb (path ++ qry params ++ media)
54− alias = foldr' (\l r -> TyInfix l (UnQual (sym ":>")) r) verb
57+ download = TyInfix rest (UnQual (sym ":<|>")) $
58+ alias (TyApp (TyApp meth octet) (TyCon "Stream"))
59+ (path ++ qry (Map.delete "alt" (_mParameters m)) ++ [alt] ++ media)
56− -- FIXME: rather than using 'terminal' to get the terminal type,
61+ alias = foldr' (\l r -> TyInfix l (UnQual (sym ":>")) r)
57− -- write a custom 'Link' for servant to specify required params.
59 path :: [Type]
63 path :: [Type]
60 path = map match
64 path = map match
@@ -73,8 +77,8 @@ verbAlias n m = TypeDecl noLoc n [] (alias (path ++ qry ++ media))
73 | otherwise = sing x
77 | otherwise = sing x
75 -- FIXME: order by _mParameterOrder
79 -- FIXME: order by _mParameterOrder
76− qry :: [Type]
80+-- qry :: [Type]
77− qry = mapMaybe f (Map.toList params)
81+ qry = mapMaybe f . Map.toList
79 f (k, x) =
83 f (k, x) =
80 let t = terminalType (_type (_pParam x))
84 let t = terminalType (_type (_pParam x))
@@ -89,39 +93,74 @@ verbAlias n m = TypeDecl noLoc n [] (alias (path ++ qry ++ media))
89 media | Just b <- _mRequest m =
93 media | Just b <- _mRequest m =
90 let g = ref b
94 let g = ref b
91 in if _mSupportsMediaUpload m
95 in if _mSupportsMediaUpload m
92− then [TyApp (TyApp (TyCon "Multipart") typ) (parts g)]
96+ then [TyApp (TyApp (TyCon "Multipart") json) (parts g)]
93− else [TyApp (TyApp (TyCon "ReqBody") typ) (tycon g)]
97+ else [TyApp (TyApp (TyCon "ReqBody") json) (tycon g)]
94 | otherwise = []
98 | otherwise = []
96− parts g = TyCon (UnQual (name (Text.unpack ("'[" <> global g <> ", Body]"))))
100+ parts g = TyCon . UnQual . name . Text.unpack $
97− typ = TyCon "'[JSON]"
101+ "'[" <> global g <> ", Body]"
100− verb = TyApp (TyApp meth typ) res
103+ verb = TyApp (TyApp meth json) $
101− where
104+ maybe (TyCon "()") (tycon . ref) (_mResponse m)
102− meth = TyCon . unqual . Text.unpack $ Text.toTitle (_mHttpMethod m)
106+ meth = TyCon . unqual . Text.unpack $ Text.toTitle (_mHttpMethod m)
108+ octet = TyCon "'[OctetStream]"
103− typ = TyCon "'[JSON]"
109+ json = TyCon "'[JSON]"
104− res = maybe (TyCon "()") (tycon . ref) (_mResponse m)
110+
111+ alt = TyApp (TyApp (TyCon "QueryParam") (sing "alt")) (TyCon "Media")
106 params = _mParameters m
113 params = _mParameters m
115+downloadDecl :: Global
122+downloadDecl n p api url fs m =
123+ googleRequestDecl n (tycon n) rs alt p api url fs m
126+ (TyApp (TyCon "Rs") (TyApp (TyCon "Download") (tycon n)))
129+ alt = Just (var "Media")
108requestDecl :: Global
131requestDecl :: Global
109 -> Prefix
132 -> Prefix
112 -> [Local]
135 -> [Local]
113− -> Method Solved -> Decl
136+ -> Method Solved
114requestDecl n p api url fs m =
138requestDecl n p api url fs m =
115− -- FIXME: associated Rs type
139+ googleRequestDecl n (tycon n) rs alt p api url fs m
141+ rs = InsType noLoc (TyApp (TyCon "Rs") (tycon n)) $
142+ maybe unit_tycon (tycon . ref) (_mResponse m)
144+ alt = var . name . Text.unpack . Text.toUpper <$>
145+ (Map.lookup "alt" (_mParameters m) >>= view iDefault)
147+googleRequestDecl :: Global
157+googleRequestDecl g n assoc alt p api url fs m =
116− InstDecl noLoc Nothing [] [] (unqual "GoogleRequest") [tycon n]
158+ InstDecl noLoc Nothing [] [] (unqual "GoogleRequest") [n]
117− [ response
159+ [ assoc
118 , request
160 , request
119 , requestWithRoute
161 , requestWithRoute
122− response = InsType noLoc (TyApp (TyCon "Rs") (tycon n)) $
123− maybe unit_tycon (tycon . ref) (_mResponse m)
125 request = funD "request" $
164 request = funD "request" $
126 appFun (var "requestWithRoute") [var "defReq", var url]
165 appFun (var "requestWithRoute") [var "defReq", var url]
@@ -130,7 +169,7 @@ requestDecl n p api url fs m =
130 match = Match noLoc (name "requestWithRoute") pats Nothing rhs decls
169 match = Match noLoc (name "requestWithRoute") pats Nothing rhs decls
132 decls = BDecls
171 decls = BDecls
133− [ patBind noLoc (pvar "go") $
172+ [ patBind noLoc pat $
134 appFun (var "clientWithRoute") $
173 appFun (var "clientWithRoute") $
135 [ ExpTypeSig noLoc (var "Proxy") $
174 [ ExpTypeSig noLoc (var "Proxy") $
136 TyApp (TyCon "Proxy") (TyCon (UnQual api))
175 TyApp (TyCon "Proxy") (TyCon (UnQual api))
@@ -138,8 +177,11 @@ requestDecl n p api url fs m =
138 , var "u"
177 , var "u"
181+ pat | _mSupportsMediaDownload m = PInfixApp (pvar "go") (UnQual (sym ":<|>")) PWildCard
182+ | otherwise = pvar "go"
142− rhs = UnGuardedRhs $ appFun (var "go") (map go fs)
184+ rhs = UnGuardedRhs $ appFun (var "go") (map go fs ++ maybeToList alt)
144 go l | Just p <- Map.lookup l ps
186 go l | Just p <- Map.lookup l ps
145 , _pLocation p == Query
187 , _pLocation p == Query
@@ -150,7 +192,7 @@ requestDecl n p api url fs m =
150 v = var . fname p
192 v = var . fname p
152 pats = [pvar "r", pvar "u", prec]
194 pats = [pvar "r", pvar "u", prec]
153− prec = PRec (UnQual (dname n)) [PFieldWildcard]
195+ prec = PRec (UnQual (dname g)) [PFieldWildcard]
155jsonDecls :: Global -> Prefix -> Map Local Solved -> [Decl]
197jsonDecls :: Global -> Prefix -> Map Local Solved -> [Decl]
156jsonDecls g p (Map.toList -> rs) = [from, to]
198jsonDecls g p (Map.toList -> rs) = [from, to]
@@ -342,7 +384,7 @@ externalLit = \case
342 Int32 -> TyCon "Int32"
384 Int32 -> TyCon "Int32"
343 Int64 -> TyCon "Int64"
385 Int64 -> TyCon "Int64"
345− Alt -> TyCon "Alt"
387+ Alt t -> TyCon (unqual (Text.unpack t))
346 Key -> TyCon "Key"
388 Key -> TyCon "Key"
347 OAuthToken -> TyCon "OAuthToken"
389 OAuthToken -> TyCon "OAuthToken"
348 Body -> TyCon "Body"
390 Body -> TyCon "Body"
@@ -362,7 +404,7 @@ internalLit = \case
362 Int32 -> TyCon "Int32"
404 Int32 -> TyCon "Int32"
363 Int64 -> TyCon "Int64"
405 Int64 -> TyCon "Int64"
365− Alt -> TyCon "Alt"
407+ Alt t -> TyCon (unqual (Text.unpack t))
366 Key -> TyCon "Key"
408 Key -> TyCon "Key"
367 OAuthToken -> TyCon "OAuthToken"
409 OAuthToken -> TyCon "OAuthToken"
368 Body -> TyCon "Body"
410 Body -> TyCon "Body"