> ## Documentation Index
> Fetch the complete documentation index at: https://docs.snipp.gg/llms.txt
> Use this file to discover all available pages before exploring further.

# Rust

> Official Rust wrapper for the Snipp API.

<Card horizontal icon="github" href="https://github.com/snipp-gg/snipp-rust">
  snipp-gg/snipp-rust
</Card>

<Card horizontal icon="rust" href="https://crates.io/crates/snipp">
  crates.io/crates/snipp
</Card>

## Installation

Add to your `Cargo.toml`:

```toml theme={null}
[dependencies]
snipp = "1"
tokio = { version = "1", features = ["full"] }
```

## Getting Started

```rust theme={null}
use snipp::SnippClient;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = SnippClient::new("YOUR_API_KEY");

    let me = client.get_user("@me", None).await?;
    println!("{}", me.user.username.unwrap_or_default());

    Ok(())
}
```

## Methods

All methods are `async` and return `Result<T, SnippError>`.

### `get_user(id, options)`

Fetch a user by ID. Pass `"@me"` for the authenticated user.

```rust theme={null}
use snipp::GetUserOptions;

// Without options
let user = client.get_user("@me", None).await?;

// With options
let opts = GetUserOptions {
    include_posts: Some(true),
    posts_limit: Some(10),
};
let user = client.get_user("@me", Some(opts)).await?;
```

### `get_post(code)`

Fetch a post by its share code.

```rust theme={null}
let post = client.get_post("AbCd1234").await?;
println!("{:?}", post.post.url);
```

### `upload(path, options)`

Upload a file from disk.

```rust theme={null}
use snipp::{Privacy, UploadOptions};

let opts = UploadOptions {
    privacy: Some(Privacy::Unlisted),
    title: Some("My screenshot".into()),
    ..Default::default()
};
let result = client.upload("image.png", Some(opts)).await?;
println!("{}", result.url.unwrap_or_default());
```

### `list_uploads(limit)`

List the authenticated user's recent uploads. Pass `Some(N)` for `limit` to control the count (max 1000), or `None` for the default (30).

```rust theme={null}
let uploads = client.list_uploads(Some(100)).await?;
```

### `edit_upload(code, options)`

Edit an existing upload's title, description, or privacy.

```rust theme={null}
use snipp::{EditUploadOptions, Privacy};

let opts = EditUploadOptions {
    title: Some("New title".into()),
    privacy: Some(Privacy::Public),
    ..Default::default()
};
client.edit_upload("AbCd1234", opts).await?;
```

### `append_upload(code, file_paths)`

Add one or more files to an existing album post. The post's share code, privacy, title, and description are preserved. Albums cap at 9 files total. Requests that would exceed the cap are rejected. New files inherit the post's privacy. Returned URLs are signed with a 24-hour expiry for private posts.

```rust theme={null}
let result = client
    .append_upload("AbCd1234", &["photo-a.png", "photo-b.png"])
    .await?;

if let Some(post) = result.post {
    println!("album now has {:?} files", post.file_count);
}
```

### `delete_upload(filename)`

Delete an upload by its filename. On albums, only that file is removed; on single-file posts the entire post is deleted.

```rust theme={null}
client.delete_upload("a3f7b2c91d4e8f0612ab34cd56ef7890.png").await?;
```

## Error Handling

All errors are returned as `SnippError`, which covers API errors, HTTP errors, deserialization failures, and IO errors.

```rust theme={null}
match client.get_user("nonexistent", None).await {
    Ok(user) => println!("{:?}", user),
    Err(e) => eprintln!("Error: {e}"),
}
```
