From 57fe12ce84e0759c7eed4a25d4a3746729496cdb Mon Sep 17 00:00:00 2001 From: Luke Clifton Date: Tue, 22 Dec 2015 15:48:49 +1100 Subject: [PATCH] MimeUnrender and MimeRender instances for Cassava This allows the same API type to be used for `serve` and `client`. --- servant-cassava/src/Servant/CSV/Cassava.hs | 25 +++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/servant-cassava/src/Servant/CSV/Cassava.hs b/servant-cassava/src/Servant/CSV/Cassava.hs index 5bd5a374..3c00a662 100644 --- a/servant-cassava/src/Servant/CSV/Cassava.hs +++ b/servant-cassava/src/Servant/CSV/Cassava.hs @@ -19,7 +19,7 @@ module Servant.CSV.Cassava where import Data.Csv import Data.Proxy (Proxy (..)) import Data.Typeable (Typeable) -import Data.Vector (Vector) +import Data.Vector (Vector, toList) import GHC.Generics (Generic) import qualified Network.HTTP.Media as M import Servant.API (Accept (..), MimeRender (..), @@ -50,6 +50,18 @@ instance ( DefaultOrdered a, ToNamedRecord a, EncodeOpts opt mimeRender _ = encodeDefaultOrderedByNameWith (encodeOpts p) where p = Proxy :: Proxy opt +-- | Encode with 'encodeByNameWith'. The 'Header' param is used for determining +-- the order of headers and fields. +instance ( ToNamedRecord a, EncodeOpts opt + ) => MimeRender (CSV', opt) (Header, Vector a) where + mimeRender _ (hdr, vals) = encodeByNameWith (encodeOpts p) hdr (toList vals) + where p = Proxy :: Proxy opt + +-- | Encode with 'encodeDefaultOrderedByNameWith' +instance ( DefaultOrdered a, ToNamedRecord a, EncodeOpts opt + ) => MimeRender (CSV', opt) (Vector a) where + mimeRender _ = encodeDefaultOrderedByNameWith (encodeOpts p) . toList + where p = Proxy :: Proxy opt -- ** Encode Options @@ -66,6 +78,17 @@ instance EncodeOpts DefaultEncodeOpts where -- ** Instances -- | Decode with 'decodeByNameWith' +instance ( FromNamedRecord a, DecodeOpts opt + ) => MimeUnrender (CSV', opt) (Header, [a]) where + mimeUnrender _ bs = fmap toList <$> decodeByNameWith (decodeOpts p) bs + where p = Proxy :: Proxy opt + +-- | Decode with 'decodeWith'. Assumes data has headers, which are stripped. +instance ( FromRecord a, DecodeOpts opt + ) => MimeUnrender (CSV', opt) [a] where + mimeUnrender _ bs = toList <$> decodeWith (decodeOpts p) HasHeader bs + where p = Proxy :: Proxy opt + instance ( FromNamedRecord a, DecodeOpts opt ) => MimeUnrender (CSV', opt) (Header, Vector a) where mimeUnrender _ = decodeByNameWith (decodeOpts p)