# Go IAM SDK - Rust

[![Crates.io](https://img.shields.io/crates/v/goiam)](https://crates.io/crates/goiam)
[![Documentation](https://docs.rs/goiam/badge.svg)](https://docs.rs/goiam)
[![License](https://img.shields.io/crates/l/goiam)](https://github.com/melvinodsa/go-iam-sdk/blob/main/LICENSE)

Rust SDK for Go IAM API - Async/Await Support

## Installation

Add this to your `Cargo.toml`:

```toml
[dependencies]
goiam-rust = "0.1.0"
tokio = { version = "1.0", features = ["full"] }
```

## Usage

```rust
use goiam_rust::{new_service, Service, Resource};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Initialize the service
    let service = new_service(
        "https://api.goiam.com".to_string(),
        "your-client-id".to_string(),
        "your-secret".to_string()
    );

    // Verify a code and get access token
    match service.verify("authorization-code").await {
        Ok(token) => {
            println!("Access Token: {}", token);

            // Get user information
            let user = service.me(&token).await?;
            println!("User: {} ({})", user.name, user.email);

            // Create a resource
            let resource = Resource::new("resource-1".to_string(), "My Resource".to_string());
            service.create_resource(&resource, &token).await?;
            println!("Resource created successfully");
        },
        Err(e) => eprintln!("Verification failed: {}", e),
    }

    Ok(())
}
```

## API Reference

### Service Trait

The main interface for interacting with Go IAM API:

```rust
#[async_trait]
pub trait Service: Send + Sync {
    async fn verify(&self, code: &str) -> Result<String, GoIamError>;
    async fn me(&self, token: &str) -> Result<User, GoIamError>;
    async fn create_resource(&self, resource: &Resource, token: &str) -> Result<(), GoIamError>;
}
```

### Types

```rust
pub struct User {
    pub id: String,
    pub project_id: String,
    pub name: String,
    pub email: String,
    pub phone: String,
    pub enabled: bool,
    pub profile_pic: String,
    pub expiry: Option<String>,
    pub roles: HashMap<String, serde_json::Value>,
    pub resources: HashMap<String, serde_json::Value>,
    pub policies: HashMap<String, serde_json::Value>,
    pub created_at: Option<String>,
    pub created_by: String,
    pub updated_at: Option<String>,
    pub updated_by: String,
}

pub struct Resource {
    pub id: String,
    pub name: String,
}
```

### Error Handling

```rust
use goiam_rust::{GoIamError, Service};

match service.verify("code").await {
    Ok(token) => println!("Success: {}", token),
    Err(GoIamError::Http(status)) => eprintln!("HTTP error: {}", status),
    Err(GoIamError::Request(e)) => eprintln!("Request error: {}", e),
    Err(GoIamError::Parse(e)) => eprintln!("Parse error: {}", e),
    Err(GoIamError::Api(msg)) => eprintln!("API error: {}", msg),
}
```

## Testing

Run the tests with:

```bash
cargo test
```

Run tests with output:

```bash
cargo test -- --nocapture
```

## License

This project is licensed under the MIT License.
