# crayon-cli

A command-line tool to interact with the [Crayon API](https://apidocs.crayon.com/), written in Rust as a learning project.

## What is this?

[Crayon](https://www.crayon.com/) is a cloud services platform for managing Microsoft/Azure subscriptions, billing, and customer tenants. This CLI tool connects to their REST API to automate common tasks.

## Current Features

- **v0.1 — Connection Test**: Authenticate against the Crayon API using OAuth2 password grant and verify the connection works.

## Planned Features

- [ ] Retrieve and display customer list
- [ ] Filter/search customers
- [ ] Export customer data

## Prerequisites

- [Rust](https://www.rust-lang.org/tools/install) (install via `rustup`)
- A Crayon API account with:
  - Client ID
  - Client Secret
  - Username (email)
  - Password

## Setup

```bash
# Clone the repository
git clone https://gitlab.com/YOUR_USERNAME/crayon-cli.git
cd crayon-cli

# Copy the example env file and fill in your real credentials
cp .env.example .env
nano .env    # or open in any text editor
```

The `.env` file is **never committed to Git** (excluded via `.gitignore`).
Only `.env.example` (with placeholder values) is in the repository.

## Build & Run

```bash
# Build and run (first build downloads dependencies, takes ~1 min)
cargo run

# Or build a release binary (optimized, faster execution)
cargo build --release
./target/release/crayon-cli
```

If the `.env` file is present and filled in, credentials are loaded automatically.
If a value is missing, the tool asks interactively.

## How Authentication Works

The Crayon API uses OAuth2 "password grant" flow:

1. The tool sends your credentials to `POST /api/v1/connect/token`
2. The API returns an access token (valid for ~5.5 hours)
3. That token is used as `Bearer` auth for all subsequent API calls

```
┌─────────┐         ┌─────────────────┐
│  CLI    │──POST──▶│ /connect/token  │
│  Tool   │  creds  │                 │
│         │◀────────│ { AccessToken } │
└─────────┘  token  └─────────────────┘
```

## Project Structure

```
crayon-cli/
├── .gitignore          # Files excluded from version control
├── .env.example        # Template for credentials (safe to commit)
├── .env                # Your real credentials (NEVER committed!)
├── Cargo.toml          # Dependencies and project metadata
├── Cargo.lock          # Exact dependency versions (auto-generated)
├── CHANGELOG.md        # What changed in each version
├── README.md           # This file
└── src/
    └── main.rs         # Application code
```

## Dependencies

| Crate       | Purpose                                    |
|-------------|--------------------------------------------|
| `reqwest`   | HTTP client (sending requests to the API)  |
| `serde`     | Serialization (JSON ↔ Rust structs)        |
| `serde_json`| JSON parsing                               |
| `base64`    | Encoding credentials for Basic auth header |
| `dotenvy`   | Reading `.env` files into env variables    |

## Learning Notes

This is a Rust learning project. Key concepts used so far:

- **Structs + Derive macros**: Defining data shapes with auto-generated JSON parsing
- **Option\<T\>**: Rust's null-safe way of saying "this value might be missing"
- **Result\<T, E\>**: Explicit error handling — functions return Ok or Err
- **Pattern matching**: `match` and `if let` for handling different outcomes
- **Ownership & borrowing**: `&str` (borrowed) vs `String` (owned)

## License

Private project — not for redistribution.
