77// Generated code from schemars violates this rule
88#![ allow( clippy:: str_to_string) ]
99
10- use std:: num:: NonZeroUsize ;
10+ use std:: { borrow :: Cow , num:: NonZeroUsize } ;
1111
1212use aide:: OperationIo ;
1313use axum:: {
@@ -64,6 +64,34 @@ impl std::ops::Deref for UlidPathParam {
6464/// The default page size if not specified
6565const DEFAULT_PAGE_SIZE : usize = 10 ;
6666
67+ #[ derive( Deserialize , JsonSchema , Clone , Copy , Default , Debug ) ]
68+ pub enum IncludeCount {
69+ /// Include the total number of items (default)
70+ #[ default]
71+ #[ serde( rename = "true" ) ]
72+ True ,
73+
74+ /// Do not include the total number of items
75+ #[ serde( rename = "false" ) ]
76+ False ,
77+
78+ /// Only include the total number of items, skip the items themselves
79+ #[ serde( rename = "only" ) ]
80+ Only ,
81+ }
82+
83+ impl IncludeCount {
84+ pub ( crate ) fn add_to_base ( self , base : & str ) -> Cow < ' _ , str > {
85+ let separator = if base. contains ( '?' ) { '&' } else { '?' } ;
86+ match self {
87+ // This is the default, don't add anything
88+ Self :: True => Cow :: Borrowed ( base) ,
89+ Self :: False => format ! ( "{base}{separator}count=false" ) . into ( ) ,
90+ Self :: Only => format ! ( "{base}{separator}count=only" ) . into ( ) ,
91+ }
92+ }
93+ }
94+
6795#[ derive( Deserialize , JsonSchema , Clone , Copy ) ]
6896struct PaginationParams {
6997 /// Retrieve the items before the given ID
@@ -83,6 +111,10 @@ struct PaginationParams {
83111 /// Retrieve the last N items
84112 #[ serde( rename = "page[last]" ) ]
85113 last : Option < NonZeroUsize > ,
114+
115+ /// Include the total number of items. Defaults to `true`.
116+ #[ serde( rename = "count" ) ]
117+ include_count : Option < IncludeCount > ,
86118}
87119
88120#[ derive( Debug , thiserror:: Error ) ]
@@ -107,7 +139,7 @@ impl IntoResponse for PaginationRejection {
107139/// An extractor for pagination parameters in the query string
108140#[ derive( OperationIo , Debug , Clone , Copy ) ]
109141#[ aide( input_with = "Query<PaginationParams>" ) ]
110- pub struct Pagination ( pub mas_storage:: Pagination ) ;
142+ pub struct Pagination ( pub mas_storage:: Pagination , pub IncludeCount ) ;
111143
112144impl < S : Send + Sync > FromRequestParts < S > for Pagination {
113145 type Rejection = PaginationRejection ;
@@ -130,11 +162,14 @@ impl<S: Send + Sync> FromRequestParts<S> for Pagination {
130162 ( None , Some ( last) ) => ( PaginationDirection :: Backward , last. into ( ) ) ,
131163 } ;
132164
133- Ok ( Self ( mas_storage:: Pagination {
134- before : params. before ,
135- after : params. after ,
136- direction,
137- count,
138- } ) )
165+ Ok ( Self (
166+ mas_storage:: Pagination {
167+ before : params. before ,
168+ after : params. after ,
169+ direction,
170+ count,
171+ } ,
172+ params. include_count . unwrap_or_default ( ) ,
173+ ) )
139174 }
140175}
0 commit comments