batata-consul-client 0.0.2

Rust client for HashiCorp Consul or batata
Documentation
//! Example demonstrating the KV store API

use batata_consul_client::{Client, Config};
use batata_consul_client::api::kv::KVPair;

#[tokio::main]
async fn main() -> batata_consul_client::Result<()> {
    // Initialize tracing
    tracing_subscriber::fmt::init();

    // Create client with default configuration
    // This connects to localhost:8500
    let client = Client::new(Config::default())?;

    let kv = client.kv();

    // Put a simple key-value pair
    println!("Putting key 'example/foo'...");
    let (success, _meta) = kv.put_string("example/foo", "bar", None).await?;
    println!("Put success: {}", success);

    // Get the value back
    println!("\nGetting key 'example/foo'...");
    let (pair, _meta) = kv.get("example/foo", None).await?;
    if let Some(p) = pair {
        println!("Key: {}", p.key);
        println!("Value: {:?}", p.value_string());
        println!("ModifyIndex: {}", p.modify_index);
    }

    // Put multiple keys under a prefix
    println!("\nPutting multiple keys under 'example/'...");
    kv.put_string("example/config/database", "postgresql://localhost:5432", None).await?;
    kv.put_string("example/config/cache", "redis://localhost:6379", None).await?;
    kv.put_string("example/config/timeout", "30", None).await?;

    // List all keys under a prefix
    println!("\nListing keys under 'example/'...");
    let (keys, _meta) = kv.keys("example/", None, None).await?;
    for key in &keys {
        println!("  - {}", key);
    }

    // List all key-value pairs under a prefix
    println!("\nListing all KV pairs under 'example/config/'...");
    let (pairs, _meta) = kv.list("example/config/", None).await?;
    for pair in &pairs {
        println!("  {} = {:?}", pair.key, pair.value_string());
    }

    // Demonstrate CAS (Check-And-Set) operation
    println!("\nDemonstrating CAS operation...");
    let (pair, _meta) = kv.get("example/foo", None).await?;
    if let Some(mut p) = pair {
        println!("Current value: {:?} (ModifyIndex: {})", p.value_string(), p.modify_index);

        // Update the value with CAS
        p.set_value_string("updated-bar");
        let (success, _meta) = kv.cas(&p, None).await?;
        println!("CAS update success: {}", success);

        // Verify the update
        let (new_pair, _meta) = kv.get("example/foo", None).await?;
        if let Some(np) = new_pair {
            println!("New value: {:?} (ModifyIndex: {})", np.value_string(), np.modify_index);
        }
    }

    // Put with flags
    println!("\nPutting key with flags...");
    let mut pair = KVPair::new_string("example/flagged", "with-flags");
    pair.flags = 42;
    let (success, _meta) = kv.put(&pair, None).await?;
    println!("Put with flags success: {}", success);

    let (pair, _meta) = kv.get("example/flagged", None).await?;
    if let Some(p) = pair {
        println!("Flags: {}", p.flags);
    }

    // Delete a single key
    println!("\nDeleting key 'example/flagged'...");
    let (success, _meta) = kv.delete("example/flagged", None).await?;
    println!("Delete success: {}", success);

    // Delete all keys under a prefix
    println!("\nDeleting all keys under 'example/'...");
    let (success, _meta) = kv.delete_tree("example/", None).await?;
    println!("Delete tree success: {}", success);

    // Verify deletion
    println!("\nVerifying deletion...");
    let (keys, _meta) = kv.keys("example/", None, None).await?;
    println!("Remaining keys: {}", keys.len());

    println!("\nKV example completed successfully!");

    Ok(())
}