3 unstable releases
Uses new Rust 2024
| 0.2.0 | Apr 13, 2026 |
|---|---|
| 0.1.1 | Apr 11, 2026 |
| 0.1.0 | Apr 10, 2026 |
#399 in Filesystem
240KB
5K
SLoC
daoxide
Caution: This repo was created using vibe coding
High-performance Rust library for accessing DAOS (Distributed Asynchronous Object Storage).
This crate provides a safe wrapper around daos-rs bindings, with an ergonomic Rust-style API.
Overview
daoxide wraps the low-level DAOS C APIs into safe Rust interfaces:
- RAII handle management: Pool, Container, and Object handles are automatically released on
Drop - Type safety: strongly typed keys, object IDs, and flags to prevent runtime errors
- Builder pattern: fluent chained calls instead of complex initialization code
- Transaction support: marker-based
Txtypes ensure correct transaction handling - Unified error handling:
DaosErrorenum instead of raw integer error codes
Feature Flags
| Feature | Enabled by Default | Description |
|---|---|---|
tracing |
Yes | Tracing observability support |
serde |
Yes | Serialization/deserialization support |
async |
No | Async runtime support (Tokio) |
mock |
No | Mock testing utilities |
[dependencies]
daoxide = { version = "0.2", features = ["async"] }
Quick Start
High-Level API (Facade)
Use DaosClient::builder() to connect to DAOS quickly:
use daoxide::prelude::*;
fn main() -> daoxide::Result<()> {
let client = DaosClient::builder()
.pool_label("mypool")
.container_label("mycontainer")
.build()?;
let oid = client.alloc_oid(
ObjectType::KvHashed,
ObjectClass::UNKNOWN,
ObjectClassHints::NONE,
)?;
client.put(oid, b"dkey1", b"akey1", b"hello world")?;
let mut buffer = vec![0u8; 1024];
client.get(oid, b"dkey1", b"akey1", &mut buffer[..11])?;
println!("Retrieved: {:?}", String::from_utf8_lossy(&buffer[..11]));
Ok(())
}
Mid-Level API (Pool/Container/Object)
Use PoolBuilder and Container APIs directly:
use daoxide::pool::{PoolBuilder, flags::POOL_CONNECT_NONE};
use daoxide::container::{ContainerOpen, flags::CONT_OPEN_RW};
fn main() -> daoxide::Result<()> {
let runtime = daoxide::runtime::DaosRuntime::new()?;
let pool = PoolBuilder::new()
.label("mypool")
.system("daos_server")
.flags(POOL_CONNECT_NONE)
.build()?;
let container = pool.create_container("testcontainer")?;
let info = container.query()?;
println!("Container UUID: {:?}", info.uuid);
Ok(())
}
Low-Level API (Object I/O)
Use DKey/AKey/IoBuffer for key-value operations:
use daoxide::io::{DKey, AKey, IoBuffer, Iod, IodSingleBuilder, Sgl};
use daoxide::prelude::*;
let object = client.object_builder()
.open(oid, ObjectOpenMode::ReadWrite)?;
let dkey = DKey::new(b"my_dkey")?;
let akey = AKey::new(b"my_akey")?;
let value = IoBuffer::from_slice(b"hello world");
let iod = Iod::Single(
IodSingleBuilder::new(akey.clone())
.value_len(value.len())
.build()?,
);
let sgl = Sgl::builder().push(value).build()?;
object.update(&Tx::none(), &dkey, &iod, &sgl)?;
Examples
| Example | File | Description |
|---|---|---|
| Minimal client | examples/minimal_client.rs |
Facade API demo |
| Object operations | examples/object_io.rs |
Object read/write and key-value operations |
| Pool/container management | examples/pool_container.rs |
Pool/Container lifecycle |
Run examples:
cargo run --example minimal_client
cargo run --example object_io
cargo run --example pool_container
Documentation
| Document | Contents |
|---|---|
| docs/MIGRATION.md | Complete guide for migrating from daos-rs to daoxide |
| RELEASE.md | Release strategy, versioning, and quality gates |
Quality Check Commands
# Code formatting check
cargo fmt --all -- --check
# Clippy check
cargo clippy --workspace --all-targets --all-features -- -D warnings
# Tests (must use --test-threads=1)
cargo test --workspace --all-features -- --test-threads=1
# Documentation build
cargo doc --workspace --all-features --no-deps
# MSRV verification
cargo +1.85 build --release
Feature Matrix Validation
# No default features
cargo check --no-default-features
# Check each feature independently
cargo check --features mock
cargo check --features async
# All features
cargo check --all-features
Known Limitations
1. OIT (Object Instance Tracking) is unavailable
daos_oit_* FFI functions are not exported by daos-rs, so crate::oit remains a stub.
Workaround: use object enumeration in the crate::iter module.
2. Async event queue is limited
daos_progress is not exposed in daos-rs. The async feature currently provides a spawn_blocking wrapper rather than native async progress.
3. Parallel testing caveat
test_runtime_init_and_fini may fail under parallel test execution because DAOS uses global state (RUNTIME_REFCOUNT).
Solution: run tests with --test-threads=1.
cargo test --workspace --all-features -- --test-threads=1
This is a pre-existing test infrastructure issue and does not affect library correctness.
Public Module Architecture
daoxide
├── error - Error types
├── facade - High-level API (DaosClient)
├── runtime - Runtime management
├── pool - Pool operations
├── container - Container operations
├── object - Object operations
├── tx - Transaction management
├── io - I/O operations (DKey/AKey/IoBuffer)
├── query - Query operations
├── iter - Iterator utilities
├── oit - Object instance tracking (currently unavailable)
└── prelude - Common exports
MSRV (Minimum Supported Rust Version)
- MSRV: Rust 1.85
- Edition: 2024
License
GPL-3.0-only
Dependencies
~5–11MB
~133K SLoC