module Web.Minion.Request.Header where

import Control.Monad.Catch (MonadThrow (..))
import Data.ByteString qualified as Bytes
import Data.List.NonEmpty (NonEmpty, nonEmpty)
import Data.String.Conversions (ConvertibleStrings (..))
import Network.HTTP.Types qualified as Http
import Web.Minion.Args.Internal
import Web.Minion.Introspect qualified as I
import Web.Minion.Request.Header.Internal
import Web.Minion.Router.Internal

{-# INLINE header' #-}
header' ::
  (I.Introspection i I.Header a, MonadThrow m) =>
  -- | .
  Http.HeaderName ->
  (MakeError -> NonEmpty Bytes.ByteString -> m a) ->
  ValueCombinator i (WithHeader Required Strict m a) ts m
header' :: forall i a (m :: * -> *) ts.
(Introspection i 'Header a, MonadThrow m) =>
HeaderName
-> (MakeError -> NonEmpty ByteString -> m a)
-> ValueCombinator i (WithHeader Required Strict m a) ts m
header' HeaderName
hn MakeError -> NonEmpty ByteString -> m a
f =
  HeaderName
-> (MakeError -> [ByteString] -> m (Arg Required Strict a))
-> Router' i (ts :+ WithHeader Required Strict m a) m
-> Router' i ts m
forall a presence parsing (m :: * -> *) ts i.
(Introspection i 'Header a, IsRequired presence,
 IsLenient parsing) =>
HeaderName
-> (MakeError -> [ByteString] -> m (Arg presence parsing a))
-> Router' i (ts :+ WithHeader presence parsing m a) m
-> Router' i ts m
Header
    HeaderName
hn
    \MakeError
makeError ->
      m a
-> (NonEmpty ByteString -> m a)
-> Maybe (NonEmpty ByteString)
-> m a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
        (ServerError -> m a
forall e a. (HasCallStack, Exception e) => e -> m a
forall (m :: * -> *) e a.
(MonadThrow m, HasCallStack, Exception e) =>
e -> m a
throwM (ServerError -> m a) -> (Text -> ServerError) -> Text -> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MakeError
makeError Status
Http.status400 (ByteString -> ServerError)
-> (Text -> ByteString) -> Text -> ServerError
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
forall a b. ConvertibleStrings a b => a -> b
convertString (Text -> m a) -> Text -> m a
forall a b. (a -> b) -> a -> b
$ HeaderName -> Text
headerNotFoundError HeaderName
hn)
        (MakeError -> NonEmpty ByteString -> m a
f MakeError
makeError)
        (Maybe (NonEmpty ByteString) -> m a)
-> ([ByteString] -> Maybe (NonEmpty ByteString))
-> [ByteString]
-> m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> Maybe (NonEmpty ByteString)
forall a. [a] -> Maybe (NonEmpty a)
nonEmpty

{-# INLINE headerLenient' #-}
headerLenient' ::
  (I.Introspection i I.Header a, MonadThrow m) =>
  -- | .
  Http.HeaderName ->
  (MakeError -> NonEmpty Bytes.ByteString -> m (Either e a)) ->
  ValueCombinator i (WithHeader Required (Lenient e) m a) ts m
headerLenient' :: forall i a (m :: * -> *) e ts.
(Introspection i 'Header a, MonadThrow m) =>
HeaderName
-> (MakeError -> NonEmpty ByteString -> m (Either e a))
-> ValueCombinator i (WithHeader Required (Lenient e) m a) ts m
headerLenient' HeaderName
hn MakeError -> NonEmpty ByteString -> m (Either e a)
f =
  HeaderName
-> (MakeError -> [ByteString] -> m (Arg Required (Lenient e) a))
-> Router' i (ts :+ WithHeader Required (Lenient e) m a) m
-> Router' i ts m
forall a presence parsing (m :: * -> *) ts i.
(Introspection i 'Header a, IsRequired presence,
 IsLenient parsing) =>
HeaderName
-> (MakeError -> [ByteString] -> m (Arg presence parsing a))
-> Router' i (ts :+ WithHeader presence parsing m a) m
-> Router' i ts m
Header
    HeaderName
hn
    \MakeError
makeError ->
      m (Either e a)
-> (NonEmpty ByteString -> m (Either e a))
-> Maybe (NonEmpty ByteString)
-> m (Either e a)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
        (ServerError -> m (Either e a)
forall e a. (HasCallStack, Exception e) => e -> m a
forall (m :: * -> *) e a.
(MonadThrow m, HasCallStack, Exception e) =>
e -> m a
throwM (ServerError -> m (Either e a))
-> (Text -> ServerError) -> Text -> m (Either e a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MakeError
makeError Status
Http.status400 (ByteString -> ServerError)
-> (Text -> ByteString) -> Text -> ServerError
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
forall a b. ConvertibleStrings a b => a -> b
convertString (Text -> m (Either e a)) -> Text -> m (Either e a)
forall a b. (a -> b) -> a -> b
$ HeaderName -> Text
headerNotFoundError HeaderName
hn)
        (MakeError -> NonEmpty ByteString -> m (Either e a)
f MakeError
makeError)
        (Maybe (NonEmpty ByteString) -> m (Either e a))
-> ([ByteString] -> Maybe (NonEmpty ByteString))
-> [ByteString]
-> m (Either e a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteString] -> Maybe (NonEmpty ByteString)
forall a. [a] -> Maybe (NonEmpty a)
nonEmpty

{-# INLINE headerLenient #-}
headerLenient ::
  (I.Introspection i I.Header a) =>
  -- | .
  Http.HeaderName ->
  (MakeError -> [Bytes.ByteString] -> m (Maybe (Either e a))) ->
  ValueCombinator i (WithHeader Optional (Lenient e) m a) ts m
headerLenient :: forall i a (m :: * -> *) e ts.
Introspection i 'Header a =>
HeaderName
-> (MakeError -> [ByteString] -> m (Maybe (Either e a)))
-> ValueCombinator i (WithHeader Optional (Lenient e) m a) ts m
headerLenient = HeaderName
-> (MakeError -> [ByteString] -> m (Maybe (Either e a)))
-> Router' i (ts :+ WithHeader Optional (Lenient e) m a) m
-> Router' i ts m
HeaderName
-> (MakeError -> [ByteString] -> m (Arg Optional (Lenient e) a))
-> Router' i (ts :+ WithHeader Optional (Lenient e) m a) m
-> Router' i ts m
forall a presence parsing (m :: * -> *) ts i.
(Introspection i 'Header a, IsRequired presence,
 IsLenient parsing) =>
HeaderName
-> (MakeError -> [ByteString] -> m (Arg presence parsing a))
-> Router' i (ts :+ WithHeader presence parsing m a) m
-> Router' i ts m
Header

{-# INLINE header #-}
header ::
  (I.Introspection i I.Header a) =>
  -- | .
  Http.HeaderName ->
  (MakeError -> [Bytes.ByteString] -> m (Maybe a)) ->
  ValueCombinator i (WithHeader Optional Strict m a) ts m
header :: forall i a (m :: * -> *) ts.
Introspection i 'Header a =>
HeaderName
-> (MakeError -> [ByteString] -> m (Maybe a))
-> ValueCombinator i (WithHeader Optional Strict m a) ts m
header = HeaderName
-> (MakeError -> [ByteString] -> m (Maybe a))
-> Router' i (ts :+ WithHeader Optional Strict m a) m
-> Router' i ts m
HeaderName
-> (MakeError -> [ByteString] -> m (Arg Optional Strict a))
-> Router' i (ts :+ WithHeader Optional Strict m a) m
-> Router' i ts m
forall a presence parsing (m :: * -> *) ts i.
(Introspection i 'Header a, IsRequired presence,
 IsLenient parsing) =>
HeaderName
-> (MakeError -> [ByteString] -> m (Arg presence parsing a))
-> Router' i (ts :+ WithHeader presence parsing m a) m
-> Router' i ts m
Header