{-# 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))