{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}

module Yesod.Paginator.Pages
    (
    -- * Type safe @'Natural'@s
    -- |
    --
    -- N.B. @'PageNumber'@ and @'PerPage'@ will currently allow @0@, but it's
    -- unclear if that's correct and may not be the case in the future.
    --
      PageNumber
    , PerPage
    , ItemsCount
    , pageOffset

    -- * Page
    , Page
    , pageItems
    , pageNumber
    , toPage

    -- * Pages
    , Pages
    , pagesCurrent
    , pagesLast
    , toPages

    -- * Safely accessing Pages data
    , takePreviousPages
    , takeNextPages
    , getPreviousPage
    , getNextPage
    ) where

import Yesod.Paginator.Prelude

import Text.Blaze (ToMarkup)
import Web.PathPieces

newtype PageNumber = PageNumber Natural
    deriving newtype (Int -> PageNumber
PageNumber -> Int
PageNumber -> [PageNumber]
PageNumber -> PageNumber
PageNumber -> PageNumber -> [PageNumber]
PageNumber -> PageNumber -> PageNumber -> [PageNumber]
(PageNumber -> PageNumber)
-> (PageNumber -> PageNumber)
-> (Int -> PageNumber)
-> (PageNumber -> Int)
-> (PageNumber -> [PageNumber])
-> (PageNumber -> PageNumber -> [PageNumber])
-> (PageNumber -> PageNumber -> [PageNumber])
-> (PageNumber -> PageNumber -> PageNumber -> [PageNumber])
-> Enum PageNumber
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: PageNumber -> PageNumber -> PageNumber -> [PageNumber]
$cenumFromThenTo :: PageNumber -> PageNumber -> PageNumber -> [PageNumber]
enumFromTo :: PageNumber -> PageNumber -> [PageNumber]
$cenumFromTo :: PageNumber -> PageNumber -> [PageNumber]
enumFromThen :: PageNumber -> PageNumber -> [PageNumber]
$cenumFromThen :: PageNumber -> PageNumber -> [PageNumber]
enumFrom :: PageNumber -> [PageNumber]
$cenumFrom :: PageNumber -> [PageNumber]
fromEnum :: PageNumber -> Int
$cfromEnum :: PageNumber -> Int
toEnum :: Int -> PageNumber
$ctoEnum :: Int -> PageNumber
pred :: PageNumber -> PageNumber
$cpred :: PageNumber -> PageNumber
succ :: PageNumber -> PageNumber
$csucc :: PageNumber -> PageNumber
Enum, PageNumber -> PageNumber -> Bool
(PageNumber -> PageNumber -> Bool)
-> (PageNumber -> PageNumber -> Bool) -> Eq PageNumber
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PageNumber -> PageNumber -> Bool
$c/= :: PageNumber -> PageNumber -> Bool
== :: PageNumber -> PageNumber -> Bool
$c== :: PageNumber -> PageNumber -> Bool
Eq, Enum PageNumber
Real PageNumber
Real PageNumber
-> Enum PageNumber
-> (PageNumber -> PageNumber -> PageNumber)
-> (PageNumber -> PageNumber -> PageNumber)
-> (PageNumber -> PageNumber -> PageNumber)
-> (PageNumber -> PageNumber -> PageNumber)
-> (PageNumber -> PageNumber -> (PageNumber, PageNumber))
-> (PageNumber -> PageNumber -> (PageNumber, PageNumber))
-> (PageNumber -> Integer)
-> Integral PageNumber
PageNumber -> Integer
PageNumber -> PageNumber -> (PageNumber, PageNumber)
PageNumber -> PageNumber -> PageNumber
forall a.
Real a
-> Enum a
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
toInteger :: PageNumber -> Integer
$ctoInteger :: PageNumber -> Integer
divMod :: PageNumber -> PageNumber -> (PageNumber, PageNumber)
$cdivMod :: PageNumber -> PageNumber -> (PageNumber, PageNumber)
quotRem :: PageNumber -> PageNumber -> (PageNumber, PageNumber)
$cquotRem :: PageNumber -> PageNumber -> (PageNumber, PageNumber)
mod :: PageNumber -> PageNumber -> PageNumber
$cmod :: PageNumber -> PageNumber -> PageNumber
div :: PageNumber -> PageNumber -> PageNumber
$cdiv :: PageNumber -> PageNumber -> PageNumber
rem :: PageNumber -> PageNumber -> PageNumber
$crem :: PageNumber -> PageNumber -> PageNumber
quot :: PageNumber -> PageNumber -> PageNumber
$cquot :: PageNumber -> PageNumber -> PageNumber
$cp2Integral :: Enum PageNumber
$cp1Integral :: Real PageNumber
Integral, Integer -> PageNumber
PageNumber -> PageNumber
PageNumber -> PageNumber -> PageNumber
(PageNumber -> PageNumber -> PageNumber)
-> (PageNumber -> PageNumber -> PageNumber)
-> (PageNumber -> PageNumber -> PageNumber)
-> (PageNumber -> PageNumber)
-> (PageNumber -> PageNumber)
-> (PageNumber -> PageNumber)
-> (Integer -> PageNumber)
-> Num PageNumber
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> PageNumber
$cfromInteger :: Integer -> PageNumber
signum :: PageNumber -> PageNumber
$csignum :: PageNumber -> PageNumber
abs :: PageNumber -> PageNumber
$cabs :: PageNumber -> PageNumber
negate :: PageNumber -> PageNumber
$cnegate :: PageNumber -> PageNumber
* :: PageNumber -> PageNumber -> PageNumber
$c* :: PageNumber -> PageNumber -> PageNumber
- :: PageNumber -> PageNumber -> PageNumber
$c- :: PageNumber -> PageNumber -> PageNumber
+ :: PageNumber -> PageNumber -> PageNumber
$c+ :: PageNumber -> PageNumber -> PageNumber
Num, Eq PageNumber
Eq PageNumber
-> (PageNumber -> PageNumber -> Ordering)
-> (PageNumber -> PageNumber -> Bool)
-> (PageNumber -> PageNumber -> Bool)
-> (PageNumber -> PageNumber -> Bool)
-> (PageNumber -> PageNumber -> Bool)
-> (PageNumber -> PageNumber -> PageNumber)
-> (PageNumber -> PageNumber -> PageNumber)
-> Ord PageNumber
PageNumber -> PageNumber -> Bool
PageNumber -> PageNumber -> Ordering
PageNumber -> PageNumber -> PageNumber
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: PageNumber -> PageNumber -> PageNumber
$cmin :: PageNumber -> PageNumber -> PageNumber
max :: PageNumber -> PageNumber -> PageNumber
$cmax :: PageNumber -> PageNumber -> PageNumber
>= :: PageNumber -> PageNumber -> Bool
$c>= :: PageNumber -> PageNumber -> Bool
> :: PageNumber -> PageNumber -> Bool
$c> :: PageNumber -> PageNumber -> Bool
<= :: PageNumber -> PageNumber -> Bool
$c<= :: PageNumber -> PageNumber -> Bool
< :: PageNumber -> PageNumber -> Bool
$c< :: PageNumber -> PageNumber -> Bool
compare :: PageNumber -> PageNumber -> Ordering
$ccompare :: PageNumber -> PageNumber -> Ordering
$cp1Ord :: Eq PageNumber
Ord, Num PageNumber
Ord PageNumber
Num PageNumber
-> Ord PageNumber -> (PageNumber -> Rational) -> Real PageNumber
PageNumber -> Rational
forall a. Num a -> Ord a -> (a -> Rational) -> Real a
toRational :: PageNumber -> Rational
$ctoRational :: PageNumber -> Rational
$cp2Real :: Ord PageNumber
$cp1Real :: Num PageNumber
Real, Int -> PageNumber -> ShowS
[PageNumber] -> ShowS
PageNumber -> String
(Int -> PageNumber -> ShowS)
-> (PageNumber -> String)
-> ([PageNumber] -> ShowS)
-> Show PageNumber
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PageNumber] -> ShowS
$cshowList :: [PageNumber] -> ShowS
show :: PageNumber -> String
$cshow :: PageNumber -> String
showsPrec :: Int -> PageNumber -> ShowS
$cshowsPrec :: Int -> PageNumber -> ShowS
Show, PageNumber -> Markup
(PageNumber -> Markup)
-> (PageNumber -> Markup) -> ToMarkup PageNumber
forall a. (a -> Markup) -> (a -> Markup) -> ToMarkup a
preEscapedToMarkup :: PageNumber -> Markup
$cpreEscapedToMarkup :: PageNumber -> Markup
toMarkup :: PageNumber -> Markup
$ctoMarkup :: PageNumber -> Markup
ToMarkup)

newtype PerPage = PerPage Natural
    deriving newtype (Int -> PerPage
PerPage -> Int
PerPage -> [PerPage]
PerPage -> PerPage
PerPage -> PerPage -> [PerPage]
PerPage -> PerPage -> PerPage -> [PerPage]
(PerPage -> PerPage)
-> (PerPage -> PerPage)
-> (Int -> PerPage)
-> (PerPage -> Int)
-> (PerPage -> [PerPage])
-> (PerPage -> PerPage -> [PerPage])
-> (PerPage -> PerPage -> [PerPage])
-> (PerPage -> PerPage -> PerPage -> [PerPage])
-> Enum PerPage
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: PerPage -> PerPage -> PerPage -> [PerPage]
$cenumFromThenTo :: PerPage -> PerPage -> PerPage -> [PerPage]
enumFromTo :: PerPage -> PerPage -> [PerPage]
$cenumFromTo :: PerPage -> PerPage -> [PerPage]
enumFromThen :: PerPage -> PerPage -> [PerPage]
$cenumFromThen :: PerPage -> PerPage -> [PerPage]
enumFrom :: PerPage -> [PerPage]
$cenumFrom :: PerPage -> [PerPage]
fromEnum :: PerPage -> Int
$cfromEnum :: PerPage -> Int
toEnum :: Int -> PerPage
$ctoEnum :: Int -> PerPage
pred :: PerPage -> PerPage
$cpred :: PerPage -> PerPage
succ :: PerPage -> PerPage
$csucc :: PerPage -> PerPage
Enum, PerPage -> PerPage -> Bool
(PerPage -> PerPage -> Bool)
-> (PerPage -> PerPage -> Bool) -> Eq PerPage
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PerPage -> PerPage -> Bool
$c/= :: PerPage -> PerPage -> Bool
== :: PerPage -> PerPage -> Bool
$c== :: PerPage -> PerPage -> Bool
Eq, Enum PerPage
Real PerPage
Real PerPage
-> Enum PerPage
-> (PerPage -> PerPage -> PerPage)
-> (PerPage -> PerPage -> PerPage)
-> (PerPage -> PerPage -> PerPage)
-> (PerPage -> PerPage -> PerPage)
-> (PerPage -> PerPage -> (PerPage, PerPage))
-> (PerPage -> PerPage -> (PerPage, PerPage))
-> (PerPage -> Integer)
-> Integral PerPage
PerPage -> Integer
PerPage -> PerPage -> (PerPage, PerPage)
PerPage -> PerPage -> PerPage
forall a.
Real a
-> Enum a
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
toInteger :: PerPage -> Integer
$ctoInteger :: PerPage -> Integer
divMod :: PerPage -> PerPage -> (PerPage, PerPage)
$cdivMod :: PerPage -> PerPage -> (PerPage, PerPage)
quotRem :: PerPage -> PerPage -> (PerPage, PerPage)
$cquotRem :: PerPage -> PerPage -> (PerPage, PerPage)
mod :: PerPage -> PerPage -> PerPage
$cmod :: PerPage -> PerPage -> PerPage
div :: PerPage -> PerPage -> PerPage
$cdiv :: PerPage -> PerPage -> PerPage
rem :: PerPage -> PerPage -> PerPage
$crem :: PerPage -> PerPage -> PerPage
quot :: PerPage -> PerPage -> PerPage
$cquot :: PerPage -> PerPage -> PerPage
$cp2Integral :: Enum PerPage
$cp1Integral :: Real PerPage
Integral, Integer -> PerPage
PerPage -> PerPage
PerPage -> PerPage -> PerPage
(PerPage -> PerPage -> PerPage)
-> (PerPage -> PerPage -> PerPage)
-> (PerPage -> PerPage -> PerPage)
-> (PerPage -> PerPage)
-> (PerPage -> PerPage)
-> (PerPage -> PerPage)
-> (Integer -> PerPage)
-> Num PerPage
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> PerPage
$cfromInteger :: Integer -> PerPage
signum :: PerPage -> PerPage
$csignum :: PerPage -> PerPage
abs :: PerPage -> PerPage
$cabs :: PerPage -> PerPage
negate :: PerPage -> PerPage
$cnegate :: PerPage -> PerPage
* :: PerPage -> PerPage -> PerPage
$c* :: PerPage -> PerPage -> PerPage
- :: PerPage -> PerPage -> PerPage
$c- :: PerPage -> PerPage -> PerPage
+ :: PerPage -> PerPage -> PerPage
$c+ :: PerPage -> PerPage -> PerPage
Num, Eq PerPage
Eq PerPage
-> (PerPage -> PerPage -> Ordering)
-> (PerPage -> PerPage -> Bool)
-> (PerPage -> PerPage -> Bool)
-> (PerPage -> PerPage -> Bool)
-> (PerPage -> PerPage -> Bool)
-> (PerPage -> PerPage -> PerPage)
-> (PerPage -> PerPage -> PerPage)
-> Ord PerPage
PerPage -> PerPage -> Bool
PerPage -> PerPage -> Ordering
PerPage -> PerPage -> PerPage
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: PerPage -> PerPage -> PerPage
$cmin :: PerPage -> PerPage -> PerPage
max :: PerPage -> PerPage -> PerPage
$cmax :: PerPage -> PerPage -> PerPage
>= :: PerPage -> PerPage -> Bool
$c>= :: PerPage -> PerPage -> Bool
> :: PerPage -> PerPage -> Bool
$c> :: PerPage -> PerPage -> Bool
<= :: PerPage -> PerPage -> Bool
$c<= :: PerPage -> PerPage -> Bool
< :: PerPage -> PerPage -> Bool
$c< :: PerPage -> PerPage -> Bool
compare :: PerPage -> PerPage -> Ordering
$ccompare :: PerPage -> PerPage -> Ordering
$cp1Ord :: Eq PerPage
Ord, Num PerPage
Ord PerPage
Num PerPage -> Ord PerPage -> (PerPage -> Rational) -> Real PerPage
PerPage -> Rational
forall a. Num a -> Ord a -> (a -> Rational) -> Real a
toRational :: PerPage -> Rational
$ctoRational :: PerPage -> Rational
$cp2Real :: Ord PerPage
$cp1Real :: Num PerPage
Real, ReadPrec [PerPage]
ReadPrec PerPage
Int -> ReadS PerPage
ReadS [PerPage]
(Int -> ReadS PerPage)
-> ReadS [PerPage]
-> ReadPrec PerPage
-> ReadPrec [PerPage]
-> Read PerPage
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [PerPage]
$creadListPrec :: ReadPrec [PerPage]
readPrec :: ReadPrec PerPage
$creadPrec :: ReadPrec PerPage
readList :: ReadS [PerPage]
$creadList :: ReadS [PerPage]
readsPrec :: Int -> ReadS PerPage
$creadsPrec :: Int -> ReadS PerPage
Read, Int -> PerPage -> ShowS
[PerPage] -> ShowS
PerPage -> String
(Int -> PerPage -> ShowS)
-> (PerPage -> String) -> ([PerPage] -> ShowS) -> Show PerPage
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PerPage] -> ShowS
$cshowList :: [PerPage] -> ShowS
show :: PerPage -> String
$cshow :: PerPage -> String
showsPrec :: Int -> PerPage -> ShowS
$cshowsPrec :: Int -> PerPage -> ShowS
Show, Text -> Maybe PerPage
PerPage -> Text
(Text -> Maybe PerPage) -> (PerPage -> Text) -> PathPiece PerPage
forall s. (Text -> Maybe s) -> (s -> Text) -> PathPiece s
toPathPiece :: PerPage -> Text
$ctoPathPiece :: PerPage -> Text
fromPathPiece :: Text -> Maybe PerPage
$cfromPathPiece :: Text -> Maybe PerPage
PathPiece)

newtype ItemsCount = ItemsCount Natural
    deriving newtype (Int -> ItemsCount
ItemsCount -> Int
ItemsCount -> [ItemsCount]
ItemsCount -> ItemsCount
ItemsCount -> ItemsCount -> [ItemsCount]
ItemsCount -> ItemsCount -> ItemsCount -> [ItemsCount]
(ItemsCount -> ItemsCount)
-> (ItemsCount -> ItemsCount)
-> (Int -> ItemsCount)
-> (ItemsCount -> Int)
-> (ItemsCount -> [ItemsCount])
-> (ItemsCount -> ItemsCount -> [ItemsCount])
-> (ItemsCount -> ItemsCount -> [ItemsCount])
-> (ItemsCount -> ItemsCount -> ItemsCount -> [ItemsCount])
-> Enum ItemsCount
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: ItemsCount -> ItemsCount -> ItemsCount -> [ItemsCount]
$cenumFromThenTo :: ItemsCount -> ItemsCount -> ItemsCount -> [ItemsCount]
enumFromTo :: ItemsCount -> ItemsCount -> [ItemsCount]
$cenumFromTo :: ItemsCount -> ItemsCount -> [ItemsCount]
enumFromThen :: ItemsCount -> ItemsCount -> [ItemsCount]
$cenumFromThen :: ItemsCount -> ItemsCount -> [ItemsCount]
enumFrom :: ItemsCount -> [ItemsCount]
$cenumFrom :: ItemsCount -> [ItemsCount]
fromEnum :: ItemsCount -> Int
$cfromEnum :: ItemsCount -> Int
toEnum :: Int -> ItemsCount
$ctoEnum :: Int -> ItemsCount
pred :: ItemsCount -> ItemsCount
$cpred :: ItemsCount -> ItemsCount
succ :: ItemsCount -> ItemsCount
$csucc :: ItemsCount -> ItemsCount
Enum, ItemsCount -> ItemsCount -> Bool
(ItemsCount -> ItemsCount -> Bool)
-> (ItemsCount -> ItemsCount -> Bool) -> Eq ItemsCount
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ItemsCount -> ItemsCount -> Bool
$c/= :: ItemsCount -> ItemsCount -> Bool
== :: ItemsCount -> ItemsCount -> Bool
$c== :: ItemsCount -> ItemsCount -> Bool
Eq, Enum ItemsCount
Real ItemsCount
Real ItemsCount
-> Enum ItemsCount
-> (ItemsCount -> ItemsCount -> ItemsCount)
-> (ItemsCount -> ItemsCount -> ItemsCount)
-> (ItemsCount -> ItemsCount -> ItemsCount)
-> (ItemsCount -> ItemsCount -> ItemsCount)
-> (ItemsCount -> ItemsCount -> (ItemsCount, ItemsCount))
-> (ItemsCount -> ItemsCount -> (ItemsCount, ItemsCount))
-> (ItemsCount -> Integer)
-> Integral ItemsCount
ItemsCount -> Integer
ItemsCount -> ItemsCount -> (ItemsCount, ItemsCount)
ItemsCount -> ItemsCount -> ItemsCount
forall a.
Real a
-> Enum a
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
toInteger :: ItemsCount -> Integer
$ctoInteger :: ItemsCount -> Integer
divMod :: ItemsCount -> ItemsCount -> (ItemsCount, ItemsCount)
$cdivMod :: ItemsCount -> ItemsCount -> (ItemsCount, ItemsCount)
quotRem :: ItemsCount -> ItemsCount -> (ItemsCount, ItemsCount)
$cquotRem :: ItemsCount -> ItemsCount -> (ItemsCount, ItemsCount)
mod :: ItemsCount -> ItemsCount -> ItemsCount
$cmod :: ItemsCount -> ItemsCount -> ItemsCount
div :: ItemsCount -> ItemsCount -> ItemsCount
$cdiv :: ItemsCount -> ItemsCount -> ItemsCount
rem :: ItemsCount -> ItemsCount -> ItemsCount
$crem :: ItemsCount -> ItemsCount -> ItemsCount
quot :: ItemsCount -> ItemsCount -> ItemsCount
$cquot :: ItemsCount -> ItemsCount -> ItemsCount
$cp2Integral :: Enum ItemsCount
$cp1Integral :: Real ItemsCount
Integral, Integer -> ItemsCount
ItemsCount -> ItemsCount
ItemsCount -> ItemsCount -> ItemsCount
(ItemsCount -> ItemsCount -> ItemsCount)
-> (ItemsCount -> ItemsCount -> ItemsCount)
-> (ItemsCount -> ItemsCount -> ItemsCount)
-> (ItemsCount -> ItemsCount)
-> (ItemsCount -> ItemsCount)
-> (ItemsCount -> ItemsCount)
-> (Integer -> ItemsCount)
-> Num ItemsCount
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> ItemsCount
$cfromInteger :: Integer -> ItemsCount
signum :: ItemsCount -> ItemsCount
$csignum :: ItemsCount -> ItemsCount
abs :: ItemsCount -> ItemsCount
$cabs :: ItemsCount -> ItemsCount
negate :: ItemsCount -> ItemsCount
$cnegate :: ItemsCount -> ItemsCount
* :: ItemsCount -> ItemsCount -> ItemsCount
$c* :: ItemsCount -> ItemsCount -> ItemsCount
- :: ItemsCount -> ItemsCount -> ItemsCount
$c- :: ItemsCount -> ItemsCount -> ItemsCount
+ :: ItemsCount -> ItemsCount -> ItemsCount
$c+ :: ItemsCount -> ItemsCount -> ItemsCount
Num, Eq ItemsCount
Eq ItemsCount
-> (ItemsCount -> ItemsCount -> Ordering)
-> (ItemsCount -> ItemsCount -> Bool)
-> (ItemsCount -> ItemsCount -> Bool)
-> (ItemsCount -> ItemsCount -> Bool)
-> (ItemsCount -> ItemsCount -> Bool)
-> (ItemsCount -> ItemsCount -> ItemsCount)
-> (ItemsCount -> ItemsCount -> ItemsCount)
-> Ord ItemsCount
ItemsCount -> ItemsCount -> Bool
ItemsCount -> ItemsCount -> Ordering
ItemsCount -> ItemsCount -> ItemsCount
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ItemsCount -> ItemsCount -> ItemsCount
$cmin :: ItemsCount -> ItemsCount -> ItemsCount
max :: ItemsCount -> ItemsCount -> ItemsCount
$cmax :: ItemsCount -> ItemsCount -> ItemsCount
>= :: ItemsCount -> ItemsCount -> Bool
$c>= :: ItemsCount -> ItemsCount -> Bool
> :: ItemsCount -> ItemsCount -> Bool
$c> :: ItemsCount -> ItemsCount -> Bool
<= :: ItemsCount -> ItemsCount -> Bool
$c<= :: ItemsCount -> ItemsCount -> Bool
< :: ItemsCount -> ItemsCount -> Bool
$c< :: ItemsCount -> ItemsCount -> Bool
compare :: ItemsCount -> ItemsCount -> Ordering
$ccompare :: ItemsCount -> ItemsCount -> Ordering
$cp1Ord :: Eq ItemsCount
Ord, Num ItemsCount
Ord ItemsCount
Num ItemsCount
-> Ord ItemsCount -> (ItemsCount -> Rational) -> Real ItemsCount
ItemsCount -> Rational
forall a. Num a -> Ord a -> (a -> Rational) -> Real a
toRational :: ItemsCount -> Rational
$ctoRational :: ItemsCount -> Rational
$cp2Real :: Ord ItemsCount
$cp1Real :: Num ItemsCount
Real, ReadPrec [ItemsCount]
ReadPrec ItemsCount
Int -> ReadS ItemsCount
ReadS [ItemsCount]
(Int -> ReadS ItemsCount)
-> ReadS [ItemsCount]
-> ReadPrec ItemsCount
-> ReadPrec [ItemsCount]
-> Read ItemsCount
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [ItemsCount]
$creadListPrec :: ReadPrec [ItemsCount]
readPrec :: ReadPrec ItemsCount
$creadPrec :: ReadPrec ItemsCount
readList :: ReadS [ItemsCount]
$creadList :: ReadS [ItemsCount]
readsPrec :: Int -> ReadS ItemsCount
$creadsPrec :: Int -> ReadS ItemsCount
Read, Int -> ItemsCount -> ShowS
[ItemsCount] -> ShowS
ItemsCount -> String
(Int -> ItemsCount -> ShowS)
-> (ItemsCount -> String)
-> ([ItemsCount] -> ShowS)
-> Show ItemsCount
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ItemsCount] -> ShowS
$cshowList :: [ItemsCount] -> ShowS
show :: ItemsCount -> String
$cshow :: ItemsCount -> String
showsPrec :: Int -> ItemsCount -> ShowS
$cshowsPrec :: Int -> ItemsCount -> ShowS
Show, Text -> Maybe ItemsCount
ItemsCount -> Text
(Text -> Maybe ItemsCount)
-> (ItemsCount -> Text) -> PathPiece ItemsCount
forall s. (Text -> Maybe s) -> (s -> Text) -> PathPiece s
toPathPiece :: ItemsCount -> Text
$ctoPathPiece :: ItemsCount -> Text
fromPathPiece :: Text -> Maybe ItemsCount
$cfromPathPiece :: Text -> Maybe ItemsCount
PathPiece)

data Page a = Page
    { Page a -> [a]
pageItems :: [a]
    , Page a -> PageNumber
pageNumber :: PageNumber
    }
    deriving stock (Page a -> Page a -> Bool
(Page a -> Page a -> Bool)
-> (Page a -> Page a -> Bool) -> Eq (Page a)
forall a. Eq a => Page a -> Page a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Page a -> Page a -> Bool
$c/= :: forall a. Eq a => Page a -> Page a -> Bool
== :: Page a -> Page a -> Bool
$c== :: forall a. Eq a => Page a -> Page a -> Bool
Eq, Int -> Page a -> ShowS
[Page a] -> ShowS
Page a -> String
(Int -> Page a -> ShowS)
-> (Page a -> String) -> ([Page a] -> ShowS) -> Show (Page a)
forall a. Show a => Int -> Page a -> ShowS
forall a. Show a => [Page a] -> ShowS
forall a. Show a => Page a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Page a] -> ShowS
$cshowList :: forall a. Show a => [Page a] -> ShowS
show :: Page a -> String
$cshow :: forall a. Show a => Page a -> String
showsPrec :: Int -> Page a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Page a -> ShowS
Show)

setPageItems :: Page a -> [b] -> Page b
setPageItems :: Page a -> [b] -> Page b
setPageItems Page a
page [b]
items = Page a
page { pageItems :: [b]
pageItems = [b]
items }

overPageItems :: ([a] -> [b]) -> Page a -> Page b
overPageItems :: ([a] -> [b]) -> Page a -> Page b
overPageItems [a] -> [b]
f Page a
page = Page a -> [b] -> Page b
forall a b. Page a -> [b] -> Page b
setPageItems Page a
page ([b] -> Page b) -> [b] -> Page b
forall a b. (a -> b) -> a -> b
$ [a] -> [b]
f ([a] -> [b]) -> [a] -> [b]
forall a b. (a -> b) -> a -> b
$ Page a -> [a]
forall a. Page a -> [a]
pageItems Page a
page

instance Functor Page where
    fmap :: (a -> b) -> Page a -> Page b
fmap a -> b
f = ([a] -> [b]) -> Page a -> Page b
forall a b. ([a] -> [b]) -> Page a -> Page b
overPageItems (([a] -> [b]) -> Page a -> Page b)
-> ([a] -> [b]) -> Page a -> Page b
forall a b. (a -> b) -> a -> b
$ (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f

instance Foldable Page where
    foldMap :: (a -> m) -> Page a -> m
foldMap a -> m
f = (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap a -> m
f ([a] -> m) -> (Page a -> [a]) -> Page a -> m
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Page a -> [a]
forall a. Page a -> [a]
pageItems

instance Traversable Page where
    traverse :: (a -> f b) -> Page a -> f (Page b)
traverse a -> f b
f Page a
page = Page a -> [b] -> Page b
forall a b. Page a -> [b] -> Page b
setPageItems Page a
page ([b] -> Page b) -> f [b] -> f (Page b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (a -> f b) -> [a] -> f [b]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse a -> f b
f (Page a -> [a]
forall a. Page a -> [a]
pageItems Page a
page)

-- | @'Page'@ constructor
toPage :: [a] -> PageNumber -> Page a
toPage :: [a] -> PageNumber -> Page a
toPage = [a] -> PageNumber -> Page a
forall a. [a] -> PageNumber -> Page a
Page

data Pages a = Pages
    { Pages a -> Page a
pagesCurrent :: Page a
    , Pages a -> [PageNumber]
pagesPrevious :: [PageNumber]
    , Pages a -> [PageNumber]
pagesNext :: [PageNumber]
    , Pages a -> PageNumber
pagesLast :: PageNumber
    }
    deriving stock (Pages a -> Pages a -> Bool
(Pages a -> Pages a -> Bool)
-> (Pages a -> Pages a -> Bool) -> Eq (Pages a)
forall a. Eq a => Pages a -> Pages a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Pages a -> Pages a -> Bool
$c/= :: forall a. Eq a => Pages a -> Pages a -> Bool
== :: Pages a -> Pages a -> Bool
$c== :: forall a. Eq a => Pages a -> Pages a -> Bool
Eq, Int -> Pages a -> ShowS
[Pages a] -> ShowS
Pages a -> String
(Int -> Pages a -> ShowS)
-> (Pages a -> String) -> ([Pages a] -> ShowS) -> Show (Pages a)
forall a. Show a => Int -> Pages a -> ShowS
forall a. Show a => [Pages a] -> ShowS
forall a. Show a => Pages a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Pages a] -> ShowS
$cshowList :: forall a. Show a => [Pages a] -> ShowS
show :: Pages a -> String
$cshow :: forall a. Show a => Pages a -> String
showsPrec :: Int -> Pages a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Pages a -> ShowS
Show)

setPagesCurrent :: Pages a -> Page b -> Pages b
setPagesCurrent :: Pages a -> Page b -> Pages b
setPagesCurrent Pages a
pages Page b
current = Pages a
pages { pagesCurrent :: Page b
pagesCurrent = Page b
current }

overPagesCurrent :: (Page a -> Page b) -> Pages a -> Pages b
overPagesCurrent :: (Page a -> Page b) -> Pages a -> Pages b
overPagesCurrent Page a -> Page b
f Pages a
pages = Pages a -> Page b -> Pages b
forall a b. Pages a -> Page b -> Pages b
setPagesCurrent Pages a
pages (Page b -> Pages b) -> Page b -> Pages b
forall a b. (a -> b) -> a -> b
$ Page a -> Page b
f (Page a -> Page b) -> Page a -> Page b
forall a b. (a -> b) -> a -> b
$ Pages a -> Page a
forall a. Pages a -> Page a
pagesCurrent Pages a
pages

instance Functor Pages where
    fmap :: (a -> b) -> Pages a -> Pages b
fmap a -> b
f = (Page a -> Page b) -> Pages a -> Pages b
forall a b. (Page a -> Page b) -> Pages a -> Pages b
overPagesCurrent ((Page a -> Page b) -> Pages a -> Pages b)
-> (Page a -> Page b) -> Pages a -> Pages b
forall a b. (a -> b) -> a -> b
$ (a -> b) -> Page a -> Page b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f

instance Foldable Pages where
    foldMap :: (a -> m) -> Pages a -> m
foldMap a -> m
f = (a -> m) -> Page a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap a -> m
f (Page a -> m) -> (Pages a -> Page a) -> Pages a -> m
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pages a -> Page a
forall a. Pages a -> Page a
pagesCurrent

instance Traversable Pages where
    traverse :: (a -> f b) -> Pages a -> f (Pages b)
traverse a -> f b
f Pages a
pages =
        Pages a -> Page b -> Pages b
forall a b. Pages a -> Page b -> Pages b
setPagesCurrent Pages a
pages (Page b -> Pages b) -> f (Page b) -> f (Pages b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (a -> f b) -> Page a -> f (Page b)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse a -> f b
f (Pages a -> Page a
forall a. Pages a -> Page a
pagesCurrent Pages a
pages)

-- | Take previous pages, going back from current
--
-- >>> takePreviousPages 3 $ Pages (Page [] 5) [1,2,3,4] [6] 6
-- [2,3,4]
--
takePreviousPages :: Natural -> Pages a -> [PageNumber]
takePreviousPages :: Natural -> Pages a -> [PageNumber]
takePreviousPages Natural
n = [PageNumber] -> [PageNumber]
forall a. [a] -> [a]
reverse ([PageNumber] -> [PageNumber])
-> (Pages a -> [PageNumber]) -> Pages a -> [PageNumber]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Natural -> [PageNumber] -> [PageNumber]
forall i a. Integral i => i -> [a] -> [a]
genericTake Natural
n ([PageNumber] -> [PageNumber])
-> (Pages a -> [PageNumber]) -> Pages a -> [PageNumber]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [PageNumber] -> [PageNumber]
forall a. [a] -> [a]
reverse ([PageNumber] -> [PageNumber])
-> (Pages a -> [PageNumber]) -> Pages a -> [PageNumber]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pages a -> [PageNumber]
forall a. Pages a -> [PageNumber]
pagesPrevious

-- | Take next pages, going forward from current
--
-- >>> takeNextPages 3 $ Pages (Page [] 2) [1] [3,4,5,6] 6
-- [3,4,5]
--
takeNextPages :: Natural -> Pages a -> [PageNumber]
takeNextPages :: Natural -> Pages a -> [PageNumber]
takeNextPages Natural
n = Natural -> [PageNumber] -> [PageNumber]
forall i a. Integral i => i -> [a] -> [a]
genericTake Natural
n ([PageNumber] -> [PageNumber])
-> (Pages a -> [PageNumber]) -> Pages a -> [PageNumber]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pages a -> [PageNumber]
forall a. Pages a -> [PageNumber]
pagesNext

-- | The previous page number, if it exists
--
-- >>> getPreviousPage $ Pages (Page [] 1) [] [2,3,4] 4
-- Nothing
--
-- >>> getPreviousPage $ Pages (Page [] 2) [1] [3,4] 4
-- Just 1
--
getPreviousPage :: Pages a -> Maybe PageNumber
getPreviousPage :: Pages a -> Maybe PageNumber
getPreviousPage Pages a
pages = do
    let prevPage :: PageNumber
prevPage = Page a -> PageNumber
forall a. Page a -> PageNumber
pageNumber (Pages a -> Page a
forall a. Pages a -> Page a
pagesCurrent Pages a
pages) PageNumber -> PageNumber -> PageNumber
forall a. Num a => a -> a -> a
- PageNumber
1
    PageNumber
firstPage <- [PageNumber] -> Maybe PageNumber
forall a. [a] -> Maybe a
headMay ([PageNumber] -> Maybe PageNumber)
-> [PageNumber] -> Maybe PageNumber
forall a b. (a -> b) -> a -> b
$ Pages a -> [PageNumber]
forall a. Pages a -> [PageNumber]
pagesPrevious Pages a
pages
    PageNumber
prevPage PageNumber -> Maybe () -> Maybe PageNumber
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (PageNumber
prevPage PageNumber -> PageNumber -> Bool
forall a. Ord a => a -> a -> Bool
>= PageNumber
firstPage)

-- | The next page number, if it exists
--
-- >>> getNextPage $ Pages (Page [] 4) [1,2,3] [] 4
-- Nothing
--
-- >>> getNextPage $ Pages (Page [] 3) [1,2] [4] 4
-- Just 4
--
getNextPage :: Pages a -> Maybe PageNumber
getNextPage :: Pages a -> Maybe PageNumber
getNextPage Pages a
pages = do
    let nextPage :: PageNumber
nextPage = Page a -> PageNumber
forall a. Page a -> PageNumber
pageNumber (Pages a -> Page a
forall a. Pages a -> Page a
pagesCurrent Pages a
pages) PageNumber -> PageNumber -> PageNumber
forall a. Num a => a -> a -> a
+ PageNumber
1
    PageNumber
lastPage <- [PageNumber] -> Maybe PageNumber
forall a. [a] -> Maybe a
lastMay ([PageNumber] -> Maybe PageNumber)
-> [PageNumber] -> Maybe PageNumber
forall a b. (a -> b) -> a -> b
$ Pages a -> [PageNumber]
forall a. Pages a -> [PageNumber]
pagesNext Pages a
pages
    PageNumber
nextPage PageNumber -> Maybe () -> Maybe PageNumber
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (PageNumber
nextPage PageNumber -> PageNumber -> Bool
forall a. Ord a => a -> a -> Bool
<= PageNumber
lastPage)

-- | Construct a @'Pages' a@ from paginated data
--
-- >>> toPages 4 3 10 []
-- Pages {pagesCurrent = Page {pageItems = [], pageNumber = 4}, pagesPrevious = [1,2,3], pagesNext = [], pagesLast = 4}
--
toPages :: PageNumber -> PerPage -> ItemsCount -> [a] -> Pages a
toPages :: PageNumber -> PerPage -> ItemsCount -> [a] -> Pages a
toPages PageNumber
number PerPage
per ItemsCount
total [a]
items = Pages :: forall a.
Page a -> [PageNumber] -> [PageNumber] -> PageNumber -> Pages a
Pages
    { pagesCurrent :: Page a
pagesCurrent = [a] -> PageNumber -> Page a
forall a. [a] -> PageNumber -> Page a
toPage [a]
items PageNumber
number
    , pagesPrevious :: [PageNumber]
pagesPrevious = [PageNumber
1 .. (PageNumber
number PageNumber -> PageNumber -> PageNumber
forall a. Num a => a -> a -> a
- PageNumber
1)]
    , pagesNext :: [PageNumber]
pagesNext = [(PageNumber
number PageNumber -> PageNumber -> PageNumber
forall a. Num a => a -> a -> a
+ PageNumber
1) .. PageNumber
lastPage]
    , pagesLast :: PageNumber
pagesLast = PageNumber
lastPage
    }
    where lastPage :: PageNumber
lastPage = ItemsCount -> PerPage -> PageNumber
getLastPage ItemsCount
total PerPage
per

-- | Calculate the last page of some paginated data
--
-- >>> getLastPage 10 3
-- 4
--
-- >>> getLastPage 10 5
-- 2
--
getLastPage :: ItemsCount -> PerPage -> PageNumber
getLastPage :: ItemsCount -> PerPage -> PageNumber
getLastPage ItemsCount
total = ItemsCount -> PageNumber
forall a b. (Integral a, Num b) => a -> b
fromIntegral (ItemsCount -> PageNumber)
-> (PerPage -> ItemsCount) -> PerPage -> PageNumber
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ItemsCount, ItemsCount) -> ItemsCount
forall a. (Eq a, Num a) => (a, a) -> a
carry ((ItemsCount, ItemsCount) -> ItemsCount)
-> (PerPage -> (ItemsCount, ItemsCount)) -> PerPage -> ItemsCount
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ItemsCount
total ItemsCount -> ItemsCount -> (ItemsCount, ItemsCount)
forall a. Integral a => a -> a -> (a, a)
`divMod`) (ItemsCount -> (ItemsCount, ItemsCount))
-> (PerPage -> ItemsCount) -> PerPage -> (ItemsCount, ItemsCount)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PerPage -> ItemsCount
forall a b. (Integral a, Num b) => a -> b
fromIntegral
  where
    carry :: (Eq a, Num a) => (a, a) -> a
    carry :: (a, a) -> a
carry (a
q, a
0) = a
q
    carry (a
q, a
_) = a
q a -> a -> a
forall a. Num a => a -> a -> a
+ a
1

-- | Calculate a page's zero-based offset in the overall items
--
-- >>> pageOffset 4 3
-- 9
--
pageOffset :: PageNumber -> PerPage -> ItemsCount
pageOffset :: PageNumber -> PerPage -> ItemsCount
pageOffset PageNumber
p PerPage
per = PerPage -> ItemsCount
forall a b. (Integral a, Num b) => a -> b
fromIntegral (PerPage -> ItemsCount) -> PerPage -> ItemsCount
forall a b. (a -> b) -> a -> b
$ (PageNumber -> PerPage
forall a b. (Integral a, Num b) => a -> b
fromIntegral PageNumber
p PerPage -> PerPage -> PerPage
forall a. Num a => a -> a -> a
- PerPage
1) PerPage -> PerPage -> PerPage
forall a. Num a => a -> a -> a
* PerPage
per