# arxivis-rs
Official Rust SDK for the [Arxivis](https://github.com/v019-Labs/arxivis) document store.
## Requirements
- Rust 2021 edition (MSRV: 1.75)
- Tokio async runtime
## Installation
Add to your `Cargo.toml`:
```toml
[dependencies]
arxivis = { path = "./sdk/rust" }
tokio = { version = "1", features = ["full"] }
```
## Quick start
```rust
use arxivis::{ArxivisClient, UploadOptions};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = ArxivisClient::new("http://localhost:8080", "axv_xxxx_yyyy")?;
// Upload
let data = std::fs::read("invoice.pdf")?;
let record = client
.upload(
data,
"invoice.pdf",
UploadOptions::new()
.path("/invoices/2024/")
.tags(vec!["cliente".into(), "enero".into()])
.compress(true),
)
.await?;
println!("stored: {}", record.id);
// List
let page = client.list("/invoices/2024/", Default::default()).await?;
for f in &page.files {
println!("{} — {} bytes", f.original_name, f.size);
}
// Search
let hits = client.search("factura", Default::default()).await?;
println!("{} results", hits.total);
// Download
let bytes = client.download(&record.id).await?;
std::fs::write("copy.pdf", &bytes)?;
// Delete
client.delete_file(&record.id).await?;
Ok(())
}
```
## API reference
### `ArxivisClient`
```rust
// Create
let client = ArxivisClient::new(base_url, api_key)?;
// Custom timeout
use std::time::Duration;
let client = ArxivisClient::new(base_url, api_key)?
.with_timeout(Duration::from_secs(120))?;
```
| `get_stats()` | `Stats` | Aggregate storage statistics |
| `upload(data, filename, opts)` | `FileRecord` | Upload raw bytes |
| `list(path, opts)` | `ListResult` | Paginated file listing |
| `get(id)` | `FileRecord` | Fetch file metadata |
| `download(id)` | `Bytes` | Download raw bytes |
| `delete_file(id)` | `()` | Soft-delete a file |
| `download_zip(ids)` | `Bytes` | Export files as ZIP |
| `create_folder(path)` | `String` | Create virtual folder |
| `search(query, opts)` | `ListResult` | Full-text search (FTS5) |
| `semantic_search(query, opts)` | `SearchResult` | Vector similarity search |
| `hybrid_search(query, opts)` | `SearchResult` | FTS5 + semantic fusion |
| `create_key(name)` | `CreateKeyResult` | Create API key |
| `list_keys()` | `Vec<ApiKey>` | List API keys |
| `revoke_key(id)` | `()` | Revoke an API key |
| `download_url(id)` | `String` | Direct download URL |
| `preview_url(id)` | `String` | Inline preview URL |
| `path_url(file_path)` | `String` | Virtual-path URL |
### `UploadOptions` builder
```rust
use arxivis::UploadOptions;
let opts = UploadOptions::new()
.path("/invoices/2024/")
.tags(vec!["cliente".into()])
.compress(true)
.encrypt(false);
```
### `ListOptions` / `SearchOptions`
```rust
use arxivis::{ListOptions, SearchOptions};
let list_opts = ListOptions::new().limit(20).offset(40);
let search_opts = SearchOptions::new().limit(10);
```
### `ArxivisError`
```rust
use arxivis::ArxivisError;
match client.get("unknown-id").await {
Err(ArxivisError::Api { status, message }) if status == 404 => {
println!("not found");
}
Err(e) if e.is_unauthorized() => println!("check your API key"),
Err(e) if e.is_rate_limited() => println!("slow down"),
Err(e) => eprintln!("error: {e}"),
Ok(record) => println!("{}", record.id),
}
```
## License
MIT