{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE UndecidableInstances #-}

-- | Html servers
module Mig.Extra.Server.Html (
  -- * Http verbs
  Get,
  Post,
  Put,
  Delete,
  Patch,
  Options,
  Head,
  Trace,

  -- * Response
  Resp (..),
  RespOr,

  -- * utils
  Link (..),

  -- * re-exports
  Body (..),
  module X,
) where

import Mig.Core (Body (..))
import Mig.Core qualified as Core
import Mig.Extra.Server.Common as X
import Text.Blaze.Html5 qualified as H
import Text.Blaze.Html5.Attributes qualified as HA

-- response

newtype Resp a = Resp (Core.Resp Html a)
  deriving newtype (MediaType
ResponseHeaders -> Resp a -> Resp a
MediaType -> Resp a -> Resp a
Status -> Resp a
Status -> RespError (Resp a) -> Resp a
Status -> Resp a -> Resp a
RespBody (Resp a) -> Resp a
Resp a -> ResponseHeaders
Resp a -> Maybe (RespError (Resp a))
Resp a -> Maybe (RespBody (Resp a))
Resp a -> Status
Resp a -> Response
forall a. ToMarkup a => MediaType
forall a. ToMarkup a => ResponseHeaders -> Resp a -> Resp a
forall a. ToMarkup a => MediaType -> Resp a -> Resp a
forall a. ToMarkup a => Status -> Resp a
forall a. ToMarkup a => Status -> RespError (Resp a) -> Resp a
forall a. ToMarkup a => Status -> Resp a -> Resp a
forall a. ToMarkup a => RespBody (Resp a) -> Resp a
forall a. ToMarkup a => Resp a -> ResponseHeaders
forall a. ToMarkup a => Resp a -> Maybe (RespError (Resp a))
forall a. ToMarkup a => Resp a -> Maybe (RespBody (Resp a))
forall a. ToMarkup a => Resp a -> Status
forall a. ToMarkup a => Resp a -> Response
forall a.
(RespBody a -> a)
-> (Status -> RespError a -> a)
-> (Status -> a)
-> (ResponseHeaders -> a -> a)
-> (a -> ResponseHeaders)
-> (Status -> a -> a)
-> (a -> Maybe (RespBody a))
-> (a -> Maybe (RespError a))
-> (a -> Status)
-> (MediaType -> a -> a)
-> MediaType
-> (a -> Response)
-> IsResp a
toResponse :: Resp a -> Response
$ctoResponse :: forall a. ToMarkup a => Resp a -> Response
getMedia :: MediaType
$cgetMedia :: forall a. ToMarkup a => MediaType
setMedia :: MediaType -> Resp a -> Resp a
$csetMedia :: forall a. ToMarkup a => MediaType -> Resp a -> Resp a
getStatus :: Resp a -> Status
$cgetStatus :: forall a. ToMarkup a => Resp a -> Status
getRespError :: Resp a -> Maybe (RespError (Resp a))
$cgetRespError :: forall a. ToMarkup a => Resp a -> Maybe (RespError (Resp a))
getRespBody :: Resp a -> Maybe (RespBody (Resp a))
$cgetRespBody :: forall a. ToMarkup a => Resp a -> Maybe (RespBody (Resp a))
setStatus :: Status -> Resp a -> Resp a
$csetStatus :: forall a. ToMarkup a => Status -> Resp a -> Resp a
getHeaders :: Resp a -> ResponseHeaders
$cgetHeaders :: forall a. ToMarkup a => Resp a -> ResponseHeaders
addHeaders :: ResponseHeaders -> Resp a -> Resp a
$caddHeaders :: forall a. ToMarkup a => ResponseHeaders -> Resp a -> Resp a
noContent :: Status -> Resp a
$cnoContent :: forall a. ToMarkup a => Status -> Resp a
bad :: Status -> RespError (Resp a) -> Resp a
$cbad :: forall a. ToMarkup a => Status -> RespError (Resp a) -> Resp a
ok :: RespBody (Resp a) -> Resp a
$cok :: forall a. ToMarkup a => RespBody (Resp a) -> Resp a
IsResp, Resp a -> Resp a -> Bool
forall a. Eq a => Resp a -> Resp a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Resp a -> Resp a -> Bool
$c/= :: forall a. Eq a => Resp a -> Resp a -> Bool
== :: Resp a -> Resp a -> Bool
$c== :: forall a. Eq a => Resp a -> Resp a -> Bool
Eq, Int -> Resp a -> ShowS
[Resp a] -> ShowS
Resp a -> String
forall a. Show a => Int -> Resp a -> ShowS
forall a. Show a => [Resp a] -> ShowS
forall a. Show a => Resp a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Resp a] -> ShowS
$cshowList :: forall a. Show a => [Resp a] -> ShowS
show :: Resp a -> String
$cshow :: forall a. Show a => Resp a -> String
showsPrec :: Int -> Resp a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Resp a -> ShowS
Show, forall a b. a -> Resp b -> Resp a
forall a b. (a -> b) -> Resp a -> Resp b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> Resp b -> Resp a
$c<$ :: forall a b. a -> Resp b -> Resp a
fmap :: forall a b. (a -> b) -> Resp a -> Resp b
$cfmap :: forall a b. (a -> b) -> Resp a -> Resp b
Functor)

type RespOr err a = Either (Resp err) (Resp a)

type Get m a = Send GET m (Resp a)
type Post m a = Send POST m (Resp a)
type Put m a = Send PUT m (Resp a)
type Delete m a = Send DELETE m (Resp a)
type Patch m a = Send PATCH m (Resp a)
type Options m a = Send OPTIONS m (Resp a)
type Head m a = Send HEAD m (Resp a)
type Trace m a = Send TRACE m (Resp a)

{-| HTML a-links, this type is useful for using
with template engines that rely on @ToJSON@ instance.
Also it can be rendered as Html with @ToMarkup@ instance.
-}
data Link = Link
  { Link -> Url
href :: Url
  , Link -> Text
name :: Text
  }
  deriving (forall x. Rep Link x -> Link
forall x. Link -> Rep Link x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Link x -> Link
$cfrom :: forall x. Link -> Rep Link x
Generic, [Link] -> Encoding
[Link] -> Value
Link -> Bool
Link -> Encoding
Link -> Value
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> (a -> Bool)
-> ToJSON a
omitField :: Link -> Bool
$comitField :: Link -> Bool
toEncodingList :: [Link] -> Encoding
$ctoEncodingList :: [Link] -> Encoding
toJSONList :: [Link] -> Value
$ctoJSONList :: [Link] -> Value
toEncoding :: Link -> Encoding
$ctoEncoding :: Link -> Encoding
toJSON :: Link -> Value
$ctoJSON :: Link -> Value
ToJSON)

instance ToMarkup Link where
  toMarkup :: Link -> Html
toMarkup Link
link = Html -> Html
H.a forall h. Attributable h => h -> Attribute -> h
H.! AttributeValue -> Attribute
HA.href (forall a. IsString a => Url -> a
renderUrl Link
link.href) forall a b. (a -> b) -> a -> b
$ Text -> Html
H.text Link
link.name