Rustのコード整形ツールrustfmtのオプションについて

**2020/7/9追記:**
本記事は内容が古くなっている、かつ独自調査なため、[公式のドキュメント](https://rust-lang.github.io/rustfmt)を見る事を推奨します。
※日本語で読める利用方法の把握記事に使えなくはないですが、オプションがわりと変わっています。
**追記ここまで**

# この記事について

この記事はRustのソースコードを整形する[rustfmt](https://github.com/rust-lang-nursery/rustfmt)の各オプションについての解説記事です、rustfmtのソースコードと実際に動作させながらの調査の為、解説に見落としがあるかもしれない事をご了承下さい。
調査時のRustとrustfmtのバージョンは以下の通りです。

- Rust(rustc 1.8.0)
- rustfmt 0.4.1


# config options早見表

configファイルに書くことが出来るオプションについてです、configファイルは--config-pathで指定も出来ますが、省略時は対象ソースと同パスにあるrustfmt.tomlが使われます。
このオプション一覧は--config-help指定で確認出来ます。

また、一部rustfmtに直接指定するオプションと被っていますが、--verboseと--skip-childrenは直接指定するオプションがソースファイルへ、configファイルに記載するオプションが標準入力から渡されたソース文字列に機能するのを確認出来ました。
(例えば、hoge.rsを対象に、他のimportされたソースを除外したい場合は、

```
$ rustfmt hoge.rs --skip-children
```

と直接指定するオプションを利用する必要があります)

|option名|設定値|原文|調査結果|
|--:|:--|:--|:--|
| verbose | \<boolean\><br>Default: false | Use verbose output|**標準入力からコードを渡した時のみ確認**、進捗を表示<br>ex)Formatting stdin
| skip_children | \<boolean\><br>Default: false | Don't reformat out of line modules|**標準入力からコードを渡した時のみ確認**、他のimportしたソースの整形をskipする
| [max_width](#max_width) | \<unsigned integer\><br>Default: 100 | Maximum width of each line|最大幅、行のコード幅をこの幅以内に収めようとする
| ideal_width | \<unsigned integer\><br>Default: 80 | Ideal width of each line|理想的な幅、**ただ、この設定の具体的な動作を確認出来ませんでした、[このissue](https://github.com/rust-lang-nursery/rustfmt/issues/861)によるとideal_widthはコメント・文字列リテラルに機能するが、問題が判明し、設定を放棄したとのことです**
| [tab_spaces](#tab_spaces) | \<unsigned integer\><br>Default: 4 | Number of spaces per tab|インデントのスペース数
| [fn_call_width](#fn_call_width) | \<unsigned integer\><br>Default: 60 | Maximum width of the args of a function call before falling back to vertical formatting|関数の引数幅、これより大きいと縦に並べる
| [struct_lit_width](#struct_lit_width) | \<unsigned integer\><br>Default: 16 | Maximum width in the body of a struct lit before falling back to vertical formatting|structのリテラル幅、これより大きいと縦に並べる
| newline_style | [Windows&#124;<br>Unix&#124;<br>Native] <br>Default: Unix | Unix or Windows line endings|改行コード。Windows:CRLF、Unix:LF、Native:OSにより自動判定
| [fn_brace_style](#fn_brace_style) | [AlwaysNextLine&#124;<br>PreferSameLine&#124;<br>SameLineWhere] <br>Default: SameLineWhere | Brace style for functions|関数のブラケットの位置。AlwaysNextLine: 改行を常に挟む、PreferSameLine: 常に同じ行、SameLineWhere:場合により改行を挟む(例えば、template使用時に規程を書いた場合は改行される)
| [item_brace_style](#item_brace_style) | [AlwaysNextLine&#124;<br>PreferSameLine&#124;<br>SameLineWhere] <br>Default: SameLineWhere | Brace style for structs and enums|fn_brace_styleのstructs・enums版
| [impl_empty_single_line](#impl_empty_single_line) | \<boolean\><br>Default: true | Put empty-body implementations on a single line|implの実装が空の時、一行にする
| [fn_empty_single_line](#fn_empty_single_line) | \<boolean\><br>Default: true | Put empty-body functions on a single line|関数の実装が空の時、一行にする<br>**fn_brace_styleをAlwaysNextLineにすると、そちらが優先される**
| [fn_single_line](#fn_single_line) | \<boolean\><br>Default: false | Put single-expression functions on a single line|一行処理の関数を一行にする
| [fn_return_indent](#fn_return_indent) | [WithArgs&#124;<br>WithWhereClause] <br>Default: WithArgs | Location of return type in function declaration|関数の戻り値の型のインデント位置。WithArgs: 引数と同じ位置、WithWhereClause: where句と同じ位置<br>**戻り値の型が改行される状況にならないと効果を発揮しない(max_width < 関数定義の文字数の時など)**
| [fn_args_paren_newline](#fn_args_paren_newline) | \<boolean\><br>Default: true | If function argument parenthesis goes on a newline|関数の長さがmax_widthより短い時、引数部分が改行されるが、その時に始まりの括弧も改行するか
| [fn_args_density](#fn_args_density) | [Compressed&#124;<br>Tall&#124;<br>CompressedIfEmpty&#124;<br>Vertical] <br>Default: Tall | Argument density in functions|関数の引数の密度。Compressed: 出来るだけmax_width以内に詰め込む、 Tall: 十分なmax_widthがあるなら一行で、足りないなら複数行にする、CompressedIfEmpty: Tallと同じ、Vertical: 常に複数行にする
| [fn_args_layout](#fn_args_layout) | [Visual&#124;<br>Block&#124;<br>BlockAlways] <br>Default: Visual | Layout of function arguments|関数の引数のレイアウト。Visual: max_widthが足りない時、各引数・戻り値の型の改行時のindentを並べる Block: max_widthが足りない時、Blockレイアウトへ、BlockAlways: 常にBlock<br>**Blockの時はfn_return_indentは無視される**
| [fn_arg_indent](#fn_arg_indent) | [Inherit&#124;<br>Tabbed&#124;<br>Visual] <br>Default: Visual |Indent on function arguments|関数の引数のindent。Inherit: 二つ目以降を関数定義と同じindentへ、Tabbed: 二つ目以降を関数定義からindent、Visual: 二つ目以降を一つ目と同じindentへ<br>**fn_args_layoutをBlockにしてると、Tabbedの効果がない(Visualと同じ)**
| [type_punctuation_density](#type_punctuation_density) | [Compressed&#124;<br>Wide] <br>Default: Wide | Determines if '+' or '=' are wrapped in spaces in the punctuation of types|struct・enum等へのGenericsのデフォルト型やbuiltin trait指定時の「=」や「+」の空白について。Compressed: 空白なし、Wide: 空白あり
| [where_density](#where_density) | [Compressed&#124;<br>Tall&#124;<br>CompressedIfEmpty&#124;<br>Vertical] <br>Default: CompressedIfEmpty | Density of a where clause|fn_args_densityのwhere句版、**ただし挙動が違う**。Compressed: max_width・ideal_width以内に収まるなら一行で、足りないなら改行、CompressedIfEmpty: Compressedに加え、関数の実装がないなら一行で、あるなら改行、Tall: Verticalと同じ。Vertical: 常に改行
| [where_indent](#where_indent) | [Inherit&#124;<br>Tabbed&#124;<br>Visual] <br>Default: Tabbed | Indentation of a where clause|where句のindent。Inherit: 関数定義と同じindentへ、Tabbed: Visualと同じ、 Visual: indentする<br>**where_densityがCompressedで改行されていない時は効果がない**
| [where_layout](#where_layout) | [Vertical&#124;<br>Horizontal&#124;<br>HorizontalVertical&#124;<br>Mixed] <br>Default: Vertical | Element layout inside a where clause|where句でカンマ区切りで複数指定した際のレイアウト。Vertical: 常に改行する、HorizontalVertical: 十分なmax_widthがあるなら一行で、足りないなら複数行にする、Mixed: 出来るだけmax_width以内に詰め込む、Horizontal: 常に一行で
| [where_pred_indent](#where_pred_indent) | [Inherit&#124;<br>Tabbed&#124;<br>Visual] <br>Default: Visual | Indentation style of a where predicate|where句の二つ目以降のindent。Inherit: where句と同じindentへ、Tabbed: indent、Visual: 一つ目と同じindentへ
| [where_trailing_comma](#where_trailing_comma) | \<boolean\><br>Default: false | Put a trailing comma on where clauses|where句の最後のカンマを付けるか
| [generics_indent](#generics_indent) | [Inherit&#124;<br>Tabbed&#124;<br>Visual] <br>Default: Visual | Indentation of generics|その他(where句や関数の引数以外、structやtraitのtype parameter等)のindent。Inherit: 定義と同じindent、Tabbed: indent, Visual: 一つ目と同じindentへ
| [struct_trailing_comma](#struct_trailing_comma) | [Always&#124;<br>Never&#124;<br>Vertical] <br>Default: Vertical | If there is a trailing comma on structs|struct定義の最後のカンマ。Always: 常に付ける、Never: 常に付けない、Vertical: **不明、structの定義をHorizontalに並べるオプションが無い為、Alwaysと同じであった**
| [struct_lit_trailing_comma](#struct_lit_trailing_comma) | [Always&#124;<br>Never&#124;<br>Vertical] <br>Default: Vertical | If there is a trailing comma on literal structs|structリテラルの最後のカンマ。Always: 常に付ける、Never: 常に付けない、Vertical: 各リテラルを改行する時に付ける
| [struct_lit_style](#struct_lit_style) | [Visual&#124;<br>Block] <br>Default: Block | Style of struct definition|structリテラルのスタイル。Visual: struct_lit_width幅が足りない時、各リテラルの改行時のindentを並べる、Block: struct_lit_width幅が足りない時、Blockスタイルへ
| [struct_lit_multiline_style](#struct_lit_multiline_style) | [PreferSingle&#124;<br>ForceMulti] <br>Default: PreferSingle | Multiline style on literal structs|structリテラルの複数行スタイル。PreferSingle: フィールドが一つか、リテラルがstruct_lit_width幅以内なら一行で、足りないなら複数行にする、ForceMulti: 常に複数行スタイル
| [enum_trailing_comma](#enum_trailing_comma) | \<boolean\><br>Default: true | Put a trailing comma on enum declarations|enum句の最後のカンマを付けるか
| report_todo | [Always&#124;<br>Unnumbered&#124;<br>Never] <br>Default: Never | Report all, none or unnumbered occurrences of TODO in source file comments|ソース中のTODOコメント一覧を表示する。Always: すべて、Unnumbered: issue番号が振られていないものだけ、Never: 無視する
| report_fixme | [Always&#124;<br>Unnumbered&#124;<br>Never] <br>Default: Never | Report all, none or unnumbered occurrences of FIXME in source file comments|ソース中のFIXMEコメント一覧を表示する。Always: すべて、Unnumbered: issue番号が振られていないものだけ、Nerver: 無視する
| [chain_base_indent](#chain_base_indent) | [Inherit&#124;<br>Tabbed&#124;<br>Visual] <br>Default: Visual | Indent on chain base|メソッドやフィールド・structリテラルチェーンの最初のindent。Inherit: 定義開始行に合わせたindent、Tabbed: 一段indent、Visual: メソッドやフィールド・structリテラルの開始位置に合わせたindent
| [chain_indent](#chain_indent) | [Inherit&#124;<br>Tabbed&#124;<br>Visual] <br>Default: Visual | Indentation of chain|メソッドやフィールド・structリテラルチェーンの二つ目以降のindent。Inherit: 定義開始行に合わせたindent、Tabbed: 一段indent、Visual: メソッドやフィールド・structリテラルの開始位置に合わせたindent
| [reorder_imports](#reorder_imports) | \<boolean\><br>Default: false | Reorder import statements alphabetically| use {YYY, XXX};の順番をアルファベット順にするか、大文字が優先
| [single_line_if_else](#single_line_if_else) | \<boolean\><br>Default: false | Put else on same line as closing brace for if statements|return式だけが書かれたif - elseを一行にまとめるか
| [format_strings](#format_strings) | \<boolean\><br>Default: true | Format string literals where necessary|max_width幅が足りない時、stringリテラルを整形する
| [force_format_strings](#force_format_strings) | \<boolean\><br>Default: false | Always format string literals|stringリテラルを整形する
| [chains_overflow_last](#chains_overflow_last) | \<boolean\><br>Default: true | Allow last call in method chain to break the line|開始と終了のindentが合わないようなチェーン整形をするか
| [take_source_hints](#take_source_hints) | \<boolean\><br>Default: true | Retain some formatting characteristics from the source code|コードの書き方に合わせた融通の利く整形をするか
| [hard_tabs](#hard_tabs) | \<boolean\><br>Default: false | Use tab characters for indentation, spaces for alignment|indentにタブを使うか
| [wrap_comments](#wrap_comments) | \<boolean\><br>Default: false | Break comments to fit on the line|コメントをmax_width・ideal_width幅以内に収めるか
| [normalise_comments](#normalise_comments) | \<boolean\><br>Default: true |Convert /* */ comments to // comments where possible|/* */コメントを//コメントにするか
| [wrap_match_arms](#wrap_match_arms) | \<boolean\><br>Default: true | Wrap multiline match arms in blocks|match句で一行式の時に冗長なblocksを取り除くか
| [match_block_trailing_comma](#match_block_trailing_comma) | \<boolean\><br>Default: false | Put a trailing comma after a block based match arm (non-block arms are not affected)|match句でblockに常にカンマを付けるか
| [match_wildcard_trailing_comma](#match_wildcard_trailing_comma) | \<boolean\><br>Default: true | Put a trailing comma after a wildcard arm|match句でwildcard指定(_)に常にカンマを付けるか
| write_mode | [Replace&#124;<br>Overwrite&#124;<br>Display&#124;<br>Diff&#124;<br>Coverage&#124;<br>Plain&#124;<br>Checkstyle] <br>Default: Replace | What Write Mode to use when none is supplied: Replace, Overwrite, Display, Diff, Coverage|結果をどうするか。Replace: ソースを置き換える、古いソースは.bkと付けて退避される、Overwrite: ソースを置き換える、Display: 結果に各対象ソース名やreport_todo・report_fixme結果を付与して標準出力へ出力する、Diff: 結果の差分を標準出力へ出力する、Plain: 結果をそのまま標準出力へ出力する、Coverage: ドキュメントコメントを残し、通常コメントやprintln!等のマクロに付けてるセミコロン等をXに変換する、マクロのセミコロンが対象になるのが理由不明


# 適用コードフォーマット一覧

コードのフォーマットと関係のあるオプションの適用例です、適用オプション以外はDefaultにしています。


## max_width

```rust
// max_width = 100
fn f(aaaaaa: i32, bbbbb: i32) -> i32
    where T: Foo
{
    3
}

// max_width = 50
fn f(aaaaaa: i32,
     bbbbb: i32)
     -> i32
    where T: Foo
{
    3
}

```


## tab_spaces

```rust
// tab_spaces = 4
fn main() {
    let x = 3;
}

// tab_spaced = 2
fn main() {
  let x = 3;
}
```


## fn_call_width

```rust
// fn_call_width = 21
fn main() {
    foo("fn", "call", "width");
}

// fn_call_width = 20
fn main() {
    foo("fn",
        "call",
        "width");
}
```


## struct_lit_width

```rust
// struct_lit_width = 16
fn main() {
    Hoge { a: "hoge", b: 12 };
}

// struct_lit_width = 15
fn main() {
    Hoge {
        a: "hoge",
        b: 12,
    };
}
```


## fn_brace_style

```rust
// fn_brace_style = "AlwaysNextLine"
fn f()
{
    3;
}
fn f2<T>()
    where T: Foo
{
    3;
}

// fn_brace_style = "PreferSameLine"
fn f() {
    3;
}
fn f<T>()
    where T: Foo {
    3;
}

// fn_brace_style = "SameLineWhere"
fn f() {
    3;
}
fn f<T>()
    where T: Foo
{
    3;
}
```


## item_brace_style

```rust
// item_brace_style = "AlwaysNextLine"
trait Trait
{
    fn f(&self) {}
}
trait Trait<T>
    where T: Foo
{
    fn f(&self) {}
}

// item_brace_style = "PreferSameLine"
trait Trait {
    fn f(&self) {}
}
trait Trait<T>
    where T: Foo {
    fn f(&self) {}
}

// item_brace_style = "SameLineWhere"
trait Trait {
    fn f(&self) {}
}
trait Trait<T>
    where T: Foo
{
    fn f(&self) {}
}
```


## impl_empty_single_line

```rust
// impl_empty_single_line = true
impl Trait {}
impl Trait<T> where T: Foo {}

// impl_empty_single_line = false
impl Trait {
}
impl Trait<T>
    where T: Foo
{
}
```

## fn_empty_single_line

```rust
// fn_empty_single_line = true
fn f() {}
fn f<T>() where T: Foo {}

// fn_empty_single_line = false
fn f() {
}
fn f<T>()
    where T: Foo
{
}
```


## fn_single_line

```rust
// fn_single_line = false
fn f() {
    foo();
}

// fn_single_line = true
fn f() { foo(); }
```


## fn_return_indent

```rust
// max_width = 40
// fn_return_indent = "WithArgs"
fn f<T>(aaa: T,
        bbb: i32,
        ccc: i32)
        -> i32
    where T: Foo
{
    3;
}

// max_width = 40
// fn_return_indent = "WithWhereClause"
fn f<T>(aaa: T,
        bbb: i32,
        ccc: i32)
    -> i32
    where T: Foo
{
    3;
}
```


## fn_args_paren_newline

```rust
// max_width = 18
// fn_args_paren_newline = true
fn long_long_func
    (aaa: i32,
     bbb: i32) {
    3;
}

// max_width = 18
// fn_args_paren_newline = false
fn long_long_func(
    aaa: i32,
    bbb: i32) {
    3;
}
```

## fn_args_density

```rust
// max_width = 39
// fn_args_density = "Compressed"
fn long_long_func(a: i32, b: i32,
                  c: i32) {
    3;
}
fn long_func(a: i32, b: i32, c: i32) {
    3;
}

// max_width = 39
// fn_args_density = "Tall" # same "CompressedIfEmpty"
fn long_long_func(a: i32,
                  b: i32,
                  c: i32) {
    3;
}
fn long_func(a: i32, b: i32, c: i32) {
    3;
}

// max_width = 39
// fn_args_density = "Vertical"
fn long_long_func(a: i32,
                  b: i32,
                  c: i32) {
    3;
}
fn long_func(a: i32,
             b: i32,
             c: i32) {
    3;
}
```


## fn_args_layout

```rust
// max_width = 39
// fn_args_layout = "Visual"
fn long_long_func(a: i32,
                  b: i32,
                  c: i32) {
    3;
}
fn long_func(a: i32, b: i32, c: i32) {
    3;
}

// max_width = 39
// fn_args_layout = "Block"
fn long_long_func(
    a: i32,
    b: i32,
    c: i32
) {
    3;
}
fn long_func(a: i32, b: i32, c: i32) {
    3;
}

// max_width = 39
// fn_args_layout = "BlockAlways"
fn long_long_func(
    a: i32,
    b: i32,
    c: i32
) {
    3;
}
fn long_func(
    a: i32, b: i32, c: i32
) {
    3;
}
```


## fn_arg_indent

```rust
// max_width = 39
// fn_arg_indent = "Inherit"
fn long_long_func(a: i32,
b: i32,
c: i32) {
    3;
}

// max_width = 39
// fn_arg_indent = "Tabbed"
fn long_long_func(a: i32,
    b: i32,
    c: i32) {
    3;
}

// max_width = 39
// fn_arg_indent = "Visual"
fn long_long_func(a: i32,
                  b: i32,
                  c: i32) {
    3;
}
```


## type_punctuation_density

```rust
// type_punctuation_density = "Compressed"
struct Hoge<T=Foo+std::marker::Copy> {
    x: T,
}

// type_punctuation_density = "Wide"
struct Hoge<T = Foo + std::marker::Copy> {
    x: T,
}
```


## where_density

```rust
// max_width = 39
// where_density = "Compressed"
trait LongLongTrait<T> where T: Foo {}
trait LongLongTrait<T> where T: Foo
{
    fn f(&self);
}
trait LongLongLongLongTrait<T>
    where T: Foo
{
}
trait LongLongLongLongTrait<T>
    where T: Foo
{
    fn f(&self);
}

// max_width = 39
// where_density = "Tall" # same "Vertical"
trait LongLongTrait<T>
    where T: Foo
{
}
trait LongLongTrait<T>
    where T: Foo
{
    fn f(&self);
}
trait LongLongLongLongTrait<T>
    where T: Foo
{
}
trait LongLongLongLongTrait<T>
    where T: Foo
{
    fn f(&self);
}

// max_width = 39
// where_density = "CompressedIfEmpty"
trait LongLongTrait<T> where T: Foo {}
trait LongLongTrait<T>
    where T: Foo
{
    fn f(&self);
}
trait LongLongLongLongTrait<T>
    where T: Foo
{
}
trait LongLongLongLongTrait<T>
    where T: Foo
{
    fn f(&self);
}
```


## where_indent

```rust
// where_indent = "Inherit"
trait Trait<T>
where T: Foo
{
    fn f(&self);
}

// where_indent = "Tabbed"
trait Trait<T>
    where T: Foo
{
    fn f(&self);
}

// where_indent = "Visual"
trait Trait<T>
    where T: Foo
{
    fn f(&self);
}
```


## where_layout

```rust
// max_width = 60
// where_layout = "Vertical"
fn f<TTT, UUU, VVV>(a: TTT, b: UUU, c: VVV)
    where TTT: Foo,
          UUU: Hoge,
          VVV: Piyo
{
    3;
}
fn f<TTTTTTTTTT, UUUUUUUUUU, VVVVVVVVVV>(a: TTTTTTTTTT,
                                         b: UUUUUUUUUU,
                                         c: VVVVVVVVVV)
    where TTTTTTTTTT: Foo,
          UUUUUUUUUU: Hoge,
          VVVVVVVVVV: Piyo
{
    3;
}

// max_width = 60
// where_layout = "HorizontalVertical"
fn f<TTT, UUU, VVV>(a: TTT, b: UUU, c: VVV)
    where TTT: Foo, UUU: Hoge, VVV: Piyo
{
    3;
}
fn f<TTTTTTTTTT, UUUUUUUUUU, VVVVVVVVVV>(a: TTTTTTTTTT,
                                         b: UUUUUUUUUU,
                                         c: VVVVVVVVVV)
    where TTTTTTTTTT: Foo,
          UUUUUUUUUU: Hoge,
          VVVVVVVVVV: Piyo
{
    3;
}

// max_width = 60
// where_layout = "Mixed"
fn f<TTT, UUU, VVV>(a: TTT, b: UUU, c: VVV)
    where TTT: Foo, UUU: Hoge, VVV: Piyo
{
    3;
}
fn f<TTTTTTTTTT, UUUUUUUUUU, VVVVVVVVVV>(a: TTTTTTTTTT,
                                         b: UUUUUUUUUU,
                                         c: VVVVVVVVVV)
    where TTTTTTTTTT: Foo, UUUUUUUUUU: Hoge,
          VVVVVVVVVV: Piyo
{
    3;
}

// max_width = 60
// where_layout = "Horizontal"
fn f<TTT, UUU, VVV>(a: TTT, b: UUU, c: VVV)
    where TTT: Foo, UUU: Hoge, VVV: Piyo
{
    3;
}
fn f<TTTTTTTTTT, UUUUUUUUUU, VVVVVVVVVV>(a: TTTTTTTTTT,
                                         b: UUUUUUUUUU,
                                         c: VVVVVVVVVV)
    where TTTTTTTTTT: Foo, UUUUUUUUUU: Hoge, VVVVVVVVVV: Piyo
{
    3;
}
```


## where_pred_indent

```rust
// where_pred_indent = "Inherit"
fn f<T, U, V>(a: T, b: U, c: V)
    where T: Foo,
    U: Hoge,
    V: Piyo
{
    3;
}

// where_pred_indent = "Tabbed"
fn f<T, U, V>(a: T, b: U, c: V)
    where T: Foo,
        U: Hoge,
        V: Piyo
{
    3;
}

// where_pred_indent = "Visual"
fn f<T, U, V>(a: T, b: U, c: V)
    where T: Foo,
          U: Hoge,
          V: Piyo
{
    3;
}
```


## where_trailing_comma

```rust
// where_trailing_comma = false
fn f<T, U, V>(a: T, b: U, c: V)
    where T: Foo,
          U: Hoge,
          V: Piyo
{
    3;
}

// where_trailing_comma = true
fn f<T, U, V>(a: T, b: U, c: V)
    where T: Foo,
          U: Hoge,
          V: Piyo,
{
    3;
}
```

## generics_indent

```rust
// max_width = 18
// generics_indent = "Inherit"
trait Trait<T,
U,
D>
    where T: Foo
{
}

// max_width = 18
// generics_indent = "Tabbed"
trait Trait<T,
    U,
    D>
    where T: Foo
{
}

// max_width = 18
// generics_indent = "Visual"
trait Trait<T,
            U,
            D>
    where T: Foo
{
}
```


## struct_trailing_comma

```rust
// struct_trailing_comma = "Always"  # same "Vertical"
struct Point {
    x: i32,
    y: i32,
}

// struct_trailing_comma = "Never"
struct Point {
    x: i32,
    y: i32
}
```

## struct_lit_trailing_comma

```rust
// struct_lit_trailing_comma = "Always"
fn main() {
    Hoge { a: "hoge", b: 12, };
    Hoge {
        long_a: "hoge",
        long_b: 12,
    };
}

// struct_lit_trailing_comma = "Never"
fn main() {
    Hoge { a: "hoge", b: 12 };
    Hoge {
        long_a: "hoge",
        long_b: 12
    };
}

// struct_lit_trailing_comma = "Vertical"
fn main() {
    Hoge { a: "hoge", b: 12 };
    Hoge {
        long_a: "hoge",
        long_b: 12,
    };
}
```

## struct_lit_style

```rust
// struct_lit_style = "Visual"
fn main() {
    Hoge { a: "hoge", b: 12 };
    Hoge { long_a: "hoge",
           long_b: 12, };
}

// struct_lit_style = "Block"
fn main() {
    Hoge { a: "hoge", b: 12 };
    Hoge {
        long_a: "hoge",
        long_b: 12,
    };
}
```


## struct_lit_multiline_style

```rust
// struct_lit_multiline_style = "PreferSingle"
fn main() {
    Hoge { a: "hoge", b: 12 };
    Hoge {
        long_a: "hoge",
        long_b: 12,
    };
}

// struct_lit_multiline_style = "ForceMulti"
fn main() {
    Hoge {
        a: "hoge",
        b: 12,
    };
    Hoge {
        long_a: "hoge",
        long_b: 12,
    };
}
```


## enum_trailing_comma

```rust
// enum_trailing_comma = true
enum Hoge {
    Foo,
    Piyo,
}

// enum_trailing_comma = false
enum Hoge {
    Foo,
    Piyo
}
```

## chain_base_indent

```rust
// chain_base_indent = "Inherit"
fn main() {
    let z = Foo {
        field1: val1,
        field2: val2,
    };

    let x = Foo {
        field1: val1,
        field2: val2,
    }
    .method_call()
    .method_call();

    let y = if cond {
        x
    } else {
        val2
    }
    .method_call();
}

// chain_base_indent = "Tabbed"
fn main() {
    let z = Foo {
        field1: val1,
        field2: val2,
    };

    let x = Foo {
            field1: val1,
            field2: val2,
        }
        .method_call()
        .method_call();

    let y = if cond {
            x
        } else {
            val2
        }
        .method_call();
}

// chain_base_indent = "Visual"
fn main() {
    let z = Foo {
        field1: val1,
        field2: val2,
    };

    let x = Foo {
                field1: val1,
                field2: val2,
            }
            .method_call()
            .method_call();

    let y = if cond {
                x
            } else {
                val2
            }
            .method_call();
}
```


## chain_indent

```rust
// chain_indent = "Inherit"
fn main() {
    let x = f().my_long_function()
               .my_even_longer_function()
               .do_it();

    let y = my_long_function()
    .my_even_longer_function()
    .do_it();
}

// chain_indent = "Tabbed"
fn main() {
    let x = f().my_long_function()
               .my_even_longer_function()
               .do_it();

    let y = my_long_function()
        .my_even_longer_function()
        .do_it();
}

// chain_indent = "Visual"
fn main() {
    let x = f().my_long_function()
               .my_even_longer_function()
               .do_it();

    let y = my_long_function()
                .my_even_longer_function()
                .do_it();
}
```


## reorder_imports

```rust
// reorder_imports = false
use {aa, ab, ac, b, Ab, Z};

// reorder_imports = true
use {Ab, Z, aa, ab, ac, b};
```


## single_line_if_else

```rust
// single_line_if_else = false
fn main() {
    let x = if 3 == 3 {
        "hoge"
    } else {
        "fuga"
    };
}

// single_line_if_else = true
fn main() {
    let x = if 3 == 3 { "hoge" } else { "fuga" };
}
```


## format_strings

```rust
// max_width = 18
// format_strings = false
mod m {
    fn f() {
        let s = "aasa aasaa";
    }

    mod m2 {
        fn f() {
            let s = "aasa aasaa";
        }
    }
}

fn main() {
    let s1 = "AAAA AAAAaAA AAA";
    let s2 = "AAAAAAAAAAAAAAaA";
}


// max_width = 18
// format_strings = true
mod m {
    fn f() {
        let s =
            "aasa \
             aasaa";
    }

    mod m2 {
        fn f() {
            let s = "aasa aasaa";
        }
    }
}

fn main() {
    let s1 = "AAAA \
              AAAAaAA \
              AAA";
    let s2 = "AAAAAAAAAAAAAAaA";
}
```


## force_format_strings

```rust
// force_format_strings = false
fn main() {
    let expected = "
        ; Function Attrs: nounwind
        declare void @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) #0
        declare i32 @write(i32, i8*, i32)
        declare i32 @putchar(i32)
        declare i32 @getchar()
        define i32 @main() {
            entry:
              ret i32 0
        }
        attributes #0 = { nounwind }
    ";
}

// force_format_strings = true
fn main() {
    let expected = "
        ; Function Attrs: nounwind
        declare void \
                    @llvm.memset.p0i8.i32(i8* nocapture, i8, i32, i32, i1) #0
        declare i32 \
                    @write(i32, i8*, i32)
        declare i32 @putchar(i32)
        declare i32 \
                    @getchar()
        define i32 @main() {
            entry:
              ret \
                    i32 0
        }
        attributes #0 = { nounwind }
    ";
}
```


## chains_overflow_last

```rust
// chains_overflow_last = true
fn main() {
    x().y(|| match cond() {
        true => (),
        false => (),
    });

    loong_func().quux(move || if true {
        1
    } else {
        2
    });

    fffffffffffffffffff(a, {
        SCRIPT_TASK_ROOT.with(|root| {
            *root.borrow_mut() = Some(&script_task);
        });
    });
}

// chains_overflow_last = false
fn main() {
    x().y(|| match cond() {
           true => (),
           false => (),
       });

    loong_func()
        .quux(move || if true {
            1
        } else {
            2
        });

    fffffffffffffffffff(a,
                        {
                            SCRIPT_TASK_ROOT.with(|root| {
                                                *root.borrow_mut() = Some(&script_task);
                                            });
                        });
}
```


## take_source_hints

```rust
// take_source_hints = true
fn main() {
    // 改行してるならそれを維持
    a.b
     .c
     .d();
    a.b.c.d();
}

// take_source_hints = false
fn main() {
    a.b.c.d();
    a.b.c.d();
}
```


## hard_tabs

```rust
// hard_tabs = false
fn main() {
    // indentがスペース
    3;
}

// hard_tabs = true
fn main() {
	// indentがタブ
	3;
}
```


## wrap_comments

```rust
// max_width = 30
// wrap_comments = false
fn main() {
    // looooooooooooooooooooooooooong comment
}

// max_width = 30
// wrap_comments = true
fn main() {
    // looooooooooooooooooooooooooong
    // comment
}
```


## normalise_comments

```rust
// normalise_comments = false
fn main() {
    /* normal comment
     * abc
     * def
     * */
}

// normalise_comments = true
fn main() {
    // normal comment
    // abc
    // def
    //
}
```


## wrap_match_arms

```rust
// wrap_match_arms = false
fn main() {
    match x {
        a => {
            "line1"
        }
        _ => {
            "other"
        }
    }
}

// wrap_match_arms = true
fn main() {
    match x {
        a => "line1",
        _ => "other",
    }
}
```


## match_block_trailing_comma

```rust
// wrap_match_arms = false
// match_block_trailing_comma = false
fn main() {
    match x {
        a => {
            "line1"
        }
        _ => {
            "other"
        }
    }
}

// wrap_match_arms = false
// match_block_trailing_comma = true
fn main() {
    match x {
        a => {
            "line1"
        },
        _ => {
            "other"
        },
    }
}
```


## match_wildcard_trailing_comma

```rust
// match_wildcard_trailing_comma = false
fn main() {
    match x {
        a => "line1",
        _ => "other"
    }
}

// match_wildcard_trailing_comma = true
fn main() {
    match x {
        a => "line1",
        _ => "other",
    }
}
```


# 参考

* [rustfmt](https://github.com/rust-lang-nursery/rustfmt)のソースコード