use dotenv::dotenv;
use pixeluvw_supabase::{ClientConfig, Middleware, RequestContext, SupabaseClient};
use serde::{Deserialize, Serialize};
use std::sync::Arc;
#[derive(Debug, Serialize, Deserialize)]
#[allow(dead_code)]
struct User {
id: Option<i32>,
name: String,
email: String,
}
struct LoggingMiddleware;
impl Middleware for LoggingMiddleware {
fn on_request(&self, ctx: &RequestContext) {
println!(
"📤 Request: {} {} (table: {})",
ctx.method, ctx.url, ctx.table
);
}
fn on_response(&self, ctx: &RequestContext, status: u16, duration_ms: u64) {
let emoji = if status < 400 { "✅" } else { "❌" };
println!(
"{} Response: {} {} -> {} ({}ms)",
emoji, ctx.method, ctx.table, status, duration_ms
);
}
fn on_error(&self, ctx: &RequestContext, error: &str) {
eprintln!("💥 Error on {}: {}", ctx.table, error);
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
dotenv().ok();
println!("🚀 pixeluvw_supabase Usage Demo\n");
println!("{}", "=".repeat(50));
println!("\n1️⃣ Creating client from environment variables (RECOMMENDED)...");
let client = SupabaseClient::from_env()?;
println!(" ✅ Client created: {:?}", client);
println!("\n2️⃣ Creating client with custom config...");
let config = ClientConfig {
timeout_secs: 60,
max_retries: 5,
retry_base_delay_ms: 200,
};
let _custom_client = SupabaseClient::from_env_with_config(config)?;
println!(" ✅ Custom client created with 60s timeout and 5 retries");
println!("\n3️⃣ Adding middleware...");
let client_with_logging =
SupabaseClient::from_env()?.with_middleware(Arc::new(LoggingMiddleware));
println!(" ✅ Logging middleware attached");
println!("\n4️⃣ Demonstrating cheap cloning...");
let client1 = SupabaseClient::from_env()?;
let _client2 = client1.clone();
println!(" ✅ Cloned client shares connection pool (Arc::ptr_eq = true)");
println!("\n5️⃣ Query Examples:\n");
println!(" 📖 SELECT query:");
let result: Result<Vec<serde_json::Value>, _> = client_with_logging
.from("users")
.select("id,name,email")
.limit(5)
.execute()
.await;
match result {
Ok(users) => println!(" Found {} users", users.len()),
Err(e) => println!(" Query failed (table might not exist): {}", e),
}
println!("\n 🔢 COUNT query:");
let count_result = client_with_logging
.from("users")
.count("exact")
.execute_count()
.await;
match count_result {
Ok(count) => println!(" Total users: {}", count),
Err(e) => println!(" Count failed: {}", e),
}
println!("\n6️⃣ Storage Example:");
let storage = client.storage();
match storage.list_buckets().await {
Ok(buckets) => {
println!(" Found {} buckets:", buckets.len());
for b in &buckets {
println!(" - {}", b.id);
}
}
Err(e) => println!(" Could not list buckets: {}", e),
}
println!("\n7️⃣ Auth Example:");
println!(" Attempting sign-in with invalid credentials (expected to fail)...");
let auth_result = client
.auth()
.sign_in_with_password("test@example.com", "test123")
.await;
match auth_result {
Ok(session) => {
println!(" Signed in! Token: {}...", &session.access_token[..20]);
}
Err(_) => println!(" ✅ Auth correctly rejected invalid credentials"),
}
println!("\n{}", "=".repeat(50));
println!("🎉 Demo complete!\n");
println!("Features demonstrated:");
println!(" ✅ Basic client creation");
println!(" ✅ Custom configuration (timeout, retries)");
println!(" ✅ Middleware system");
println!(" ✅ Cheap cloning with Arc<Inner>");
println!(" ✅ SELECT queries");
println!(" ✅ COUNT queries");
println!(" ✅ Storage bucket listing");
println!(" ✅ Authentication");
Ok(())
}