#[cfg(feature = "bulk")]
mod example {
use anyhow::Context;
use force::auth::ClientCredentials;
use force::client::ForceClientBuilder;
use futures::StreamExt;
use serde::Deserialize;
#[derive(Deserialize, Debug)]
struct Account {
#[serde(rename = "Id")]
id: String,
#[serde(rename = "Name")]
name: String,
#[serde(rename = "Industry")]
industry: Option<String>,
#[serde(rename = "Website")]
website: Option<String>,
}
fn required_env(name: &str) -> anyhow::Result<String> {
std::env::var(name).with_context(|| format!("{name} environment variable not set"))
}
pub async fn main() -> anyhow::Result<()> {
tracing_subscriber::fmt::init();
let client_id = required_env("SF_CLIENT_ID")?;
let client_secret = required_env("SF_CLIENT_SECRET")?;
let my_domain_url = required_env("SF_MY_DOMAIN_URL")?;
println!("═══ Authenticating ═══");
let auth = ClientCredentials::new_my_domain(client_id, client_secret, my_domain_url);
let client = ForceClientBuilder::new().authenticate(auth).build().await?;
println!("✓ Authentication successful\n");
println!("═══ Bulk Query ═══");
let soql = "SELECT Id, Name, Industry, Website FROM Account WHERE Industry = 'Technology'";
println!("Query: {soql}");
let stream = client.bulk().query::<Account>(soql).await?;
let stream = stream.into_stream();
let mut stream = std::pin::pin!(stream);
println!("\n═══ Results ═══");
let mut count = 0;
while let Some(account_result) = stream.next().await {
let account = account_result?;
count += 1;
println!(
"{}. {} [{}] ({})",
count,
account.name,
account.id,
account.industry.unwrap_or_else(|| "N/A".to_string())
);
if let Some(website) = &account.website {
println!(" Website: {website}");
}
}
println!("\n✓ Retrieved {count} records");
Ok(())
}
}
#[cfg(feature = "bulk")]
#[tokio::main]
async fn main() -> anyhow::Result<()> {
example::main().await
}
#[cfg(not(feature = "bulk"))]
fn main() {
println!("This example requires the 'bulk' feature.");
}