SDK Reference

Rust

Async-native Rust SDK built on tokio and reqwest. Optimized for high-throughput backends, web servers (Actix Web, Axum), and microservices with absolute thread-safety.

Installation

Cargo.toml
[dependencies]
toggleai = "0.1.0"
tokio = { version = "1.0", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

Basic Usage

The Rust SDK leverages asynchronous design patterns to deliver maximum speed, concurrent safety, and background data synchronization in parallel concurrent runtimes:

⚡ Local In-Memory Evaluation

Upon invoking client.init().await, the SDK downloads the active ruleset from GET /sdk/config and atomic-swaps them locally using lock-free ArcSwap. Subsequent evaluations via client.get_flag_bool() or client.get_flag_value() execute instantly in-memory (sub-millisecond latency)—completely bypassing HTTP overhead on high-frequency paths.

🛰️ Edge Remote Evaluation

For security-sensitive computations requiring real-time server-side validation bypassing cached states, client.evaluate_flag_remote().await makes a direct network call to the edge gateway POST /sdk/evaluate, returning fresh determinations immediately.

main.rs
use toggleai::{ToggleAIClient, Options, EvaluationContext, LogLevel};
use std::collections::HashMap;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Setup Options
    let mut options = Options::default();
    options.client_id = "pk_live_xxx".to_string();
    options.secret = "sk_live_xxx".to_string();
    options.polling_interval_ms = 30000;

    // Create client
    let mut client = ToggleAIClient::new(options)?;

    // Initialize (fetches rules, starts background polling task)
    client.init().await?;

    // Create evaluation context
    let mut attrs = HashMap::new();
    attrs.insert("plan".to_string(), serde_json::json!("premium"));
    let ctx = EvaluationContext {
        user_id: Some("user_123".to_string()),
        attributes: Some(attrs),
    };

    // 1. Evaluate Feature Flag (Synchronous local evaluation)
    let is_enabled = client.get_flag_bool("new-checkout", Some(&ctx), false);
    if is_enabled {
        println!("Show new checkout experience");
    }

    // 2. Typed Flag Value
    let button_color = client.get_flag_value::<String>("button-color", Some(&ctx), "#000000".to_string());

    // 3. Remote Config Value
    let timeout_ms = client.get_config::<i32>("api_timeout_ms", 5000);

    // 4. Thread-Safe Background Logging
    let logger = client.get_logger()?;
    logger.info("Checkout viewed");

    // Close (shuts down scheduled worker tasks and flushes final logs)
    client.close();

    Ok(())
}

Concurrency Axiom (Axum / Axum-like)

The client is fully thread-safe and safe to wrap inside an Arc to share as shared state across multiple web-server connection handlers:

axum_server.rs
use axum::{routing::get, Router, Extension};
use std::sync::Arc;
use toggleai::{ToggleAIClient, Options, EvaluationContext};

struct AppState {
    client: ToggleAIClient,
}

#[tokio::main]
async fn main() {
    let mut options = Options::default();
    options.client_id = "pk_live_xxx".to_string();
    options.secret = "sk_live_xxx".to_string();

    let mut client = ToggleAIClient::new(options).unwrap();
    client.init().await.unwrap();

    let shared_state = Arc::new(AppState { client });

    let app = Router::new()
        .route("/api/checkout", get(handle_checkout))
        .layer(Extension(shared_state));

    let listener = tokio::net::TcpListener::bind("127.0.0.1:8080").await.unwrap();
    axum::serve(listener, app).await.unwrap();
}

async fn handle_checkout(Extension(state): Extension<Arc<AppState>>) -> &'static str {
    let ctx = EvaluationContext {
        user_id: Some("u_42".to_string()),
        attributes: None,
    };
    
    // Thread-safe lock-free local evaluation
    let show_new = state.client.get_flag_bool("new-checkout", Some(&ctx), false);
    
    if show_new {
        "New Checkout UI"
    } else {
        "Legacy Checkout UI"
    }
}

Configuration Options

FieldTypeDefault
client_idStringrequired
secretStringrequired
polling_interval_msu6430000
evaluation_modeEvaluationModeEvaluationMode::Local
disable_cacheboolfalse
default_contextOption<EvaluationContext>None
timeout_msu6410000

API Reference

MethodReturnsDescription
new(opts)Result<Self, ToggleAIError>Instantiate a new client
init()async Result<(), ToggleAIError>Fetch configurations, spawn background polling
close()voidStop polling threads, drop log queues
refresh()async Result<(), ToggleAIError>Manually force ruleset refresh
get_flag(key, ctx)Result<FlagEvaluationResult, ...>Full local evaluation result
get_flag_bool(key, ctx, default)boolIn-memory local boolean check
get_flag_bool_async(key, ctx, default)async boolAsynchronous boolean check, server if needed
get_flag_value<T>(key, ctx, default)TIn-memory typed flag value
get_flag_value_async<T>(key, ctx, default)async TAsynchronous typed flag value, server if needed
get_config<T>(key, default)TIn-memory typed config value
evaluate_flag_remote(key, ctx)async Result<...>Edge server-side evaluation
evaluate_all_flags_remote(ctx)async Result<...>Edge server-side evaluation for all flags
get_logger()Result<ToggleAILogger, ...>Get a cloned concurrency-safe background logger instance