crud-api 0.1.7

CLI generator for your API.
Documentation
## Crud Api

This crate provides a framework to generate an executable to manipulate your HTTP API from CLI.

The apps using this lib can replace your _curl_ queries when you need to access to your favorite API.

### Features

API:
- data are encoded in JSON. It don't support XML, grpc, ...
- output can be formated on json, yaml, toml, csv or tsv
- output stream on stdout or in a file


### Tutorial

Let's create an CLI for [jsonplaceholder](http://jsonplaceholder.typicode.com/) API.
For the impatients, the whole code of this example can be found in [`examples/jsonplaceholder_api.rs`](./examples/jsonplaceholder_api.rs "jsonplaceholder_api.rs")

First add these dependencies to `Cargo.toml`:
```toml
[dependencies]
log = "0.4"
pretty_env_logger = "0.5"
clap = "4.3"
crud-api = {version = "0.1", path="../crud/crud-api", default-features=false, features=["toml","json","yaml"]}
crud-auth = {version = "0.1", path="../crud/crud-auth"}
crud-auth-bearer = {version = "0.1", path="../crud/crud-auth-bearer"}
hyper = { version = "0.14", features = ["client","http1"] }
hyper-tls = "0.5"
miette = { version = "5.9", features = ["fancy"] }
tokio = { version = "1", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }
# To force static openssl
openssl = { version = "0.10", features = ["vendored"] }
```

Now, create a minimal runner stucture and a `main` function.
`ApiRun` on `JSONPlaceHolder` derives all the CLI.
```rust
use crud_api::ApiRun;
use crud_auth::CrudAuth;
use crud_auth_no_auth::Auth;
use miette::{IntoDiagnostic, Result};

#[derive(ApiRun)]
struct JSONPlaceHolder;

#[tokio::main]
async fn main() -> Result<()> {
  JSONPlaceHolder::run().await
}
```
[`crud_api_endpoint::ApiRun`] accepts some parameters. They are documented in `crud_api_endoint` crate.
Let's customize our CLI with a `base_url` for our API, a `name` used in the documentation and the settings. `qualifier` and `organisation` is used to compute the settings location and `env_prefix` is the prefix of the environment variables
```rust
#[derive(ApiRun)]
#[api(infos(
  base_url = "http://jsonplaceholder.typicode.com",
  name = "jsonplaceholder",
  qualifier = "com",
  organisation = "typicode",
  env_prefix = "JSONPLACEHOLDER"
))]
struct JSONPlaceHolder;
```
Before creating the first endpoint we need to describe its output structure.
```rust
use serde::{Deserialize, Serialize};
#[derive(Debug, Default, Deserialize, Serialize)]
struct Post {
  id: u32,
  #[serde(rename = "userId")]
  user_id: u32,
  title: String,
  body: String,
}
```

Now, we can declare the endpoint.
The minimal parameters are:
- `route`, the target api route.
- `cli_route`, the route transcipted as cli arguments. Each slash separate a subcommand.
The other parameters can found in [`crud_api_endpoint::Api`] and [`crud_api_endpoint::Enpoint`] structs documentation.

```rust
use crud_api::Api;
#[derive(Api, Debug, Default, Deserialize, Serialize)]
#[api(
  endpoint(
    route = "/posts",
    cli_route = "/post",
    multiple_results,
  ))]
struct Post {
  id: u32,
  #[serde(rename = "userId")]
  user_id: u32,
  title: String,
  body: String,
}
```
We can create more complex enpoint. Let's create an edit route.

- The `route` parameter takes a post's `id` argument. This argument should be present in the `cli_route`.
- the HTTP method is set with the `method` parameter.
- Some help can be provided via the parameters `cli_help` and `cli_long_help`.
- the payload is described by the struct declared with the `payload_struct`. The query parameter can be add with the `query_struct` parameter.

In this step, the payload structure is `PostCreate` (the same structure is used for both creation and update). `PostCreate` derives `ApiInput`. All `PostCreate` fields parameters are describe in the [`crud_api_endpoint::ApiInputConfig`] structs.


```rust
use crud_api::{Api, ApiInput};
#[derive(Api, Debug, Default, Deserialize, Serialize)]
#[api(
  endpoint(
    route = "/posts",
    cli_route = "/post",
    multiple_results,
  ),
  endpoint(
    route = "/posts/{id}",
    method = "PUT",
    payload_struct = "PostCreate",
    cli_route = "/post/{id}/replace",
    cli_help = "Update a Posts (replace the whole post)"
  )
)]
struct Post {
  id: u32,
  #[serde(rename = "userId")]
  user_id: u32,
  title: String,
  body: String,
}

#[derive(Debug, ApiInput, Default, Serialize, Deserialize)]
#[allow(dead_code, non_snake_case)]
struct PostCreate {
  #[api(long = "user-id")]
  userId: u32,
  #[api(no_short, help = "Title of the post")]
  title: String,
  #[api(no_short)]
  body: String,
}
```

### Output Customization

#### Tables

Results arrays are formatted using the crate [`crud-tidy-viewer`](crud_tidy_viewer).
The available table column options are:
- [`table_skip`]../crud_api_endpoint/struct.ApiField.html#structfield.table_skip: don't display this field in the table.
- [`table_format`]../crud_api_endpoint/struct.ApiField.html#structfield.table_format: format this field in table.
  - date formatter: `date(format = "%Y-%m-%d %H:%M:%S")`

#### Pretty Structures

The crate [`crud-pretty-struct`](crud_pretty_struct) can format a single (json) struct.