# Problem Details

[![Build status](https://github.com/sazzer/problemdetails/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/sazzer/problemdetails/actions/workflows/ci.yml)
[![Crates.io](https://img.shields.io/crates/v/problemdetails)](https://crates.io/crates/problemdetails)
[![Documentation](https://docs.rs/problemdetails/badge.svg)](https://docs.rs/problemdetails)

This crate provides an implementation of a Problem Details response for HTTP APIs, as defined in [RFC-7807](https://datatracker.ietf.org/doc/html/rfc7807) / [RFC-9457](https://datatracker.ietf.org/doc/html/rfc9457). This is a standard way for HTTP APIs to indicate that a problem occurred with the request, including some standard payload fields as required.

## Example Usage

The following is a valid handler for Axum that returns the Forbidden example from [RFC-9457 Section 3](https://datatracker.ietf.org/doc/html/rfc9457#section-3):

```rust
async fn forbidden() -> problemdetails::Result<String> {
    Err(problemdetails::new(StatusCode::FORBIDDEN)
            .with_type("https://example.com/probs/out-of-credit")
            .with_title("You do not have enough credit.")
            .with_detail("Your current balance is 30, but that costs 50.")
            .with_instance("/account/12345/msgs/abc")
            .with_value("balance", 30)
            .with_value("accounts", vec!["/account/12345", "/account/67890"]))
}
```

When used with a supported HTTP Server, this will automatically generate the correct JSON response and set the Content-Type header to the correct value of `application/problem+json`.

If used with an unsupported HTTP Server, the status code and body of the problem details can be extracted and sent manually. The `body` field is in the correct structure to format into JSON using something like `serde` already, so serializing it should be as simple as the HTTP Server allows for.

## Supported HTTP Servers

Currently this is only supported with the following HTTP Servers:

- [Axum](https://crates.io/crates/axum)
- [Poem](https://crates.io/crates/poem)

Examples of use with the different HTTP Servers can be found in the [examples](https://github.com/sazzer/problemdetails/tree/main/examples) directory.

# Features

HTTP Server support is behind feature flags for the appropriate HTTP Server. As such, you will need to enable the correct feature for the HTTP Server that you are using.

Currently supported features are:

- `axum` - For the [Axum](https://crates.io/crates/axum) HTTP Server.
- `poem` - For the [Poem](https://crates.io/crates/poem) HTTP Server.

## Safety

This crate uses `#![forbid(unsafe_code)]` to ensure everything is implemented in 100% safe Rust.

## Minimum supported Rust version

The MSRV for `problemdetails` is 1.85.1. However, the HTTP Servers that are used with it might need a higher version.

## License

This project is licensed under the MIT license.

## Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in `problemdetails` by you, shall be licensed as MIT, without any additional terms or conditions.
