-- | Provides pagination API combinator.
module Servant.Util.Combinators.Pagination
    ( PaginationParams
    , PaginationPageSize (..)
    , KnownPaginationPageSize
    , PaginationSpec (..)
    , defPageSize
    , itemsOnPage
    , skipping
    , fullContent
    ) where

import Universum

import Control.Lens ((<>~), (?~))
import Data.Default (Default (..))
import qualified Data.Swagger as S
import qualified Data.Text as T
import Servant (DefaultErrorFormatters, ErrorFormatters, HasContextEntry, HasServer (..),
                QueryParam, (:>))
import Servant.Client (HasClient (..))
import Servant.Swagger (HasSwagger (..))

import Servant.Server.Internal.Context (type (.++))
import Servant.Util.Combinators.Logging
import Servant.Util.Common
import Servant.Util.Internal.Util

-- | API combinator which enables pagination.
--
-- Pagination parameters are specified via @offset@ and @limit@ query parameters.
-- Both fields are optional; @offset@ defaults to @0@ and default value of @limit@
-- is defined in @settings@ argument.
--
-- Your endpoint implementation will be provided with 'PaginationSpec' variable
-- which will contain parameters provided by the user.
data PaginationParams (settings :: PaginationPageSize)

-- | Determines the page size used when client leaves it unspecified.
data PaginationPageSize
    -- | Use specified default.
    = DefPageSize Nat
    -- | Display all contents.
    | DefUnlimitedPageSize

-- | Contains pagination parameters provided by the user.
data PaginationSpec = PaginationSpec
    { PaginationSpec -> Natural
psOffset :: Natural
      -- ^ How many elements to skip.
    , PaginationSpec -> Maybe (Positive Natural)
psLimit  :: Maybe (Positive Natural)
      -- ^ Maximum number of elements to leave.
      -- 'Nothing' stands for infinity.
    }

class KnownPaginationPageSize (settings :: PaginationPageSize) where
  settingDefPageSize :: Maybe (Positive Natural)

instance KnownPositive pageSize => KnownPaginationPageSize ('DefPageSize pageSize) where
  settingDefPageSize :: Maybe (Positive Natural)
settingDefPageSize = Positive Natural -> Maybe (Positive Natural)
forall a. a -> Maybe a
Just (forall i. (KnownPositive pageSize, Num i) => Positive i
forall (k :: Nat) i. (KnownPositive k, Num i) => Positive i
positiveVal @pageSize)

instance KnownPaginationPageSize 'DefUnlimitedPageSize where
  settingDefPageSize :: Maybe (Positive Natural)
settingDefPageSize = Maybe (Positive Natural)
forall a. Maybe a
Nothing

-- | How servant sees 'PaginationParams' under the hood.
type PaginationParamsExpanded subApi =
    QueryParam "offset" Natural :>
    QueryParam "limit" (Positive Natural) :>
    subApi

instance ( HasServer subApi ctx
         , HasContextEntry (ctx .++ DefaultErrorFormatters) ErrorFormatters
         , KnownPaginationPageSize settings
         ) => HasServer (PaginationParams settings :> subApi) ctx where
    type ServerT (PaginationParams settings :> subApi) m =
        PaginationSpec -> ServerT subApi m

    route :: Proxy (PaginationParams settings :> subApi)
-> Context ctx
-> Delayed env (Server (PaginationParams settings :> subApi))
-> Router env
route =
        (Proxy (PaginationParamsExpanded subApi)
 -> Context ctx
 -> Delayed env (Server (PaginationParamsExpanded subApi))
 -> Router env)
-> (Server (PaginationParams settings :> subApi)
    -> Server (PaginationParamsExpanded subApi))
-> Proxy (PaginationParams settings :> subApi)
-> Context ctx
-> Delayed env (Server (PaginationParams settings :> subApi))
-> Router env
forall api api' (ctx :: [*]) env.
(Proxy api
 -> Context ctx -> Delayed env (Server api) -> Router env)
-> (Server api' -> Server api)
-> Proxy api'
-> Context ctx
-> Delayed env (Server api')
-> Router env
inRouteServer @(PaginationParamsExpanded subApi) Proxy (PaginationParamsExpanded subApi)
-> Context ctx
-> Delayed env (Server (PaginationParamsExpanded subApi))
-> Router env
forall k (api :: k) (context :: [*]) env.
HasServer api context =>
Proxy api
-> Context context -> Delayed env (Server api) -> Router env
route ((Server (PaginationParams settings :> subApi)
  -> Server (PaginationParamsExpanded subApi))
 -> Proxy (PaginationParams settings :> subApi)
 -> Context ctx
 -> Delayed env (Server (PaginationParams settings :> subApi))
 -> Router env)
-> (Server (PaginationParams settings :> subApi)
    -> Server (PaginationParamsExpanded subApi))
-> Proxy (PaginationParams settings :> subApi)
-> Context ctx
-> Delayed env (Server (PaginationParams settings :> subApi))
-> Router env
forall a b. (a -> b) -> a -> b
$
        \Server (PaginationParams settings :> subApi)
handler Maybe Natural
offset Maybe (Positive Natural)
limit ->
            Server (PaginationParams settings :> subApi)
PaginationSpec -> ServerT subApi Handler
handler PaginationSpec :: Natural -> Maybe (Positive Natural) -> PaginationSpec
PaginationSpec
            { psOffset :: Natural
psOffset = Maybe Natural
offset Maybe Natural -> Natural -> Natural
forall a. Maybe a -> a -> a
?: Natural
0
            , psLimit :: Maybe (Positive Natural)
psLimit = Maybe (Positive Natural)
limit Maybe (Positive Natural)
-> Maybe (Positive Natural) -> Maybe (Positive Natural)
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> KnownPaginationPageSize settings => Maybe (Positive Natural)
forall (settings :: PaginationPageSize).
KnownPaginationPageSize settings =>
Maybe (Positive Natural)
settingDefPageSize @settings
            }

    hoistServerWithContext :: Proxy (PaginationParams settings :> subApi)
-> Proxy ctx
-> (forall x. m x -> n x)
-> ServerT (PaginationParams settings :> subApi) m
-> ServerT (PaginationParams settings :> subApi) n
hoistServerWithContext Proxy (PaginationParams settings :> subApi)
_ Proxy ctx
pc forall x. m x -> n x
nt ServerT (PaginationParams settings :> subApi) m
s =
        Proxy subApi
-> Proxy ctx
-> (forall x. m x -> n x)
-> ServerT subApi m
-> ServerT subApi n
forall k (api :: k) (context :: [*]) (m :: * -> *) (n :: * -> *).
HasServer api context =>
Proxy api
-> Proxy context
-> (forall x. m x -> n x)
-> ServerT api m
-> ServerT api n
hoistServerWithContext (Proxy subApi
forall k (t :: k). Proxy t
Proxy @subApi) Proxy ctx
pc forall x. m x -> n x
nt (ServerT subApi m -> ServerT subApi n)
-> (PaginationSpec -> ServerT subApi m)
-> PaginationSpec
-> ServerT subApi n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ServerT (PaginationParams settings :> subApi) m
PaginationSpec -> ServerT subApi m
s

instance
  ( HasLoggingServer config lcontext subApi ctx
  , KnownPaginationPageSize settings
  , HasContextEntry (ctx .++ DefaultErrorFormatters) ErrorFormatters
  ) =>
  HasLoggingServer config lcontext (PaginationParams settings :> subApi) ctx where
    routeWithLog :: Proxy
  (LoggingApiRec
     config lcontext (PaginationParams settings :> subApi))
-> Context ctx
-> Delayed
     env
     (Server
        (LoggingApiRec
           config lcontext (PaginationParams settings :> subApi)))
-> Router env
routeWithLog =
        (Proxy
   (PaginationParams settings :> LoggingApiRec config lcontext subApi)
 -> Context ctx
 -> Delayed
      env
      (Server
         (PaginationParams settings
          :> LoggingApiRec config lcontext subApi))
 -> Router env)
-> (Server
      (LoggingApiRec
         config lcontext (PaginationParams settings :> subApi))
    -> Server
         (PaginationParams settings
          :> LoggingApiRec config lcontext subApi))
-> Proxy
     (LoggingApiRec
        config lcontext (PaginationParams settings :> subApi))
-> Context ctx
-> Delayed
     env
     (Server
        (LoggingApiRec
           config lcontext (PaginationParams settings :> subApi)))
-> Router env
forall api api' (ctx :: [*]) env.
(Proxy api
 -> Context ctx -> Delayed env (Server api) -> Router env)
-> (Server api' -> Server api)
-> Proxy api'
-> Context ctx
-> Delayed env (Server api')
-> Router env
inRouteServer @(PaginationParams settings :> LoggingApiRec config lcontext subApi) Proxy
  (PaginationParams settings :> LoggingApiRec config lcontext subApi)
-> Context ctx
-> Delayed
     env
     (Server
        (PaginationParams settings
         :> LoggingApiRec config lcontext subApi))
-> Router env
forall k (api :: k) (context :: [*]) env.
HasServer api context =>
Proxy api
-> Context context -> Delayed env (Server api) -> Router env
route ((Server
    (LoggingApiRec
       config lcontext (PaginationParams settings :> subApi))
  -> Server
       (PaginationParams settings
        :> LoggingApiRec config lcontext subApi))
 -> Proxy
      (LoggingApiRec
         config lcontext (PaginationParams settings :> subApi))
 -> Context ctx
 -> Delayed
      env
      (Server
         (LoggingApiRec
            config lcontext (PaginationParams settings :> subApi)))
 -> Router env)
-> (Server
      (LoggingApiRec
         config lcontext (PaginationParams settings :> subApi))
    -> Server
         (PaginationParams settings
          :> LoggingApiRec config lcontext subApi))
-> Proxy
     (LoggingApiRec
        config lcontext (PaginationParams settings :> subApi))
-> Context ctx
-> Delayed
     env
     (Server
        (LoggingApiRec
           config lcontext (PaginationParams settings :> subApi)))
-> Router env
forall a b. (a -> b) -> a -> b
$
        \(paramsInfo, handler) pagination :: PaginationSpec
pagination@PaginationSpec{Natural
Maybe (Positive Natural)
psLimit :: Maybe (Positive Natural)
psOffset :: Natural
psLimit :: PaginationSpec -> Maybe (Positive Natural)
psOffset :: PaginationSpec -> Natural
..} ->
            let text :: Text
text = [Text] -> Text
merge ([Text] -> Text)
-> ([Maybe Text] -> [Text]) -> [Maybe Text] -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Maybe Text] -> [Text]
forall a. [Maybe a] -> [a]
catMaybes ([Maybe Text] -> Text) -> [Maybe Text] -> Text
forall a b. (a -> b) -> a -> b
$
                  [ Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Natural
psOffset Natural -> Natural -> Bool
forall a. Ord a => a -> a -> Bool
> Natural
0) Maybe () -> Text -> Maybe Text
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> (Text
"offset " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Natural -> Text
forall b a. (Show a, IsString b) => a -> b
show Natural
psOffset)
                  , (Positive Natural -> Text)
-> Maybe (Positive Natural) -> Maybe Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap @Maybe
                      (\Positive Natural
limit -> Natural -> Text
forall b a. (Show a, IsString b) => a -> b
show (Positive Natural -> Natural
forall a. Positive a -> a
unPositive Positive Natural
limit) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" per page")
                      Maybe (Positive Natural)
psLimit
                  ]
            in (Text -> ApiParamsLogInfo -> ApiParamsLogInfo
addParamLogInfo Text
text ApiParamsLogInfo
paramsInfo, PaginationSpec -> ServerT subApi Handler
handler PaginationSpec
pagination)
      where
        merge :: [Text] -> Text
merge [Text]
ts
            | [Text] -> Bool
forall t. Container t => t -> Bool
null [Text]
ts = Text
"no pagination"
            | Bool
otherwise = Text -> [Text] -> Text
T.intercalate Text
", " [Text]
ts


-- | Do not paginate anything, use default page size.
defPageSize :: PaginationSpec
defPageSize :: PaginationSpec
defPageSize = PaginationSpec :: Natural -> Maybe (Positive Natural) -> PaginationSpec
PaginationSpec{ psOffset :: Natural
psOffset = Natural
0, psLimit :: Maybe (Positive Natural)
psLimit = Maybe (Positive Natural)
forall a. Maybe a
Nothing }

-- | Conveient builder for 'PaginationRequest', creates pagination
-- with zero offset and given limit.
itemsOnPage :: HasCallStack => Natural -> PaginationSpec
itemsOnPage :: Natural -> PaginationSpec
itemsOnPage Natural
limit = PaginationSpec :: Natural -> Maybe (Positive Natural) -> PaginationSpec
PaginationSpec
  { psOffset :: Natural
psOffset = Natural
0
  , psLimit :: Maybe (Positive Natural)
psLimit = Positive Natural -> Maybe (Positive Natural)
forall a. a -> Maybe a
Just (Natural -> Positive Natural
forall a. (Show a, Ord a, Num a, HasCallStack) => a -> Positive a
unsafeToPositive Natural
limit)
  }

-- | Convenient builder for 'PaginationRequest', modifies offset.
skipping :: Natural -> PaginationSpec -> PaginationSpec
skipping :: Natural -> PaginationSpec -> PaginationSpec
skipping Natural
offset PaginationSpec
pagination = PaginationSpec
pagination{ psOffset :: Natural
psOffset = Natural
offset }

-- | Do not paginate anything.
fullContent :: PaginationSpec
fullContent :: PaginationSpec
fullContent = PaginationSpec
defPageSize
{-# DEPRECATED fullContent "Use `defPageSize` instead" #-}

-- | Retains full content.
instance Default PaginationSpec where
    def :: PaginationSpec
def = PaginationSpec
defPageSize

instance HasClient m subApi =>
         HasClient m (PaginationParams settings :> subApi) where
    type Client m (PaginationParams settings :> subApi) =
        PaginationSpec -> Client m subApi

    clientWithRoute :: Proxy m
-> Proxy (PaginationParams settings :> subApi)
-> Request
-> Client m (PaginationParams settings :> subApi)
clientWithRoute Proxy m
mp Proxy (PaginationParams settings :> subApi)
_ Request
req PaginationSpec{Natural
Maybe (Positive Natural)
psLimit :: Maybe (Positive Natural)
psOffset :: Natural
psLimit :: PaginationSpec -> Maybe (Positive Natural)
psOffset :: PaginationSpec -> Natural
..} =
        Proxy m
-> Proxy (PaginationParamsExpanded subApi)
-> Request
-> Maybe Natural
-> Maybe (Positive Natural)
-> Client m subApi
forall (m :: * -> *) api.
HasClient m api =>
Proxy m -> Proxy api -> Request -> Client m api
clientWithRoute Proxy m
mp (Proxy (PaginationParamsExpanded subApi)
forall k (t :: k). Proxy t
Proxy @(PaginationParamsExpanded subApi)) Request
req
            (Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Natural
psOffset Natural -> Natural -> Bool
forall a. Ord a => a -> a -> Bool
> Natural
0) Maybe () -> Natural -> Maybe Natural
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Natural
psOffset)
            Maybe (Positive Natural)
psLimit

    hoistClientMonad :: Proxy m
-> Proxy (PaginationParams settings :> subApi)
-> (forall x. mon x -> mon' x)
-> Client mon (PaginationParams settings :> subApi)
-> Client mon' (PaginationParams settings :> subApi)
hoistClientMonad Proxy m
pm Proxy (PaginationParams settings :> subApi)
_ forall x. mon x -> mon' x
hst Client mon (PaginationParams settings :> 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)
-> (PaginationSpec -> Client mon subApi)
-> PaginationSpec
-> Client mon' subApi
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Client mon (PaginationParams settings :> subApi)
PaginationSpec -> Client mon subApi
subCli

instance (HasSwagger api, KnownPaginationPageSize settings) =>
         HasSwagger (PaginationParams settings :> api) where
    toSwagger :: Proxy (PaginationParams settings :> api) -> Swagger
toSwagger Proxy (PaginationParams settings :> api)
_ = Proxy api -> Swagger
forall k (api :: k). HasSwagger api => Proxy api -> Swagger
toSwagger (Proxy api
forall k (t :: k). Proxy t
Proxy @api)
        Swagger -> (Swagger -> Swagger) -> Swagger
forall a b. a -> (a -> b) -> b
& (Operation -> Identity Operation) -> Swagger -> Identity Swagger
Traversal' Swagger Operation
S.allOperations ((Operation -> Identity Operation) -> Swagger -> Identity Swagger)
-> (([Referenced Param] -> Identity [Referenced Param])
    -> Operation -> Identity Operation)
-> ([Referenced Param] -> Identity [Referenced Param])
-> Swagger
-> Identity Swagger
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Referenced Param] -> Identity [Referenced Param])
-> Operation -> Identity Operation
forall s a. HasParameters s a => Lens' s a
S.parameters (([Referenced Param] -> Identity [Referenced Param])
 -> Swagger -> Identity Swagger)
-> [Referenced Param] -> Swagger -> Swagger
forall a s t. Semigroup a => ASetter s t a a -> a -> s -> t
<>~ [Param -> Referenced Param
forall a. a -> Referenced a
S.Inline Param
offsetParam, Param -> Referenced Param
forall a. a -> Referenced a
S.Inline Param
limitParam]
      where
        offsetParam :: S.Param
        limitParam :: S.Param
        offsetParam :: Param
offsetParam = Param
forall a. Monoid a => a
mempty
            Param -> (Param -> Param) -> Param
forall a b. a -> (a -> b) -> b
& (Text -> Identity Text) -> Param -> Identity Param
forall s a. HasName s a => Lens' s a
S.name ((Text -> Identity Text) -> Param -> Identity Param)
-> Text -> Param -> Param
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Text
"offset"
            Param -> (Param -> Param) -> Param
forall a b. a -> (a -> b) -> b
& (Maybe Text -> Identity (Maybe Text)) -> Param -> Identity Param
forall s a. HasDescription s a => Lens' s a
S.description ((Maybe Text -> Identity (Maybe Text)) -> Param -> Identity Param)
-> Text -> Param -> Param
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~
                Text
"Pagination parameter. How many items to skip from the beginning."
            Param -> (Param -> Param) -> Param
forall a b. a -> (a -> b) -> b
& (Maybe Bool -> Identity (Maybe Bool)) -> Param -> Identity Param
forall s a. HasRequired s a => Lens' s a
S.required ((Maybe Bool -> Identity (Maybe Bool)) -> Param -> Identity Param)
-> Bool -> Param -> Param
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ Bool
False
            Param -> (Param -> Param) -> Param
forall a b. a -> (a -> b) -> b
& (ParamAnySchema -> Identity ParamAnySchema)
-> Param -> Identity Param
forall s a. HasSchema s a => Lens' s a
S.schema ((ParamAnySchema -> Identity ParamAnySchema)
 -> Param -> Identity Param)
-> ParamAnySchema -> Param -> Param
forall s t a b. ASetter s t a b -> b -> s -> t
.~ ParamOtherSchema -> ParamAnySchema
S.ParamOther (ParamOtherSchema
forall a. Monoid a => a
mempty
                ParamOtherSchema
-> (ParamOtherSchema -> ParamOtherSchema) -> ParamOtherSchema
forall a b. a -> (a -> b) -> b
& (ParamLocation -> Identity ParamLocation)
-> ParamOtherSchema -> Identity ParamOtherSchema
forall s a. HasIn s a => Lens' s a
S.in_ ((ParamLocation -> Identity ParamLocation)
 -> ParamOtherSchema -> Identity ParamOtherSchema)
-> ParamLocation -> ParamOtherSchema -> ParamOtherSchema
forall s t a b. ASetter s t a b -> b -> s -> t
.~ ParamLocation
S.ParamQuery
                ParamOtherSchema
-> (ParamOtherSchema -> ParamOtherSchema) -> ParamOtherSchema
forall a b. a -> (a -> b) -> b
& (ParamSchema 'SwaggerKindParamOtherSchema
 -> Identity (ParamSchema 'SwaggerKindParamOtherSchema))
-> ParamOtherSchema -> Identity ParamOtherSchema
forall s a. HasParamSchema s a => Lens' s a
S.paramSchema ((ParamSchema 'SwaggerKindParamOtherSchema
  -> Identity (ParamSchema 'SwaggerKindParamOtherSchema))
 -> ParamOtherSchema -> Identity ParamOtherSchema)
-> ParamSchema 'SwaggerKindParamOtherSchema
-> ParamOtherSchema
-> ParamOtherSchema
forall s t a b. ASetter s t a b -> b -> s -> t
.~ ParamSchema 'SwaggerKindParamOtherSchema
offsetParamSchema
                )
        offsetParamSchema :: ParamSchema 'SwaggerKindParamOtherSchema
offsetParamSchema = ParamSchema 'SwaggerKindParamOtherSchema
forall a. Monoid a => a
mempty
            ParamSchema 'SwaggerKindParamOtherSchema
-> (ParamSchema 'SwaggerKindParamOtherSchema
    -> ParamSchema 'SwaggerKindParamOtherSchema)
-> ParamSchema 'SwaggerKindParamOtherSchema
forall a b. a -> (a -> b) -> b
& (Maybe (SwaggerType 'SwaggerKindParamOtherSchema)
 -> Identity (Maybe (SwaggerType 'SwaggerKindParamOtherSchema)))
-> ParamSchema 'SwaggerKindParamOtherSchema
-> Identity (ParamSchema 'SwaggerKindParamOtherSchema)
forall s a. HasType s a => Lens' s a
S.type_ ((Maybe (SwaggerType 'SwaggerKindParamOtherSchema)
  -> Identity (Maybe (SwaggerType 'SwaggerKindParamOtherSchema)))
 -> ParamSchema 'SwaggerKindParamOtherSchema
 -> Identity (ParamSchema 'SwaggerKindParamOtherSchema))
-> SwaggerType 'SwaggerKindParamOtherSchema
-> ParamSchema 'SwaggerKindParamOtherSchema
-> ParamSchema 'SwaggerKindParamOtherSchema
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ SwaggerType 'SwaggerKindParamOtherSchema
forall (t :: SwaggerKind *). SwaggerType t
S.SwaggerInteger
            ParamSchema 'SwaggerKindParamOtherSchema
-> (ParamSchema 'SwaggerKindParamOtherSchema
    -> ParamSchema 'SwaggerKindParamOtherSchema)
-> ParamSchema 'SwaggerKindParamOtherSchema
forall a b. a -> (a -> b) -> b
& (Maybe Text -> Identity (Maybe Text))
-> ParamSchema 'SwaggerKindParamOtherSchema
-> Identity (ParamSchema 'SwaggerKindParamOtherSchema)
forall s a. HasFormat s a => Lens' s a
S.format ((Maybe Text -> Identity (Maybe Text))
 -> ParamSchema 'SwaggerKindParamOtherSchema
 -> Identity (ParamSchema 'SwaggerKindParamOtherSchema))
-> Text
-> ParamSchema 'SwaggerKindParamOtherSchema
-> ParamSchema 'SwaggerKindParamOtherSchema
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ Text
"int32"

        limitParam :: Param
limitParam = Param
forall a. Monoid a => a
mempty
            Param -> (Param -> Param) -> Param
forall a b. a -> (a -> b) -> b
& (Text -> Identity Text) -> Param -> Identity Param
forall s a. HasName s a => Lens' s a
S.name ((Text -> Identity Text) -> Param -> Identity Param)
-> Text -> Param -> Param
forall s t a b. ASetter s t a b -> b -> s -> t
.~ Text
"limit"
            Param -> (Param -> Param) -> Param
forall a b. a -> (a -> b) -> b
& (Maybe Text -> Identity (Maybe Text)) -> Param -> Identity Param
forall s a. HasDescription s a => Lens' s a
S.description ((Maybe Text -> Identity (Maybe Text)) -> Param -> Identity Param)
-> Text -> Param -> Param
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat
                [ Text
"Pagination parameter. Maximum number of items to return.\n"
                , Text
defaultPageSizeDesc
                ]
            Param -> (Param -> Param) -> Param
forall a b. a -> (a -> b) -> b
& (Maybe Bool -> Identity (Maybe Bool)) -> Param -> Identity Param
forall s a. HasRequired s a => Lens' s a
S.required ((Maybe Bool -> Identity (Maybe Bool)) -> Param -> Identity Param)
-> Bool -> Param -> Param
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ Bool
False
            Param -> (Param -> Param) -> Param
forall a b. a -> (a -> b) -> b
& (ParamAnySchema -> Identity ParamAnySchema)
-> Param -> Identity Param
forall s a. HasSchema s a => Lens' s a
S.schema ((ParamAnySchema -> Identity ParamAnySchema)
 -> Param -> Identity Param)
-> ParamAnySchema -> Param -> Param
forall s t a b. ASetter s t a b -> b -> s -> t
.~ ParamOtherSchema -> ParamAnySchema
S.ParamOther (ParamOtherSchema
forall a. Monoid a => a
mempty
                ParamOtherSchema
-> (ParamOtherSchema -> ParamOtherSchema) -> ParamOtherSchema
forall a b. a -> (a -> b) -> b
& (ParamLocation -> Identity ParamLocation)
-> ParamOtherSchema -> Identity ParamOtherSchema
forall s a. HasIn s a => Lens' s a
S.in_ ((ParamLocation -> Identity ParamLocation)
 -> ParamOtherSchema -> Identity ParamOtherSchema)
-> ParamLocation -> ParamOtherSchema -> ParamOtherSchema
forall s t a b. ASetter s t a b -> b -> s -> t
.~ ParamLocation
S.ParamQuery
                ParamOtherSchema
-> (ParamOtherSchema -> ParamOtherSchema) -> ParamOtherSchema
forall a b. a -> (a -> b) -> b
& (ParamSchema 'SwaggerKindParamOtherSchema
 -> Identity (ParamSchema 'SwaggerKindParamOtherSchema))
-> ParamOtherSchema -> Identity ParamOtherSchema
forall s a. HasParamSchema s a => Lens' s a
S.paramSchema ((ParamSchema 'SwaggerKindParamOtherSchema
  -> Identity (ParamSchema 'SwaggerKindParamOtherSchema))
 -> ParamOtherSchema -> Identity ParamOtherSchema)
-> ParamSchema 'SwaggerKindParamOtherSchema
-> ParamOtherSchema
-> ParamOtherSchema
forall s t a b. ASetter s t a b -> b -> s -> t
.~ ParamSchema 'SwaggerKindParamOtherSchema
limitParamSchema
                )
        limitParamSchema :: ParamSchema 'SwaggerKindParamOtherSchema
limitParamSchema = ParamSchema 'SwaggerKindParamOtherSchema
forall a. Monoid a => a
mempty
            ParamSchema 'SwaggerKindParamOtherSchema
-> (ParamSchema 'SwaggerKindParamOtherSchema
    -> ParamSchema 'SwaggerKindParamOtherSchema)
-> ParamSchema 'SwaggerKindParamOtherSchema
forall a b. a -> (a -> b) -> b
& (Maybe (SwaggerType 'SwaggerKindParamOtherSchema)
 -> Identity (Maybe (SwaggerType 'SwaggerKindParamOtherSchema)))
-> ParamSchema 'SwaggerKindParamOtherSchema
-> Identity (ParamSchema 'SwaggerKindParamOtherSchema)
forall s a. HasType s a => Lens' s a
S.type_ ((Maybe (SwaggerType 'SwaggerKindParamOtherSchema)
  -> Identity (Maybe (SwaggerType 'SwaggerKindParamOtherSchema)))
 -> ParamSchema 'SwaggerKindParamOtherSchema
 -> Identity (ParamSchema 'SwaggerKindParamOtherSchema))
-> SwaggerType 'SwaggerKindParamOtherSchema
-> ParamSchema 'SwaggerKindParamOtherSchema
-> ParamSchema 'SwaggerKindParamOtherSchema
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ SwaggerType 'SwaggerKindParamOtherSchema
forall (t :: SwaggerKind *). SwaggerType t
S.SwaggerInteger
            ParamSchema 'SwaggerKindParamOtherSchema
-> (ParamSchema 'SwaggerKindParamOtherSchema
    -> ParamSchema 'SwaggerKindParamOtherSchema)
-> ParamSchema 'SwaggerKindParamOtherSchema
forall a b. a -> (a -> b) -> b
& (Maybe Text -> Identity (Maybe Text))
-> ParamSchema 'SwaggerKindParamOtherSchema
-> Identity (ParamSchema 'SwaggerKindParamOtherSchema)
forall s a. HasFormat s a => Lens' s a
S.format ((Maybe Text -> Identity (Maybe Text))
 -> ParamSchema 'SwaggerKindParamOtherSchema
 -> Identity (ParamSchema 'SwaggerKindParamOtherSchema))
-> Text
-> ParamSchema 'SwaggerKindParamOtherSchema
-> ParamSchema 'SwaggerKindParamOtherSchema
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ Text
"int32"
            ParamSchema 'SwaggerKindParamOtherSchema
-> (ParamSchema 'SwaggerKindParamOtherSchema
    -> ParamSchema 'SwaggerKindParamOtherSchema)
-> ParamSchema 'SwaggerKindParamOtherSchema
forall a b. a -> (a -> b) -> b
& (Maybe Text -> Identity (Maybe Text))
-> ParamSchema 'SwaggerKindParamOtherSchema
-> Identity (ParamSchema 'SwaggerKindParamOtherSchema)
forall s a. HasPattern s a => Lens' s a
S.pattern ((Maybe Text -> Identity (Maybe Text))
 -> ParamSchema 'SwaggerKindParamOtherSchema
 -> Identity (ParamSchema 'SwaggerKindParamOtherSchema))
-> Text
-> ParamSchema 'SwaggerKindParamOtherSchema
-> ParamSchema 'SwaggerKindParamOtherSchema
forall s t a b. ASetter s t a (Maybe b) -> b -> s -> t
?~ Text
"^\\d*[1-9]\\d*$"
        defaultPageSizeDesc :: Text
defaultPageSizeDesc = case KnownPaginationPageSize settings => Maybe (Positive Natural)
forall (settings :: PaginationPageSize).
KnownPaginationPageSize settings =>
Maybe (Positive Natural)
settingDefPageSize @settings of
          Maybe (Positive Natural)
Nothing -> Text
"By default, no limit will be applied."
          Just Positive Natural
s  -> Text
"Defaults to " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Natural -> Text
forall b a. (Show a, IsString b) => a -> b
show (Positive Natural -> Natural
forall a. Positive a -> a
unPositive Positive Natural
s) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"."