#[cfg(feature = "rest")]
mod example {
use anyhow::Context;
use force::api::RestOperation;
use force::auth::ClientCredentials;
use force::client::{ForceClient, ForceClientBuilder};
use force::types::DynamicSObject;
fn required_env(name: &str) -> anyhow::Result<String> {
std::env::var(name).with_context(|| format!("{name} environment variable not set"))
}
async fn build_client() -> anyhow::Result<ForceClient<ClientCredentials>> {
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")?;
let auth = ClientCredentials::new_my_domain(client_id, client_secret, my_domain_url);
ForceClientBuilder::new()
.authenticate(auth)
.build()
.await
.map_err(Into::into)
}
pub async fn main() -> anyhow::Result<()> {
tracing_subscriber::fmt::init();
let client = build_client().await?;
let accounts = client
.rest()
.query::<DynamicSObject>("SELECT Id, Name, Industry FROM Account LIMIT 5")
.await?;
println!("Accounts:");
for record in &accounts.records {
let id = record.get_field_as::<String>("Id")?.unwrap_or_default();
let name = record.get_field_as::<String>("Name")?.unwrap_or_default();
let industry = record
.get_field_as::<String>("Industry")?
.unwrap_or_else(|| "(none)".to_string());
println!("- {name} ({id}) [{industry}]");
}
let revenue_rows = client
.rest()
.query::<DynamicSObject>(
"SELECT Name, AnnualRevenue FROM Account WHERE AnnualRevenue != null LIMIT 10",
)
.await?;
let revenues: Vec<f64> = revenue_rows
.records
.iter()
.filter_map(|row| row.get_field_as::<f64>("AnnualRevenue").ok().flatten())
.collect();
if !revenues.is_empty() {
let total: f64 = revenues.iter().sum();
let count_u32 =
u32::try_from(revenues.len()).context("too many revenues to aggregate")?;
let average = total / f64::from(count_u32);
println!("\nRevenue rows: {}", revenues.len());
println!("Total revenue: ${total:.2}");
println!("Average revenue: ${average:.2}");
}
Ok(())
}
}
#[cfg(feature = "rest")]
#[tokio::main]
async fn main() -> anyhow::Result<()> {
example::main().await
}
#[cfg(not(feature = "rest"))]
fn main() {
println!("This example requires the 'rest' feature.");
}