# mcias-client (Rust)

Async Rust client library for the [MCIAS](../../README.md) identity and access management API.

## Requirements

- Rust 2021 edition (stable toolchain)
- Tokio async runtime

## Installation

Add to `Cargo.toml`:

```toml
[dependencies]
mcias-client = { path = "path/to/clients/rust" }
```

## Quick Start

```rust
use mcias_client::{Client, ClientOptions};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::new(
        "https://auth.example.com".to_string(),
        ClientOptions::default(),
    )?;

    // Authenticate.
    let (token, expires_at) = client.login("alice", "s3cret", None).await?;
    println!("token expires at {expires_at}");

    // The token is stored in the client automatically.
    let accounts = client.list_accounts().await?;

    // Revoke the token when done.
    client.logout().await?;

    Ok(())
}
```

## Custom CA Certificate

```rust
let ca_pem = std::fs::read("/etc/mcias/ca.pem")?;
let client = Client::new(
    "https://auth.example.com".to_string(),
    ClientOptions {
        ca_cert_pem: Some(ca_pem),
        token: None,
    },
)?;
```

## Error Handling

All methods return `Result<_, MciasError>`:

```rust
use mcias_client::MciasError;

match client.login("alice", "wrongpass", None).await {
    Err(MciasError::Auth { message }) => eprintln!("auth failed: {message}"),
    Err(MciasError::Forbidden { message }) => eprintln!("forbidden: {message}"),
    Err(MciasError::NotFound { message }) => eprintln!("not found: {message}"),
    Err(MciasError::InvalidInput { message }) => eprintln!("bad input: {message}"),
    Err(MciasError::Conflict { message }) => eprintln!("conflict: {message}"),
    Err(MciasError::Server { status, message }) => eprintln!("server error {status}: {message}"),
    Err(MciasError::Transport(e)) => eprintln!("network error: {e}"),
    Err(MciasError::Decode(e)) => eprintln!("parse error: {e}"),
    Ok((token, _)) => println!("ok: {token}"),
}
```

## Thread Safety

`Client` is `Send + Sync`. The internal token is wrapped in
`Arc<RwLock<Option<String>>>` for safe concurrent access.

## Running Tests

```sh
cargo test
cargo clippy -- -D warnings
```
