7
7
// Generated code from schemars violates this rule
8
8
#![ allow( clippy:: str_to_string) ]
9
9
10
- use std:: num:: NonZeroUsize ;
10
+ use std:: { borrow :: Cow , num:: NonZeroUsize } ;
11
11
12
12
use aide:: OperationIo ;
13
13
use axum:: {
@@ -64,6 +64,34 @@ impl std::ops::Deref for UlidPathParam {
64
64
/// The default page size if not specified
65
65
const DEFAULT_PAGE_SIZE : usize = 10 ;
66
66
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
+
67
95
#[ derive( Deserialize , JsonSchema , Clone , Copy ) ]
68
96
struct PaginationParams {
69
97
/// Retrieve the items before the given ID
@@ -83,6 +111,10 @@ struct PaginationParams {
83
111
/// Retrieve the last N items
84
112
#[ serde( rename = "page[last]" ) ]
85
113
last : Option < NonZeroUsize > ,
114
+
115
+ /// Include the total number of items. Defaults to `true`.
116
+ #[ serde( rename = "count" ) ]
117
+ include_count : Option < IncludeCount > ,
86
118
}
87
119
88
120
#[ derive( Debug , thiserror:: Error ) ]
@@ -107,7 +139,7 @@ impl IntoResponse for PaginationRejection {
107
139
/// An extractor for pagination parameters in the query string
108
140
#[ derive( OperationIo , Debug , Clone , Copy ) ]
109
141
#[ aide( input_with = "Query<PaginationParams>" ) ]
110
- pub struct Pagination ( pub mas_storage:: Pagination ) ;
142
+ pub struct Pagination ( pub mas_storage:: Pagination , pub IncludeCount ) ;
111
143
112
144
impl < S : Send + Sync > FromRequestParts < S > for Pagination {
113
145
type Rejection = PaginationRejection ;
@@ -130,11 +162,14 @@ impl<S: Send + Sync> FromRequestParts<S> for Pagination {
130
162
( None , Some ( last) ) => ( PaginationDirection :: Backward , last. into ( ) ) ,
131
163
} ;
132
164
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
+ ) )
139
174
}
140
175
}
0 commit comments