# `formattable`
Make it easy and ergonomic to provide formatted output.
[`Format`] is an enum that allows selecting a particular format, but supports
standard methods for serializing content. This makes it convenient to select a
user-selected serializer at runtime.
For usage with [clap](https://docs.rs/clap/latest/clap/), we also provide
[`FormatArg`] and [`FormatArgOpt`] which standardizes the flags and parsing for
selecting a serializer.
## Usage
Make sure you enable/disable the appropriate [features](#features) for the functionality
you want.
### Basic
```rust
use formattable::Format;
use serde::Serialize;
// Have some data structure that can be serialized.
#[derive(Serialize)]
struct Foo;
// Instantiate a Format variant. Format is Copy, so it's easy to use and pass
// around.
let fmt = Format::Json;
// Write your data structure to a JSON string.
let foo = Foo;
fmt.to_string(&foo).unwrap();
```
### `clap` Integration \[feature: clap\]
```rust
use clap::Parser;
use formattable::Format;
use serde::Serialize;
/// Demonstrate how to use [`Format`] in a `clap`-based CLI.
///
/// This example just dumps the CLI arguments themselves as the selected format.
#[derive(Debug, Parser, Serialize)]
struct Cli {
/// Select a format for output.
#[clap(short, long, value_enum, default_value_t = Format::Json)]
format: Format,
}
fn main() {
let cli = Cli::parse();
println!("{}", cli.format.to_string(&cli).unwrap());
}
```
### Flattened `clap` Integration \[feature: clap\]
The easiest way to consistently integrate [`Format`] with clap is to use
[`FormatArg`], which implements
[`clap::Args`](https://docs.rs/clap/latest/clap/trait.Args.html):
```rust
use clap::Parser;
use formattable::FormatArg;
use serde::Serialize;
/// Demonstrate how to use `formattable` in a `clap`-based CLI.
///
/// This example just dumps the CLI arguments themselves as the selected format.
#[derive(Debug, Parser, Serialize)]
struct Cli {
#[clap(flatten)]
format: FormatArg,
}
fn main() {
let cli = Cli::parse_from(["", "-f", "json"]);
println!("{}", cli.format.to_string_pretty(&cli).unwrap());
}
```
## Features
* `default` [toml, json, yaml]
* `clap` - enables the `clap` CLI integration
* `json` - default; enables serialization to JSON
* `yaml` - default; enables serialization to YAML
* `toml` - default; enables serialization to TOML
## Roadmap
There's no concrete roadmap or plans, but general ideas that would be
interesting to implement include:
* Use a macro to remove the boilerplate around the [`FormatArg`] and
[`FormatArgOpt`] struct definitions and implementations;
* Instead of providing dedicated argument types, provide a macro that can be
used to add format support to structs;
* Add support for a default format. This would be relatively easy if
functionality was provided via macro;
* Figure out some way to have text be a selectable format.