入力値の処理をtraitで書いてみる

元ネタ： [Rustで競技プログラミング スターターキット](https://qiita.com/hatoo@github/items/fa14ad36a1b568d14f3e#%E3%83%9E%E3%82%AF%E3%83%AD%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%8B)

マクロで書く必要がない部分もマクロで書いてるのでtraitに直してみる

```rust
use std::io::stdin;
use std::str::FromStr;
use std::error::Error;

pub type Result<T> = ::std::result::Result<T, Box<Error>>;

pub trait Get: Sized {
    fn get() -> Result<Self>;
    fn getn(n: usize) -> Result<Vec<Self>> {
        (0..n).map(|_| Self::get()).collect()
    }
}

fn read() -> Vec<String> {
    let mut line = String::new();
    stdin().read_line(&mut line).unwrap();
    line.split_whitespace().map(|s| s.to_string()).collect()
}

impl<T: FromStr> Get for (T,)
where
    T::Err: 'static + Error,
{
    fn get() -> Result<Self> {
        Ok((read()[0].trim().parse()?,))
    }
}

impl<T1: FromStr, T2: FromStr> Get for (T1, T2)
where
    T1::Err: 'static + Error,
    T2::Err: 'static + Error,
{
    fn get() -> Result<Self> {
        let val = read();
        Ok((val[0].trim().parse()?, val[1].trim().parse()?))
    }
}

fn main() {
    let (a,) = <(usize,)>::get().unwrap();
    let (b, c) = <(u32, f32)>::get().unwrap();
    println!("a = {}", a);
    println!("b = {}", b);
    println!("c = {}", c);
}
```

これで以下のように実行できる：

```
cargo run << EOF
2
3 1.1
EOF
```

出力：

```
a = 2
b = 3
c = 1.1
```

よくわかる解説
-------------

※特にわかりやすくはありません

```rust
let a = <usize>::get().unwrap();
let (b, c) = <(u32, f32)>::get().unwrap();
```

方針としてはまずこの形で書けることを想定します。元のネタで`q`個取得するのがあるので`getn(q: usize)`関数もあります。`Iterator<Result<T>>`は`Result<Vec<T>>`に`collect()`できるので簡単に書けますね。
エラーは`get()`内で`unwrap()`してしまってもいいですが、`Box<Error>`として適当に括るのもいいでしょう：

```rust
use std::error::Error;
pub type Result<T> = ::std::result::Result<T, Box<Error>>;
```

さて、`get()`をどうやって書くかです。様々な型に読み込む必要があるため、`get() -> Self`型の関数を持つtraitを定義しましょう：

```rust
pub trait Get: Sized {
    fn get() -> Result<Self>;
    ...
}
```

`Self`自身が戻り値になるので`Self: Sized`である必要があります。
一つの場合には落とし穴があるので、まず2つの場合を考えてみましょう：

```rust
impl<T1: FromStr, T2: FromStr> Get for (T1, T2)
where
    T1::Err: 'static + Error,
    T2::Err: 'static + Error,
{ ... }
```

なにかゴテゴテしいのが来ましたね(´・ω・｀)
でも特に難しいわけではないので安心してください。まず`String`からパースするには`T: FromStr`である必要があります：

```rust
pub trait FromStr {
    type Err;
    fn from_str(s: &str) -> Result<Self, Self::Err>;
}
```

なんかtrait自体に`Err`型がついてますね。これは関連型と言って、`T: FromStr`なら常に`T::Err`という型が定義されていることが保証されているということです。`from_str()`関数はパースに失敗した場合、整数型なら`ParseIntError`、浮動小数なら`ParseFloatError`を返しますが、この辺の違いを`Err`で吸収してるわけです。今はエラーは全部`Box<Error>`に変換してしまいたいので、この変換を保証する必要があります。それが`T::Err: 'static + Error` の部分で、`T::Err`が静的な型で、`Error` traitを実装していることを保証する、という制約です。この辺は雰囲気で書いたらコンパイラが付けてって言ってくれます(*'▽')

次に一つの場合を考えてみましょう。

```rust
impl<T: FromStr> Get for T
where
    T::Err: 'static + Error,
{ ... }
```

こうしようと思いますよね？でもこれではダメなんです。`T`が`(T1, T2)`と一致する可能性があるので、この定義は2個の場合の定義と衝突してコンパイルエラーになります。なので要素が一つのタプルとしてマッチさせます：

```rust
impl<T: FromStr> Get for (T,)
where
    T::Err: 'static + Error,
{ ... }
```

これだと`(T1, T2)`と衝突する可能性がないので無事定義できますが、インターフェースを変える必要があります：

```rust
let (a,) = <(usize,)>::get().unwrap();
```

こういう落とし穴はだいたい2個の場合を書いたときに気付くわけです(´・ω・｀)

上の例では2個までしかパースできず、3個以上の値をパースする場合は`(T1, T2, T3)`のパーサを書く必要があります。このあたりはC++の可変長テンプレートに慣れてる人は呪いの言葉が出てくるところですが、現状無理なので仕方がありません。この`impl`部分をマクロで生成するのが行儀のよいマクロの使い方かと思います。そうすればライブラリとして外部に見える部分にはマクロが含まれず`Get` traitだけが見えることになります。

最後に
-------

マクロは用法用量を守って正しく使いましょう(/・ω・)/