README.md

# Fist 👊
A declarative, type-safe router for the [Mist](https://github.com/rawhat/mist) web server in Gleam, inspired by Axum.

## Features
- **Declarative API**: Build your router with a clean, chainable syntax: `fist.get("/", to: handler)`.
- **Dynamic Routing**: Capture URL parameters with `:parameter_name`.
- **Generic Output**: Handlers can return anything (`Response`, `String`, or your own custom types).
- **Transformation Pipeline**: Use `fist.map` to transform your router's output (e.g., from `String` to `mist.ResponseData`).
- **Response Helpers**: Built-in functions like `fist.ok`, `fist.json`, and `fist.text` for faster development.
- **Type Safe**: Gleam's type system ensures your handlers always match your router's expectations.

## Installation
Add `fist` to your `gleam.toml`:
```toml
[dependencies]
fist = { path = "../fist" } # Or from Hex when available
```

## Quick Start

### 1. Define your handlers
With `fist`, you can return standard `Response` types using built-in helpers.

```gleam
import gleam/dict.{type Dict}
import gleam/http/request.{type Request}
import gleam/result
import fist

fn hello_handler(_req: Request(body), params: Dict(String, String)) {
  let name = dict.get(params, "name") |> result.unwrap("stranger")
  fist.ok("Hello, " <> name <> "!")
}
```

### 2. Create and transform the router
You can write your business logic using simple `Response(String)` and then transform it for your web server (like Mist) at the end.

```gleam
import fist

pub fn main() {
  fist.new()
  |> fist.get("/hello/:name", to: hello_handler)
  |> fist.get("/json", to: fn(_, _) { fist.json("{\"status\": \"ok\"}") })
  // Transform all Response(String) to Response(mist.ResponseData)
  |> fist.map(fist.render_mist)
  |> fist.start(port: 8080)
}
```


## Advanced: Custom Return Types (ADTs)
Because `fist` is generic over the handler's output, you can use your own Algebraic Data Types and map them.

```gleam
pub type MyAnswer {
  Success(String)
  UserFound(User)
  Error(String)
}

fn my_handler(_, _) {
  Success("Operation completed")
}

pub fn start() {
  fist.new()
  |> fist.get("/", to: my_handler)
  |> fist.map(fn(answer) {
    case answer {
      Success(msg) -> fist.ok(msg)
      UserFound(user) -> fist.json(user_to_json(user))
      Error(err) -> fist.text("Error: " <> err) // Adicione .set_status(400) se necessário
    }
  })
  |> fist.map(fist.render_mist)
  |> fist.start(8080)
}
```

## Integration with Mist
The `fist.start` function provides a convenient way to run your router with Mist. It expects a router where handlers return `Response(mist.ResponseData)`.

```gleam
import mist
import fist

pub fn main() {
  fist.new()
  |> fist.get("/", to: fn(_req, _params) {
    fist.ok("Hello from Mist!")
  })
  |> fist.map(fist.render_mist)
  |> fist.start(port: 8080)
}
```