@@ -49,12 +49,16 @@ apiAlias n ls = TypeDecl noLoc n [] alias
4949
5050-- type Method = :> ...
5151verbAlias :: 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
5355 where
54− alias = foldr' (\l r -> TyInfix l (UnQual (sym ":>")) r) verb
56+ rest = alias verb (path ++ qry params ++ media)
57+ download = TyInfix rest (UnQual (sym ":<|>")) $
58+ alias (TyApp (TyApp meth octet) (TyCon "Stream"))
59+ (path ++ qry (Map.delete "alt" (_mParameters m)) ++ [alt] ++ media)
5560
56− -- FIXME: rather than using 'terminal' to get the terminal type,
57− -- write a custom 'Link' for servant to specify required params.
61+ alias = foldr' (\l r -> TyInfix l (UnQual (sym ":>")) r)
5862
5963 path :: [Type]
6064 path = map match
@@ -73,8 +77,8 @@ verbAlias n m = TypeDecl noLoc n [] (alias (path ++ qry ++ media))
7377 | otherwise = sing x
7478
7579 -- FIXME: order by _mParameterOrder
76− qry :: [Type]
77− qry = mapMaybe f (Map.toList params)
80+-- qry :: [Type]
81+ qry = mapMaybe f . Map.toList
7882 where
7983 f (k, x) =
8084 let t = terminalType (_type (_pParam x))
@@ -89,39 +93,74 @@ verbAlias n m = TypeDecl noLoc n [] (alias (path ++ qry ++ media))
8993 media | Just b <- _mRequest m =
9094 let g = ref b
9195 in if _mSupportsMediaUpload m
92− then [TyApp (TyApp (TyCon "Multipart") typ) (parts g)]
93− else [TyApp (TyApp (TyCon "ReqBody") typ) (tycon g)]
96+ then [TyApp (TyApp (TyCon "Multipart") json) (parts g)]
97+ else [TyApp (TyApp (TyCon "ReqBody") json) (tycon g)]
9498 | otherwise = []
9599 where
96− parts g = TyCon (UnQual (name (Text.unpack ("'[" <> global g <> ", Body]"))))
97− typ = TyCon "'[JSON]"
100+ parts g = TyCon . UnQual . name . Text.unpack $
101+ "'[" <> global g <> ", Body]"
98102
99− verb :: Type
100− verb = TyApp (TyApp meth typ) res
101− where
102− meth = TyCon . unqual . Text.unpack $ Text.toTitle (_mHttpMethod m)
103− typ = TyCon "'[JSON]"
104− res = maybe (TyCon "()") (tycon . ref) (_mResponse m)
103+ verb = TyApp (TyApp meth json) $
104+ maybe (TyCon "()") (tycon . ref) (_mResponse m)
105+
106+ meth = TyCon . unqual . Text.unpack $ Text.toTitle (_mHttpMethod m)
107+
108+ octet = TyCon "'[OctetStream]"
109+ json = TyCon "'[JSON]"
110+
111+ alt = TyApp (TyApp (TyCon "QueryParam") (sing "alt")) (TyCon "Media")
105112
106113 params = _mParameters m
107114
115+downloadDecl :: Global
116+ -> Prefix
117+ -> Name
118+ -> Name
119+ -> [Local]
120+ -> Method Solved
121+ -> Decl
122+downloadDecl n p api url fs m =
123+ googleRequestDecl n (tycon n) rs alt p api url fs m
124+ where
125+ rs = InsType noLoc
126+ (TyApp (TyCon "Rs") (TyApp (TyCon "Download") (tycon n)))
127+ (TyCon "Stream")
128+
129+ alt = Just (var "Media")
130+
108131requestDecl :: Global
109132 -> Prefix
110133 -> Name
111134 -> Name
112135 -> [Local]
113− -> Method Solved -> Decl
136+ -> Method Solved
137+ -> Decl
114138requestDecl n p api url fs m =
115− -- FIXME: associated Rs type
116− InstDecl noLoc Nothing [] [] (unqual "GoogleRequest") [tycon n]
117− [ response
139+ googleRequestDecl n (tycon n) rs alt p api url fs m
140+ where
141+ rs = InsType noLoc (TyApp (TyCon "Rs") (tycon n)) $
142+ maybe unit_tycon (tycon . ref) (_mResponse m)
143+
144+ alt = var . name . Text.unpack . Text.toUpper <$>
145+ (Map.lookup "alt" (_mParameters m) >>= view iDefault)
146+
147+googleRequestDecl :: Global
148+ -> Type
149+ -> InstDecl
150+ -> Maybe Exp
151+ -> Prefix
152+ -> Name
153+ -> Name
154+ -> [Local]
155+ -> Method Solved
156+ -> Decl
157+googleRequestDecl g n assoc alt p api url fs m =
158+ InstDecl noLoc Nothing [] [] (unqual "GoogleRequest") [n]
159+ [ assoc
118160 , request
119161 , requestWithRoute
120162 ]
121163 where
122− response = InsType noLoc (TyApp (TyCon "Rs") (tycon n)) $
123− maybe unit_tycon (tycon . ref) (_mResponse m)
124−
125164 request = funD "request" $
126165 appFun (var "requestWithRoute") [var "defReq", var url]
127166
@@ -130,7 +169,7 @@ requestDecl n p api url fs m =
130169 match = Match noLoc (name "requestWithRoute") pats Nothing rhs decls
131170
132171 decls = BDecls
133− [ patBind noLoc (pvar "go") $
172+ [ patBind noLoc pat $
134173 appFun (var "clientWithRoute") $
135174 [ ExpTypeSig noLoc (var "Proxy") $
136175 TyApp (TyCon "Proxy") (TyCon (UnQual api))
@@ -138,8 +177,11 @@ requestDecl n p api url fs m =
138177 , var "u"
139178 ]
140179 ]
180+ where
181+ pat | _mSupportsMediaDownload m = PInfixApp (pvar "go") (UnQual (sym ":<|>")) PWildCard
182+ | otherwise = pvar "go"
141183
142− rhs = UnGuardedRhs $ appFun (var "go") (map go fs)
184+ rhs = UnGuardedRhs $ appFun (var "go") (map go fs ++ maybeToList alt)
143185 where
144186 go l | Just p <- Map.lookup l ps
145187 , _pLocation p == Query
@@ -150,7 +192,7 @@ requestDecl n p api url fs m =
150192 v = var . fname p
151193
152194 pats = [pvar "r", pvar "u", prec]
153− prec = PRec (UnQual (dname n)) [PFieldWildcard]
195+ prec = PRec (UnQual (dname g)) [PFieldWildcard]
154196
155197jsonDecls :: Global -> Prefix -> Map Local Solved -> [Decl]
156198jsonDecls g p (Map.toList -> rs) = [from, to]
@@ -342,7 +384,7 @@ externalLit = \case
342384 Int32 -> TyCon "Int32"
343385 Int64 -> TyCon "Int64"
344386
345− Alt -> TyCon "Alt"
387+ Alt t -> TyCon (unqual (Text.unpack t))
346388 Key -> TyCon "Key"
347389 OAuthToken -> TyCon "OAuthToken"
348390 Body -> TyCon "Body"
@@ -362,7 +404,7 @@ internalLit = \case
362404 Int32 -> TyCon "Int32"
363405 Int64 -> TyCon "Int64"
364406
365− Alt -> TyCon "Alt"
407+ Alt t -> TyCon (unqual (Text.unpack t))
366408 Key -> TyCon "Key"
367409 OAuthToken -> TyCon "OAuthToken"
368410 Body -> TyCon "Body"