#[cfg(feature = "ui")]
mod example {
use anyhow::{Context, Result};
use force::api::ui::{FavoriteInput, LayoutType, Mode};
use force::auth::ClientCredentials;
use force::client::ForceClientBuilder;
use std::env;
#[allow(clippy::too_many_lines)]
pub async fn run() -> Result<()> {
let client_id = env::var("SF_CLIENT_ID").context("SF_CLIENT_ID not set")?;
let client_secret = env::var("SF_CLIENT_SECRET").context("SF_CLIENT_SECRET not set")?;
let my_domain_url = env::var("SF_MY_DOMAIN_URL").context("SF_MY_DOMAIN_URL not set")?;
let record_id =
env::var("SF_RECORD_ID").unwrap_or_else(|_| "001000000000001AAA".to_string());
let auth = ClientCredentials::new_my_domain(client_id, client_secret, my_domain_url);
let client = ForceClientBuilder::new()
.authenticate(auth)
.build()
.await
.context("Failed to build client")?;
let ui = client.ui();
println!("=== Object Info: Account ===");
let info = ui.object_info("Account").await?;
println!(" Label: {}", info.label);
println!(" Label Plural: {}", info.label_plural);
println!(" Key Prefix: {:?}", info.key_prefix);
println!(" Fields: {} field(s)", info.fields.len());
if let Some(name_field) = info.fields.get("Name") {
println!(
" Name field — required={} updateable={}",
name_field.required, name_field.updateable
);
}
println!();
println!("=== Record UI: {record_id} ===");
match ui
.record_ui(
&[record_id.as_str()],
Some(&[LayoutType::Full]),
Some(&[Mode::View]),
)
.await
{
Ok(record_ui) => {
println!(" Records in response: {}", record_ui.records.len());
if let Some(record) = record_ui.records.get(&record_id) {
println!(" API name: {}", record.api_name);
println!(" Fields: {} field(s)", record.fields.len());
if let Some(name_field) = record.fields.get("Name") {
println!(" Name: {:?}", name_field.display_value);
}
}
}
Err(e) => println!(" (skipped — record not found or inaccessible: {e})"),
}
println!();
println!("=== Layout: Account (Full, View) ===");
match ui
.layout("Account", Some(&LayoutType::Full), Some(&Mode::View))
.await
{
Ok(layout) => {
println!(" Layout ID: {}", layout.id);
println!(" Layout type: {}", layout.layout_type);
println!(" Mode: {}", layout.mode);
println!(" Sections: {}", layout.sections.len());
for section in &layout.sections {
let heading = section.heading.as_deref().unwrap_or("(no heading)");
println!(
" Section: {} ({} columns, {} rows)",
heading, section.columns, section.rows
);
}
}
Err(e) => println!(" (skipped: {e})"),
}
println!();
println!("=== List Views: Account ===");
match ui.list_views("Account").await {
Ok(collection) => {
println!(" Total views: {}", collection.count);
for lv in collection.list_views.iter().take(3) {
println!(" - {} ({})", lv.label, lv.api_name);
}
}
Err(e) => println!(" (skipped: {e})"),
}
println!();
println!("=== Lookup: Contact.AccountId for 'Acme' ===");
match ui.lookup("Contact", "AccountId", "Acme").await {
Ok(results) => {
println!(" Found {} result(s)", results.count);
for entry in results.lookup_results.iter().take(5) {
println!(" - {} ({})", entry.label, entry.id);
}
}
Err(e) => println!(" (skipped: {e})"),
}
println!();
println!("=== Favorites ===");
let favs = ui.get_favorites().await?;
println!(" Current favorites: {}", favs.favorites.len());
for fav in favs.favorites.iter().take(3) {
println!(" - {} (type: {:?})", fav.label, fav.target_type);
}
println!("\n Creating test favorite...");
let input = FavoriteInput {
label: "UI API Example Favorite".to_string(),
name: None,
target: record_id.clone(),
target_type: "Record".to_string(),
};
match ui.create_favorite(&input).await {
Ok(created) => {
println!(" Created: id={} label={}", created.id, created.label);
let update_input = FavoriteInput {
label: "Renamed by UI API Example".to_string(),
..input
};
match ui.update_favorite(&created.id, &update_input).await {
Ok(updated) => println!(" Updated label: {}", updated.label),
Err(e) => println!(" Update failed: {e}"),
}
match ui.delete_favorite(&created.id).await {
Ok(()) => println!(" Deleted favorite: {}", created.id),
Err(e) => println!(" Delete failed: {e}"),
}
}
Err(e) => println!(" Create failed (record may not exist): {e}"),
}
println!("\nUI API example complete.");
Ok(())
}
}
#[cfg(feature = "ui")]
#[tokio::main]
async fn main() -> anyhow::Result<()> {
tracing_subscriber::fmt::init();
example::run().await
}
#[cfg(not(feature = "ui"))]
fn main() {
eprintln!("Run with --features ui");
}