persistent-pagination-0.1.1.0: src/Database/Persist/Pagination/Types.hs
{-# LANGUAGE DeriveFoldable #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveTraversable #-}
module Database.Persist.Pagination.Types where
import Control.Applicative (Alternative(..))
import Database.Persist.Sql (Entity)
-- | The amount of records in a 'Page' of results.
--
-- @since 0.1.0.0
newtype PageSize = PageSize { unPageSize :: Int }
deriving (Eq, Show)
-- | Whether to sort by @ASC@ or @DESC@ when you're paging over results.
--
-- @since 0.1.0.0
data SortOrder = Ascend | Descend
deriving (Eq, Show)
-- | A datatype describing the min and max value of the relevant field that
-- you are ranging over in a non-empty sequence of records.
--
-- @since 0.1.0.0
data Range t = Range { rangeMin :: t, rangeMax :: t }
deriving (Eq, Show, Functor, Foldable, Traversable)
instance Ord t => Semigroup (Range t) where
Range l h <> Range l' h' = Range (min l l') (max h h')
instance (Bounded t, Ord t) => Monoid (Range t) where
mempty = Range minBound maxBound
mappend = (<>)
-- | Users aren't required to put a value in for the range - a value of
-- 'Nothing' is equivalent to saying "unbounded from below."
--
-- @since 0.1.0.0
type DesiredRange t = Range (Maybe t)
-- | Modify the 'DesiredRange' according to the 'Range' that was provided
-- by the query and the 'SortOrder'.
--
-- @since 0.1.0.0
bumpPageRange
:: Ord typ
=> SortOrder
-> DesiredRange typ
-> Range typ
-> DesiredRange typ
bumpPageRange sortOrder (Range mmin mmax) (Range min' max') =
case sortOrder of
Ascend ->
Range (mmin `max` Just max') mmax
Descend ->
Range mmin (Just min' <|> (Just min' `min` mmax))