#[cfg(feature = "rest")]
mod example {
use anyhow::Context;
use force::api::rest::OrgLimits;
use force::auth::ClientCredentials;
use force::client::ForceClientBuilder;
fn required_env(name: &str) -> anyhow::Result<String> {
std::env::var(name).with_context(|| format!("{name} environment variable not set"))
}
fn print_api_usage(limits: &OrgLimits) {
println!("=== API USAGE ===");
let Some(api) = &limits.daily_api_requests else {
println!("Daily API Requests: not reported by this org");
return;
};
println!(
"Daily API Requests: {}/{} ({:.1}% used)",
api.used.unwrap_or(api.max - api.remaining),
api.max,
api.percentage_used()
);
if api.is_above_threshold(80.0) {
println!("WARNING: API usage above 80% threshold");
}
if api.is_at_limit() {
println!("ERROR: Daily API limit reached");
}
}
fn print_storage(limits: &OrgLimits) {
println!("\n=== STORAGE ===");
if let Some(data_storage) = &limits.data_storage_mb {
println!(
"Data Storage: {}/{} MB ({:.1}% used)",
data_storage.max - data_storage.remaining,
data_storage.max,
data_storage.percentage_used()
);
}
if let Some(file_storage) = &limits.file_storage_mb {
println!(
"File Storage: {}/{} MB ({:.1}% used)",
file_storage.max - file_storage.remaining,
file_storage.max,
file_storage.percentage_used()
);
}
}
fn print_email_limits(limits: &OrgLimits) {
println!("\n=== EMAIL LIMITS ===");
if let Some(workflow_email) = &limits.daily_workflow_emails {
println!(
"Daily Workflow Emails: {}/{} ({:.1}% used)",
workflow_email
.used
.unwrap_or(workflow_email.max - workflow_email.remaining),
workflow_email.max,
workflow_email.percentage_used()
);
}
if let Some(mass_email) = &limits.mass_email {
println!(
"Mass Emails: {}/{} remaining",
mass_email.remaining, mass_email.max
);
}
if let Some(single_email) = &limits.single_email {
println!(
"Single Emails: {}/{} remaining",
single_email.remaining, single_email.max
);
}
}
fn print_batch_and_streaming_limits(limits: &OrgLimits) {
println!("\n=== BATCH & ASYNC ===");
if let Some(batch_apex) = &limits.daily_batch_apex_executions {
println!(
"Daily Batch Apex: {}/{} remaining",
batch_apex.remaining, batch_apex.max
);
}
if let Some(async_apex) = &limits.daily_async_apex_executions {
println!(
"Daily Async Apex: {}/{} remaining",
async_apex.remaining, async_apex.max
);
}
println!("\n=== STREAMING API ===");
if let Some(streaming) = &limits.daily_streaming_api_events {
println!(
"Daily Streaming Events: {}/{} remaining",
streaming.remaining, streaming.max
);
}
}
fn print_additional_limits(limits: &OrgLimits) {
if limits.additional_limits.is_empty() {
return;
}
println!("\n=== ADDITIONAL LIMITS ===");
for (name, limit) in &limits.additional_limits {
println!(
"{}: {}/{} ({:.1}% used)",
name,
limit.max - limit.remaining,
limit.max,
limit.percentage_used()
);
}
}
fn print_summary(limits: &OrgLimits) {
println!("\n=== SUMMARY ===");
let mut warnings = Vec::new();
if let Some(api) = &limits.daily_api_requests {
if api.is_above_threshold(90.0) {
warnings.push("API usage critical (>90%)");
} else if api.is_above_threshold(75.0) {
warnings.push("API usage high (>75%)");
}
}
if let Some(data_storage) = &limits.data_storage_mb {
if data_storage.is_above_threshold(90.0) {
warnings.push("Data storage critical (>90%)");
} else if data_storage.is_above_threshold(75.0) {
warnings.push("Data storage high (>75%)");
}
}
if let Some(file_storage) = &limits.file_storage_mb {
if file_storage.is_above_threshold(90.0) {
warnings.push("File storage critical (>90%)");
} else if file_storage.is_above_threshold(75.0) {
warnings.push("File storage high (>75%)");
}
}
if warnings.is_empty() {
println!("All limits within normal ranges");
return;
}
for warning in warnings {
println!("WARNING: {warning}");
}
}
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 with Salesforce...");
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!("Fetching organization limits...");
let limits = client.rest().limits().await?;
println!("Retrieved limits\n");
print_api_usage(&limits);
print_storage(&limits);
print_email_limits(&limits);
print_batch_and_streaming_limits(&limits);
print_additional_limits(&limits);
print_summary(&limits);
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.");
}