apify_client/clients/
store_collection.rs1use crate::clients::base::{list_resource, ResourceContext};
4use crate::common::{PaginationList, QueryParams};
5use crate::error::ApifyClientResult;
6use crate::http_client::HttpClient;
7use crate::models::ActorStoreListItem;
8
9#[derive(Debug, Default, Clone)]
11pub struct StoreListOptions {
12 pub offset: Option<i64>,
14 pub limit: Option<i64>,
16 pub search: Option<String>,
18 pub sort_by: Option<String>,
20 pub category: Option<String>,
22 pub username: Option<String>,
24 pub pricing_model: Option<String>,
26 pub include_unrunnable_actors: Option<bool>,
28 pub allows_agentic_users: Option<bool>,
30 pub response_format: Option<String>,
32}
33
34#[derive(Debug, Clone)]
36pub struct StoreCollectionClient {
37 ctx: ResourceContext,
38}
39
40impl StoreCollectionClient {
41 pub(crate) fn new(http: HttpClient, base_url: &str) -> Self {
42 Self {
43 ctx: ResourceContext::collection(http, base_url, "store"),
44 }
45 }
46
47 pub async fn list(
52 &self,
53 options: StoreListOptions,
54 ) -> ApifyClientResult<PaginationList<ActorStoreListItem>> {
55 let params = self.build_params(&options);
56 list_resource(&self.ctx, None, ¶ms).await
57 }
58
59 pub fn iterate(&self, options: StoreListOptions) -> StoreActorIterator {
64 StoreActorIterator {
65 client: self.clone(),
66 options,
67 buffer: std::collections::VecDeque::new(),
68 next_offset: 0,
69 total: None,
70 exhausted: false,
71 }
72 }
73
74 fn build_params(&self, options: &StoreListOptions) -> QueryParams {
75 let mut params = QueryParams::new();
76 params
77 .add_int("offset", options.offset)
78 .add_int("limit", options.limit)
79 .add_str("search", options.search.clone())
80 .add_str("sortBy", options.sort_by.clone())
81 .add_str("category", options.category.clone())
82 .add_str("username", options.username.clone())
83 .add_str("pricingModel", options.pricing_model.clone())
84 .add_bool("includeUnrunnableActors", options.include_unrunnable_actors)
85 .add_bool("allowsAgenticUsers", options.allows_agentic_users)
86 .add_str("responseFormat", options.response_format.clone());
87 params
88 }
89}
90
91pub struct StoreActorIterator {
97 client: StoreCollectionClient,
98 options: StoreListOptions,
99 buffer: std::collections::VecDeque<ActorStoreListItem>,
100 next_offset: i64,
101 total: Option<i64>,
102 exhausted: bool,
103}
104
105impl StoreActorIterator {
106 pub async fn next(&mut self) -> ApifyClientResult<Option<ActorStoreListItem>> {
108 if let Some(item) = self.buffer.pop_front() {
109 return Ok(Some(item));
110 }
111 if self.exhausted {
112 return Ok(None);
113 }
114
115 let start_offset = self.options.offset.unwrap_or(0) + self.next_offset;
117 let mut page_options = self.options.clone();
118 page_options.offset = Some(start_offset);
119
120 let page = self.client.list(page_options).await?;
121 if self.total.is_none() {
122 self.total = Some(page.total);
123 }
124 if page.items.is_empty() {
125 self.exhausted = true;
126 return Ok(None);
127 }
128
129 self.next_offset += page.items.len() as i64;
130 if let Some(total) = self.total {
132 if start_offset + page.items.len() as i64 >= total {
133 self.exhausted = true;
134 }
135 }
136 self.buffer.extend(page.items);
137 Ok(self.buffer.pop_front())
138 }
139}