webgear-openapi-1.0.0: src/WebGear/OpenApi/Trait/Header.hs
{-# OPTIONS_GHC -Wno-orphans #-}
-- | OpenApi implementation of 'Header' trait.
module WebGear.OpenApi.Trait.Header () where
import Control.Lens ((&), (.~), (?~))
import Data.OpenApi hiding (Response)
import Data.Proxy (Proxy (Proxy))
import Data.String (fromString)
import Data.Text (Text)
import GHC.TypeLits (KnownSymbol, symbolVal)
import WebGear.Core.Modifiers (Existence (..))
import WebGear.Core.Request (Request)
import WebGear.Core.Response (Response)
import WebGear.Core.Trait (Get (..), Set (..), Trait, TraitAbsence)
import qualified WebGear.Core.Trait.Header as WG
import WebGear.OpenApi.Handler (DocNode (..), OpenApiHandler (..), nullNode, singletonNode)
mkParam ::
forall name val.
(KnownSymbol name, ToSchema val) =>
Proxy name ->
Proxy val ->
Bool ->
Param
mkParam _ _ isRequired =
(mempty :: Param)
& name .~ fromString @Text (symbolVal $ Proxy @name)
& in_ .~ ParamHeader
& required ?~ isRequired
& schema ?~ Inline (toSchema $ Proxy @val)
instance (KnownSymbol name, ToSchema val, TraitAbsence (WG.Header Required ps name val) Request) => Get (OpenApiHandler m) (WG.Header Required ps name val) Request where
{-# INLINEABLE getTrait #-}
getTrait WG.Header =
OpenApiHandler $ singletonNode (DocRequestHeader $ mkParam (Proxy @name) (Proxy @val) True)
instance (KnownSymbol name, ToSchema val, TraitAbsence (WG.Header Optional ps name val) Request) => Get (OpenApiHandler m) (WG.Header Optional ps name val) Request where
{-# INLINEABLE getTrait #-}
getTrait WG.Header =
OpenApiHandler $ singletonNode (DocRequestHeader $ mkParam (Proxy @name) (Proxy @val) False)
instance (KnownSymbol name, ToSchema val, Trait (WG.Header Required ps name val) Response) => Set (OpenApiHandler m) (WG.Header Required ps name val) Response where
{-# INLINEABLE setTrait #-}
setTrait WG.Header _ =
let headerName = fromString $ symbolVal $ Proxy @name
header =
mempty @Header
& required ?~ True
& schema ?~ Inline (toSchema $ Proxy @val)
in if headerName == "Content-Type"
then OpenApiHandler nullNode
else OpenApiHandler $ singletonNode (DocResponseHeader headerName header)
instance (KnownSymbol name, ToSchema val, Trait (WG.Header Optional ps name val) Response) => Set (OpenApiHandler m) (WG.Header Optional ps name val) Response where
{-# INLINEABLE setTrait #-}
setTrait WG.Header _ =
let headerName = fromString $ symbolVal $ Proxy @name
header =
mempty @Header
& required ?~ True
& schema ?~ Inline (toSchema $ Proxy @val)
in OpenApiHandler $ singletonNode (DocResponseHeader headerName header)