use azure_core::http::Transport;
use azure_security_keyvault_secrets::{ResourceExt as _, SecretClient, SecretClientOptions};
use example::setup;
use futures::TryStreamExt as _;
async fn example_pager() -> Result<(), Box<dyn std::error::Error>> {
let mut options = SecretClientOptions::default();
let (credential, transport) = setup()?;
options.client_options.transport = Some(Transport::new(transport));
let client = SecretClient::new(
"https://my-vault.vault.azure.net",
credential,
Some(options),
)?;
let mut pager = client.list_secret_properties(None)?;
let mut names = Vec::new();
while let Some(secret) = pager.try_next().await? {
names.push(secret.resource_id()?.name);
}
assert_eq!(names, vec!["secret-a", "secret-b", "secret-c"]);
Ok(())
}
async fn example_page_iterator() -> Result<(), Box<dyn std::error::Error>> {
let mut options = SecretClientOptions::default();
let (credential, transport) = setup()?;
options.client_options.transport = Some(Transport::new(transport));
let client = SecretClient::new(
"https://my-vault.vault.azure.net",
credential,
Some(options),
)?;
let mut pager = client.list_secret_properties(None)?.into_pages();
let mut names = Vec::new();
while let Some(page) = pager.try_next().await? {
let page = page.into_model()?;
for secret in page.value {
names.push(secret.resource_id()?.name);
}
}
assert_eq!(names, vec!["secret-a", "secret-b", "secret-c"]);
Ok(())
}
#[tokio::test]
async fn test_core_pager() -> Result<(), Box<dyn std::error::Error>> {
example_pager().await
}
#[tokio::test]
async fn test_core_page_iterator() -> Result<(), Box<dyn std::error::Error>> {
example_page_iterator().await
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
example_pager().await?;
example_page_iterator().await?;
Ok(())
}
mod example {
use azure_core::{
credentials::TokenCredential,
http::{headers::Headers, AsyncRawResponse, HttpClient, Method, StatusCode},
};
use azure_core_test::{credentials::MockCredential, http::MockHttpClient};
use futures::FutureExt;
use std::sync::{
atomic::{AtomicUsize, Ordering},
Arc,
};
#[allow(clippy::type_complexity)]
pub fn setup(
) -> Result<(Arc<dyn TokenCredential>, Arc<dyn HttpClient>), Box<dyn std::error::Error>> {
let credential: Arc<dyn TokenCredential> = MockCredential::new()?;
let calls = Arc::new(AtomicUsize::new(0));
let transport = {
let calls = calls.clone();
MockHttpClient::new(move |request| {
let calls = calls.clone();
async move {
let idx = calls.fetch_add(1, Ordering::SeqCst);
assert_eq!(request.method(), Method::Get);
assert_eq!(request.url().path(), "/secrets");
match idx {
0 => Ok(AsyncRawResponse::from_bytes(
StatusCode::Ok,
Headers::new(),
r#"{"value":[
{"id":"https://my-vault.vault.azure.net/secrets/secret-a"},
{"id":"https://my-vault.vault.azure.net/secrets/secret-b"}
],
"nextLink":"https://my-vault.vault.azure.net/secrets?api-version=7.4&$skiptoken=page2"}"#,
)),
1 => Ok(AsyncRawResponse::from_bytes(
StatusCode::Ok,
Headers::new(),
r#"{"value":[{"id":"https://my-vault.vault.azure.net/secrets/secret-c"}]}"#,
)),
_ => panic!("unexpected request count {idx}"),
}
}
.boxed()
})
};
Ok((credential, Arc::new(transport)))
}
}