{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
module Servant.XML where
import Data.ByteString.Builder (toLazyByteString)
import Data.ByteString.Lazy (toStrict)
import qualified Data.List.NonEmpty as NE
import qualified Network.HTTP.Media as M
import Servant.API
import Xmlbf (FromXml(..), ToXml(..), encode, parse)
import Xmlbf.Xeno (fromRawXml)
data XML
instance Accept XML where
contentTypes :: Proxy XML -> NonEmpty MediaType
contentTypes Proxy XML
_ =
ByteString
"application" ByteString -> ByteString -> MediaType
M.// ByteString
"xml" MediaType -> (ByteString, ByteString) -> MediaType
M./: (ByteString
"charset", ByteString
"utf-8") MediaType -> [MediaType] -> NonEmpty MediaType
forall a. a -> [a] -> NonEmpty a
NE.:| [ ByteString
"application" ByteString -> ByteString -> MediaType
M.// ByteString
"xml" ]
instance ToXml a => MimeRender XML a where
mimeRender :: Proxy XML -> a -> ByteString
mimeRender Proxy XML
_ = Builder -> ByteString
toLazyByteString (Builder -> ByteString) -> (a -> Builder) -> a -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Node] -> Builder
encode ([Node] -> Builder) -> (a -> [Node]) -> a -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> [Node]
forall a. ToXml a => a -> [Node]
toXml
instance FromXml a => MimeUnrender XML a where
mimeUnrender :: Proxy XML -> ByteString -> Either String a
mimeUnrender Proxy XML
_ ByteString
bs = ByteString -> Either String [Node]
fromRawXml (ByteString -> ByteString
toStrict ByteString
bs) Either String [Node]
-> ([Node] -> Either String a) -> Either String a
forall a b.
Either String a -> (a -> Either String b) -> Either String b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Parser a -> [Node] -> Either String a
forall a. Parser a -> [Node] -> Either String a
parse Parser a
forall a (m :: * -> *). (FromXml a, Monad m) => ParserT m a
forall (m :: * -> *). Monad m => ParserT m a
fromXml