{-# LANGUAGE LambdaCase        #-}
{-# LANGUAGE OverloadedStrings #-}
module Web.Eved.Header
    where

import           Data.ByteString    (ByteString)
import           Data.Text          (Text)
import qualified Network.HTTP.Types as HTTP
import           Web.HttpApiData    (FromHttpApiData (parseHeader),
                                     ToHttpApiData (toHeader))

data Header a = Header
    { Header a -> a -> Maybe ByteString
toHeaderValue   :: a -> Maybe ByteString
    , Header a -> Maybe ByteString -> Either Text a
fromHeaderValue :: Maybe ByteString -> Either Text a
    }

auto :: (Applicative f, ToHttpApiData a, FromHttpApiData a) => f (Header a)
auto :: f (Header a)
auto = Header a -> f (Header a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Header a -> f (Header a)) -> Header a -> f (Header a)
forall a b. (a -> b) -> a -> b
$ Header :: forall a.
(a -> Maybe ByteString)
-> (Maybe ByteString -> Either Text a) -> Header a
Header
    { toHeaderValue :: a -> Maybe ByteString
toHeaderValue = ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just (ByteString -> Maybe ByteString)
-> (a -> ByteString) -> a -> Maybe ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> ByteString
forall a. ToHttpApiData a => a -> ByteString
toHeader
    , fromHeaderValue :: Maybe ByteString -> Either Text a
fromHeaderValue = Either Text a
-> (ByteString -> Either Text a)
-> Maybe ByteString
-> Either Text a
forall b a. b -> (a -> b) -> Maybe a -> b
Prelude.maybe (Text -> Either Text a
forall a b. a -> Either a b
Left Text
"No Header Found") ByteString -> Either Text a
forall a. FromHttpApiData a => ByteString -> Either Text a
parseHeader
    }

maybe :: Functor f => f (Header a) -> f (Header (Maybe a))
maybe :: f (Header a) -> f (Header (Maybe a))
maybe = (Header a -> Header (Maybe a))
-> f (Header a) -> f (Header (Maybe a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Header a -> Header (Maybe a))
 -> f (Header a) -> f (Header (Maybe a)))
-> (Header a -> Header (Maybe a))
-> f (Header a)
-> f (Header (Maybe a))
forall a b. (a -> b) -> a -> b
$ \Header a
h ->
    Header :: forall a.
(a -> Maybe ByteString)
-> (Maybe ByteString -> Either Text a) -> Header a
Header
        { fromHeaderValue :: Maybe ByteString -> Either Text (Maybe a)
fromHeaderValue = \case
            Just ByteString
v  -> a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a) -> Either Text a -> Either Text (Maybe a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Header a -> Maybe ByteString -> Either Text a
forall a. Header a -> Maybe ByteString -> Either Text a
fromHeaderValue Header a
h (ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just ByteString
v)
            Maybe ByteString
Nothing -> Maybe a -> Either Text (Maybe a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe a
forall a. Maybe a
Nothing
        , toHeaderValue :: Maybe a -> Maybe ByteString
toHeaderValue = \case
            Just a
a  -> Header a -> a -> Maybe ByteString
forall a. Header a -> a -> Maybe ByteString
toHeaderValue Header a
h a
a
            Maybe a
Nothing -> Maybe ByteString
forall a. Maybe a
Nothing
        }