libchat/conversations/examples/persist_chat.rs
2026-02-05 16:58:30 +08:00

135 lines
4.7 KiB
Rust

//! Example: Chat Flow with Automatic Persistence
//!
//! This example demonstrates the complete chat flow using ChatManager,
//! which automatically handles all storage operations.
//!
//! Run with: cargo run -p logos-chat --example persist_chat
use logos_chat::{ChatManager, StorageConfig};
use tempfile::TempDir;
fn main() {
println!("=== Chat Flow Example ===\n");
// Create temporary directories for databases
let alice_dir = TempDir::new().expect("Failed to create temp dir");
let bob_dir = TempDir::new().expect("Failed to create temp dir");
let alice_db = alice_dir.path().join("alice.db");
let bob_db = bob_dir.path().join("bob.db");
// =========================================
// Step 1: Create chat managers
// =========================================
println!("Step 1: Creating chat managers...\n");
// In production, use StorageConfig::Encrypted { path, key }
let mut alice = ChatManager::open(StorageConfig::File(alice_db.to_str().unwrap().to_string()))
.expect("Failed to create Alice's chat manager");
let mut bob = ChatManager::open(StorageConfig::File(bob_db.to_str().unwrap().to_string()))
.expect("Failed to create Bob's chat manager");
println!(" Alice's address: {}", alice.local_address());
println!(" Bob's address: {}", bob.local_address());
println!();
// =========================================
// Step 2: Bob creates intro bundle to share
// =========================================
println!("Step 2: Bob creates introduction bundle...\n");
let bob_intro = bob
.create_intro_bundle()
.expect("Failed to create intro bundle");
println!(" Bob shares his intro bundle with Alice");
println!(
" (Installation key: {})",
hex::encode(bob_intro.installation_key.as_bytes())
);
println!();
// =========================================
// Step 3: Alice starts a chat with Bob
// =========================================
println!("Step 3: Alice starts a private chat with Bob...\n");
let (chat_id, envelopes) = alice
.start_private_chat(&bob_intro, "Hello Bob! 👋")
.expect("Failed to start chat");
println!(" Chat created: {}", chat_id);
println!(" Envelopes to deliver: {}", envelopes.len());
println!(" (Chat automatically persisted to storage)");
println!();
// =========================================
// Step 4: Alice sends more messages
// =========================================
println!("Step 4: Alice sends more messages...\n");
let messages = ["How are you?", "Are you there?", ""];
for msg in &messages {
let envelopes = alice
.send_message(&chat_id, msg.as_bytes())
.expect("Failed to send message");
println!("\"{}\" ({} envelope)", msg, envelopes.len());
}
println!();
// =========================================
// Step 5: Verify persistence
// =========================================
println!("Step 5: Verifying persistence...\n");
println!(
" Chats persisted to storage: {:?}",
alice.list_chats().unwrap()
);
println!();
// =========================================
// Step 6: Simulate app restart
// =========================================
println!("Step 6: Simulating app restart...\n");
let alice_address = alice.local_address();
drop(alice); // Close Alice's chat manager
println!(" Chat manager closed. Reopening...\n");
let alice_restored =
ChatManager::open(StorageConfig::File(alice_db.to_str().unwrap().to_string()))
.expect("Failed to reopen Alice's chat manager");
println!(" ✓ Chat manager restored!");
println!(
" ✓ Same address: {}",
alice_restored.local_address() == alice_address
);
println!(
" ✓ Stored chats: {:?}",
alice_restored.list_chats().unwrap()
);
println!();
// =========================================
// Done!
// =========================================
println!("=== Example Complete ===\n");
println!("Key points:");
println!(" • ChatManager handles all storage internally");
println!(" • Identity is automatically created and persisted");
println!(" • Chats are automatically saved when created");
println!(" • State survives app restarts");
println!();
println!("For production, use encrypted storage:");
println!(" ChatManager::open(StorageConfig::Encrypted {{");
println!(" path: \"chat.db\".into(),");
println!(" key: \"user_encryption_key\".into(),");
println!(" }})");
// Temp directories are automatically cleaned up
}