module Web.Minion.Media.Json where import Data.Aeson (FromJSON, ToJSON, eitherDecode) import Data.Aeson qualified as Aeson import Data.Bifunctor (Bifunctor (..)) import Data.ByteString.Builder qualified as Bytes.Builder import Data.List.NonEmpty qualified as Nel import Data.Text qualified as Text import Network.HTTP.Media qualified as Http import Network.HTTP.Types qualified as Http import Network.Wai qualified as Wai import Web.Minion.Media import Web.Minion.Request.Body import Web.Minion.Response.Body (Encode (encode)) data Json instance ContentType Json where media :: NonEmpty MediaType media = ByteString "application" ByteString -> ByteString -> MediaType Http.// ByteString "json" MediaType -> (ByteString, ByteString) -> MediaType Http./: (ByteString "charset", ByteString "utf-8") MediaType -> [MediaType] -> NonEmpty MediaType forall a. a -> [a] -> NonEmpty a Nel.:| [ByteString "application" ByteString -> ByteString -> MediaType Http.// ByteString "json"] instance (FromJSON a) => Decode Json a where decode :: ByteString -> Either Text a decode = (String -> Text) -> Either String a -> Either Text a forall a b c. (a -> b) -> Either a c -> Either b c forall (p :: * -> * -> *) a b c. Bifunctor p => (a -> b) -> p a c -> p b c first String -> Text Text.pack (Either String a -> Either Text a) -> (ByteString -> Either String a) -> ByteString -> Either Text a forall b c a. (b -> c) -> (a -> b) -> a -> c . ByteString -> Either String a forall a. FromJSON a => ByteString -> Either String a eitherDecode instance (ToJSON a) => Encode Json a where encode :: a -> Response encode a a = Status -> ResponseHeaders -> Builder -> Response Wai.responseBuilder Status Http.status200 [(HeaderName Http.hContentType, MediaType -> ByteString forall h. RenderHeader h => h -> ByteString Http.renderHeader (MediaType -> ByteString) -> MediaType -> ByteString forall a b. (a -> b) -> a -> b $ NonEmpty MediaType -> MediaType forall a. NonEmpty a -> a Nel.head (NonEmpty MediaType -> MediaType) -> NonEmpty MediaType -> MediaType forall a b. (a -> b) -> a -> b $ forall a. ContentType a => NonEmpty MediaType forall {k} (a :: k). ContentType a => NonEmpty MediaType media @Json)] (ByteString -> Builder Bytes.Builder.lazyByteString (ByteString -> Builder) -> ByteString -> Builder forall a b. (a -> b) -> a -> b $ a -> ByteString forall a. ToJSON a => a -> ByteString Aeson.encode a a)