@@ -81,6 +81,7 @@ import qualified Data.ByteString as BS
81import Data.ByteString.Lazy (ByteString, fromStrict,
81import Data.ByteString.Lazy (ByteString, fromStrict,
83import qualified Data.ByteString.Lazy.Char8 as BC
83import qualified Data.ByteString.Lazy.Char8 as BC
84+import qualified Data.List.NonEmpty as NE
84import Data.Maybe (isJust)
85import Data.Maybe (isJust)
85import Data.String.Conversions (cs)
86import Data.String.Conversions (cs)
86import qualified Data.Text as TextS
87import qualified Data.Text as TextS
@@ -120,6 +121,9 @@ data OctetStream deriving Typeable
120class Accept ctype where
121class Accept ctype where
121 contentType :: Proxy ctype -> M.MediaType
122 contentType :: Proxy ctype -> M.MediaType
124+ contentTypes :: Proxy ctype -> NE.NonEmpty M.MediaType
125+ contentTypes = (NE.:| []) . contentType
123-- | @application/json@
127-- | @application/json@
124instance Accept JSON where
128instance Accept JSON where
125 contentType _ = "application" M.// "json"
129 contentType _ = "application" M.// "json"
@@ -219,9 +223,10 @@ instance AllMime '[] where
219 allMime _ = []
223 allMime _ = []
221instance (Accept ctyp, AllMime ctyps) => AllMime (ctyp ': ctyps) where
225instance (Accept ctyp, AllMime ctyps) => AllMime (ctyp ': ctyps) where
222− allMime _ = (contentType pctyp):allMime pctyps
226+ allMime _ = NE.toList (contentTypes pctyp) ++ allMime pctyps
223− where pctyp = Proxy :: Proxy ctyp
228+ pctyp = Proxy :: Proxy ctyp
224− pctyps = Proxy :: Proxy ctyps
229+ pctyps = Proxy :: Proxy ctyps
226canHandleAcceptH :: AllMime list => Proxy list -> AcceptHeader -> Bool
231canHandleAcceptH :: AllMime list => Proxy list -> AcceptHeader -> Bool
227canHandleAcceptH p (AcceptHeader h ) = isJust $ M.matchAccept (allMime p) h
232canHandleAcceptH p (AcceptHeader h ) = isJust $ M.matchAccept (allMime p) h
@@ -235,25 +240,31 @@ class (AllMime list) => AllMimeRender (list :: [*]) a where
235 -> [(M.MediaType, ByteString)] -- content-types/response pairs
240 -> [(M.MediaType, ByteString)] -- content-types/response pairs
237instance OVERLAPPABLE_ ( MimeRender ctyp a ) => AllMimeRender '[ctyp] a where
242instance OVERLAPPABLE_ ( MimeRender ctyp a ) => AllMimeRender '[ctyp] a where
238− allMimeRender _ a = [(contentType pctyp, mimeRender pctyp a)]
243+ allMimeRender _ a = [ (ct, bs) | ct <- NE.toList $ contentTypes pctyp ]
245+ bs = mimeRender pctyp a
239− where pctyp = Proxy :: Proxy ctyp
246+ pctyp = Proxy :: Proxy ctyp
241instance OVERLAPPABLE_
248instance OVERLAPPABLE_
242 ( MimeRender ctyp a
249 ( MimeRender ctyp a
243 , AllMimeRender (ctyp' ': ctyps) a
250 , AllMimeRender (ctyp' ': ctyps) a
244 ) => AllMimeRender (ctyp ': ctyp' ': ctyps) a where
251 ) => AllMimeRender (ctyp ': ctyp' ': ctyps) a where
253+ [ (ct, bs) | ct <- NE.toList $ contentTypes pctyp ]
254+ ++ allMimeRender pctyps a
245− allMimeRender _ a = (contentType pctyp, mimeRender pctyp a)
256+ bs = mimeRender pctyp a
246− :(allMimeRender pctyps a)
247− where pctyp = Proxy :: Proxy ctyp
257+ pctyp = Proxy :: Proxy ctyp
248− pctyps = Proxy :: Proxy (ctyp' ': ctyps)
258+ pctyps = Proxy :: Proxy (ctyp' ': ctyps)
251-- Ideally we would like to declare a 'MimeRender a NoContent' instance, and
261-- Ideally we would like to declare a 'MimeRender a NoContent' instance, and
252-- then this would be taken care of. However there is no more specific instance
262-- then this would be taken care of. However there is no more specific instance
253-- between that and 'MimeRender JSON a', so we do this instead
263-- between that and 'MimeRender JSON a', so we do this instead
254instance OVERLAPPING_ ( Accept ctyp ) => AllMimeRender '[ctyp] NoContent where
264instance OVERLAPPING_ ( Accept ctyp ) => AllMimeRender '[ctyp] NoContent where
255− allMimeRender _ _ = [(contentType pctyp, "")]
265+ allMimeRender _ _ = [ (ct, "") | ct <- NE.toList $ contentTypes pctyp ]
256− where pctyp = Proxy :: Proxy ctyp
267+ pctyp = Proxy :: Proxy ctyp
258instance OVERLAPPING_
269instance OVERLAPPING_
259 ( AllMime (ctyp ': ctyp' ': ctyps)
270 ( AllMime (ctyp ': ctyp' ': ctyps)
@@ -274,10 +285,13 @@ instance AllMimeUnrender '[] a where
274instance ( MimeUnrender ctyp a
285instance ( MimeUnrender ctyp a
275 , AllMimeUnrender ctyps a
286 , AllMimeUnrender ctyps a
276 ) => AllMimeUnrender (ctyp ': ctyps) a where
287 ) => AllMimeUnrender (ctyp ': ctyps) a where
288+ allMimeUnrender _ bs =
289+ [ (ct, x) | ct <- NE.toList $ contentTypes pctyp ]
290+ ++ allMimeUnrender pctyps bs
277− allMimeUnrender _ val = (contentType pctyp, mimeUnrender pctyp val)
292+ x = mimeUnrender pctyp bs
278− :(allMimeUnrender pctyps val)
279− where pctyp = Proxy :: Proxy ctyp
293+ pctyp = Proxy :: Proxy ctyp
280− pctyps = Proxy :: Proxy ctyps
294+ pctyps = Proxy :: Proxy ctyps
282--------------------------------------------------------------------------
296--------------------------------------------------------------------------
283-- * MimeRender Instances
297-- * MimeRender Instances