11//! Cache key generation for metadata collections.
22//!
33//! This module provides functions to generate deterministic cache keys from
4- //! API parameters. The cache key is used to identify unique list configurations
4+ //! filter parameters. The cache key is used to identify unique list configurations
55//! in the metadata store.
66
77use url:: Url ;
88use wp_api:: {
9- posts:: { PostListParams , PostListParamsField } ,
9+ posts:: PostListParamsField ,
1010 request:: endpoint:: posts_endpoint:: PostEndpointType ,
1111 url_query:: AsQueryValue ,
1212} ;
1313
14+ use crate :: filters:: PostListFilter ;
15+
1416/// Generates a cache key segment from a `PostEndpointType`.
1517///
1618/// Uses a `post_type_` prefix to avoid conflicts with custom post type names
@@ -66,137 +68,76 @@ impl QueryPairsExt for url::form_urlencoded::Serializer<'_, url::UrlQuery<'_>> {
6668 }
6769}
6870
69- /// Generates a deterministic cache key from `PostListParams `.
71+ /// Generates a deterministic cache key from `PostListFilter `.
7072///
71- /// This function explicitly includes only filter-relevant fields, excluding
72- /// pagination and instance-specific fields. Each excluded field has a comment
73- /// explaining why it's not part of the cache key .
73+ /// All fields in `PostListFilter` are included in the cache key since it only
74+ /// contains filter-relevant fields (pagination, instance-specific, and date
75+ /// range fields are excluded by design in `PostListFilter`) .
7476///
7577/// # Arguments
76- /// * `params ` - The post list parameters to generate a cache key from
78+ /// * `filter ` - The post list filter to generate a cache key from
7779///
7880/// # Returns
79- /// A URL query string containing only the filter-relevant parameters,
81+ /// A URL query string containing the filter parameters in alphabetical order ,
8082/// suitable for use as a cache key suffix.
8183///
8284/// # Example
8385/// ```ignore
84- /// let params = PostListParams {
86+ /// let filter = PostListFilter {
8587/// status: vec![PostStatus::Publish],
8688/// author: vec![UserId(5)],
8789/// ..Default::default()
8890/// };
89- /// let key = post_list_params_cache_key(¶ms );
91+ /// let key = post_list_filter_cache_key(&filter );
9092/// // key = "author=5&status=publish"
9193/// ```
92- pub fn post_list_params_cache_key ( params : & PostListParams ) -> String {
94+ pub fn post_list_filter_cache_key ( filter : & PostListFilter ) -> String {
9395 let mut url = Url :: parse ( "https://cache-key-generator.local" ) . expect ( "valid base URL" ) ;
9496
9597 {
9698 let mut q = url. query_pairs_mut ( ) ;
9799
98- // ============================================================
99- // EXCLUDED FIELDS (not part of cache key)
100- // ============================================================
101-
102- // `page` - Excluded: pagination is managed by the collection, not the filter
103- // `per_page` - Excluded: pagination is managed by the collection, not the filter
104- // `offset` - Excluded: pagination is managed by the collection, not the filter
105- // `include` - Excluded: instance-specific, used for fetching specific posts by ID
106- // `exclude` - Excluded: instance-specific, used for excluding specific posts by ID
107-
108- // ============================================================
109- // INCLUDED FIELDS (alphabetically ordered for determinism)
110- // ============================================================
111-
112- // after - Filter: limit to posts published after this date
113- q. append_option ( PostListParamsField :: After . into ( ) , params. after . as_ref ( ) ) ;
114-
115- // author - Filter: limit to posts by specific authors
116- q. append_vec ( PostListParamsField :: Author . into ( ) , & params. author ) ;
100+ // All fields in PostListFilter are included (alphabetically ordered for determinism).
101+ // Fields excluded from PostListFilter (pagination, instance-specific, date ranges)
102+ // are documented in the PostListFilter type definition.
117103
118- // author_exclude - Filter: exclude posts by specific authors
104+ q . append_vec ( PostListParamsField :: Author . into ( ) , & filter . author ) ;
119105 q. append_vec (
120106 PostListParamsField :: AuthorExclude . into ( ) ,
121- & params . author_exclude ,
107+ & filter . author_exclude ,
122108 ) ;
123-
124- // before - Filter: limit to posts published before this date
125- q. append_option ( PostListParamsField :: Before . into ( ) , params. before . as_ref ( ) ) ;
126-
127- // categories - Filter: limit to posts in specific categories
128- q. append_vec ( PostListParamsField :: Categories . into ( ) , & params. categories ) ;
129-
130- // categories_exclude - Filter: exclude posts in specific categories
109+ q. append_vec ( PostListParamsField :: Categories . into ( ) , & filter. categories ) ;
131110 q. append_vec (
132111 PostListParamsField :: CategoriesExclude . into ( ) ,
133- & params . categories_exclude ,
112+ & filter . categories_exclude ,
134113 ) ;
135-
136- // menu_order - Filter: limit by menu order (for hierarchical post types)
137114 q. append_option (
138115 PostListParamsField :: MenuOrder . into ( ) ,
139- params. menu_order . as_ref ( ) ,
140- ) ;
141-
142- // modified_after - Filter: limit to posts modified after this date
143- q. append_option (
144- PostListParamsField :: ModifiedAfter . into ( ) ,
145- params. modified_after . as_ref ( ) ,
146- ) ;
147-
148- // modified_before - Filter: limit to posts modified before this date
149- q. append_option (
150- PostListParamsField :: ModifiedBefore . into ( ) ,
151- params. modified_before . as_ref ( ) ,
116+ filter. menu_order . as_ref ( ) ,
152117 ) ;
153-
154- // order - Ordering: affects which posts appear on each page
155- q. append_option ( PostListParamsField :: Order . into ( ) , params. order . as_ref ( ) ) ;
156-
157- // orderby - Ordering: affects which posts appear on each page
158- q. append_option ( PostListParamsField :: Orderby . into ( ) , params. orderby . as_ref ( ) ) ;
159-
160- // parent - Filter: limit to posts with specific parent (hierarchical)
161- q. append_option ( PostListParamsField :: Parent . into ( ) , params. parent . as_ref ( ) ) ;
162-
163- // parent_exclude - Filter: exclude posts with specific parents
118+ q. append_option ( PostListParamsField :: Order . into ( ) , filter. order . as_ref ( ) ) ;
119+ q. append_option ( PostListParamsField :: Orderby . into ( ) , filter. orderby . as_ref ( ) ) ;
120+ q. append_option ( PostListParamsField :: Parent . into ( ) , filter. parent . as_ref ( ) ) ;
164121 q. append_vec (
165122 PostListParamsField :: ParentExclude . into ( ) ,
166- & params . parent_exclude ,
123+ & filter . parent_exclude ,
167124 ) ;
168-
169- // search - Filter: limit to posts matching search string
170- q. append_option ( PostListParamsField :: Search . into ( ) , params. search . as_ref ( ) ) ;
171-
172- // search_columns - Filter: which columns to search in
125+ q. append_option ( PostListParamsField :: Search . into ( ) , filter. search . as_ref ( ) ) ;
173126 q. append_vec (
174127 PostListParamsField :: SearchColumns . into ( ) ,
175- & params . search_columns ,
128+ & filter . search_columns ,
176129 ) ;
177-
178- // slug - Filter: limit to posts with specific slugs
179- q. append_vec ( PostListParamsField :: Slug . into ( ) , & params. slug ) ;
180-
181- // status - Filter: limit to posts with specific statuses
182- q. append_vec ( PostListParamsField :: Status . into ( ) , & params. status ) ;
183-
184- // sticky - Filter: limit to sticky or non-sticky posts
185- q. append_option ( PostListParamsField :: Sticky . into ( ) , params. sticky . as_ref ( ) ) ;
186-
187- // tags - Filter: limit to posts with specific tags
188- q. append_vec ( PostListParamsField :: Tags . into ( ) , & params. tags ) ;
189-
190- // tags_exclude - Filter: exclude posts with specific tags
130+ q. append_vec ( PostListParamsField :: Slug . into ( ) , & filter. slug ) ;
131+ q. append_vec ( PostListParamsField :: Status . into ( ) , & filter. status ) ;
132+ q. append_option ( PostListParamsField :: Sticky . into ( ) , filter. sticky . as_ref ( ) ) ;
133+ q. append_vec ( PostListParamsField :: Tags . into ( ) , & filter. tags ) ;
191134 q. append_vec (
192135 PostListParamsField :: TagsExclude . into ( ) ,
193- & params . tags_exclude ,
136+ & filter . tags_exclude ,
194137 ) ;
195-
196- // tax_relation - Filter: relationship between taxonomy filters (AND/OR)
197138 q. append_option (
198139 PostListParamsField :: TaxRelation . into ( ) ,
199- params . tax_relation . as_ref ( ) ,
140+ filter . tax_relation . as_ref ( ) ,
200141 ) ;
201142 }
202143
@@ -209,72 +150,43 @@ mod tests {
209150 use wp_api:: posts:: PostStatus ;
210151
211152 #[ test]
212- fn test_empty_params_produces_empty_key ( ) {
213- let params = PostListParams :: default ( ) ;
214- let key = post_list_params_cache_key ( & params ) ;
153+ fn test_empty_filter_produces_empty_key ( ) {
154+ let filter = PostListFilter :: default ( ) ;
155+ let key = post_list_filter_cache_key ( & filter ) ;
215156 assert_eq ! ( key, "" ) ;
216157 }
217158
218159 #[ test]
219160 fn test_status_filter ( ) {
220- let params = PostListParams {
161+ let filter = PostListFilter {
221162 status : vec ! [ PostStatus :: Publish ] ,
222163 ..Default :: default ( )
223164 } ;
224- let key = post_list_params_cache_key ( & params ) ;
165+ let key = post_list_filter_cache_key ( & filter ) ;
225166 assert_eq ! ( key, "status=publish" ) ;
226167 }
227168
228169 #[ test]
229170 fn test_multiple_statuses ( ) {
230- let params = PostListParams {
171+ let filter = PostListFilter {
231172 status : vec ! [ PostStatus :: Publish , PostStatus :: Draft ] ,
232173 ..Default :: default ( )
233174 } ;
234- let key = post_list_params_cache_key ( & params ) ;
175+ let key = post_list_filter_cache_key ( & filter ) ;
235176 assert_eq ! ( key, "status=publish%2Cdraft" ) ;
236177 }
237178
238- #[ test]
239- fn test_pagination_fields_excluded ( ) {
240- let params = PostListParams {
241- page : Some ( 5 ) ,
242- per_page : Some ( 20 ) ,
243- offset : Some ( 100 ) ,
244- status : vec ! [ PostStatus :: Publish ] ,
245- ..Default :: default ( )
246- } ;
247- let key = post_list_params_cache_key ( & params) ;
248- // Should only contain status, not page/per_page/offset
249- assert_eq ! ( key, "status=publish" ) ;
250- }
251-
252- #[ test]
253- fn test_include_exclude_fields_excluded ( ) {
254- use wp_api:: posts:: PostId ;
255-
256- let params = PostListParams {
257- include : vec ! [ PostId ( 1 ) , PostId ( 2 ) ] ,
258- exclude : vec ! [ PostId ( 3 ) , PostId ( 4 ) ] ,
259- status : vec ! [ PostStatus :: Draft ] ,
260- ..Default :: default ( )
261- } ;
262- let key = post_list_params_cache_key ( & params) ;
263- // Should only contain status, not include/exclude
264- assert_eq ! ( key, "status=draft" ) ;
265- }
266-
267179 #[ test]
268180 fn test_multiple_filters_alphabetically_ordered ( ) {
269181 use wp_api:: users:: UserId ;
270182
271- let params = PostListParams {
183+ let filter = PostListFilter {
272184 status : vec ! [ PostStatus :: Publish ] ,
273185 author : vec ! [ UserId ( 5 ) ] ,
274186 search : Some ( "hello" . to_string ( ) ) ,
275187 ..Default :: default ( )
276188 } ;
277- let key = post_list_params_cache_key ( & params ) ;
189+ let key = post_list_filter_cache_key ( & filter ) ;
278190 // Fields should be in alphabetical order: author, search, status
279191 assert_eq ! ( key, "author=5&search=hello&status=publish" ) ;
280192 }
0 commit comments