@@ -8,6 +8,7 @@
88{-# LANGUAGE OverloadedStrings #-}
99{-# LANGUAGE PolyKinds #-}
1010{-# LANGUAGE ScopedTypeVariables #-}
11+{-# LANGUAGE TupleSections #-}
1112{-# LANGUAGE TypeFamilies #-}
1213{-# LANGUAGE TypeOperators #-}
1314{-# LANGUAGE UndecidableInstances #-}
@@ -81,6 +82,7 @@ import qualified Data.ByteString as BS
8182import Data.ByteString.Lazy (ByteString, fromStrict,
8283 toStrict)
8384import qualified Data.ByteString.Lazy.Char8 as BC
85+import qualified Data.List.NonEmpty as NE
8486import Data.Maybe (isJust)
8587import Data.String.Conversions (cs)
8688import qualified Data.Text as TextS
@@ -119,6 +121,12 @@ data OctetStream deriving Typeable
119121--
120122class Accept ctype where
121123 contentType :: Proxy ctype -> M.MediaType
124+ contentType = NE.head . contentTypes
125+
126+ contentTypes :: Proxy ctype -> NE.NonEmpty M.MediaType
127+ contentTypes = (NE.:| []) . contentType
128+
129+ {-# MINIMAL contentType | contentTypes #-}
122130
123131-- | @application/json@
124132instance Accept JSON where
@@ -219,9 +227,10 @@ instance AllMime '[] where
219227 allMime _ = []
220228
221229instance (Accept ctyp, AllMime ctyps) => AllMime (ctyp ': ctyps) where
222− allMime _ = (contentType pctyp):allMime pctyps
223− where pctyp = Proxy :: Proxy ctyp
224− pctyps = Proxy :: Proxy ctyps
230+ allMime _ = NE.toList (contentTypes pctyp) ++ allMime pctyps
231+ where
232+ pctyp = Proxy :: Proxy ctyp
233+ pctyps = Proxy :: Proxy ctyps
225234
226235canHandleAcceptH :: AllMime list => Proxy list -> AcceptHeader -> Bool
227236canHandleAcceptH p (AcceptHeader h ) = isJust $ M.matchAccept (allMime p) h
@@ -235,25 +244,31 @@ class (AllMime list) => AllMimeRender (list :: [*]) a where
235244 -> [(M.MediaType, ByteString)] -- content-types/response pairs
236245
237246instance OVERLAPPABLE_ ( MimeRender ctyp a ) => AllMimeRender '[ctyp] a where
238− allMimeRender _ a = [(contentType pctyp, mimeRender pctyp a)]
239− where pctyp = Proxy :: Proxy ctyp
247+ allMimeRender _ a = map (, bs) $ NE.toList $ contentTypes pctyp
248+ where
249+ bs = mimeRender pctyp a
250+ pctyp = Proxy :: Proxy ctyp
240251
241252instance OVERLAPPABLE_
242253 ( MimeRender ctyp a
243254 , AllMimeRender (ctyp' ': ctyps) a
244255 ) => AllMimeRender (ctyp ': ctyp' ': ctyps) a where
245− allMimeRender _ a = (contentType pctyp, mimeRender pctyp a)
246− :(allMimeRender pctyps a)
247− where pctyp = Proxy :: Proxy ctyp
248− pctyps = Proxy :: Proxy (ctyp' ': ctyps)
256+ allMimeRender _ a =
257+ (map (, bs) $ NE.toList $ contentTypes pctyp)
258+ ++ allMimeRender pctyps a
259+ where
260+ bs = mimeRender pctyp a
261+ pctyp = Proxy :: Proxy ctyp
262+ pctyps = Proxy :: Proxy (ctyp' ': ctyps)
249263
250264
251265-- Ideally we would like to declare a 'MimeRender a NoContent' instance, and
252266-- then this would be taken care of. However there is no more specific instance
253267-- between that and 'MimeRender JSON a', so we do this instead
254268instance OVERLAPPING_ ( Accept ctyp ) => AllMimeRender '[ctyp] NoContent where
255− allMimeRender _ _ = [(contentType pctyp, "")]
256− where pctyp = Proxy :: Proxy ctyp
269+ allMimeRender _ _ = map (, "") $ NE.toList $ contentTypes pctyp
270+ where
271+ pctyp = Proxy :: Proxy ctyp
257272
258273instance OVERLAPPING_
259274 ( AllMime (ctyp ': ctyp' ': ctyps)
@@ -274,10 +289,13 @@ instance AllMimeUnrender '[] a where
274289instance ( MimeUnrender ctyp a
275290 , AllMimeUnrender ctyps a
276291 ) => AllMimeUnrender (ctyp ': ctyps) a where
277− allMimeUnrender _ val = (contentType pctyp, mimeUnrender pctyp val)
278− :(allMimeUnrender pctyps val)
279− where pctyp = Proxy :: Proxy ctyp
280− pctyps = Proxy :: Proxy ctyps
292+ allMimeUnrender _ bs =
293+ (map (, x) $ NE.toList $ contentTypes pctyp)
294+ ++ allMimeUnrender pctyps bs
295+ where
296+ x = mimeUnrender pctyp bs
297+ pctyp = Proxy :: Proxy ctyp
298+ pctyps = Proxy :: Proxy ctyps
281299
282300--------------------------------------------------------------------------
283301-- * MimeRender Instances