{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
module Blockfrost.Client.Pagination
( Paged (..)
, page
, paged
, nextPage
, allPages
) where
import Data.Default (Default (def))
import Data.Proxy (Proxy (..))
import Servant.API ((:>))
import Servant.Client.Core (Client, HasClient (..))
import Blockfrost.Util.Pagination
( Paged (..)
, Pagination
, PaginationExpanded
, page
, paged
, maxPageSize
, nextPage
)
allPages :: Monad m => (Paged -> m [a]) -> m [a]
allPages :: (Paged -> m [a]) -> m [a]
allPages Paged -> m [a]
act = do
let fetch :: Paged -> m [a]
fetch Paged
page' = do
[a]
res <- Paged -> m [a]
act Paged
page'
case [a]
res of
[a]
xs | [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
xs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
maxPageSize -> [a] -> m [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [a]
xs
[a]
xs -> do
[a]
next <- Paged -> m [a]
fetch (Paged -> Paged
nextPage Paged
page')
[a] -> m [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([a] -> m [a]) -> [a] -> m [a]
forall a b. (a -> b) -> a -> b
$ [a]
next [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ [a]
xs
Paged -> m [a]
fetch Paged
forall a. Default a => a
def
instance HasClient m subApi => HasClient m (Pagination :> subApi) where
type Client m (Pagination :> subApi) = Paged -> Client m subApi
clientWithRoute :: Proxy m
-> Proxy (Pagination :> subApi)
-> Request
-> Client m (Pagination :> subApi)
clientWithRoute Proxy m
pm Proxy (Pagination :> subApi)
_ Request
req Paged
paged' =
Proxy m
-> Proxy (PaginationExpanded subApi)
-> Request
-> Maybe Int
-> Maybe Int
-> Client m subApi
forall (m :: * -> *) api.
HasClient m api =>
Proxy m -> Proxy api -> Request -> Client m api
clientWithRoute
Proxy m
pm
(Proxy (PaginationExpanded subApi)
forall k (t :: k). Proxy t
Proxy @(PaginationExpanded subApi))
Request
req
(Int -> Maybe Int
forall a. a -> Maybe a
Just (Int -> Maybe Int) -> Int -> Maybe Int
forall a b. (a -> b) -> a -> b
$ Paged -> Int
countPerPage Paged
paged')
(Int -> Maybe Int
forall a. a -> Maybe a
Just (Int -> Maybe Int) -> Int -> Maybe Int
forall a b. (a -> b) -> a -> b
$ Paged -> Int
pageNumber Paged
paged')
hoistClientMonad :: Proxy m
-> Proxy (Pagination :> subApi)
-> (forall x. mon x -> mon' x)
-> Client mon (Pagination :> subApi)
-> Client mon' (Pagination :> subApi)
hoistClientMonad Proxy m
pm Proxy (Pagination :> subApi)
_ forall x. mon x -> mon' x
hst Client mon (Pagination :> subApi)
subCli = Proxy m
-> Proxy subApi
-> (forall x. mon x -> mon' x)
-> Client mon subApi
-> Client mon' subApi
forall (m :: * -> *) api (mon :: * -> *) (mon' :: * -> *).
HasClient m api =>
Proxy m
-> Proxy api
-> (forall x. mon x -> mon' x)
-> Client mon api
-> Client mon' api
hoistClientMonad Proxy m
pm (Proxy subApi
forall k (t :: k). Proxy t
Proxy @subApi) forall x. mon x -> mon' x
hst (Client mon subApi -> Client mon' subApi)
-> (Paged -> Client mon subApi) -> Paged -> Client mon' subApi
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Client mon (Pagination :> subApi)
Paged -> Client mon subApi
subCli