bindist 0.1.0

Rust client library for the BinDist Customer API
Documentation
# bindist

[![Crates.io](https://img.shields.io/crates/v/bindist.svg)](https://crates.io/crates/bindist)
[![Docs.rs](https://docs.rs/bindist/badge.svg)](https://docs.rs/bindist)

Rust client for the [BinDist](https://bindist.eu) Customer API — the
customer-facing half of an application distribution platform. Covers
listing applications and versions, browsing version files, requesting
pre-signed download URLs, and minting public share links.

## Install

```toml
[dependencies]
bindist = "0.1"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
```

The crate is async and uses `reqwest` with `rustls-tls` (no OpenSSL).

## Usage

```rust
use bindist::{Client, GetDownloadInfoOptions, ListApplicationsOptions, ListVersionsOptions};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::new("https://api.bindist.eu", "your-api-key")?;

    let apps = client
        .list_applications(&ListApplicationsOptions::default())
        .await?;
    for app in &apps.items {
        println!("{} ({})", app.name, app.application_id);
    }

    let versions = client
        .list_versions("myapp", &ListVersionsOptions::default())
        .await?;
    for v in &versions.items {
        println!("  {} ({} bytes)", v.version, v.file_size);
    }

    let info = client
        .get_download_info("myapp", "1.0.0", &GetDownloadInfoOptions::default())
        .await?;
    println!("Download URL: {}", info.url);

    Ok(())
}
```

## Release channels

Versions can be published on non-default channels (for example, disabled
pre-release builds sit on the `Test` channel). Pass
`channel: Some(Channel::Test)` in the options struct to send the
`X-Channel` header:

```rust
use bindist::{Channel, Client, ListVersionsOptions};

# async fn run(client: &Client) -> bindist::Result<()> {
let versions = client
    .list_versions(
        "myapp",
        &ListVersionsOptions {
            channel: Some(Channel::Test),
            ..Default::default()
        },
    )
    .await?;
# Ok(())
# }
```

## Errors

All API methods return `Result<T, bindist::Error>`. `Error::Api(ApiError)`
covers both server-returned error envelopes and non-2xx responses from
auth middleware / proxies / load balancers that never reach the API's
structured error renderer — in the latter case, `ApiError::code` is
derived from the HTTP status (`unauthorized`, `forbidden`, `not_found`,
`rate_limited`, `server_error`, `http_error`) and `http_status` holds
the underlying status.

## Example

```sh
BINDIST_API_KEY=... cargo run --example list
```

## License

MIT — see [LICENSE](LICENSE).