# Option sets with built-in Serde support

[![option_set on crates.io](https://img.shields.io/crates/v/option_set.svg)](https://crates.io/crates/option_set)
[![option_set on docs.rs](https://docs.rs/option_set/badge.svg)](https://docs.rs/option_set)
[![option_set Downloads](https://img.shields.io/crates/d/option_set.svg)](https://crates.io/crates/option_set)
[![option_set License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/H2CO3/option_set#license)
[![Lines of Code](https://tokei.rs/b1/github/H2CO3/option_set)](https://github.com/Aaronepower/tokei)
[![Twitter](https://img.shields.io/badge/twitter-@H2CO3_iOS-blue.svg?style=flat&colorB=64A5DE&label=Twitter)](http://twitter.com/H2CO3_iOS)

This crate implements a macro `option_set` which knows how to serialize and deserialize itself to/from a sequence of strings. The macro invocation looks very much like [`bitflags!()`](https://doc.rust-lang.org/bitflags/bitflags/index.html), with a few useful additions. In fact, the underlying type *is* generated by the `bitflags!()` macro, therefore you will need the bitflags crate if you are using this library.

## Usage

```
#[macro_use]
extern crate option_set;
#[macro_use]
extern crate bitflags;
extern crate serde;
extern crate serde_json;

option_set! {
    struct FooOptions: UpperCamel + u16 {
        const BAR_FIRST        = 0x0001;
        const QUX_SECOND_THING = 0x0080;
        const LOL_3RD          = 0x4000;
    }
}

fn main() {
    let opts_in = FooOptions::BAR_FIRST | FooOptions::LOL_3RD;
    let json = serde_json::to_string_pretty(&opts_in).unwrap();

    println!("{}", json);

    let opts_out: FooOptions = serde_json::from_str(&json).unwrap();

    println!("{:?}", opts_out);
    assert!(opts_out == opts_in);
}
```

In the struct declaration, the first identifier after the colon (`UpperCamel` in the above example) controls how the name of each flag is transformed before serialization. This is necessary because the flags are not real `struct` fields or `enum` variants, so `#[serde(rename_all = "...")]` and the like don't work on them.

The possible name transformations are the variants of the `CaseTransform` enum.

The second type, after the `+` sign, is the underlying type of the bitmask, which is usually an exact-width integer.

## License

MIT
