packages feed

eved-0.0.1.0: src/Web/Eved/QueryParam.hs

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

import           Data.Text       (Text)
import qualified Web.HttpApiData as HttpApiData

data QueryParam a = QueryParam
    { fromQueryParam :: [Text] -> Either Text a
    , toQueryParam   :: a -> [Text]
    }

auto :: (Applicative f, HttpApiData.FromHttpApiData a, HttpApiData.ToHttpApiData a) => f (QueryParam a)
auto = pure $ QueryParam
    { fromQueryParam = \case
          []  -> Left "Value not found"
          x:_ -> HttpApiData.parseQueryParam x
    , toQueryParam = pure . HttpApiData.toQueryParam
    }

list ::  Functor f => f (QueryParam a) -> f (QueryParam [a])
list = fmap $ \qp ->
    QueryParam
        { fromQueryParam = traverse (fromQueryParam qp . pure)
        , toQueryParam = (=<<) (toQueryParam qp)
        }

defaulted :: Functor f => a -> f (QueryParam a) -> f (QueryParam a)
defaulted defaultValue = fmap $ \qp ->
    QueryParam
        { fromQueryParam = \xs ->
            if null xs
               then pure defaultValue
               else fromQueryParam qp xs
        , toQueryParam = toQueryParam qp
        }

maybe :: Functor f => f (QueryParam a) -> f (QueryParam (Maybe a))
maybe = fmap $ \qp ->
    QueryParam
        { fromQueryParam = \xs ->
            if null xs
               then pure Nothing
               else Just <$> fromQueryParam qp xs
        , toQueryParam = \case
            Just a  -> toQueryParam qp a
            Nothing -> []
        }

integer :: Applicative f => f (QueryParam Integer)
integer = auto

text :: Applicative f => f (QueryParam Text)
text = auto