Skip to content

Commit a57bc38

Browse files
committed
Iterate over items asynchronously from Pager (#2659)
* Iterator over items asynchronously from Pager For functions that return a `Pager<T>`, callers will iterate over items across all pages asynchronously by default but can get an async iterator (`Stream`) over pages as well. Resolves #2205 * Update CHANGELOG for PagerResult changes * Resolve PR feedback
1 parent cebe76d commit a57bc38

File tree

37 files changed

+832
-431
lines changed

37 files changed

+832
-431
lines changed

Cargo.lock

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sdk/core/azure_core/CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,16 @@
55
### Features Added
66

77
- Added `#[safe]` attribute helper for `SafeDebug` derive macro to show or hide types and members as appropriate.
8+
- Added `Page` trait to facilitate the `ItemIterator`.
9+
- Added `PageIterator` to asynchronously iterator all pages.
810

911
### Breaking Changes
1012

11-
- Removed `AccessToken::is_expired()`
13+
- A `Pager` now asynchronously iterates over items across all pages. Call `Pager::into_pages()` to get a `PageIterator` to asynchronously iterate over all pages.
14+
- Removed `AccessToken::is_expired()`.
15+
- Renamed `PagerResult::Continue` to `More` and its `continuation` field to `next`.
16+
- Renamed `PagerResult::Complete` to `Done`.
17+
- Renamed `PageStream` to `ItemIterator`.
1218

1319
### Bugs Fixed
1420

sdk/core/azure_core/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ edition.workspace = true
1414
rust-version.workspace = true
1515

1616
[dependencies]
17-
async-lock = { workspace = true }
17+
async-lock.workspace = true
1818
async-trait.workspace = true
1919
bytes.workspace = true
2020
futures.workspace = true

sdk/core/azure_core/README.md

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ so that once you learn how to use these APIs in one client library, you will kno
1414
Typically, you will not need to install `azure_core`;
1515
it will be installed for you when you install one of the client libraries using it.
1616
In case you want to install it explicitly - to implement your own client library, for example -
17-
you can find the crates.io package [here][Package (crates.io)].
17+
you can find the [package on crates.io][Package (crates.io)].
1818

1919
## Key concepts
2020

@@ -178,7 +178,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
178178

179179
### Consuming service methods returning `Pager<T>`
180180

181-
If a service call returns multiple values in pages, it would return `Result<Pager<T>>` as a result. You can iterator over each page's vector of results.
181+
If a service call returns multiple values in pages, it would return `Result<Pager<T>>` as a result. You can iterate all items from all pages.
182182

183183
```rust no_run
184184
use azure_identity::DefaultAzureCredential;
@@ -195,8 +195,39 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
195195
None,
196196
)?;
197197

198-
// get a stream
199-
let mut pager = client.list_secret_properties(None)?.into_stream();
198+
// get a stream of items
199+
let mut pager = client.list_secret_properties(None)?;
200+
201+
// poll the pager until there are no more SecretListResults
202+
while let Some(secret) = pager.try_next().await? {
203+
// get the secret name from the ID
204+
let name = secret.resource_id()?.name;
205+
println!("Found secret with name: {}", name);
206+
}
207+
208+
Ok(())
209+
}
210+
```
211+
212+
To instead iterate over all pages, call `into_pages()` on the returned `Pager`.
213+
214+
```rust no_run
215+
use azure_identity::DefaultAzureCredential;
216+
use azure_security_keyvault_secrets::{ResourceExt, SecretClient};
217+
use futures::TryStreamExt;
218+
219+
#[tokio::main]
220+
async fn main() -> Result<(), Box<dyn std::error::Error>> {
221+
// create a client
222+
let credential = DefaultAzureCredential::new()?;
223+
let client = SecretClient::new(
224+
"https://<your-key-vault-name>.vault.azure.net/",
225+
credential.clone(),
226+
None,
227+
)?;
228+
229+
// get a stream of pages
230+
let mut pager = client.list_secret_properties(None)?.into_pages();
200231

201232
// poll the pager until there are no more SecretListResults
202233
while let Some(secrets) = pager.try_next().await? {
@@ -213,7 +244,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
213244
}
214245
```
215246

216-
<!-- ## Troubleshooting -->
217247
## Troubleshooting
218248

219249
### Logging

0 commit comments

Comments
 (0)