VeltrixDB Docs
v1.1.0 GitHub FAQ Quickstart

Rust Client

The Rust client is a minimal, blocking, pure-stdlib driver (no tokio, no bytes) that implements the full single-key surface plus the complete atomic-operations set: CAS, INCR, DECR, and SETNX.

Install

The crate is not yet published to crates.io — use a path or git dependency:

toml
# Cargo.toml — path dep while crates.io publishing is pending [dependencies] veltrixdb-client = { path = "rust" }

Once published, install will be the standard cargo add veltrixdb-client. Edition 2021; zero dependencies — the crate name inside code is veltrixdb (see [lib] name = "veltrixdb" in the crate's own Cargo.toml).

Quick start

From the crate's own examples/smoke.rs:

rust
use veltrixdb::{CasOutcome, Client, SetNxOutcome}; fn main() { let mut c = Client::connect("127.0.0.1:19000").expect("connect"); c.put("hello", b"world").expect("put"); let v = c.get("hello").expect("get").expect("present"); assert_eq!(v, b"world"); println!("get hello -> {}", String::from_utf8_lossy(&v)); let n = c.incr("counter", 5).expect("incr"); assert_eq!(n, 5); let n = c.incr("counter", 3).expect("incr"); assert_eq!(n, 8); let n = c.decr("counter", 2).expect("decr"); assert_eq!(n, 6); println!("counter = {}", n); let r = c.cas("hello", b"world", b"earth").expect("cas"); assert_eq!(r, CasOutcome::Swapped); let r = c.cas("hello", b"world", b"mars").expect("cas mismatch"); assert_eq!(r, CasOutcome::Mismatch); println!("cas: outcomes ok"); assert_eq!(c.setnx("lock", b"owner-A").expect("setnx"), SetNxOutcome::Created); assert_eq!(c.setnx("lock", b"owner-B").expect("setnx"), SetNxOutcome::Existed); println!("setnx: outcomes ok"); }

Run it against a live server:

bash
# Start a server go run ../VeltrixDB/cmd/server -addr :19000 -data /tmp/veltrix-rust-smoke # Run the smoke test cargo run --manifest-path rust/Cargo.toml --example smoke

API surface

Client owns a single blocking TcpStream — one connection per Client, not Send across threads without your own synchronization.

MethodDescription
Client::connect(addr)Open a connection; sets TCP_NODELAY
Client::connect_timeout(addr, timeout)Connect with an explicit timeout, trying each resolved address
put(key, value)Write a key
get(key)Returns Ok(Some(value)), Ok(None) if missing, or Err
delete(key)Delete a key
ping()Check connection health
cas(key, expected, new_value)Compare-and-swap; returns a CasOutcome
incr(key, delta) / decr(key, delta)Atomic signed i64 delta; returns the new value
setnx(key, value)Set only if absent; returns a SetNxOutcome

Outcome types

rust
pub enum CasOutcome { Swapped, Mismatch, NotFound } pub enum SetNxOutcome { Created, Existed }

cas returns Swapped when the current value matched expected and was replaced, Mismatch when it didn't match, and NotFound when the key doesn't exist at all. setnx returns Created on a fresh write and Existed when the key was already present (not an error in either case).

Error handling

All fallible methods return Result<T, Error>, where Error is an enum covering both I/O and protocol-level failures:

rust
pub enum Error { Io(std::io::Error), Server(String), // STATUS_ERR with a message payload NotFound, Exists, Mismatch, Unknown(u8), // unrecognized status byte }

Error implements std::error::Error and Display, and From<io::Error> converts automatically so ? works cleanly through I/O calls:

rust
fn run() -> veltrixdb::Result<()> { let mut c = veltrixdb::Client::connect("127.0.0.1:9000")?; match c.get("key")? { Some(v) => println!("found: {:?}", v), None => println!("not found"), } Ok(()) }
Not yet in this crate The Rust client intentionally stays blocking-only and single-connection to avoid pulling in 50+ transitive dependencies. Not yet implemented: an async client (would add tokio + bytes), MultiPut/MultiGet batch framing (the wire format matches the Go client's — see the Go batch operations section), TLS (planned via rustls), and connection pooling (wrap Client in your own pool, e.g. r2d2, for concurrent callers).